OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/func-name-inferrer.h" | 8 #include "src/func-name-inferrer.h" |
9 #include "src/hashmap.h" | 9 #include "src/hashmap.h" |
10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 // }; | 54 // }; |
55 // // ... | 55 // // ... |
56 // }; | 56 // }; |
57 | 57 |
58 template <typename Traits> | 58 template <typename Traits> |
59 class ParserBase : public Traits { | 59 class ParserBase : public Traits { |
60 public: | 60 public: |
61 // Shorten type names defined by Traits. | 61 // Shorten type names defined by Traits. |
62 typedef typename Traits::Type::Expression ExpressionT; | 62 typedef typename Traits::Type::Expression ExpressionT; |
63 typedef typename Traits::Type::Identifier IdentifierT; | 63 typedef typename Traits::Type::Identifier IdentifierT; |
| 64 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
64 | 65 |
65 ParserBase(Scanner* scanner, uintptr_t stack_limit, | 66 ParserBase(Scanner* scanner, uintptr_t stack_limit, |
66 v8::Extension* extension, | 67 v8::Extension* extension, |
67 ParserRecorder* log, | 68 ParserRecorder* log, |
68 typename Traits::Type::Zone* zone, | 69 typename Traits::Type::Zone* zone, |
69 typename Traits::Type::Parser this_object) | 70 typename Traits::Type::Parser this_object) |
70 : Traits(this_object), | 71 : Traits(this_object), |
71 parenthesized_function_(false), | 72 parenthesized_function_(false), |
72 scope_(NULL), | 73 scope_(NULL), |
73 function_state_(NULL), | 74 function_state_(NULL), |
74 extension_(extension), | 75 extension_(extension), |
75 fni_(NULL), | 76 fni_(NULL), |
76 log_(log), | 77 log_(log), |
77 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
78 scanner_(scanner), | 79 scanner_(scanner), |
79 stack_limit_(stack_limit), | 80 stack_limit_(stack_limit), |
80 stack_overflow_(false), | 81 stack_overflow_(false), |
81 allow_lazy_(false), | 82 allow_lazy_(false), |
82 allow_natives_syntax_(false), | 83 allow_natives_syntax_(false), |
83 allow_generators_(false), | 84 allow_generators_(false), |
84 allow_for_of_(false), | 85 allow_for_of_(false), |
| 86 allow_arrow_functions_(false), |
85 zone_(zone) { } | 87 zone_(zone) { } |
86 | 88 |
87 // Getters that indicate whether certain syntactical constructs are | 89 // Getters that indicate whether certain syntactical constructs are |
88 // allowed to be parsed by this instance of the parser. | 90 // allowed to be parsed by this instance of the parser. |
89 bool allow_lazy() const { return allow_lazy_; } | 91 bool allow_lazy() const { return allow_lazy_; } |
90 bool allow_natives_syntax() const { return allow_natives_syntax_; } | 92 bool allow_natives_syntax() const { return allow_natives_syntax_; } |
91 bool allow_generators() const { return allow_generators_; } | 93 bool allow_generators() const { return allow_generators_; } |
92 bool allow_for_of() const { return allow_for_of_; } | 94 bool allow_for_of() const { return allow_for_of_; } |
| 95 bool allow_arrow_functions() const { return allow_arrow_functions_; } |
93 bool allow_modules() const { return scanner()->HarmonyModules(); } | 96 bool allow_modules() const { return scanner()->HarmonyModules(); } |
94 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
95 bool allow_harmony_numeric_literals() const { | 98 bool allow_harmony_numeric_literals() const { |
96 return scanner()->HarmonyNumericLiterals(); | 99 return scanner()->HarmonyNumericLiterals(); |
97 } | 100 } |
98 | 101 |
99 // Setters that determine whether certain syntactical constructs are | 102 // Setters that determine whether certain syntactical constructs are |
100 // allowed to be parsed by this instance of the parser. | 103 // allowed to be parsed by this instance of the parser. |
101 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 104 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
102 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 105 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
103 void set_allow_generators(bool allow) { allow_generators_ = allow; } | 106 void set_allow_generators(bool allow) { allow_generators_ = allow; } |
104 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 107 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
| 108 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } |
105 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 109 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
106 void set_allow_harmony_scoping(bool allow) { | 110 void set_allow_harmony_scoping(bool allow) { |
107 scanner()->SetHarmonyScoping(allow); | 111 scanner()->SetHarmonyScoping(allow); |
108 } | 112 } |
109 void set_allow_harmony_numeric_literals(bool allow) { | 113 void set_allow_harmony_numeric_literals(bool allow) { |
110 scanner()->SetHarmonyNumericLiterals(allow); | 114 scanner()->SetHarmonyNumericLiterals(allow); |
111 } | 115 } |
112 | 116 |
113 protected: | 117 protected: |
114 enum AllowEvalOrArgumentsAsIdentifier { | 118 enum AllowEvalOrArgumentsAsIdentifier { |
(...skipping 29 matching lines...) Expand all Loading... |
144 }; | 148 }; |
145 | 149 |
146 class FunctionState BASE_EMBEDDED { | 150 class FunctionState BASE_EMBEDDED { |
147 public: | 151 public: |
148 FunctionState( | 152 FunctionState( |
149 FunctionState** function_state_stack, | 153 FunctionState** function_state_stack, |
150 typename Traits::Type::Scope** scope_stack, | 154 typename Traits::Type::Scope** scope_stack, |
151 typename Traits::Type::Scope* scope, | 155 typename Traits::Type::Scope* scope, |
152 typename Traits::Type::Zone* zone = NULL, | 156 typename Traits::Type::Zone* zone = NULL, |
153 AstValueFactory* ast_value_factory = NULL); | 157 AstValueFactory* ast_value_factory = NULL); |
| 158 FunctionState( |
| 159 FunctionState** function_state_stack, |
| 160 typename Traits::Type::Scope** scope_stack, |
| 161 typename Traits::Type::Scope** scope, |
| 162 typename Traits::Type::Zone* zone, |
| 163 AstValueFactory* ast_value_factory); |
154 ~FunctionState(); | 164 ~FunctionState(); |
155 | 165 |
156 int NextMaterializedLiteralIndex() { | 166 int NextMaterializedLiteralIndex() { |
157 return next_materialized_literal_index_++; | 167 return next_materialized_literal_index_++; |
158 } | 168 } |
159 int materialized_literal_count() { | 169 int materialized_literal_count() { |
160 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; | 170 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
161 } | 171 } |
162 | 172 |
163 int NextHandlerIndex() { return next_handler_index_++; } | 173 int NextHandlerIndex() { return next_handler_index_++; } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 337 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
328 Scanner::Location octal = scanner()->octal_position(); | 338 Scanner::Location octal = scanner()->octal_position(); |
329 if (octal.IsValid() && beg_pos <= octal.beg_pos && | 339 if (octal.IsValid() && beg_pos <= octal.beg_pos && |
330 octal.end_pos <= end_pos) { | 340 octal.end_pos <= end_pos) { |
331 ReportMessageAt(octal, "strict_octal_literal"); | 341 ReportMessageAt(octal, "strict_octal_literal"); |
332 scanner()->clear_octal_position(); | 342 scanner()->clear_octal_position(); |
333 *ok = false; | 343 *ok = false; |
334 } | 344 } |
335 } | 345 } |
336 | 346 |
| 347 // Validates strict mode for function parameter lists. This has to be |
| 348 // done after parsing the function, since the function can declare |
| 349 // itself strict. |
| 350 void CheckStrictFunctionNameAndParameters( |
| 351 IdentifierT function_name, |
| 352 bool function_name_is_strict_reserved, |
| 353 const Scanner::Location& function_name_loc, |
| 354 const Scanner::Location& eval_args_error_loc, |
| 355 const Scanner::Location& dupe_error_loc, |
| 356 const Scanner::Location& reserved_loc, |
| 357 bool* ok) { |
| 358 if (this->IsEvalOrArguments(function_name)) { |
| 359 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments"); |
| 360 *ok = false; |
| 361 return; |
| 362 } |
| 363 if (function_name_is_strict_reserved) { |
| 364 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved"); |
| 365 *ok = false; |
| 366 return; |
| 367 } |
| 368 if (eval_args_error_loc.IsValid()) { |
| 369 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); |
| 370 *ok = false; |
| 371 return; |
| 372 } |
| 373 if (dupe_error_loc.IsValid()) { |
| 374 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe"); |
| 375 *ok = false; |
| 376 return; |
| 377 } |
| 378 if (reserved_loc.IsValid()) { |
| 379 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); |
| 380 *ok = false; |
| 381 return; |
| 382 } |
| 383 } |
| 384 |
337 // Determine precedence of given token. | 385 // Determine precedence of given token. |
338 static int Precedence(Token::Value token, bool accept_IN) { | 386 static int Precedence(Token::Value token, bool accept_IN) { |
339 if (token == Token::IN && !accept_IN) | 387 if (token == Token::IN && !accept_IN) |
340 return 0; // 0 precedence will terminate binary expression parsing | 388 return 0; // 0 precedence will terminate binary expression parsing |
341 return Token::Precedence(token); | 389 return Token::Precedence(token); |
342 } | 390 } |
343 | 391 |
344 typename Traits::Type::Factory* factory() { | 392 typename Traits::Type::Factory* factory() { |
345 return function_state_->factory(); | 393 return function_state_->factory(); |
346 } | 394 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 445 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
398 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 446 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
399 ExpressionT ParseUnaryExpression(bool* ok); | 447 ExpressionT ParseUnaryExpression(bool* ok); |
400 ExpressionT ParsePostfixExpression(bool* ok); | 448 ExpressionT ParsePostfixExpression(bool* ok); |
401 ExpressionT ParseLeftHandSideExpression(bool* ok); | 449 ExpressionT ParseLeftHandSideExpression(bool* ok); |
402 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 450 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
403 ExpressionT ParseMemberExpression(bool* ok); | 451 ExpressionT ParseMemberExpression(bool* ok); |
404 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 452 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
405 bool* ok); | 453 bool* ok); |
406 | 454 |
| 455 // There are two ways of parsing arrow functions: if the beginning of an |
| 456 // arrow function can be determined prior to process the parameter list |
| 457 // (e.g. the current scanning position is known to be an arrow function |
| 458 // and not an AssignmentExpression) then the first version is used. In |
| 459 // most cases, we parse the parameter list as an AssignmentExpression |
| 460 // and interpret the AST when the arrow "=>" token is found, using the |
| 461 // second version. |
| 462 // The overloaded ParseArrowFunctionLiteral() functions mainly deal with |
| 463 // parsing/interpreting the parameter list, and then they both call |
| 464 // ParseArrowFunctionLiteralBody() before consuming the arrow token. |
| 465 ExpressionT ParseArrowFunctionLiteral(bool* ok); |
| 466 ExpressionT ParseArrowFunctionLiteral(int start_pos, |
| 467 ExpressionT params_ast, |
| 468 bool* ok); |
| 469 ExpressionT ParseArrowFunctionLiteralBody( |
| 470 FunctionState* function_state, |
| 471 typename Traits::Type::ScopePtr scope, |
| 472 int num_parameters, |
| 473 const Scanner::Location& eval_args_error_loc, |
| 474 const Scanner::Location& dupe_error_loc, |
| 475 const Scanner::Location& reserved_loc, |
| 476 FunctionLiteral::IsParenthesizedFlag parenthesized, |
| 477 int start_pos, |
| 478 bool* ok); |
| 479 |
407 // Checks if the expression is a valid reference expression (e.g., on the | 480 // Checks if the expression is a valid reference expression (e.g., on the |
408 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 481 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
409 // we allow calls for web compatibility and rewrite them to a runtime throw. | 482 // we allow calls for web compatibility and rewrite them to a runtime throw. |
410 ExpressionT CheckAndRewriteReferenceExpression( | 483 ExpressionT CheckAndRewriteReferenceExpression( |
411 ExpressionT expression, | 484 ExpressionT expression, |
412 Scanner::Location location, const char* message, bool* ok); | 485 Scanner::Location location, const char* message, bool* ok); |
413 | 486 |
414 // Used to detect duplicates in object literals. Each of the values | 487 // Used to detect duplicates in object literals. Each of the values |
415 // kGetterProperty, kSetterProperty and kValueProperty represents | 488 // kGetterProperty, kSetterProperty and kValueProperty represents |
416 // a type of object literal property. When parsing a property, its | 489 // a type of object literal property. When parsing a property, its |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 | 553 |
481 private: | 554 private: |
482 Scanner* scanner_; | 555 Scanner* scanner_; |
483 uintptr_t stack_limit_; | 556 uintptr_t stack_limit_; |
484 bool stack_overflow_; | 557 bool stack_overflow_; |
485 | 558 |
486 bool allow_lazy_; | 559 bool allow_lazy_; |
487 bool allow_natives_syntax_; | 560 bool allow_natives_syntax_; |
488 bool allow_generators_; | 561 bool allow_generators_; |
489 bool allow_for_of_; | 562 bool allow_for_of_; |
| 563 bool allow_arrow_functions_; |
490 | 564 |
491 typename Traits::Type::Zone* zone_; // Only used by Parser. | 565 typename Traits::Type::Zone* zone_; // Only used by Parser. |
492 }; | 566 }; |
493 | 567 |
494 | 568 |
495 class PreParserIdentifier { | 569 class PreParserIdentifier { |
496 public: | 570 public: |
497 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 571 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
498 static PreParserIdentifier Default() { | 572 static PreParserIdentifier Default() { |
499 return PreParserIdentifier(kUnknownIdentifier); | 573 return PreParserIdentifier(kUnknownIdentifier); |
500 } | 574 } |
501 static PreParserIdentifier Eval() { | 575 static PreParserIdentifier Eval() { |
502 return PreParserIdentifier(kEvalIdentifier); | 576 return PreParserIdentifier(kEvalIdentifier); |
503 } | 577 } |
504 static PreParserIdentifier Arguments() { | 578 static PreParserIdentifier Arguments() { |
505 return PreParserIdentifier(kArgumentsIdentifier); | 579 return PreParserIdentifier(kArgumentsIdentifier); |
506 } | 580 } |
507 static PreParserIdentifier FutureReserved() { | 581 static PreParserIdentifier FutureReserved() { |
508 return PreParserIdentifier(kFutureReservedIdentifier); | 582 return PreParserIdentifier(kFutureReservedIdentifier); |
509 } | 583 } |
510 static PreParserIdentifier FutureStrictReserved() { | 584 static PreParserIdentifier FutureStrictReserved() { |
511 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 585 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
512 } | 586 } |
513 static PreParserIdentifier Yield() { | 587 static PreParserIdentifier Yield() { |
514 return PreParserIdentifier(kYieldIdentifier); | 588 return PreParserIdentifier(kYieldIdentifier); |
515 } | 589 } |
516 bool IsEval() { return type_ == kEvalIdentifier; } | 590 bool IsEval() const { return type_ == kEvalIdentifier; } |
517 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 591 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
518 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 592 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } |
519 bool IsYield() { return type_ == kYieldIdentifier; } | 593 bool IsYield() const { return type_ == kYieldIdentifier; } |
520 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 594 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } |
521 bool IsFutureStrictReserved() { | 595 bool IsFutureStrictReserved() const { |
522 return type_ == kFutureStrictReservedIdentifier; | 596 return type_ == kFutureStrictReservedIdentifier; |
523 } | 597 } |
524 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 598 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } |
525 | 599 |
| 600 // Allow identifier->name()[->length()] to work. The preparser |
| 601 // does not need the actual positions/lengths of the identifiers. |
| 602 const PreParserIdentifier* operator->() const { return this; } |
| 603 const PreParserIdentifier raw_name() const { return *this; } |
| 604 |
| 605 int position() const { |
| 606 return 0; |
| 607 } |
| 608 |
| 609 int length() const { |
| 610 if (IsEval()) return 4; |
| 611 if (IsArguments()) return 9; |
| 612 if (IsYield()) return 5; |
| 613 return 0; |
| 614 } |
| 615 |
526 private: | 616 private: |
527 enum Type { | 617 enum Type { |
528 kUnknownIdentifier, | 618 kUnknownIdentifier, |
529 kFutureReservedIdentifier, | 619 kFutureReservedIdentifier, |
530 kFutureStrictReservedIdentifier, | 620 kFutureStrictReservedIdentifier, |
531 kYieldIdentifier, | 621 kYieldIdentifier, |
532 kEvalIdentifier, | 622 kEvalIdentifier, |
533 kArgumentsIdentifier | 623 kArgumentsIdentifier |
534 }; | 624 }; |
535 explicit PreParserIdentifier(Type type) : type_(type) {} | 625 explicit PreParserIdentifier(Type type) : type_(type) {} |
536 Type type_; | 626 Type type_; |
537 | 627 |
538 friend class PreParserExpression; | 628 friend class PreParserExpression; |
| 629 friend class PreParserScope; |
539 }; | 630 }; |
540 | 631 |
541 | 632 |
542 // Bits 0 and 1 are used to identify the type of expression: | 633 // Bits 0 and 1 are used to identify the type of expression: |
543 // If bit 0 is set, it's an identifier. | 634 // If bit 0 is set, it's an identifier. |
544 // if bit 1 is set, it's a string literal. | 635 // if bit 1 is set, it's a string literal. |
545 // If neither is set, it's no particular type, and both set isn't | 636 // If neither is set, it's no particular type, and both set isn't |
546 // use yet. | 637 // use yet. |
547 class PreParserExpression { | 638 class PreParserExpression { |
548 public: | 639 public: |
549 static PreParserExpression Default() { | 640 static PreParserExpression Default() { |
550 return PreParserExpression(kUnknownExpression); | 641 return PreParserExpression(kUnknownExpression); |
551 } | 642 } |
552 | 643 |
553 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 644 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
554 return PreParserExpression(kIdentifierFlag | | 645 return PreParserExpression(kTypeIdentifier | |
555 (id.type_ << kIdentifierShift)); | 646 (id.type_ << kIdentifierShift)); |
556 } | 647 } |
557 | 648 |
| 649 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 650 PreParserExpression right) { |
| 651 int left_bits = left.BinaryOperationBits(); |
| 652 int right_bits = right.BinaryOperationBits(); |
| 653 |
| 654 int code = left_bits | right_bits; |
| 655 if (left_bits & right_bits & kBinaryOperationHasEval) |
| 656 code |= kBinaryOperationHasDuplicatedIdentifier; |
| 657 else if (left_bits & right_bits & kBinaryOperationHasArguments) |
| 658 code |= kBinaryOperationHasDuplicatedIdentifier; |
| 659 // TODO(aperezdc): Handle other duplicate identifier |
| 660 |
| 661 return PreParserExpression(kTypeBinaryOperation | code); |
| 662 } |
| 663 |
558 static PreParserExpression StringLiteral() { | 664 static PreParserExpression StringLiteral() { |
559 return PreParserExpression(kUnknownStringLiteral); | 665 return PreParserExpression(kUnknownStringLiteral); |
560 } | 666 } |
561 | 667 |
562 static PreParserExpression UseStrictStringLiteral() { | 668 static PreParserExpression UseStrictStringLiteral() { |
563 return PreParserExpression(kUseStrictString); | 669 return PreParserExpression(kUseStrictString); |
564 } | 670 } |
565 | 671 |
566 static PreParserExpression This() { | 672 static PreParserExpression This() { |
567 return PreParserExpression(kThisExpression); | 673 return PreParserExpression(kThisExpression); |
568 } | 674 } |
569 | 675 |
570 static PreParserExpression ThisProperty() { | 676 static PreParserExpression ThisProperty() { |
571 return PreParserExpression(kThisPropertyExpression); | 677 return PreParserExpression(kThisPropertyExpression); |
572 } | 678 } |
573 | 679 |
574 static PreParserExpression Property() { | 680 static PreParserExpression Property() { |
575 return PreParserExpression(kPropertyExpression); | 681 return PreParserExpression(kPropertyExpression); |
576 } | 682 } |
577 | 683 |
578 static PreParserExpression Call() { | 684 static PreParserExpression Call() { |
579 return PreParserExpression(kCallExpression); | 685 return PreParserExpression(kCallExpression); |
580 } | 686 } |
581 | 687 |
582 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } | 688 bool IsIdentifier() const { |
| 689 return (code_ & kTypeMask) == kTypeIdentifier; |
| 690 } |
583 | 691 |
584 PreParserIdentifier AsIdentifier() { | 692 PreParserIdentifier AsIdentifier() const { |
585 ASSERT(IsIdentifier()); | 693 ASSERT(IsIdentifier()); |
586 return PreParserIdentifier( | 694 return PreParserIdentifier( |
587 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 695 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); |
588 } | 696 } |
589 | 697 |
590 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 698 bool IsStringLiteral() const { |
| 699 return (code_ & kTypeMask) == kTypeStringLiteral; |
| 700 } |
591 | 701 |
592 bool IsUseStrictLiteral() { | 702 bool IsUseStrictLiteral() { |
593 return (code_ & kStringLiteralMask) == kUseStrictString; | 703 return (code_ & kUseStrictString) == kUseStrictString; |
594 } | 704 } |
595 | 705 |
596 bool IsThis() { return code_ == kThisExpression; } | 706 bool IsThis() { return code_ == kThisExpression; } |
597 | 707 |
598 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 708 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
599 | 709 |
600 bool IsProperty() { | 710 bool IsProperty() { |
601 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 711 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
602 } | 712 } |
603 | 713 |
604 bool IsCall() { return code_ == kCallExpression; } | 714 bool IsCall() { return code_ == kCallExpression; } |
605 | 715 |
606 bool IsValidReferenceExpression() { | 716 bool IsValidReferenceExpression() { |
607 return IsIdentifier() || IsProperty(); | 717 return IsIdentifier() || IsProperty(); |
608 } | 718 } |
609 | 719 |
610 // At the moment PreParser doesn't track these expression types. | 720 // At the moment PreParser doesn't track these expression types. |
611 bool IsFunctionLiteral() const { return false; } | 721 bool IsFunctionLiteral() const { return false; } |
612 bool IsCallNew() const { return false; } | 722 bool IsCallNew() const { return false; } |
613 | 723 |
614 PreParserExpression AsFunctionLiteral() { return *this; } | 724 PreParserExpression AsFunctionLiteral() { return *this; } |
615 | 725 |
| 726 bool IsBinaryOperation() const { |
| 727 return (code_ & kTypeMask) == kTypeBinaryOperation; |
| 728 } |
| 729 |
616 // Dummy implementation for making expression->somefunc() work in both Parser | 730 // Dummy implementation for making expression->somefunc() work in both Parser |
617 // and PreParser. | 731 // and PreParser. |
618 PreParserExpression* operator->() { return this; } | 732 PreParserExpression* operator->() { return this; } |
619 | 733 |
620 // More dummy implementations of things PreParser doesn't need to track: | 734 // More dummy implementations of things PreParser doesn't need to track: |
621 void set_index(int index) {} // For YieldExpressions | 735 void set_index(int index) {} // For YieldExpressions |
622 void set_parenthesized() {} | 736 void set_parenthesized() {} |
623 | 737 |
| 738 int position() const { return RelocInfo::kNoPosition; } |
| 739 void set_function_token_position(int position) {} |
| 740 void set_ast_properties(int* ast_properties) {} |
| 741 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} |
| 742 |
| 743 bool HasEval() const { |
| 744 if (IsBinaryOperation()) return (code_ & kBinaryOperationHasEval) != 0; |
| 745 if (IsIdentifier()) return AsIdentifier().IsEval(); |
| 746 return false; |
| 747 } |
| 748 |
| 749 bool HasArguments() const { |
| 750 if (IsBinaryOperation()) return (code_ & kBinaryOperationHasArguments) != 0; |
| 751 if (IsIdentifier()) return AsIdentifier().IsArguments(); |
| 752 return false; |
| 753 } |
| 754 |
| 755 bool HasFutureStrictReserved() const { |
| 756 if (IsBinaryOperation()) |
| 757 return (code_ & kBinaryOperationHasFutureStrictReserved) != 0; |
| 758 if (IsIdentifier()) |
| 759 return (AsIdentifier().IsFutureStrictReserved() || |
| 760 AsIdentifier().IsYield()); |
| 761 return false; |
| 762 } |
| 763 bool HasDuplicatedIdentifier() const { |
| 764 return IsBinaryOperation() && |
| 765 (code_ & kBinaryOperationHasDuplicatedIdentifier) != 0; |
| 766 } |
| 767 |
| 768 bool operator==(const PreParserExpression& other) const { |
| 769 return code_ == other.code_; |
| 770 } |
| 771 bool operator!=(const PreParserExpression& other) const { |
| 772 return code_ != other.code_; |
| 773 } |
| 774 |
624 private: | 775 private: |
625 // Least significant 2 bits are used as flags. Bits 0 and 1 represent | 776 // Least significant 2 bits are used as expression type. If the expression |
626 // identifiers or strings literals, and are mutually exclusive, but can both | 777 // is an identifier or a string literal, the other bits describe the type |
627 // be absent. If the expression is an identifier or a string literal, the | 778 // (see PreParserIdentifier::Type and string literal constants below). For |
628 // other bits describe the type (see PreParserIdentifier::Type and string | 779 // binary operations, the other bits are flags which further describe the |
629 // literal constants below). | 780 // contents of the expression. |
630 enum { | 781 enum { |
631 kUnknownExpression = 0, | 782 kUnknownExpression = 0, |
| 783 |
| 784 kTypeMask = 1 | 2, |
| 785 |
632 // Identifiers | 786 // Identifiers |
633 kIdentifierFlag = 1, // Used to detect labels. | 787 kTypeIdentifier = 1, // Used to detect labels. |
634 kIdentifierShift = 3, | 788 kIdentifierShift = 3, |
635 | 789 |
636 kStringLiteralFlag = 2, // Used to detect directive prologue. | 790 kTypeStringLiteral = 2, // Used to detect directive prologue. |
637 kUnknownStringLiteral = kStringLiteralFlag, | 791 kUnknownStringLiteral = kTypeStringLiteral, |
638 kUseStrictString = kStringLiteralFlag | 8, | 792 kUseStrictString = kTypeStringLiteral | 8, |
639 kStringLiteralMask = kUseStrictString, | 793 kStringLiteralMask = kUseStrictString, |
640 | 794 |
| 795 // Binary operations. Those are needed to detect certain keywords and |
| 796 // duplicated identifier in parameter lists for arrow functions, because |
| 797 // they are initially parsed as comma-separated expressions. |
| 798 kTypeBinaryOperation = 3, |
| 799 kBinaryOperationHasEval = 1 << 2, |
| 800 kBinaryOperationHasArguments = 2 << 2, |
| 801 kBinaryOperationHasFutureStrictReserved = 4 << 2, |
| 802 kBinaryOperationHasDuplicatedIdentifier = 8 << 2, |
| 803 |
641 // Below here applies if neither identifier nor string literal. Reserve the | 804 // Below here applies if neither identifier nor string literal. Reserve the |
642 // 2 least significant bits for flags. | 805 // 2 least significant bits for flags. |
643 kThisExpression = 1 << 2, | 806 kThisExpression = 1 << 2, |
644 kThisPropertyExpression = 2 << 2, | 807 kThisPropertyExpression = 2 << 2, |
645 kPropertyExpression = 3 << 2, | 808 kPropertyExpression = 3 << 2, |
646 kCallExpression = 4 << 2 | 809 kCallExpression = 4 << 2 |
647 }; | 810 }; |
648 | 811 |
649 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 812 explicit PreParserExpression(int expression_code) : code_(expression_code) {} |
650 | 813 |
| 814 V8_INLINE int BinaryOperationBits() const { |
| 815 if (IsBinaryOperation()) return code_; |
| 816 if (IsIdentifier()) { |
| 817 const PreParserIdentifier ident = AsIdentifier(); |
| 818 if (ident.IsEval()) return kBinaryOperationHasEval; |
| 819 if (ident.IsArguments()) return kBinaryOperationHasArguments; |
| 820 if (ident.IsYield() || ident.IsFutureStrictReserved()) |
| 821 return kBinaryOperationHasFutureStrictReserved; |
| 822 } |
| 823 return 0; |
| 824 } |
| 825 |
651 int code_; | 826 int code_; |
652 }; | 827 }; |
653 | 828 |
654 | 829 |
655 // PreParserExpressionList doesn't actually store the expressions because | 830 // PreParserExpressionList doesn't actually store the expressions because |
656 // PreParser doesn't need to. | 831 // PreParser doesn't need to. |
657 class PreParserExpressionList { | 832 class PreParserExpressionList { |
658 public: | 833 public: |
659 // These functions make list->Add(some_expression) work (and do nothing). | 834 // These functions make list->Add(some_expression) work (and do nothing). |
660 PreParserExpressionList() : length_(0) {} | 835 PreParserExpressionList() : length_(0) {} |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 public: | 897 public: |
723 // These functions make list->Add(some_expression) work as no-ops. | 898 // These functions make list->Add(some_expression) work as no-ops. |
724 PreParserStatementList() {} | 899 PreParserStatementList() {} |
725 PreParserStatementList* operator->() { return this; } | 900 PreParserStatementList* operator->() { return this; } |
726 void Add(PreParserStatement, void*) {} | 901 void Add(PreParserStatement, void*) {} |
727 }; | 902 }; |
728 | 903 |
729 | 904 |
730 class PreParserScope { | 905 class PreParserScope { |
731 public: | 906 public: |
732 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) | 907 explicit PreParserScope(PreParserScope* outer_scope, |
733 : scope_type_(scope_type) { | 908 ScopeType scope_type, |
| 909 void* = NULL) |
| 910 : scope_type_(scope_type), declared_parameters_(0) { |
734 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 911 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
735 } | 912 } |
736 | 913 |
737 ScopeType type() { return scope_type_; } | 914 ScopeType type() { return scope_type_; } |
738 StrictMode strict_mode() const { return strict_mode_; } | 915 StrictMode strict_mode() const { return strict_mode_; } |
739 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 916 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
740 | 917 |
| 918 // TODO(aperezdc): Would allowing lazy compilation in preparser make sense? |
| 919 bool AllowsLazyCompilation() const { return false; } |
| 920 |
| 921 void set_start_position(int position) {} |
| 922 void set_end_position(int position) {} |
| 923 |
| 924 bool IsDeclared(const PreParserIdentifier& identifier) const { |
| 925 return (declared_parameters_ & (1 << identifier.type_)) != 0; |
| 926 } |
| 927 |
| 928 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) { |
| 929 declared_parameters_ |= (1 << identifier.type_); |
| 930 } |
| 931 |
| 932 // Allow scope->Foo() to work. |
| 933 PreParserScope* operator->() { return this; } |
| 934 |
741 private: | 935 private: |
742 ScopeType scope_type_; | 936 ScopeType scope_type_; |
743 StrictMode strict_mode_; | 937 StrictMode strict_mode_; |
| 938 int declared_parameters_; |
744 }; | 939 }; |
745 | 940 |
746 | 941 |
747 class PreParserFactory { | 942 class PreParserFactory { |
748 public: | 943 public: |
749 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} | 944 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} |
750 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 945 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
751 int pos) { | 946 int pos) { |
752 return PreParserExpression::Default(); | 947 return PreParserExpression::Default(); |
753 } | 948 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 return PreParserExpression::Property(); | 989 return PreParserExpression::Property(); |
795 } | 990 } |
796 PreParserExpression NewUnaryOperation(Token::Value op, | 991 PreParserExpression NewUnaryOperation(Token::Value op, |
797 PreParserExpression expression, | 992 PreParserExpression expression, |
798 int pos) { | 993 int pos) { |
799 return PreParserExpression::Default(); | 994 return PreParserExpression::Default(); |
800 } | 995 } |
801 PreParserExpression NewBinaryOperation(Token::Value op, | 996 PreParserExpression NewBinaryOperation(Token::Value op, |
802 PreParserExpression left, | 997 PreParserExpression left, |
803 PreParserExpression right, int pos) { | 998 PreParserExpression right, int pos) { |
804 return PreParserExpression::Default(); | 999 return PreParserExpression::BinaryOperation(left, right); |
805 } | 1000 } |
806 PreParserExpression NewCompareOperation(Token::Value op, | 1001 PreParserExpression NewCompareOperation(Token::Value op, |
807 PreParserExpression left, | 1002 PreParserExpression left, |
808 PreParserExpression right, int pos) { | 1003 PreParserExpression right, int pos) { |
809 return PreParserExpression::Default(); | 1004 return PreParserExpression::Default(); |
810 } | 1005 } |
811 PreParserExpression NewAssignment(Token::Value op, | 1006 PreParserExpression NewAssignment(Token::Value op, |
812 PreParserExpression left, | 1007 PreParserExpression left, |
813 PreParserExpression right, | 1008 PreParserExpression right, |
814 int pos) { | 1009 int pos) { |
(...skipping 20 matching lines...) Expand all Loading... |
835 PreParserExpression NewCall(PreParserExpression expression, | 1030 PreParserExpression NewCall(PreParserExpression expression, |
836 PreParserExpressionList arguments, | 1031 PreParserExpressionList arguments, |
837 int pos) { | 1032 int pos) { |
838 return PreParserExpression::Call(); | 1033 return PreParserExpression::Call(); |
839 } | 1034 } |
840 PreParserExpression NewCallNew(PreParserExpression expression, | 1035 PreParserExpression NewCallNew(PreParserExpression expression, |
841 PreParserExpressionList arguments, | 1036 PreParserExpressionList arguments, |
842 int pos) { | 1037 int pos) { |
843 return PreParserExpression::Default(); | 1038 return PreParserExpression::Default(); |
844 } | 1039 } |
| 1040 PreParserStatement NewReturnStatement(PreParserExpression expression, |
| 1041 int pos) { |
| 1042 return PreParserStatement::Default(); |
| 1043 } |
| 1044 PreParserExpression |
| 1045 NewFunctionLiteral(PreParserIdentifier name, |
| 1046 AstValueFactory* ast_value_factory, |
| 1047 PreParserScope& scope, |
| 1048 PreParserStatementList body, |
| 1049 int materialized_literal_count, |
| 1050 int expected_property_count, |
| 1051 int handler_count, |
| 1052 int parameter_count, |
| 1053 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
| 1054 FunctionLiteral::FunctionType function_type, |
| 1055 FunctionLiteral::IsFunctionFlag is_function, |
| 1056 FunctionLiteral::IsParenthesizedFlag is_parenthesized, |
| 1057 FunctionLiteral::IsGeneratorFlag is_generator, |
| 1058 int position) { |
| 1059 return PreParserExpression::Default(); |
| 1060 } |
| 1061 |
| 1062 // Return the object itself as AstVisitor and implement the needed |
| 1063 // dummy method right in this class. |
| 1064 PreParserFactory* visitor() { return this; } |
| 1065 BailoutReason dont_optimize_reason() { return kNoReason; } |
| 1066 int* ast_properties() { static int dummy = 42; return &dummy; } |
845 }; | 1067 }; |
846 | 1068 |
847 | 1069 |
848 class PreParser; | 1070 class PreParser; |
849 | 1071 |
850 class PreParserTraits { | 1072 class PreParserTraits { |
851 public: | 1073 public: |
852 struct Type { | 1074 struct Type { |
853 // TODO(marja): To be removed. The Traits object should contain all the data | 1075 // TODO(marja): To be removed. The Traits object should contain all the data |
854 // it needs. | 1076 // it needs. |
855 typedef PreParser* Parser; | 1077 typedef PreParser* Parser; |
856 | 1078 |
857 // Used by FunctionState and BlockState. | 1079 // Used by FunctionState and BlockState. |
858 typedef PreParserScope Scope; | 1080 typedef PreParserScope Scope; |
| 1081 typedef PreParserScope ScopePtr; |
| 1082 |
859 // PreParser doesn't need to store generator variables. | 1083 // PreParser doesn't need to store generator variables. |
860 typedef void GeneratorVariable; | 1084 typedef void GeneratorVariable; |
861 // No interaction with Zones. | 1085 // No interaction with Zones. |
862 typedef void Zone; | 1086 typedef void Zone; |
863 | 1087 |
| 1088 typedef int AstProperties; |
| 1089 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; |
| 1090 |
864 // Return types for traversing functions. | 1091 // Return types for traversing functions. |
865 typedef PreParserIdentifier Identifier; | 1092 typedef PreParserIdentifier Identifier; |
866 typedef PreParserExpression Expression; | 1093 typedef PreParserExpression Expression; |
867 typedef PreParserExpression YieldExpression; | 1094 typedef PreParserExpression YieldExpression; |
868 typedef PreParserExpression FunctionLiteral; | 1095 typedef PreParserExpression FunctionLiteral; |
869 typedef PreParserExpression ObjectLiteralProperty; | 1096 typedef PreParserExpression ObjectLiteralProperty; |
870 typedef PreParserExpression Literal; | 1097 typedef PreParserExpression Literal; |
871 typedef PreParserExpressionList ExpressionList; | 1098 typedef PreParserExpressionList ExpressionList; |
872 typedef PreParserExpressionList PropertyList; | 1099 typedef PreParserExpressionList PropertyList; |
873 typedef PreParserStatementList StatementList; | 1100 typedef PreParserStatementList StatementList; |
(...skipping 22 matching lines...) Expand all Loading... |
896 } | 1123 } |
897 | 1124 |
898 static bool IsIdentifier(PreParserExpression expression) { | 1125 static bool IsIdentifier(PreParserExpression expression) { |
899 return expression.IsIdentifier(); | 1126 return expression.IsIdentifier(); |
900 } | 1127 } |
901 | 1128 |
902 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { | 1129 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
903 return expression.AsIdentifier(); | 1130 return expression.AsIdentifier(); |
904 } | 1131 } |
905 | 1132 |
| 1133 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { |
| 1134 return identifier.IsYield() || identifier.IsFutureStrictReserved(); |
| 1135 } |
| 1136 |
906 static bool IsBoilerplateProperty(PreParserExpression property) { | 1137 static bool IsBoilerplateProperty(PreParserExpression property) { |
907 // PreParser doesn't count boilerplate properties. | 1138 // PreParser doesn't count boilerplate properties. |
908 return false; | 1139 return false; |
909 } | 1140 } |
910 | 1141 |
911 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1142 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
912 return false; | 1143 return false; |
913 } | 1144 } |
914 | 1145 |
915 // Functions for encapsulating the differences between parsing and preparsing; | 1146 // Functions for encapsulating the differences between parsing and preparsing; |
916 // operations interleaved with the recursive descent. | 1147 // operations interleaved with the recursive descent. |
917 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1148 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
918 // PreParser should not use FuncNameInferrer. | 1149 // PreParser should not use FuncNameInferrer. |
919 UNREACHABLE(); | 1150 UNREACHABLE(); |
920 } | 1151 } |
921 static void PushPropertyName(FuncNameInferrer* fni, | 1152 static void PushPropertyName(FuncNameInferrer* fni, |
922 PreParserExpression expression) { | 1153 PreParserExpression expression) { |
923 // PreParser should not use FuncNameInferrer. | 1154 // PreParser should not use FuncNameInferrer. |
924 UNREACHABLE(); | 1155 UNREACHABLE(); |
925 } | 1156 } |
| 1157 static void InferFunctionName(FuncNameInferrer* fni, |
| 1158 PreParserExpression expression) { |
| 1159 // PreParser should not use FuncNameInferrer. |
| 1160 UNREACHABLE(); |
| 1161 } |
926 | 1162 |
927 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1163 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
928 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 1164 PreParserScope* scope, PreParserExpression value, bool* has_function) {} |
929 | 1165 |
930 static void CheckAssigningFunctionLiteralToProperty( | 1166 static void CheckAssigningFunctionLiteralToProperty( |
931 PreParserExpression left, PreParserExpression right) {} | 1167 PreParserExpression left, PreParserExpression right) {} |
932 | 1168 |
933 // PreParser doesn't need to keep track of eval calls. | 1169 // PreParser doesn't need to keep track of eval calls. |
934 static void CheckPossibleEvalCall(PreParserExpression expression, | 1170 static void CheckPossibleEvalCall(PreParserExpression expression, |
935 PreParserScope* scope) {} | 1171 PreParserScope* scope) {} |
936 | 1172 |
937 static PreParserExpression MarkExpressionAsLValue( | 1173 static PreParserExpression MarkExpressionAsLValue( |
938 PreParserExpression expression) { | 1174 PreParserExpression expression) { |
939 // TODO(marja): To be able to produce the same errors, the preparser needs | 1175 // TODO(marja): To be able to produce the same errors, the preparser needs |
940 // to start tracking which expressions are variables and which are lvalues. | 1176 // to start tracking which expressions are variables and which are lvalues. |
941 return expression; | 1177 return expression; |
942 } | 1178 } |
943 | 1179 |
| 1180 static AstValueFactory* ast_value_factory() { return NULL; } |
| 1181 |
944 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, | 1182 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, |
945 PreParserExpression y, | 1183 PreParserExpression y, |
946 Token::Value op, | 1184 Token::Value op, |
947 int pos, | 1185 int pos, |
948 PreParserFactory* factory) { | 1186 PreParserFactory* factory) { |
949 return false; | 1187 return false; |
950 } | 1188 } |
951 | 1189 |
952 PreParserExpression BuildUnaryExpression(PreParserExpression expression, | 1190 PreParserExpression BuildUnaryExpression(PreParserExpression expression, |
953 Token::Value op, int pos, | 1191 Token::Value op, int pos, |
954 PreParserFactory* factory) { | 1192 PreParserFactory* factory) { |
955 return PreParserExpression::Default(); | 1193 return PreParserExpression::Default(); |
956 } | 1194 } |
957 | 1195 |
958 PreParserExpression NewThrowReferenceError(const char* type, int pos) { | 1196 PreParserExpression NewThrowReferenceError(const char* type, int pos) { |
959 return PreParserExpression::Default(); | 1197 return PreParserExpression::Default(); |
960 } | 1198 } |
961 PreParserExpression NewThrowSyntaxError( | 1199 PreParserExpression NewThrowSyntaxError( |
962 const char* type, Handle<Object> arg, int pos) { | 1200 const char* type, Handle<Object> arg, int pos) { |
963 return PreParserExpression::Default(); | 1201 return PreParserExpression::Default(); |
964 } | 1202 } |
965 PreParserExpression NewThrowTypeError( | 1203 PreParserExpression NewThrowTypeError( |
966 const char* type, Handle<Object> arg, int pos) { | 1204 const char* type, Handle<Object> arg, int pos) { |
967 return PreParserExpression::Default(); | 1205 return PreParserExpression::Default(); |
968 } | 1206 } |
| 1207 PreParserScope NewScope(PreParserScope* outer_scope, |
| 1208 ScopeType scope_type) { |
| 1209 return PreParserScope(outer_scope, scope_type); |
| 1210 } |
969 | 1211 |
970 // Reporting errors. | 1212 // Reporting errors. |
971 void ReportMessageAt(Scanner::Location location, | 1213 void ReportMessageAt(Scanner::Location location, |
972 const char* message, | 1214 const char* message, |
973 const char* arg = NULL, | 1215 const char* arg = NULL, |
974 bool is_reference_error = false); | 1216 bool is_reference_error = false); |
975 void ReportMessageAt(int start_pos, | 1217 void ReportMessageAt(int start_pos, |
976 int end_pos, | 1218 int end_pos, |
977 const char* message, | 1219 const char* message, |
978 const char* arg = NULL, | 1220 const char* arg = NULL, |
979 bool is_reference_error = false); | 1221 bool is_reference_error = false); |
980 | 1222 |
981 // "null" return type creators. | 1223 // "null" return type creators. |
982 static PreParserIdentifier EmptyIdentifier() { | 1224 static PreParserIdentifier EmptyIdentifier() { |
983 return PreParserIdentifier::Default(); | 1225 return PreParserIdentifier::Default(); |
984 } | 1226 } |
| 1227 static PreParserIdentifier EmptyIdentifierString() { |
| 1228 return PreParserIdentifier::Default(); |
| 1229 } |
985 static PreParserExpression EmptyExpression() { | 1230 static PreParserExpression EmptyExpression() { |
986 return PreParserExpression::Default(); | 1231 return PreParserExpression::Default(); |
987 } | 1232 } |
988 static PreParserExpression EmptyLiteral() { | 1233 static PreParserExpression EmptyLiteral() { |
989 return PreParserExpression::Default(); | 1234 return PreParserExpression::Default(); |
990 } | 1235 } |
991 static PreParserExpressionList NullExpressionList() { | 1236 static PreParserExpressionList NullExpressionList() { |
992 return PreParserExpressionList(); | 1237 return PreParserExpressionList(); |
993 } | 1238 } |
994 | 1239 |
995 // Odd-ball literal creators. | 1240 // Odd-ball literal creators. |
996 static PreParserExpression GetLiteralTheHole(int position, | 1241 static PreParserExpression GetLiteralTheHole(int position, |
997 PreParserFactory* factory) { | 1242 PreParserFactory* factory) { |
998 return PreParserExpression::Default(); | 1243 return PreParserExpression::Default(); |
999 } | 1244 } |
1000 | 1245 |
1001 // Producing data during the recursive descent. | 1246 // Producing data during the recursive descent. |
1002 PreParserIdentifier GetSymbol(Scanner* scanner); | 1247 PreParserIdentifier GetSymbol(Scanner* scanner); |
1003 | 1248 |
1004 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { | 1249 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { |
1005 return PreParserIdentifier::Default(); | 1250 return PreParserIdentifier::Default(); |
1006 } | 1251 } |
1007 | 1252 |
1008 static PreParserExpression ThisExpression(PreParserScope* scope, | 1253 static PreParserExpression ThisExpression(PreParserScope* scope, |
1009 PreParserFactory* factory) { | 1254 PreParserFactory* factory, |
| 1255 int pos) { |
1010 return PreParserExpression::This(); | 1256 return PreParserExpression::This(); |
1011 } | 1257 } |
1012 | 1258 |
1013 static PreParserExpression ExpressionFromLiteral( | 1259 static PreParserExpression ExpressionFromLiteral( |
1014 Token::Value token, int pos, Scanner* scanner, | 1260 Token::Value token, int pos, Scanner* scanner, |
1015 PreParserFactory* factory) { | 1261 PreParserFactory* factory) { |
1016 return PreParserExpression::Default(); | 1262 return PreParserExpression::Default(); |
1017 } | 1263 } |
1018 | 1264 |
1019 static PreParserExpression ExpressionFromIdentifier( | 1265 static PreParserExpression ExpressionFromIdentifier( |
(...skipping 11 matching lines...) Expand all Loading... |
1031 } | 1277 } |
1032 | 1278 |
1033 static PreParserStatementList NewStatementList(int size, void* zone) { | 1279 static PreParserStatementList NewStatementList(int size, void* zone) { |
1034 return PreParserStatementList(); | 1280 return PreParserStatementList(); |
1035 } | 1281 } |
1036 | 1282 |
1037 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1283 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
1038 return PreParserExpressionList(); | 1284 return PreParserExpressionList(); |
1039 } | 1285 } |
1040 | 1286 |
| 1287 V8_INLINE void SkipLazyFunctionBody( |
| 1288 PreParserIdentifier function_name, |
| 1289 int* materialized_literal_count, |
| 1290 int* expected_property_count, |
| 1291 bool* ok) { |
| 1292 UNREACHABLE(); |
| 1293 } |
| 1294 |
| 1295 V8_INLINE PreParserStatementList ParseEagerFunctionBody( |
| 1296 PreParserIdentifier function_name, |
| 1297 int pos, |
| 1298 Variable* fvar, |
| 1299 Token::Value fvar_init_op, |
| 1300 bool is_generator, |
| 1301 bool* ok); |
| 1302 |
| 1303 // Utility functions |
| 1304 V8_INLINE Vector<PreParserIdentifier> ParameterListFromExpression( |
| 1305 PreParserExpression expression, bool* ok); |
| 1306 |
| 1307 void CheckConflictingVarDeclarations( |
| 1308 PreParserScope scope, |
| 1309 bool* ok) {} |
| 1310 |
1041 // Temporary glue; these functions will move to ParserBase. | 1311 // Temporary glue; these functions will move to ParserBase. |
1042 PreParserExpression ParseV8Intrinsic(bool* ok); | 1312 PreParserExpression ParseV8Intrinsic(bool* ok); |
1043 PreParserExpression ParseFunctionLiteral( | 1313 PreParserExpression ParseFunctionLiteral( |
1044 PreParserIdentifier name, | 1314 PreParserIdentifier name, |
1045 Scanner::Location function_name_location, | 1315 Scanner::Location function_name_location, |
1046 bool name_is_strict_reserved, | 1316 bool name_is_strict_reserved, |
1047 bool is_generator, | 1317 bool is_generator, |
1048 int function_token_position, | 1318 int function_token_position, |
1049 FunctionLiteral::FunctionType type, | 1319 FunctionLiteral::FunctionType type, |
1050 bool* ok); | 1320 bool* ok); |
(...skipping 29 matching lines...) Expand all Loading... |
1080 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1350 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
1081 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1351 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
1082 this) {} | 1352 this) {} |
1083 | 1353 |
1084 // Pre-parse the program from the character stream; returns true on | 1354 // Pre-parse the program from the character stream; returns true on |
1085 // success (even if parsing failed, the pre-parse data successfully | 1355 // success (even if parsing failed, the pre-parse data successfully |
1086 // captured the syntax error), and false if a stack-overflow happened | 1356 // captured the syntax error), and false if a stack-overflow happened |
1087 // during parsing. | 1357 // during parsing. |
1088 PreParseResult PreParseProgram() { | 1358 PreParseResult PreParseProgram() { |
1089 PreParserScope scope(scope_, GLOBAL_SCOPE); | 1359 PreParserScope scope(scope_, GLOBAL_SCOPE); |
1090 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); | 1360 FunctionState top_scope(&function_state_, &scope_, &scope, NULL, NULL); |
1091 bool ok = true; | 1361 bool ok = true; |
1092 int start_position = scanner()->peek_location().beg_pos; | 1362 int start_position = scanner()->peek_location().beg_pos; |
1093 ParseSourceElements(Token::EOS, &ok); | 1363 ParseSourceElements(Token::EOS, &ok); |
1094 if (stack_overflow()) return kPreParseStackOverflow; | 1364 if (stack_overflow()) return kPreParseStackOverflow; |
1095 if (!ok) { | 1365 if (!ok) { |
1096 ReportUnexpectedToken(scanner()->current_token()); | 1366 ReportUnexpectedToken(scanner()->current_token()); |
1097 } else if (scope_->strict_mode() == STRICT) { | 1367 } else if (scope_->strict_mode() == STRICT) { |
1098 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 1368 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
1099 } | 1369 } |
1100 return kPreParseSuccess; | 1370 return kPreParseSuccess; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 Statement ParseDoWhileStatement(bool* ok); | 1432 Statement ParseDoWhileStatement(bool* ok); |
1163 Statement ParseWhileStatement(bool* ok); | 1433 Statement ParseWhileStatement(bool* ok); |
1164 Statement ParseForStatement(bool* ok); | 1434 Statement ParseForStatement(bool* ok); |
1165 Statement ParseThrowStatement(bool* ok); | 1435 Statement ParseThrowStatement(bool* ok); |
1166 Statement ParseTryStatement(bool* ok); | 1436 Statement ParseTryStatement(bool* ok); |
1167 Statement ParseDebuggerStatement(bool* ok); | 1437 Statement ParseDebuggerStatement(bool* ok); |
1168 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1438 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1169 Expression ParseObjectLiteral(bool* ok); | 1439 Expression ParseObjectLiteral(bool* ok); |
1170 Expression ParseV8Intrinsic(bool* ok); | 1440 Expression ParseV8Intrinsic(bool* ok); |
1171 | 1441 |
| 1442 V8_INLINE void SkipLazyFunctionBody( |
| 1443 PreParserIdentifier function_name, |
| 1444 int* materialized_literal_count, |
| 1445 int* expected_property_count, |
| 1446 bool* ok); |
| 1447 V8_INLINE PreParserStatementList ParseEagerFunctionBody( |
| 1448 PreParserIdentifier function_name, |
| 1449 int pos, |
| 1450 Variable* fvar, |
| 1451 Token::Value fvar_init_op, |
| 1452 bool is_generator, |
| 1453 bool* ok); |
| 1454 |
1172 Expression ParseFunctionLiteral( | 1455 Expression ParseFunctionLiteral( |
1173 Identifier name, | 1456 Identifier name, |
1174 Scanner::Location function_name_location, | 1457 Scanner::Location function_name_location, |
1175 bool name_is_strict_reserved, | 1458 bool name_is_strict_reserved, |
1176 bool is_generator, | 1459 bool is_generator, |
1177 int function_token_pos, | 1460 int function_token_pos, |
1178 FunctionLiteral::FunctionType function_type, | 1461 FunctionLiteral::FunctionType function_type, |
1179 bool* ok); | 1462 bool* ok); |
1180 void ParseLazyFunctionLiteralBody(bool* ok); | 1463 void ParseLazyFunctionLiteralBody(bool* ok); |
1181 | 1464 |
1182 bool CheckInOrOf(bool accept_OF); | 1465 bool CheckInOrOf(bool accept_OF); |
1183 }; | 1466 }; |
1184 | 1467 |
| 1468 |
| 1469 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1470 PreParserIdentifier function_name, |
| 1471 int pos, |
| 1472 Variable* fvar, |
| 1473 Token::Value fvar_init_op, |
| 1474 bool is_generator, |
| 1475 bool* ok) { |
| 1476 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1477 |
| 1478 ParseSourceElements(Token::RBRACE, ok); |
| 1479 if (!*ok) return PreParserStatementList(); |
| 1480 |
| 1481 Expect(Token::RBRACE, ok); |
| 1482 return PreParserStatementList(); |
| 1483 } |
| 1484 |
| 1485 |
| 1486 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( |
| 1487 PreParserIdentifier function_name, |
| 1488 int pos, |
| 1489 Variable* fvar, |
| 1490 Token::Value fvar_init_op, |
| 1491 bool is_generator, |
| 1492 bool* ok) { |
| 1493 return pre_parser_->ParseEagerFunctionBody(function_name, |
| 1494 pos, fvar, fvar_init_op, is_generator, ok); |
| 1495 } |
| 1496 |
| 1497 |
| 1498 Vector<PreParserIdentifier> PreParserTraits::ParameterListFromExpression( |
| 1499 PreParserExpression expression, bool* ok) { |
| 1500 Collector<PreParserIdentifier> collector; |
| 1501 |
| 1502 if (expression.HasEval()) |
| 1503 collector.Add(PreParserIdentifier::Eval()); |
| 1504 if (expression.HasArguments()) |
| 1505 collector.Add(PreParserIdentifier::Arguments()); |
| 1506 if (expression.HasFutureStrictReserved()) |
| 1507 collector.Add(PreParserIdentifier::FutureStrictReserved()); |
| 1508 |
| 1509 if (expression.HasDuplicatedIdentifier() || |
| 1510 pre_parser_->scanner()->parameter_list()->HasDuplicateIdentifiers()) { |
| 1511 collector.Add(PreParserIdentifier::Default()); |
| 1512 collector.Add(PreParserIdentifier::Default()); |
| 1513 } |
| 1514 |
| 1515 return collector.ToVector(); |
| 1516 } |
| 1517 |
| 1518 |
1185 template<class Traits> | 1519 template<class Traits> |
1186 ParserBase<Traits>::FunctionState::FunctionState( | 1520 ParserBase<Traits>::FunctionState::FunctionState( |
1187 FunctionState** function_state_stack, | 1521 FunctionState** function_state_stack, |
1188 typename Traits::Type::Scope** scope_stack, | 1522 typename Traits::Type::Scope** scope_stack, |
1189 typename Traits::Type::Scope* scope, | 1523 typename Traits::Type::Scope* scope, |
1190 typename Traits::Type::Zone* extra_param, | 1524 typename Traits::Type::Zone* extra_param, |
1191 AstValueFactory* ast_value_factory) | 1525 AstValueFactory* ast_value_factory) |
1192 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1526 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
1193 next_handler_index_(0), | 1527 next_handler_index_(0), |
1194 expected_property_count_(0), | 1528 expected_property_count_(0), |
1195 is_generator_(false), | 1529 is_generator_(false), |
1196 generator_object_variable_(NULL), | 1530 generator_object_variable_(NULL), |
1197 function_state_stack_(function_state_stack), | 1531 function_state_stack_(function_state_stack), |
1198 outer_function_state_(*function_state_stack), | 1532 outer_function_state_(*function_state_stack), |
1199 scope_stack_(scope_stack), | 1533 scope_stack_(scope_stack), |
1200 outer_scope_(*scope_stack), | 1534 outer_scope_(*scope_stack), |
1201 saved_ast_node_id_(0), | 1535 saved_ast_node_id_(0), |
1202 extra_param_(extra_param), | 1536 extra_param_(extra_param), |
1203 factory_(extra_param, ast_value_factory) { | 1537 factory_(extra_param, ast_value_factory) { |
1204 *scope_stack_ = scope; | 1538 *scope_stack_ = scope; |
1205 *function_state_stack = this; | 1539 *function_state_stack = this; |
1206 Traits::SetUpFunctionState(this, extra_param); | 1540 Traits::SetUpFunctionState(this, extra_param); |
1207 } | 1541 } |
1208 | 1542 |
1209 | 1543 |
1210 template<class Traits> | 1544 template<class Traits> |
| 1545 ParserBase<Traits>::FunctionState::FunctionState( |
| 1546 FunctionState** function_state_stack, |
| 1547 typename Traits::Type::Scope** scope_stack, |
| 1548 typename Traits::Type::Scope** scope, |
| 1549 typename Traits::Type::Zone* extra_param, |
| 1550 AstValueFactory* ast_value_factory) |
| 1551 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 1552 next_handler_index_(0), |
| 1553 expected_property_count_(0), |
| 1554 is_generator_(false), |
| 1555 generator_object_variable_(NULL), |
| 1556 function_state_stack_(function_state_stack), |
| 1557 outer_function_state_(*function_state_stack), |
| 1558 scope_stack_(scope_stack), |
| 1559 outer_scope_(*scope_stack), |
| 1560 saved_ast_node_id_(0), |
| 1561 extra_param_(extra_param), |
| 1562 factory_(extra_param, ast_value_factory) { |
| 1563 *scope_stack_ = *scope; |
| 1564 *function_state_stack = this; |
| 1565 Traits::SetUpFunctionState(this, extra_param); |
| 1566 } |
| 1567 |
| 1568 |
| 1569 template<class Traits> |
1211 ParserBase<Traits>::FunctionState::~FunctionState() { | 1570 ParserBase<Traits>::FunctionState::~FunctionState() { |
1212 *scope_stack_ = outer_scope_; | 1571 *scope_stack_ = outer_scope_; |
1213 *function_state_stack_ = outer_function_state_; | 1572 *function_state_stack_ = outer_function_state_; |
1214 Traits::TearDownFunctionState(this, extra_param_); | 1573 Traits::TearDownFunctionState(this, extra_param_); |
1215 } | 1574 } |
1216 | 1575 |
1217 | 1576 |
1218 template<class Traits> | 1577 template<class Traits> |
1219 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1578 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
1220 Scanner::Location source_location = scanner()->location(); | 1579 Scanner::Location source_location = scanner()->location(); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 // ObjectLiteral | 1726 // ObjectLiteral |
1368 // RegExpLiteral | 1727 // RegExpLiteral |
1369 // '(' Expression ')' | 1728 // '(' Expression ')' |
1370 | 1729 |
1371 int pos = peek_position(); | 1730 int pos = peek_position(); |
1372 ExpressionT result = this->EmptyExpression(); | 1731 ExpressionT result = this->EmptyExpression(); |
1373 Token::Value token = peek(); | 1732 Token::Value token = peek(); |
1374 switch (token) { | 1733 switch (token) { |
1375 case Token::THIS: { | 1734 case Token::THIS: { |
1376 Consume(Token::THIS); | 1735 Consume(Token::THIS); |
1377 result = this->ThisExpression(scope_, factory()); | 1736 result = this->ThisExpression(scope_, factory(), position()); |
1378 break; | 1737 break; |
1379 } | 1738 } |
1380 | 1739 |
1381 case Token::NULL_LITERAL: | 1740 case Token::NULL_LITERAL: |
1382 case Token::TRUE_LITERAL: | 1741 case Token::TRUE_LITERAL: |
1383 case Token::FALSE_LITERAL: | 1742 case Token::FALSE_LITERAL: |
1384 case Token::NUMBER: | 1743 case Token::NUMBER: |
1385 Next(); | 1744 Next(); |
1386 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); | 1745 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
1387 break; | 1746 break; |
(...skipping 24 matching lines...) Expand all Loading... |
1412 case Token::LBRACK: | 1771 case Token::LBRACK: |
1413 result = this->ParseArrayLiteral(CHECK_OK); | 1772 result = this->ParseArrayLiteral(CHECK_OK); |
1414 break; | 1773 break; |
1415 | 1774 |
1416 case Token::LBRACE: | 1775 case Token::LBRACE: |
1417 result = this->ParseObjectLiteral(CHECK_OK); | 1776 result = this->ParseObjectLiteral(CHECK_OK); |
1418 break; | 1777 break; |
1419 | 1778 |
1420 case Token::LPAREN: | 1779 case Token::LPAREN: |
1421 Consume(Token::LPAREN); | 1780 Consume(Token::LPAREN); |
1422 // Heuristically try to detect immediately called functions before | 1781 if (allow_arrow_functions() && peek() == Token::RPAREN) { |
1423 // seeing the call parentheses. | 1782 // Arrow functions are the only expression type constructions |
1424 parenthesized_function_ = (peek() == Token::FUNCTION); | 1783 // for which an empty parameter list "()" is valid input. |
1425 result = this->ParseExpression(true, CHECK_OK); | 1784 Consume(Token::RPAREN); |
1426 Expect(Token::RPAREN, CHECK_OK); | 1785 return this->ParseArrowFunctionLiteral(pos, |
| 1786 this->EmptyExpression(), |
| 1787 CHECK_OK); |
| 1788 } else { |
| 1789 // Heuristically try to detect immediately called functions before |
| 1790 // seeing the call parentheses. |
| 1791 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 1792 result = this->ParseExpression(true, CHECK_OK); |
| 1793 Expect(Token::RPAREN, CHECK_OK); |
| 1794 } |
1427 break; | 1795 break; |
1428 | 1796 |
1429 case Token::MOD: | 1797 case Token::MOD: |
1430 if (allow_natives_syntax() || extension_ != NULL) { | 1798 if (allow_natives_syntax() || extension_ != NULL) { |
1431 result = this->ParseV8Intrinsic(CHECK_OK); | 1799 result = this->ParseV8Intrinsic(CHECK_OK); |
1432 break; | 1800 break; |
1433 } | 1801 } |
1434 // If we're not allowing special syntax we fall-through to the | 1802 // If we're not allowing special syntax we fall-through to the |
1435 // default case. | 1803 // default case. |
1436 | 1804 |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2053 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1686 return result; | 2054 return result; |
1687 } | 2055 } |
1688 | 2056 |
1689 // Precedence = 2 | 2057 // Precedence = 2 |
1690 template <class Traits> | 2058 template <class Traits> |
1691 typename ParserBase<Traits>::ExpressionT | 2059 typename ParserBase<Traits>::ExpressionT |
1692 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2060 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
1693 // AssignmentExpression :: | 2061 // AssignmentExpression :: |
1694 // ConditionalExpression | 2062 // ConditionalExpression |
| 2063 // ArrowFunction |
1695 // YieldExpression | 2064 // YieldExpression |
1696 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2065 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1697 | 2066 |
1698 Scanner::Location lhs_location = scanner()->peek_location(); | 2067 Scanner::Location lhs_location = scanner()->peek_location(); |
1699 | 2068 |
1700 if (peek() == Token::YIELD && is_generator()) { | 2069 if (peek() == Token::YIELD && is_generator()) { |
1701 return this->ParseYieldExpression(ok); | 2070 return this->ParseYieldExpression(ok); |
1702 } | 2071 } |
1703 | 2072 |
1704 if (fni_ != NULL) fni_->Enter(); | 2073 if (fni_ != NULL) fni_->Enter(); |
1705 ExpressionT expression = | 2074 ExpressionT expression = |
1706 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2075 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
1707 | 2076 |
| 2077 if (allow_arrow_functions() && peek() == Token::ARROW) |
| 2078 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, |
| 2079 expression, |
| 2080 CHECK_OK); |
| 2081 |
1708 if (!Token::IsAssignmentOp(peek())) { | 2082 if (!Token::IsAssignmentOp(peek())) { |
1709 if (fni_ != NULL) fni_->Leave(); | 2083 if (fni_ != NULL) fni_->Leave(); |
1710 // Parsed conditional expression only (no assignment). | 2084 // Parsed conditional expression only (no assignment). |
1711 return expression; | 2085 return expression; |
1712 } | 2086 } |
1713 | 2087 |
1714 expression = this->CheckAndRewriteReferenceExpression( | 2088 expression = this->CheckAndRewriteReferenceExpression( |
1715 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2089 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
1716 expression = this->MarkExpressionAsLValue(expression); | 2090 expression = this->MarkExpressionAsLValue(expression); |
1717 | 2091 |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2102 } | 2476 } |
2103 default: | 2477 default: |
2104 return expression; | 2478 return expression; |
2105 } | 2479 } |
2106 } | 2480 } |
2107 ASSERT(false); | 2481 ASSERT(false); |
2108 return this->EmptyExpression(); | 2482 return this->EmptyExpression(); |
2109 } | 2483 } |
2110 | 2484 |
2111 | 2485 |
| 2486 template <class Traits> |
| 2487 typename ParserBase<Traits>::ExpressionT |
| 2488 ParserBase<Traits>::ParseArrowFunctionLiteralBody( |
| 2489 FunctionState* function_state, |
| 2490 typename Traits::Type::ScopePtr scope, |
| 2491 int num_parameters, |
| 2492 const Scanner::Location& eval_args_error_loc, |
| 2493 const Scanner::Location& dupe_error_loc, |
| 2494 const Scanner::Location& reserved_loc, |
| 2495 FunctionLiteral::IsParenthesizedFlag parenthesized, |
| 2496 int start_pos, |
| 2497 bool* ok) { |
| 2498 |
| 2499 typename Traits::Type::StatementList body; |
| 2500 int materialized_literal_count = -1; |
| 2501 int expected_property_count = -1; |
| 2502 |
| 2503 Expect(Token::ARROW, CHECK_OK); |
| 2504 |
| 2505 if (peek() == Token::LBRACE) { |
| 2506 // Multiple statemente body |
| 2507 Consume(Token::LBRACE); |
| 2508 |
| 2509 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
| 2510 scope_->AllowsLazyCompilation() && |
| 2511 !parenthesized_function_); |
| 2512 parenthesized_function_ = false; // This Was set for this funciton only. |
| 2513 |
| 2514 if (is_lazily_parsed) { |
| 2515 this->SkipLazyFunctionBody(this->EmptyIdentifier(), |
| 2516 &materialized_literal_count, |
| 2517 &expected_property_count, |
| 2518 CHECK_OK); |
| 2519 } else { |
| 2520 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(), |
| 2521 RelocInfo::kNoPosition, |
| 2522 NULL, |
| 2523 Token::INIT_VAR, |
| 2524 false, // Not a generator. |
| 2525 CHECK_OK); |
| 2526 } |
| 2527 } else { |
| 2528 // Single-expression body |
| 2529 parenthesized_function_ = false; |
| 2530 ParseAssignmentExpression(true, CHECK_OK); |
| 2531 } |
| 2532 |
| 2533 scope->set_start_position(start_pos); |
| 2534 scope->set_end_position(scanner()->location().end_pos); |
| 2535 |
| 2536 // Validate strict mode. |
| 2537 if (strict_mode() == STRICT) { |
| 2538 CheckStrictFunctionNameAndParameters(this->EmptyIdentifierString(), |
| 2539 false, |
| 2540 Scanner::Location::invalid(), |
| 2541 eval_args_error_loc, |
| 2542 dupe_error_loc, |
| 2543 reserved_loc, |
| 2544 CHECK_OK); |
| 2545 CheckOctalLiteral(start_pos, |
| 2546 scanner()->location().end_pos, |
| 2547 CHECK_OK); |
| 2548 } |
| 2549 |
| 2550 if (allow_harmony_scoping() && strict_mode() == STRICT) |
| 2551 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 2552 |
| 2553 return this->EmptyExpression(); |
| 2554 } |
| 2555 |
| 2556 |
| 2557 template <class Traits> |
| 2558 typename ParserBase<Traits>::ExpressionT |
| 2559 ParserBase<Traits>::ParseArrowFunctionLiteral(bool* ok) { |
| 2560 // TODO(aperez): Change this to use ARROW_SCOPE |
| 2561 typename Traits::Type::ScopePtr scope = |
| 2562 this->NewScope(scope_, FUNCTION_SCOPE); |
| 2563 |
| 2564 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 2565 ? FunctionLiteral::kIsParenthesized |
| 2566 : FunctionLiteral::kNotParenthesized; |
| 2567 parenthesized_function_ = false; |
| 2568 |
| 2569 int start_pos = position(); |
| 2570 int num_parameters = 0; |
| 2571 FunctionState function_state(&function_state_, &scope_, &scope, zone(), |
| 2572 this->ast_value_factory()); |
| 2573 |
| 2574 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); |
| 2575 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 2576 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 2577 |
| 2578 if (peek() == Token::LPAREN) { |
| 2579 // Parse a parenthesized parameter list. |
| 2580 Consume(Token::LPAREN); |
| 2581 bool done = (peek() == Token::RPAREN); |
| 2582 while (!done) { |
| 2583 bool is_strict_reserved = false; |
| 2584 IdentifierT param_name = |
| 2585 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, |
| 2586 CHECK_OK); |
| 2587 |
| 2588 // Store locations for possible future error reports. |
| 2589 if (!eval_args_error_loc.IsValid() && |
| 2590 this->IsEvalOrArguments(param_name)) { |
| 2591 eval_args_error_loc = scanner()->location(); |
| 2592 } |
| 2593 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 2594 reserved_loc = scanner()->location(); |
| 2595 } |
| 2596 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| 2597 dupe_error_loc = scanner()->location(); |
| 2598 } |
| 2599 |
| 2600 scope_->DeclareParameter(param_name, VAR); |
| 2601 num_parameters++; |
| 2602 if (num_parameters > Code::kMaxArguments) { |
| 2603 this->ReportMessageAt(scanner()->location(), "too_many_parameters"); |
| 2604 *ok = false; |
| 2605 return this->EmptyExpression(); |
| 2606 } |
| 2607 done = (peek() == Token::RPAREN); |
| 2608 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 2609 } |
| 2610 Expect(Token::RPAREN, CHECK_OK); |
| 2611 } else { |
| 2612 // Parse a single parameter identifier. |
| 2613 bool is_strict_reserved = false; |
| 2614 IdentifierT param_name = |
| 2615 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 2616 |
| 2617 // Store locations for possible future error reports. |
| 2618 if (this->IsEvalOrArguments(param_name)) |
| 2619 eval_args_error_loc = scanner()->location(); |
| 2620 if (is_strict_reserved) |
| 2621 reserved_loc = scanner()->location(); |
| 2622 |
| 2623 scope_->DeclareParameter(param_name, VAR); |
| 2624 } |
| 2625 |
| 2626 ExpressionT literal = ParseArrowFunctionLiteralBody(&function_state, |
| 2627 scope, |
| 2628 num_parameters, |
| 2629 eval_args_error_loc, |
| 2630 dupe_error_loc, |
| 2631 reserved_loc, |
| 2632 parenthesized, |
| 2633 start_pos, |
| 2634 CHECK_OK); |
| 2635 return literal; |
| 2636 } |
| 2637 |
| 2638 |
| 2639 template <class Traits> |
| 2640 typename ParserBase<Traits>::ExpressionT |
| 2641 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
| 2642 ExpressionT params_ast, |
| 2643 bool* ok) { |
| 2644 // TODO(aperez): Change this to use ARROW_SCOPE |
| 2645 typename Traits::Type::ScopePtr scope = |
| 2646 this->NewScope(scope_, FUNCTION_SCOPE); |
| 2647 |
| 2648 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 2649 ? FunctionLiteral::kIsParenthesized |
| 2650 : FunctionLiteral::kNotParenthesized; |
| 2651 parenthesized_function_ = false; |
| 2652 |
| 2653 FunctionState function_state(&function_state_, &scope_, &scope, zone(), |
| 2654 this->ast_value_factory()); |
| 2655 |
| 2656 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); |
| 2657 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 2658 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 2659 |
| 2660 if (!scanner()->parameter_list()->IsValid(start_pos)) { |
| 2661 ReportMessageAt(Scanner::Location(start_pos, position()), |
| 2662 "malformed_parameter_list"); |
| 2663 *ok = false; |
| 2664 return this->EmptyExpression(); |
| 2665 } |
| 2666 |
| 2667 // Function parameters are already parsed into an AST |
| 2668 typename Traits::Type::ParameterIdentifierVector params = |
| 2669 Traits::ParameterListFromExpression(params_ast, CHECK_OK); |
| 2670 |
| 2671 if (params.length() > Code::kMaxArguments) { |
| 2672 ReportMessageAt(Scanner::Location(params_ast->position(), position()), |
| 2673 "too_many_parameters"); |
| 2674 *ok = false; |
| 2675 return this->EmptyExpression(); |
| 2676 } |
| 2677 |
| 2678 // The vector has the items in reverse order. |
| 2679 for (int i = params.length() - 1; i >= 0; --i) { |
| 2680 IdentifierT param_name = params.at(i)->raw_name(); |
| 2681 int param_pos = params.at(i)->position(); |
| 2682 |
| 2683 // Store locations for possible future error reports. |
| 2684 if (!eval_args_error_loc.IsValid() && this->IsEvalOrArguments(param_name)) { |
| 2685 eval_args_error_loc = |
| 2686 Scanner::Location(param_pos, param_pos + param_name->length()); |
| 2687 } |
| 2688 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| 2689 dupe_error_loc = |
| 2690 Scanner::Location(param_pos, param_pos + param_name->length()); |
| 2691 } |
| 2692 if (!reserved_loc.IsValid() && this->IsFutureStrictReserved(param_name)) { |
| 2693 reserved_loc = |
| 2694 Scanner::Location(param_pos, param_pos + param_name->length()); |
| 2695 } |
| 2696 |
| 2697 scope_->DeclareParameter(param_name, VAR); |
| 2698 } |
| 2699 |
| 2700 ExpressionT literal = ParseArrowFunctionLiteralBody(&function_state, |
| 2701 scope, |
| 2702 params.length(), |
| 2703 eval_args_error_loc, |
| 2704 dupe_error_loc, |
| 2705 reserved_loc, |
| 2706 parenthesized, |
| 2707 start_pos, |
| 2708 CHECK_OK); |
| 2709 return literal; |
| 2710 } |
| 2711 |
| 2712 |
2112 template <typename Traits> | 2713 template <typename Traits> |
2113 typename ParserBase<Traits>::ExpressionT | 2714 typename ParserBase<Traits>::ExpressionT |
2114 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2715 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2115 ExpressionT expression, | 2716 ExpressionT expression, |
2116 Scanner::Location location, const char* message, bool* ok) { | 2717 Scanner::Location location, const char* message, bool* ok) { |
2117 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2718 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2118 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2719 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2119 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2720 this->ReportMessageAt(location, "strict_eval_arguments", false); |
2120 *ok = false; | 2721 *ok = false; |
2121 return this->EmptyExpression(); | 2722 return this->EmptyExpression(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2165 parser()->ReportMessage("accessor_get_set"); | 2766 parser()->ReportMessage("accessor_get_set"); |
2166 } | 2767 } |
2167 *ok = false; | 2768 *ok = false; |
2168 } | 2769 } |
2169 } | 2770 } |
2170 | 2771 |
2171 | 2772 |
2172 } } // v8::internal | 2773 } } // v8::internal |
2173 | 2774 |
2174 #endif // V8_PREPARSER_H | 2775 #endif // V8_PREPARSER_H |
OLD | NEW |