Chromium Code Reviews| 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/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 55 // }; | 55 // }; |
| 56 // // ... | 56 // // ... |
| 57 // }; | 57 // }; |
| 58 | 58 |
| 59 template <typename Traits> | 59 template <typename Traits> |
| 60 class ParserBase : public Traits { | 60 class ParserBase : public Traits { |
| 61 public: | 61 public: |
| 62 // Shorten type names defined by Traits. | 62 // Shorten type names defined by Traits. |
| 63 typedef typename Traits::Type::Expression ExpressionT; | 63 typedef typename Traits::Type::Expression ExpressionT; |
| 64 typedef typename Traits::Type::Identifier IdentifierT; | 64 typedef typename Traits::Type::Identifier IdentifierT; |
| 65 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | |
| 65 | 66 |
| 66 ParserBase(Scanner* scanner, uintptr_t stack_limit, | 67 ParserBase(Scanner* scanner, uintptr_t stack_limit, |
| 67 v8::Extension* extension, | 68 v8::Extension* extension, |
| 68 ParserRecorder* log, | 69 ParserRecorder* log, |
| 69 typename Traits::Type::Zone* zone, | 70 typename Traits::Type::Zone* zone, |
| 70 typename Traits::Type::Parser this_object) | 71 typename Traits::Type::Parser this_object) |
| 71 : Traits(this_object), | 72 : Traits(this_object), |
| 72 parenthesized_function_(false), | 73 parenthesized_function_(false), |
| 73 scope_(NULL), | 74 scope_(NULL), |
| 74 function_state_(NULL), | 75 function_state_(NULL), |
| 75 extension_(extension), | 76 extension_(extension), |
| 76 fni_(NULL), | 77 fni_(NULL), |
| 77 log_(log), | 78 log_(log), |
| 78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 79 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
| 79 scanner_(scanner), | 80 scanner_(scanner), |
| 80 stack_limit_(stack_limit), | 81 stack_limit_(stack_limit), |
| 81 stack_overflow_(false), | 82 stack_overflow_(false), |
| 82 allow_lazy_(false), | 83 allow_lazy_(false), |
| 83 allow_natives_syntax_(false), | 84 allow_natives_syntax_(false), |
| 84 allow_generators_(false), | 85 allow_generators_(false), |
| 85 allow_for_of_(false), | 86 allow_for_of_(false), |
| 87 allow_arrow_functions_(false), | |
| 86 zone_(zone) { } | 88 zone_(zone) { } |
| 87 | 89 |
| 88 // Getters that indicate whether certain syntactical constructs are | 90 // Getters that indicate whether certain syntactical constructs are |
| 89 // allowed to be parsed by this instance of the parser. | 91 // allowed to be parsed by this instance of the parser. |
| 90 bool allow_lazy() const { return allow_lazy_; } | 92 bool allow_lazy() const { return allow_lazy_; } |
| 91 bool allow_natives_syntax() const { return allow_natives_syntax_; } | 93 bool allow_natives_syntax() const { return allow_natives_syntax_; } |
| 92 bool allow_generators() const { return allow_generators_; } | 94 bool allow_generators() const { return allow_generators_; } |
| 93 bool allow_for_of() const { return allow_for_of_; } | 95 bool allow_for_of() const { return allow_for_of_; } |
| 96 bool allow_arrow_functions() const { return allow_arrow_functions_; } | |
| 94 bool allow_modules() const { return scanner()->HarmonyModules(); } | 97 bool allow_modules() const { return scanner()->HarmonyModules(); } |
| 95 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 98 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
| 96 bool allow_harmony_numeric_literals() const { | 99 bool allow_harmony_numeric_literals() const { |
| 97 return scanner()->HarmonyNumericLiterals(); | 100 return scanner()->HarmonyNumericLiterals(); |
| 98 } | 101 } |
| 99 | 102 |
| 100 // Setters that determine whether certain syntactical constructs are | 103 // Setters that determine whether certain syntactical constructs are |
| 101 // allowed to be parsed by this instance of the parser. | 104 // allowed to be parsed by this instance of the parser. |
| 102 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 105 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
| 103 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 106 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
| 104 void set_allow_generators(bool allow) { allow_generators_ = allow; } | 107 void set_allow_generators(bool allow) { allow_generators_ = allow; } |
| 105 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 108 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
| 109 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } | |
| 106 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 110 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
| 107 void set_allow_harmony_scoping(bool allow) { | 111 void set_allow_harmony_scoping(bool allow) { |
| 108 scanner()->SetHarmonyScoping(allow); | 112 scanner()->SetHarmonyScoping(allow); |
| 109 } | 113 } |
| 110 void set_allow_harmony_numeric_literals(bool allow) { | 114 void set_allow_harmony_numeric_literals(bool allow) { |
| 111 scanner()->SetHarmonyNumericLiterals(allow); | 115 scanner()->SetHarmonyNumericLiterals(allow); |
| 112 } | 116 } |
| 113 | 117 |
| 114 protected: | 118 protected: |
| 115 enum AllowEvalOrArgumentsAsIdentifier { | 119 enum AllowEvalOrArgumentsAsIdentifier { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 143 typename Traits::Type::Scope* outer_scope_; | 147 typename Traits::Type::Scope* outer_scope_; |
| 144 typename Traits::Type::Scope* scope_; | 148 typename Traits::Type::Scope* scope_; |
| 145 }; | 149 }; |
| 146 | 150 |
| 147 class FunctionState BASE_EMBEDDED { | 151 class FunctionState BASE_EMBEDDED { |
| 148 public: | 152 public: |
| 149 FunctionState( | 153 FunctionState( |
| 150 FunctionState** function_state_stack, | 154 FunctionState** function_state_stack, |
| 151 typename Traits::Type::Scope** scope_stack, | 155 typename Traits::Type::Scope** scope_stack, |
| 152 typename Traits::Type::Scope* scope, | 156 typename Traits::Type::Scope* scope, |
| 153 typename Traits::Type::Zone* zone = NULL, | 157 typename Traits::Type::Zone* zone, |
| 154 AstValueFactory* ast_value_factory = NULL); | 158 AstValueFactory* ast_value_factory); |
| 159 FunctionState( | |
| 160 FunctionState** function_state_stack, | |
| 161 typename Traits::Type::Scope** scope_stack, | |
| 162 typename Traits::Type::Scope** scope, | |
| 163 typename Traits::Type::Zone* zone, | |
| 164 AstValueFactory* ast_value_factory); | |
| 155 ~FunctionState(); | 165 ~FunctionState(); |
| 156 | 166 |
| 157 int NextMaterializedLiteralIndex() { | 167 int NextMaterializedLiteralIndex() { |
| 158 return next_materialized_literal_index_++; | 168 return next_materialized_literal_index_++; |
| 159 } | 169 } |
| 160 int materialized_literal_count() { | 170 int materialized_literal_count() { |
| 161 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; | 171 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
| 162 } | 172 } |
| 163 | 173 |
| 164 int NextHandlerIndex() { return next_handler_index_++; } | 174 int NextHandlerIndex() { return next_handler_index_++; } |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 446 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 437 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 447 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 438 ExpressionT ParseUnaryExpression(bool* ok); | 448 ExpressionT ParseUnaryExpression(bool* ok); |
| 439 ExpressionT ParsePostfixExpression(bool* ok); | 449 ExpressionT ParsePostfixExpression(bool* ok); |
| 440 ExpressionT ParseLeftHandSideExpression(bool* ok); | 450 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 441 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 451 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 442 ExpressionT ParseMemberExpression(bool* ok); | 452 ExpressionT ParseMemberExpression(bool* ok); |
| 443 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 453 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 444 bool* ok); | 454 bool* ok); |
| 445 | 455 |
| 456 // There are two ways of parsing arrow functions: if the beginning of an | |
| 457 // arrow function can be determined prior to process the parameter list | |
| 458 // (e.g. the current scanning position is known to be an arrow function | |
| 459 // and not an AssignmentExpression) then the first version is used. In | |
| 460 // most cases, we parse the parameter list as an AssignmentExpression | |
| 461 // and interpret the AST when the arrow "=>" token is found, using the | |
| 462 // second version. | |
| 463 // The overloaded ParseArrowFunctionLiteral() functions mainly deal with | |
| 464 // parsing/interpreting the parameter list, and then they both call | |
| 465 // ParseArrowFunctionLiteralBody() before consuming the arrow token. | |
| 466 ExpressionT ParseArrowFunctionLiteral(bool* ok); | |
|
marja
2014/06/26 14:38:13
Isn't this one dead code? (And isn't the comment a
| |
| 467 ExpressionT ParseArrowFunctionLiteral(int start_pos, | |
| 468 ExpressionT params_ast, | |
| 469 bool* ok); | |
| 470 ExpressionT ParseArrowFunctionLiteralBody( | |
| 471 FunctionState* function_state, | |
| 472 typename Traits::Type::ScopePtr scope, | |
| 473 int num_parameters, | |
| 474 const Scanner::Location& eval_args_error_loc, | |
| 475 const Scanner::Location& dupe_error_loc, | |
| 476 const Scanner::Location& reserved_loc, | |
| 477 FunctionLiteral::IsParenthesizedFlag parenthesized, | |
| 478 int start_pos, | |
| 479 bool* ok); | |
| 480 | |
| 446 // Checks if the expression is a valid reference expression (e.g., on the | 481 // Checks if the expression is a valid reference expression (e.g., on the |
| 447 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 482 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 448 // we allow calls for web compatibility and rewrite them to a runtime throw. | 483 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 449 ExpressionT CheckAndRewriteReferenceExpression( | 484 ExpressionT CheckAndRewriteReferenceExpression( |
| 450 ExpressionT expression, | 485 ExpressionT expression, |
| 451 Scanner::Location location, const char* message, bool* ok); | 486 Scanner::Location location, const char* message, bool* ok); |
| 452 | 487 |
| 453 // Used to detect duplicates in object literals. Each of the values | 488 // Used to detect duplicates in object literals. Each of the values |
| 454 // kGetterProperty, kSetterProperty and kValueProperty represents | 489 // kGetterProperty, kSetterProperty and kValueProperty represents |
| 455 // a type of object literal property. When parsing a property, its | 490 // a type of object literal property. When parsing a property, its |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 | 554 |
| 520 private: | 555 private: |
| 521 Scanner* scanner_; | 556 Scanner* scanner_; |
| 522 uintptr_t stack_limit_; | 557 uintptr_t stack_limit_; |
| 523 bool stack_overflow_; | 558 bool stack_overflow_; |
| 524 | 559 |
| 525 bool allow_lazy_; | 560 bool allow_lazy_; |
| 526 bool allow_natives_syntax_; | 561 bool allow_natives_syntax_; |
| 527 bool allow_generators_; | 562 bool allow_generators_; |
| 528 bool allow_for_of_; | 563 bool allow_for_of_; |
| 564 bool allow_arrow_functions_; | |
| 529 | 565 |
| 530 typename Traits::Type::Zone* zone_; // Only used by Parser. | 566 typename Traits::Type::Zone* zone_; // Only used by Parser. |
| 531 }; | 567 }; |
| 532 | 568 |
| 533 | 569 |
| 534 class PreParserIdentifier { | 570 class PreParserIdentifier { |
| 535 public: | 571 public: |
| 536 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 572 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 537 static PreParserIdentifier Default() { | 573 static PreParserIdentifier Default() { |
| 538 return PreParserIdentifier(kUnknownIdentifier); | 574 return PreParserIdentifier(kUnknownIdentifier); |
| 539 } | 575 } |
| 540 static PreParserIdentifier Eval() { | 576 static PreParserIdentifier Eval() { |
| 541 return PreParserIdentifier(kEvalIdentifier); | 577 return PreParserIdentifier(kEvalIdentifier); |
| 542 } | 578 } |
| 543 static PreParserIdentifier Arguments() { | 579 static PreParserIdentifier Arguments() { |
| 544 return PreParserIdentifier(kArgumentsIdentifier); | 580 return PreParserIdentifier(kArgumentsIdentifier); |
| 545 } | 581 } |
| 546 static PreParserIdentifier FutureReserved() { | 582 static PreParserIdentifier FutureReserved() { |
| 547 return PreParserIdentifier(kFutureReservedIdentifier); | 583 return PreParserIdentifier(kFutureReservedIdentifier); |
| 548 } | 584 } |
| 549 static PreParserIdentifier FutureStrictReserved() { | 585 static PreParserIdentifier FutureStrictReserved() { |
| 550 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 586 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
| 551 } | 587 } |
| 552 static PreParserIdentifier Yield() { | 588 static PreParserIdentifier Yield() { |
| 553 return PreParserIdentifier(kYieldIdentifier); | 589 return PreParserIdentifier(kYieldIdentifier); |
| 554 } | 590 } |
| 555 bool IsEval() { return type_ == kEvalIdentifier; } | 591 bool IsEval() const { return type_ == kEvalIdentifier; } |
| 556 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 592 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
| 557 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 593 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } |
| 558 bool IsYield() { return type_ == kYieldIdentifier; } | 594 bool IsYield() const { return type_ == kYieldIdentifier; } |
| 559 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 595 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } |
| 560 bool IsFutureStrictReserved() { | 596 bool IsFutureStrictReserved() const { |
| 561 return type_ == kFutureStrictReservedIdentifier; | 597 return type_ == kFutureStrictReservedIdentifier; |
| 562 } | 598 } |
| 563 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 599 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } |
| 564 | 600 |
| 601 // Allow identifier->name()[->length()] to work. The preparser | |
| 602 // does not need the actual positions/lengths of the identifiers. | |
| 603 const PreParserIdentifier* operator->() const { return this; } | |
| 604 const PreParserIdentifier raw_name() const { return *this; } | |
| 605 | |
| 606 int position() const { | |
| 607 return 0; | |
| 608 } | |
| 609 | |
| 610 int length() const { | |
|
marja
2014/06/26 14:38:13
This is used for duplicate parameter error message
| |
| 611 if (IsEval()) return 4; | |
| 612 if (IsArguments()) return 9; | |
| 613 if (IsYield()) return 5; | |
| 614 return 0; | |
| 615 } | |
| 616 | |
| 565 private: | 617 private: |
| 566 enum Type { | 618 enum Type { |
| 567 kUnknownIdentifier, | 619 kUnknownIdentifier, |
| 568 kFutureReservedIdentifier, | 620 kFutureReservedIdentifier, |
| 569 kFutureStrictReservedIdentifier, | 621 kFutureStrictReservedIdentifier, |
| 570 kYieldIdentifier, | 622 kYieldIdentifier, |
| 571 kEvalIdentifier, | 623 kEvalIdentifier, |
| 572 kArgumentsIdentifier | 624 kArgumentsIdentifier |
| 573 }; | 625 }; |
| 574 explicit PreParserIdentifier(Type type) : type_(type) {} | 626 explicit PreParserIdentifier(Type type) : type_(type) {} |
| 575 Type type_; | 627 Type type_; |
| 576 | 628 |
| 577 friend class PreParserExpression; | 629 friend class PreParserExpression; |
| 630 friend class PreParserScope; | |
| 578 }; | 631 }; |
| 579 | 632 |
| 580 | 633 |
| 581 // Bits 0 and 1 are used to identify the type of expression: | 634 // Bits 0 and 1 are used to identify the type of expression: |
| 582 // If bit 0 is set, it's an identifier. | 635 // If bit 0 is set, it's an identifier. |
| 583 // if bit 1 is set, it's a string literal. | 636 // if bit 1 is set, it's a string literal. |
| 584 // If neither is set, it's no particular type, and both set isn't | 637 // If neither is set, it's no particular type, and both set isn't |
| 585 // use yet. | 638 // use yet. |
| 586 class PreParserExpression { | 639 class PreParserExpression { |
| 587 public: | 640 public: |
| 588 static PreParserExpression Default() { | 641 static PreParserExpression Default() { |
| 589 return PreParserExpression(kUnknownExpression); | 642 return PreParserExpression(kUnknownExpression); |
| 590 } | 643 } |
| 591 | 644 |
| 592 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 645 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
| 593 return PreParserExpression(kIdentifierFlag | | 646 return PreParserExpression(kTypeIdentifier | |
| 594 (id.type_ << kIdentifierShift)); | 647 (id.type_ << kIdentifierShift)); |
| 595 } | 648 } |
| 596 | 649 |
| 650 static PreParserExpression BinaryOperation(PreParserExpression left, | |
| 651 Token::Value op, | |
| 652 PreParserExpression right) { | |
| 653 int code = ((op == Token::COMMA) && | |
| 654 !left.is_parenthesized() && | |
| 655 !right.is_parenthesized()) | |
| 656 ? left.ArrowParamListBit() & right.ArrowParamListBit() : 0; | |
| 657 return PreParserExpression(kTypeBinaryOperation | code); | |
| 658 } | |
| 659 | |
| 660 static PreParserExpression EmptyArrowParamList() { | |
| 661 // Any expression for which IsValidArrowParamList() returns true | |
| 662 // will work here. | |
| 663 return FromIdentifier(PreParserIdentifier::Default()); | |
| 664 } | |
| 665 | |
| 597 static PreParserExpression StringLiteral() { | 666 static PreParserExpression StringLiteral() { |
| 598 return PreParserExpression(kUnknownStringLiteral); | 667 return PreParserExpression(kUnknownStringLiteral); |
| 599 } | 668 } |
| 600 | 669 |
| 601 static PreParserExpression UseStrictStringLiteral() { | 670 static PreParserExpression UseStrictStringLiteral() { |
| 602 return PreParserExpression(kUseStrictString); | 671 return PreParserExpression(kUseStrictString); |
| 603 } | 672 } |
| 604 | 673 |
| 605 static PreParserExpression This() { | 674 static PreParserExpression This() { |
| 606 return PreParserExpression(kThisExpression); | 675 return PreParserExpression(kThisExpression); |
| 607 } | 676 } |
| 608 | 677 |
| 609 static PreParserExpression ThisProperty() { | 678 static PreParserExpression ThisProperty() { |
| 610 return PreParserExpression(kThisPropertyExpression); | 679 return PreParserExpression(kThisPropertyExpression); |
| 611 } | 680 } |
| 612 | 681 |
| 613 static PreParserExpression Property() { | 682 static PreParserExpression Property() { |
| 614 return PreParserExpression(kPropertyExpression); | 683 return PreParserExpression(kPropertyExpression); |
| 615 } | 684 } |
| 616 | 685 |
| 617 static PreParserExpression Call() { | 686 static PreParserExpression Call() { |
| 618 return PreParserExpression(kCallExpression); | 687 return PreParserExpression(kCallExpression); |
| 619 } | 688 } |
| 620 | 689 |
| 621 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } | 690 bool IsIdentifier() const { |
| 691 return (code_ & kTypeMask) == kTypeIdentifier; | |
| 692 } | |
| 622 | 693 |
| 623 PreParserIdentifier AsIdentifier() { | 694 PreParserIdentifier AsIdentifier() const { |
| 624 ASSERT(IsIdentifier()); | 695 ASSERT(IsIdentifier()); |
| 625 return PreParserIdentifier( | 696 return PreParserIdentifier( |
| 626 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 697 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); |
| 627 } | 698 } |
| 628 | 699 |
| 629 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 700 bool IsStringLiteral() const { |
| 701 return (code_ & kTypeMask) == kTypeStringLiteral; | |
| 702 } | |
| 630 | 703 |
| 631 bool IsUseStrictLiteral() { | 704 bool IsUseStrictLiteral() { |
| 632 return (code_ & kStringLiteralMask) == kUseStrictString; | 705 return (code_ & kUseStrictString) == kUseStrictString; |
| 633 } | 706 } |
| 634 | 707 |
| 635 bool IsThis() { return code_ == kThisExpression; } | 708 bool IsThis() { return code_ == kThisExpression; } |
| 636 | 709 |
| 637 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 710 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
| 638 | 711 |
| 639 bool IsProperty() { | 712 bool IsProperty() { |
| 640 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 713 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
| 641 } | 714 } |
| 642 | 715 |
| 643 bool IsCall() { return code_ == kCallExpression; } | 716 bool IsCall() { return code_ == kCallExpression; } |
| 644 | 717 |
| 645 bool IsValidReferenceExpression() { | 718 bool IsValidReferenceExpression() { |
| 646 return IsIdentifier() || IsProperty(); | 719 return IsIdentifier() || IsProperty(); |
| 647 } | 720 } |
| 648 | 721 |
| 722 bool IsValidArrowParamList() const { | |
| 723 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 | |
| 724 && (code_ & kMultiParenthesizedExpression) == 0; | |
| 725 } | |
| 726 | |
| 649 // At the moment PreParser doesn't track these expression types. | 727 // At the moment PreParser doesn't track these expression types. |
| 650 bool IsFunctionLiteral() const { return false; } | 728 bool IsFunctionLiteral() const { return false; } |
| 651 bool IsCallNew() const { return false; } | 729 bool IsCallNew() const { return false; } |
| 652 | 730 |
| 653 PreParserExpression AsFunctionLiteral() { return *this; } | 731 PreParserExpression AsFunctionLiteral() { return *this; } |
| 654 | 732 |
| 733 bool IsBinaryOperation() const { | |
| 734 return (code_ & kTypeMask) == kTypeBinaryOperation; | |
| 735 } | |
| 736 | |
| 737 bool is_parenthesized() const { | |
| 738 return (code_ & kParenthesizedExpression) != 0; | |
| 739 } | |
| 740 void set_is_parenthesized(bool value) { | |
| 741 if (value) { | |
| 742 code_ |= is_parenthesized() | |
| 743 ? kMultiParenthesizedExpression | |
| 744 : kParenthesizedExpression; | |
| 745 } else { | |
| 746 code_ &= ~kParenthesizedExpression; | |
| 747 } | |
| 748 } | |
| 749 | |
| 655 // Dummy implementation for making expression->somefunc() work in both Parser | 750 // Dummy implementation for making expression->somefunc() work in both Parser |
| 656 // and PreParser. | 751 // and PreParser. |
| 657 PreParserExpression* operator->() { return this; } | 752 PreParserExpression* operator->() { return this; } |
| 658 | 753 |
| 659 // More dummy implementations of things PreParser doesn't need to track: | 754 // More dummy implementations of things PreParser doesn't need to track: |
| 660 void set_index(int index) {} // For YieldExpressions | 755 void set_index(int index) {} // For YieldExpressions |
| 661 void set_parenthesized() {} | 756 void set_parenthesized() {} |
| 662 | 757 |
| 758 int position() const { return RelocInfo::kNoPosition; } | |
| 759 void set_function_token_position(int position) {} | |
| 760 void set_ast_properties(int* ast_properties) {} | |
| 761 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} | |
| 762 | |
| 763 bool operator==(const PreParserExpression& other) const { | |
| 764 return code_ == other.code_; | |
| 765 } | |
| 766 bool operator!=(const PreParserExpression& other) const { | |
| 767 return code_ != other.code_; | |
| 768 } | |
| 769 | |
| 663 private: | 770 private: |
| 664 // Least significant 2 bits are used as flags. Bits 0 and 1 represent | 771 // Least significant 2 bits are used as expression type. The third least |
| 665 // identifiers or strings literals, and are mutually exclusive, but can both | 772 // significant bit tracks whether an expression is parenthesized. If the |
| 666 // be absent. If the expression is an identifier or a string literal, the | 773 // expression is an identifier or a string literal, the other bits |
| 667 // other bits describe the type (see PreParserIdentifier::Type and string | 774 // describe the type/ (see PreParserIdentifier::Type and string literal |
| 668 // literal constants below). | 775 // constants below). For binary operations, the other bits are flags |
| 776 // which further describe the contents of the expression. | |
| 669 enum { | 777 enum { |
| 670 kUnknownExpression = 0, | 778 kUnknownExpression = 0, |
| 779 | |
| 780 kTypeMask = 1 | 2, | |
| 781 kParenthesizedExpression = (1 << 2), | |
| 782 kMultiParenthesizedExpression = (1 << 3), | |
| 783 | |
| 671 // Identifiers | 784 // Identifiers |
| 672 kIdentifierFlag = 1, // Used to detect labels. | 785 kTypeIdentifier = 1, // Used to detect labels. |
| 673 kIdentifierShift = 3, | 786 kIdentifierShift = 5, |
| 674 | 787 |
| 675 kStringLiteralFlag = 2, // Used to detect directive prologue. | 788 kTypeStringLiteral = 2, // Used to detect directive prologue. |
| 676 kUnknownStringLiteral = kStringLiteralFlag, | 789 kUnknownStringLiteral = kTypeStringLiteral, |
| 677 kUseStrictString = kStringLiteralFlag | 8, | 790 kUseStrictString = kTypeStringLiteral | 32, |
| 678 kStringLiteralMask = kUseStrictString, | 791 kStringLiteralMask = kUseStrictString, |
| 679 | 792 |
| 793 // Binary operations. Those are needed to detect certain keywords and | |
| 794 // duplicated identifier in parameter lists for arrow functions, because | |
| 795 // they are initially parsed as comma-separated expressions. | |
| 796 kTypeBinaryOperation = 3, | |
| 797 kBinaryOperationArrowParamList = (1 << 4), | |
| 798 | |
| 680 // Below here applies if neither identifier nor string literal. Reserve the | 799 // Below here applies if neither identifier nor string literal. Reserve the |
| 681 // 2 least significant bits for flags. | 800 // 2 least significant bits for flags. |
| 682 kThisExpression = 1 << 2, | 801 kThisExpression = (1 << 4), |
| 683 kThisPropertyExpression = 2 << 2, | 802 kThisPropertyExpression = (2 << 4), |
| 684 kPropertyExpression = 3 << 2, | 803 kPropertyExpression = (3 << 4), |
| 685 kCallExpression = 4 << 2 | 804 kCallExpression = (4 << 4) |
| 686 }; | 805 }; |
| 687 | 806 |
| 688 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 807 explicit PreParserExpression(int expression_code) : code_(expression_code) {} |
| 689 | 808 |
| 809 V8_INLINE int ArrowParamListBit() const { | |
| 810 if (IsBinaryOperation()) | |
| 811 return code_ & kBinaryOperationArrowParamList; | |
| 812 if (IsIdentifier()) { | |
| 813 const PreParserIdentifier ident = AsIdentifier(); | |
| 814 // A valid identifier can be an arrow function parameter list | |
| 815 // except for eval, arguments, yield, and reserved keywords. | |
| 816 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() | |
| 817 || ident.IsFutureStrictReserved()) | |
| 818 return 0; | |
| 819 return kBinaryOperationArrowParamList; | |
| 820 } | |
| 821 return 0; | |
| 822 } | |
| 823 | |
| 690 int code_; | 824 int code_; |
| 691 }; | 825 }; |
| 692 | 826 |
| 693 | 827 |
| 694 // PreParserExpressionList doesn't actually store the expressions because | 828 // PreParserExpressionList doesn't actually store the expressions because |
| 695 // PreParser doesn't need to. | 829 // PreParser doesn't need to. |
| 696 class PreParserExpressionList { | 830 class PreParserExpressionList { |
| 697 public: | 831 public: |
| 698 // These functions make list->Add(some_expression) work (and do nothing). | 832 // These functions make list->Add(some_expression) work (and do nothing). |
| 699 PreParserExpressionList() : length_(0) {} | 833 PreParserExpressionList() : length_(0) {} |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 761 public: | 895 public: |
| 762 // These functions make list->Add(some_expression) work as no-ops. | 896 // These functions make list->Add(some_expression) work as no-ops. |
| 763 PreParserStatementList() {} | 897 PreParserStatementList() {} |
| 764 PreParserStatementList* operator->() { return this; } | 898 PreParserStatementList* operator->() { return this; } |
| 765 void Add(PreParserStatement, void*) {} | 899 void Add(PreParserStatement, void*) {} |
| 766 }; | 900 }; |
| 767 | 901 |
| 768 | 902 |
| 769 class PreParserScope { | 903 class PreParserScope { |
| 770 public: | 904 public: |
| 771 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) | 905 explicit PreParserScope(PreParserScope* outer_scope, |
| 772 : scope_type_(scope_type) { | 906 ScopeType scope_type, |
| 907 void* = NULL) | |
| 908 : scope_type_(scope_type), declared_parameters_(0) { | |
| 773 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 909 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
| 774 } | 910 } |
| 775 | 911 |
| 776 ScopeType type() { return scope_type_; } | 912 ScopeType type() { return scope_type_; } |
| 777 StrictMode strict_mode() const { return strict_mode_; } | 913 StrictMode strict_mode() const { return strict_mode_; } |
| 778 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 914 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
| 779 | 915 |
| 916 // TODO(aperezdc): Would allowing lazy compilation in preparser make sense? | |
| 917 bool AllowsLazyCompilation() const { return false; } | |
| 918 | |
| 919 void set_start_position(int position) {} | |
| 920 void set_end_position(int position) {} | |
| 921 | |
| 922 bool IsDeclared(const PreParserIdentifier& identifier) const { | |
| 923 return (declared_parameters_ & (1 << identifier.type_)) != 0; | |
| 924 } | |
| 925 | |
| 926 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) { | |
| 927 declared_parameters_ |= (1 << identifier.type_); | |
| 928 } | |
| 929 | |
| 930 // Allow scope->Foo() to work. | |
| 931 PreParserScope* operator->() { return this; } | |
| 932 | |
| 780 private: | 933 private: |
| 781 ScopeType scope_type_; | 934 ScopeType scope_type_; |
| 782 StrictMode strict_mode_; | 935 StrictMode strict_mode_; |
| 936 int declared_parameters_; | |
| 783 }; | 937 }; |
| 784 | 938 |
| 785 | 939 |
| 786 class PreParserFactory { | 940 class PreParserFactory { |
| 787 public: | 941 public: |
| 788 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} | 942 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} |
| 789 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 943 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
| 790 int pos) { | 944 int pos) { |
| 791 return PreParserExpression::Default(); | 945 return PreParserExpression::Default(); |
| 792 } | 946 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 833 return PreParserExpression::Property(); | 987 return PreParserExpression::Property(); |
| 834 } | 988 } |
| 835 PreParserExpression NewUnaryOperation(Token::Value op, | 989 PreParserExpression NewUnaryOperation(Token::Value op, |
| 836 PreParserExpression expression, | 990 PreParserExpression expression, |
| 837 int pos) { | 991 int pos) { |
| 838 return PreParserExpression::Default(); | 992 return PreParserExpression::Default(); |
| 839 } | 993 } |
| 840 PreParserExpression NewBinaryOperation(Token::Value op, | 994 PreParserExpression NewBinaryOperation(Token::Value op, |
| 841 PreParserExpression left, | 995 PreParserExpression left, |
| 842 PreParserExpression right, int pos) { | 996 PreParserExpression right, int pos) { |
| 843 return PreParserExpression::Default(); | 997 return PreParserExpression::BinaryOperation(left, op, right); |
| 844 } | 998 } |
| 845 PreParserExpression NewCompareOperation(Token::Value op, | 999 PreParserExpression NewCompareOperation(Token::Value op, |
| 846 PreParserExpression left, | 1000 PreParserExpression left, |
| 847 PreParserExpression right, int pos) { | 1001 PreParserExpression right, int pos) { |
| 848 return PreParserExpression::Default(); | 1002 return PreParserExpression::Default(); |
| 849 } | 1003 } |
| 850 PreParserExpression NewAssignment(Token::Value op, | 1004 PreParserExpression NewAssignment(Token::Value op, |
| 851 PreParserExpression left, | 1005 PreParserExpression left, |
| 852 PreParserExpression right, | 1006 PreParserExpression right, |
| 853 int pos) { | 1007 int pos) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 874 PreParserExpression NewCall(PreParserExpression expression, | 1028 PreParserExpression NewCall(PreParserExpression expression, |
| 875 PreParserExpressionList arguments, | 1029 PreParserExpressionList arguments, |
| 876 int pos) { | 1030 int pos) { |
| 877 return PreParserExpression::Call(); | 1031 return PreParserExpression::Call(); |
| 878 } | 1032 } |
| 879 PreParserExpression NewCallNew(PreParserExpression expression, | 1033 PreParserExpression NewCallNew(PreParserExpression expression, |
| 880 PreParserExpressionList arguments, | 1034 PreParserExpressionList arguments, |
| 881 int pos) { | 1035 int pos) { |
| 882 return PreParserExpression::Default(); | 1036 return PreParserExpression::Default(); |
| 883 } | 1037 } |
| 1038 PreParserStatement NewReturnStatement(PreParserExpression expression, | |
| 1039 int pos) { | |
| 1040 return PreParserStatement::Default(); | |
| 1041 } | |
| 1042 PreParserExpression | |
| 1043 NewFunctionLiteral(PreParserIdentifier name, | |
| 1044 PreParserScope& scope, | |
| 1045 PreParserStatementList body, | |
| 1046 int materialized_literal_count, | |
| 1047 int expected_property_count, | |
| 1048 int handler_count, | |
| 1049 int parameter_count, | |
| 1050 FunctionLiteral::ParameterFlag has_duplicate_parameters, | |
| 1051 FunctionLiteral::FunctionType function_type, | |
| 1052 FunctionLiteral::IsFunctionFlag is_function, | |
| 1053 FunctionLiteral::IsParenthesizedFlag is_parenthesized, | |
| 1054 FunctionLiteral::IsGeneratorFlag is_generator, | |
| 1055 int position) { | |
| 1056 return PreParserExpression::Default(); | |
| 1057 } | |
| 1058 | |
| 1059 // Return the object itself as AstVisitor and implement the needed | |
| 1060 // dummy method right in this class. | |
| 1061 PreParserFactory* visitor() { return this; } | |
| 1062 BailoutReason dont_optimize_reason() { return kNoReason; } | |
| 1063 int* ast_properties() { static int dummy = 42; return &dummy; } | |
| 884 }; | 1064 }; |
| 885 | 1065 |
| 886 | 1066 |
| 887 class PreParser; | 1067 class PreParser; |
| 888 | 1068 |
| 889 class PreParserTraits { | 1069 class PreParserTraits { |
| 890 public: | 1070 public: |
| 891 struct Type { | 1071 struct Type { |
| 892 // TODO(marja): To be removed. The Traits object should contain all the data | 1072 // TODO(marja): To be removed. The Traits object should contain all the data |
| 893 // it needs. | 1073 // it needs. |
| 894 typedef PreParser* Parser; | 1074 typedef PreParser* Parser; |
| 895 | 1075 |
| 896 // Used by FunctionState and BlockState. | 1076 // Used by FunctionState and BlockState. |
| 897 typedef PreParserScope Scope; | 1077 typedef PreParserScope Scope; |
| 1078 typedef PreParserScope ScopePtr; | |
| 1079 | |
| 898 // PreParser doesn't need to store generator variables. | 1080 // PreParser doesn't need to store generator variables. |
| 899 typedef void GeneratorVariable; | 1081 typedef void GeneratorVariable; |
| 900 // No interaction with Zones. | 1082 // No interaction with Zones. |
| 901 typedef void Zone; | 1083 typedef void Zone; |
| 902 | 1084 |
| 1085 typedef int AstProperties; | |
| 1086 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; | |
| 1087 | |
| 903 // Return types for traversing functions. | 1088 // Return types for traversing functions. |
| 904 typedef PreParserIdentifier Identifier; | 1089 typedef PreParserIdentifier Identifier; |
| 905 typedef PreParserExpression Expression; | 1090 typedef PreParserExpression Expression; |
| 906 typedef PreParserExpression YieldExpression; | 1091 typedef PreParserExpression YieldExpression; |
| 907 typedef PreParserExpression FunctionLiteral; | 1092 typedef PreParserExpression FunctionLiteral; |
| 908 typedef PreParserExpression ObjectLiteralProperty; | 1093 typedef PreParserExpression ObjectLiteralProperty; |
| 909 typedef PreParserExpression Literal; | 1094 typedef PreParserExpression Literal; |
| 910 typedef PreParserExpressionList ExpressionList; | 1095 typedef PreParserExpressionList ExpressionList; |
| 911 typedef PreParserExpressionList PropertyList; | 1096 typedef PreParserExpressionList PropertyList; |
| 912 typedef PreParserStatementList StatementList; | 1097 typedef PreParserStatementList StatementList; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 935 } | 1120 } |
| 936 | 1121 |
| 937 static bool IsIdentifier(PreParserExpression expression) { | 1122 static bool IsIdentifier(PreParserExpression expression) { |
| 938 return expression.IsIdentifier(); | 1123 return expression.IsIdentifier(); |
| 939 } | 1124 } |
| 940 | 1125 |
| 941 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { | 1126 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
| 942 return expression.AsIdentifier(); | 1127 return expression.AsIdentifier(); |
| 943 } | 1128 } |
| 944 | 1129 |
| 1130 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { | |
| 1131 return identifier.IsYield() || identifier.IsFutureStrictReserved(); | |
| 1132 } | |
| 1133 | |
| 945 static bool IsBoilerplateProperty(PreParserExpression property) { | 1134 static bool IsBoilerplateProperty(PreParserExpression property) { |
| 946 // PreParser doesn't count boilerplate properties. | 1135 // PreParser doesn't count boilerplate properties. |
| 947 return false; | 1136 return false; |
| 948 } | 1137 } |
| 949 | 1138 |
| 950 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1139 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
| 951 return false; | 1140 return false; |
| 952 } | 1141 } |
| 953 | 1142 |
| 954 // Functions for encapsulating the differences between parsing and preparsing; | 1143 // Functions for encapsulating the differences between parsing and preparsing; |
| 955 // operations interleaved with the recursive descent. | 1144 // operations interleaved with the recursive descent. |
| 956 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1145 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
| 957 // PreParser should not use FuncNameInferrer. | 1146 // PreParser should not use FuncNameInferrer. |
| 958 UNREACHABLE(); | 1147 UNREACHABLE(); |
| 959 } | 1148 } |
| 960 static void PushPropertyName(FuncNameInferrer* fni, | 1149 static void PushPropertyName(FuncNameInferrer* fni, |
| 961 PreParserExpression expression) { | 1150 PreParserExpression expression) { |
| 962 // PreParser should not use FuncNameInferrer. | 1151 // PreParser should not use FuncNameInferrer. |
| 963 UNREACHABLE(); | 1152 UNREACHABLE(); |
| 964 } | 1153 } |
| 1154 static void InferFunctionName(FuncNameInferrer* fni, | |
| 1155 PreParserExpression expression) { | |
| 1156 // PreParser should not use FuncNameInferrer. | |
| 1157 UNREACHABLE(); | |
| 1158 } | |
| 965 | 1159 |
| 966 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1160 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
| 967 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 1161 PreParserScope* scope, PreParserExpression value, bool* has_function) {} |
| 968 | 1162 |
| 969 static void CheckAssigningFunctionLiteralToProperty( | 1163 static void CheckAssigningFunctionLiteralToProperty( |
| 970 PreParserExpression left, PreParserExpression right) {} | 1164 PreParserExpression left, PreParserExpression right) {} |
| 971 | 1165 |
| 972 // PreParser doesn't need to keep track of eval calls. | 1166 // PreParser doesn't need to keep track of eval calls. |
| 973 static void CheckPossibleEvalCall(PreParserExpression expression, | 1167 static void CheckPossibleEvalCall(PreParserExpression expression, |
| 974 PreParserScope* scope) {} | 1168 PreParserScope* scope) {} |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 998 return PreParserExpression::Default(); | 1192 return PreParserExpression::Default(); |
| 999 } | 1193 } |
| 1000 PreParserExpression NewThrowSyntaxError( | 1194 PreParserExpression NewThrowSyntaxError( |
| 1001 const char* type, Handle<Object> arg, int pos) { | 1195 const char* type, Handle<Object> arg, int pos) { |
| 1002 return PreParserExpression::Default(); | 1196 return PreParserExpression::Default(); |
| 1003 } | 1197 } |
| 1004 PreParserExpression NewThrowTypeError( | 1198 PreParserExpression NewThrowTypeError( |
| 1005 const char* type, Handle<Object> arg, int pos) { | 1199 const char* type, Handle<Object> arg, int pos) { |
| 1006 return PreParserExpression::Default(); | 1200 return PreParserExpression::Default(); |
| 1007 } | 1201 } |
| 1202 PreParserScope NewScope(PreParserScope* outer_scope, | |
| 1203 ScopeType scope_type) { | |
| 1204 return PreParserScope(outer_scope, scope_type); | |
| 1205 } | |
| 1008 | 1206 |
| 1009 // Reporting errors. | 1207 // Reporting errors. |
| 1010 void ReportMessageAt(Scanner::Location location, | 1208 void ReportMessageAt(Scanner::Location location, |
| 1011 const char* message, | 1209 const char* message, |
| 1012 const char* arg = NULL, | 1210 const char* arg = NULL, |
| 1013 bool is_reference_error = false); | 1211 bool is_reference_error = false); |
| 1014 void ReportMessageAt(int start_pos, | 1212 void ReportMessageAt(int start_pos, |
| 1015 int end_pos, | 1213 int end_pos, |
| 1016 const char* message, | 1214 const char* message, |
| 1017 const char* arg = NULL, | 1215 const char* arg = NULL, |
| 1018 bool is_reference_error = false); | 1216 bool is_reference_error = false); |
| 1019 | 1217 |
| 1020 // "null" return type creators. | 1218 // "null" return type creators. |
| 1021 static PreParserIdentifier EmptyIdentifier() { | 1219 static PreParserIdentifier EmptyIdentifier() { |
| 1022 return PreParserIdentifier::Default(); | 1220 return PreParserIdentifier::Default(); |
| 1023 } | 1221 } |
| 1222 static PreParserIdentifier EmptyIdentifierString() { | |
| 1223 return PreParserIdentifier::Default(); | |
| 1224 } | |
| 1024 static PreParserExpression EmptyExpression() { | 1225 static PreParserExpression EmptyExpression() { |
| 1025 return PreParserExpression::Default(); | 1226 return PreParserExpression::Default(); |
| 1026 } | 1227 } |
| 1228 static PreParserExpression EmptyArrowParamList() { | |
| 1229 return PreParserExpression::EmptyArrowParamList(); | |
| 1230 } | |
| 1027 static PreParserExpression EmptyLiteral() { | 1231 static PreParserExpression EmptyLiteral() { |
| 1028 return PreParserExpression::Default(); | 1232 return PreParserExpression::Default(); |
| 1029 } | 1233 } |
| 1030 static PreParserExpressionList NullExpressionList() { | 1234 static PreParserExpressionList NullExpressionList() { |
| 1031 return PreParserExpressionList(); | 1235 return PreParserExpressionList(); |
| 1032 } | 1236 } |
| 1033 | 1237 |
| 1034 // Odd-ball literal creators. | 1238 // Odd-ball literal creators. |
| 1035 static PreParserExpression GetLiteralTheHole(int position, | 1239 static PreParserExpression GetLiteralTheHole(int position, |
| 1036 PreParserFactory* factory) { | 1240 PreParserFactory* factory) { |
| 1037 return PreParserExpression::Default(); | 1241 return PreParserExpression::Default(); |
| 1038 } | 1242 } |
| 1039 | 1243 |
| 1040 // Producing data during the recursive descent. | 1244 // Producing data during the recursive descent. |
| 1041 PreParserIdentifier GetSymbol(Scanner* scanner); | 1245 PreParserIdentifier GetSymbol(Scanner* scanner); |
| 1042 | 1246 |
| 1043 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { | 1247 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { |
| 1044 return PreParserIdentifier::Default(); | 1248 return PreParserIdentifier::Default(); |
| 1045 } | 1249 } |
| 1046 | 1250 |
| 1047 static PreParserExpression ThisExpression(PreParserScope* scope, | 1251 static PreParserExpression ThisExpression(PreParserScope* scope, |
| 1048 PreParserFactory* factory) { | 1252 PreParserFactory* factory, |
| 1253 int pos) { | |
| 1049 return PreParserExpression::This(); | 1254 return PreParserExpression::This(); |
| 1050 } | 1255 } |
| 1051 | 1256 |
| 1052 static PreParserExpression ExpressionFromLiteral( | 1257 static PreParserExpression ExpressionFromLiteral( |
| 1053 Token::Value token, int pos, Scanner* scanner, | 1258 Token::Value token, int pos, Scanner* scanner, |
| 1054 PreParserFactory* factory) { | 1259 PreParserFactory* factory) { |
| 1055 return PreParserExpression::Default(); | 1260 return PreParserExpression::Default(); |
| 1056 } | 1261 } |
| 1057 | 1262 |
| 1058 static PreParserExpression ExpressionFromIdentifier( | 1263 static PreParserExpression ExpressionFromIdentifier( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1070 } | 1275 } |
| 1071 | 1276 |
| 1072 static PreParserStatementList NewStatementList(int size, void* zone) { | 1277 static PreParserStatementList NewStatementList(int size, void* zone) { |
| 1073 return PreParserStatementList(); | 1278 return PreParserStatementList(); |
| 1074 } | 1279 } |
| 1075 | 1280 |
| 1076 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1281 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
| 1077 return PreParserExpressionList(); | 1282 return PreParserExpressionList(); |
| 1078 } | 1283 } |
| 1079 | 1284 |
| 1285 V8_INLINE void SkipLazyFunctionBody( | |
| 1286 PreParserIdentifier function_name, | |
| 1287 int* materialized_literal_count, | |
| 1288 int* expected_property_count, | |
| 1289 bool* ok) { | |
| 1290 UNREACHABLE(); | |
| 1291 } | |
| 1292 | |
| 1293 V8_INLINE PreParserStatementList ParseEagerFunctionBody( | |
| 1294 PreParserIdentifier function_name, | |
| 1295 int pos, | |
| 1296 Variable* fvar, | |
| 1297 Token::Value fvar_init_op, | |
| 1298 bool is_generator, | |
| 1299 bool* ok); | |
| 1300 | |
| 1301 // Utility functions | |
| 1302 Vector<PreParserIdentifier> ParameterListFromExpression( | |
| 1303 PreParserExpression expression) { | |
| 1304 return Vector<PreParserIdentifier>::empty(); | |
| 1305 } | |
| 1306 bool IsValidArrowFunctionParameterList(PreParserExpression expression) { | |
| 1307 // TODO(aperez): Detect duplicated identifiers in paramlists. | |
| 1308 return expression.IsValidArrowParamList(); | |
| 1309 } | |
| 1310 static AstValueFactory* ast_value_factory() { return NULL; } | |
| 1311 | |
| 1312 void CheckConflictingVarDeclarations( | |
| 1313 PreParserScope scope, | |
| 1314 bool* ok) {} | |
| 1315 | |
| 1080 // Temporary glue; these functions will move to ParserBase. | 1316 // Temporary glue; these functions will move to ParserBase. |
| 1081 PreParserExpression ParseV8Intrinsic(bool* ok); | 1317 PreParserExpression ParseV8Intrinsic(bool* ok); |
| 1082 PreParserExpression ParseFunctionLiteral( | 1318 PreParserExpression ParseFunctionLiteral( |
| 1083 PreParserIdentifier name, | 1319 PreParserIdentifier name, |
| 1084 Scanner::Location function_name_location, | 1320 Scanner::Location function_name_location, |
| 1085 bool name_is_strict_reserved, | 1321 bool name_is_strict_reserved, |
| 1086 bool is_generator, | 1322 bool is_generator, |
| 1087 int function_token_position, | 1323 int function_token_position, |
| 1088 FunctionLiteral::FunctionType type, | 1324 FunctionLiteral::FunctionType type, |
| 1089 FunctionLiteral::ArityRestriction arity_restriction, | 1325 FunctionLiteral::ArityRestriction arity_restriction, |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1120 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1356 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
| 1121 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1357 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
| 1122 this) {} | 1358 this) {} |
| 1123 | 1359 |
| 1124 // Pre-parse the program from the character stream; returns true on | 1360 // Pre-parse the program from the character stream; returns true on |
| 1125 // success (even if parsing failed, the pre-parse data successfully | 1361 // success (even if parsing failed, the pre-parse data successfully |
| 1126 // captured the syntax error), and false if a stack-overflow happened | 1362 // captured the syntax error), and false if a stack-overflow happened |
| 1127 // during parsing. | 1363 // during parsing. |
| 1128 PreParseResult PreParseProgram() { | 1364 PreParseResult PreParseProgram() { |
| 1129 PreParserScope scope(scope_, GLOBAL_SCOPE); | 1365 PreParserScope scope(scope_, GLOBAL_SCOPE); |
| 1130 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); | 1366 FunctionState top_scope(&function_state_, &scope_, &scope, |
| 1367 zone(), this->ast_value_factory()); | |
| 1131 bool ok = true; | 1368 bool ok = true; |
| 1132 int start_position = scanner()->peek_location().beg_pos; | 1369 int start_position = scanner()->peek_location().beg_pos; |
| 1133 ParseSourceElements(Token::EOS, &ok); | 1370 ParseSourceElements(Token::EOS, &ok); |
| 1134 if (stack_overflow()) return kPreParseStackOverflow; | 1371 if (stack_overflow()) return kPreParseStackOverflow; |
| 1135 if (!ok) { | 1372 if (!ok) { |
| 1136 ReportUnexpectedToken(scanner()->current_token()); | 1373 ReportUnexpectedToken(scanner()->current_token()); |
| 1137 } else if (scope_->strict_mode() == STRICT) { | 1374 } else if (scope_->strict_mode() == STRICT) { |
| 1138 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 1375 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
| 1139 } | 1376 } |
| 1140 return kPreParseSuccess; | 1377 return kPreParseSuccess; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1202 Statement ParseDoWhileStatement(bool* ok); | 1439 Statement ParseDoWhileStatement(bool* ok); |
| 1203 Statement ParseWhileStatement(bool* ok); | 1440 Statement ParseWhileStatement(bool* ok); |
| 1204 Statement ParseForStatement(bool* ok); | 1441 Statement ParseForStatement(bool* ok); |
| 1205 Statement ParseThrowStatement(bool* ok); | 1442 Statement ParseThrowStatement(bool* ok); |
| 1206 Statement ParseTryStatement(bool* ok); | 1443 Statement ParseTryStatement(bool* ok); |
| 1207 Statement ParseDebuggerStatement(bool* ok); | 1444 Statement ParseDebuggerStatement(bool* ok); |
| 1208 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1445 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
| 1209 Expression ParseObjectLiteral(bool* ok); | 1446 Expression ParseObjectLiteral(bool* ok); |
| 1210 Expression ParseV8Intrinsic(bool* ok); | 1447 Expression ParseV8Intrinsic(bool* ok); |
| 1211 | 1448 |
| 1449 V8_INLINE void SkipLazyFunctionBody( | |
| 1450 PreParserIdentifier function_name, | |
| 1451 int* materialized_literal_count, | |
| 1452 int* expected_property_count, | |
| 1453 bool* ok); | |
| 1454 V8_INLINE PreParserStatementList ParseEagerFunctionBody( | |
| 1455 PreParserIdentifier function_name, | |
| 1456 int pos, | |
| 1457 Variable* fvar, | |
| 1458 Token::Value fvar_init_op, | |
| 1459 bool is_generator, | |
| 1460 bool* ok); | |
| 1461 | |
| 1212 Expression ParseFunctionLiteral( | 1462 Expression ParseFunctionLiteral( |
| 1213 Identifier name, | 1463 Identifier name, |
| 1214 Scanner::Location function_name_location, | 1464 Scanner::Location function_name_location, |
| 1215 bool name_is_strict_reserved, | 1465 bool name_is_strict_reserved, |
| 1216 bool is_generator, | 1466 bool is_generator, |
| 1217 int function_token_pos, | 1467 int function_token_pos, |
| 1218 FunctionLiteral::FunctionType function_type, | 1468 FunctionLiteral::FunctionType function_type, |
| 1219 FunctionLiteral::ArityRestriction arity_restriction, | 1469 FunctionLiteral::ArityRestriction arity_restriction, |
| 1220 bool* ok); | 1470 bool* ok); |
| 1221 void ParseLazyFunctionLiteralBody(bool* ok); | 1471 void ParseLazyFunctionLiteralBody(bool* ok); |
| 1222 | 1472 |
| 1223 bool CheckInOrOf(bool accept_OF); | 1473 bool CheckInOrOf(bool accept_OF); |
| 1224 }; | 1474 }; |
| 1225 | 1475 |
| 1476 | |
| 1477 PreParserStatementList PreParser::ParseEagerFunctionBody( | |
| 1478 PreParserIdentifier function_name, | |
| 1479 int pos, | |
| 1480 Variable* fvar, | |
| 1481 Token::Value fvar_init_op, | |
| 1482 bool is_generator, | |
| 1483 bool* ok) { | |
| 1484 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | |
| 1485 | |
| 1486 ParseSourceElements(Token::RBRACE, ok); | |
| 1487 if (!*ok) return PreParserStatementList(); | |
| 1488 | |
| 1489 Expect(Token::RBRACE, ok); | |
| 1490 return PreParserStatementList(); | |
| 1491 } | |
| 1492 | |
| 1493 | |
| 1494 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( | |
| 1495 PreParserIdentifier function_name, | |
| 1496 int pos, | |
| 1497 Variable* fvar, | |
| 1498 Token::Value fvar_init_op, | |
| 1499 bool is_generator, | |
| 1500 bool* ok) { | |
| 1501 return pre_parser_->ParseEagerFunctionBody(function_name, | |
| 1502 pos, fvar, fvar_init_op, is_generator, ok); | |
| 1503 } | |
| 1504 | |
| 1505 | |
| 1226 template<class Traits> | 1506 template<class Traits> |
| 1227 ParserBase<Traits>::FunctionState::FunctionState( | 1507 ParserBase<Traits>::FunctionState::FunctionState( |
| 1228 FunctionState** function_state_stack, | 1508 FunctionState** function_state_stack, |
| 1229 typename Traits::Type::Scope** scope_stack, | 1509 typename Traits::Type::Scope** scope_stack, |
| 1230 typename Traits::Type::Scope* scope, | 1510 typename Traits::Type::Scope* scope, |
| 1231 typename Traits::Type::Zone* extra_param, | 1511 typename Traits::Type::Zone* extra_param, |
| 1232 AstValueFactory* ast_value_factory) | 1512 AstValueFactory* ast_value_factory) |
| 1233 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1513 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 1234 next_handler_index_(0), | 1514 next_handler_index_(0), |
| 1235 expected_property_count_(0), | 1515 expected_property_count_(0), |
| 1236 is_generator_(false), | 1516 is_generator_(false), |
| 1237 generator_object_variable_(NULL), | 1517 generator_object_variable_(NULL), |
| 1238 function_state_stack_(function_state_stack), | 1518 function_state_stack_(function_state_stack), |
| 1239 outer_function_state_(*function_state_stack), | 1519 outer_function_state_(*function_state_stack), |
| 1240 scope_stack_(scope_stack), | 1520 scope_stack_(scope_stack), |
| 1241 outer_scope_(*scope_stack), | 1521 outer_scope_(*scope_stack), |
| 1242 saved_ast_node_id_(0), | 1522 saved_ast_node_id_(0), |
| 1243 extra_param_(extra_param), | 1523 extra_param_(extra_param), |
| 1244 factory_(extra_param, ast_value_factory) { | 1524 factory_(extra_param, ast_value_factory) { |
| 1245 *scope_stack_ = scope; | 1525 *scope_stack_ = scope; |
| 1246 *function_state_stack = this; | 1526 *function_state_stack = this; |
| 1247 Traits::SetUpFunctionState(this, extra_param); | 1527 Traits::SetUpFunctionState(this, extra_param); |
| 1248 } | 1528 } |
| 1249 | 1529 |
| 1250 | 1530 |
| 1251 template<class Traits> | 1531 template<class Traits> |
| 1532 ParserBase<Traits>::FunctionState::FunctionState( | |
| 1533 FunctionState** function_state_stack, | |
| 1534 typename Traits::Type::Scope** scope_stack, | |
| 1535 typename Traits::Type::Scope** scope, | |
| 1536 typename Traits::Type::Zone* extra_param, | |
| 1537 AstValueFactory* ast_value_factory) | |
| 1538 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | |
| 1539 next_handler_index_(0), | |
| 1540 expected_property_count_(0), | |
| 1541 is_generator_(false), | |
| 1542 generator_object_variable_(NULL), | |
| 1543 function_state_stack_(function_state_stack), | |
| 1544 outer_function_state_(*function_state_stack), | |
| 1545 scope_stack_(scope_stack), | |
| 1546 outer_scope_(*scope_stack), | |
| 1547 saved_ast_node_id_(0), | |
| 1548 extra_param_(extra_param), | |
| 1549 factory_(extra_param, ast_value_factory) { | |
| 1550 *scope_stack_ = *scope; | |
| 1551 *function_state_stack = this; | |
| 1552 Traits::SetUpFunctionState(this, extra_param); | |
| 1553 } | |
| 1554 | |
| 1555 | |
| 1556 template<class Traits> | |
| 1252 ParserBase<Traits>::FunctionState::~FunctionState() { | 1557 ParserBase<Traits>::FunctionState::~FunctionState() { |
| 1253 *scope_stack_ = outer_scope_; | 1558 *scope_stack_ = outer_scope_; |
| 1254 *function_state_stack_ = outer_function_state_; | 1559 *function_state_stack_ = outer_function_state_; |
| 1255 Traits::TearDownFunctionState(this, extra_param_); | 1560 Traits::TearDownFunctionState(this, extra_param_); |
| 1256 } | 1561 } |
| 1257 | 1562 |
| 1258 | 1563 |
| 1259 template<class Traits> | 1564 template<class Traits> |
| 1260 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1565 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
| 1261 Scanner::Location source_location = scanner()->location(); | 1566 Scanner::Location source_location = scanner()->location(); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1408 // ObjectLiteral | 1713 // ObjectLiteral |
| 1409 // RegExpLiteral | 1714 // RegExpLiteral |
| 1410 // '(' Expression ')' | 1715 // '(' Expression ')' |
| 1411 | 1716 |
| 1412 int pos = peek_position(); | 1717 int pos = peek_position(); |
| 1413 ExpressionT result = this->EmptyExpression(); | 1718 ExpressionT result = this->EmptyExpression(); |
| 1414 Token::Value token = peek(); | 1719 Token::Value token = peek(); |
| 1415 switch (token) { | 1720 switch (token) { |
| 1416 case Token::THIS: { | 1721 case Token::THIS: { |
| 1417 Consume(Token::THIS); | 1722 Consume(Token::THIS); |
| 1418 result = this->ThisExpression(scope_, factory()); | 1723 result = this->ThisExpression(scope_, factory(), position()); |
| 1419 break; | 1724 break; |
| 1420 } | 1725 } |
| 1421 | 1726 |
| 1422 case Token::NULL_LITERAL: | 1727 case Token::NULL_LITERAL: |
| 1423 case Token::TRUE_LITERAL: | 1728 case Token::TRUE_LITERAL: |
| 1424 case Token::FALSE_LITERAL: | 1729 case Token::FALSE_LITERAL: |
| 1425 case Token::NUMBER: | 1730 case Token::NUMBER: |
| 1426 Next(); | 1731 Next(); |
| 1427 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); | 1732 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
| 1428 break; | 1733 break; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1453 case Token::LBRACK: | 1758 case Token::LBRACK: |
| 1454 result = this->ParseArrayLiteral(CHECK_OK); | 1759 result = this->ParseArrayLiteral(CHECK_OK); |
| 1455 break; | 1760 break; |
| 1456 | 1761 |
| 1457 case Token::LBRACE: | 1762 case Token::LBRACE: |
| 1458 result = this->ParseObjectLiteral(CHECK_OK); | 1763 result = this->ParseObjectLiteral(CHECK_OK); |
| 1459 break; | 1764 break; |
| 1460 | 1765 |
| 1461 case Token::LPAREN: | 1766 case Token::LPAREN: |
| 1462 Consume(Token::LPAREN); | 1767 Consume(Token::LPAREN); |
| 1463 // Heuristically try to detect immediately called functions before | 1768 if (allow_arrow_functions() && peek() == Token::RPAREN) { |
| 1464 // seeing the call parentheses. | 1769 // Arrow functions are the only expression type constructions |
| 1465 parenthesized_function_ = (peek() == Token::FUNCTION); | 1770 // for which an empty parameter list "()" is valid input. |
| 1466 result = this->ParseExpression(true, CHECK_OK); | 1771 Consume(Token::RPAREN); |
| 1467 Expect(Token::RPAREN, CHECK_OK); | 1772 return this->ParseArrowFunctionLiteral(pos, |
| 1773 this->EmptyArrowParamList(), | |
| 1774 CHECK_OK); | |
| 1775 } else { | |
| 1776 // Heuristically try to detect immediately called functions before | |
| 1777 // seeing the call parentheses. | |
| 1778 parenthesized_function_ = (peek() == Token::FUNCTION); | |
| 1779 result = this->ParseExpression(true, CHECK_OK); | |
| 1780 result->set_is_parenthesized(true); | |
| 1781 Expect(Token::RPAREN, CHECK_OK); | |
| 1782 } | |
| 1468 break; | 1783 break; |
| 1469 | 1784 |
| 1470 case Token::MOD: | 1785 case Token::MOD: |
| 1471 if (allow_natives_syntax() || extension_ != NULL) { | 1786 if (allow_natives_syntax() || extension_ != NULL) { |
| 1472 result = this->ParseV8Intrinsic(CHECK_OK); | 1787 result = this->ParseV8Intrinsic(CHECK_OK); |
| 1473 break; | 1788 break; |
| 1474 } | 1789 } |
| 1475 // If we're not allowing special syntax we fall-through to the | 1790 // If we're not allowing special syntax we fall-through to the |
| 1476 // default case. | 1791 // default case. |
| 1477 | 1792 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1725 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2040 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1726 return result; | 2041 return result; |
| 1727 } | 2042 } |
| 1728 | 2043 |
| 1729 // Precedence = 2 | 2044 // Precedence = 2 |
| 1730 template <class Traits> | 2045 template <class Traits> |
| 1731 typename ParserBase<Traits>::ExpressionT | 2046 typename ParserBase<Traits>::ExpressionT |
| 1732 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2047 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 1733 // AssignmentExpression :: | 2048 // AssignmentExpression :: |
| 1734 // ConditionalExpression | 2049 // ConditionalExpression |
| 2050 // ArrowFunction | |
| 1735 // YieldExpression | 2051 // YieldExpression |
| 1736 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2052 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 1737 | 2053 |
| 1738 Scanner::Location lhs_location = scanner()->peek_location(); | 2054 Scanner::Location lhs_location = scanner()->peek_location(); |
| 1739 | 2055 |
| 1740 if (peek() == Token::YIELD && is_generator()) { | 2056 if (peek() == Token::YIELD && is_generator()) { |
| 1741 return this->ParseYieldExpression(ok); | 2057 return this->ParseYieldExpression(ok); |
| 1742 } | 2058 } |
| 1743 | 2059 |
| 1744 if (fni_ != NULL) fni_->Enter(); | 2060 if (fni_ != NULL) fni_->Enter(); |
| 1745 ExpressionT expression = | 2061 ExpressionT expression = |
| 1746 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2062 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
| 1747 | 2063 |
| 2064 if (allow_arrow_functions() && peek() == Token::ARROW) | |
| 2065 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | |
| 2066 expression, | |
| 2067 CHECK_OK); | |
| 2068 | |
| 1748 if (!Token::IsAssignmentOp(peek())) { | 2069 if (!Token::IsAssignmentOp(peek())) { |
| 1749 if (fni_ != NULL) fni_->Leave(); | 2070 if (fni_ != NULL) fni_->Leave(); |
| 1750 // Parsed conditional expression only (no assignment). | 2071 // Parsed conditional expression only (no assignment). |
| 1751 return expression; | 2072 return expression; |
| 1752 } | 2073 } |
| 1753 | 2074 |
| 1754 expression = this->CheckAndRewriteReferenceExpression( | 2075 expression = this->CheckAndRewriteReferenceExpression( |
| 1755 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2076 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
| 1756 expression = this->MarkExpressionAsLValue(expression); | 2077 expression = this->MarkExpressionAsLValue(expression); |
| 1757 | 2078 |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2143 } | 2464 } |
| 2144 default: | 2465 default: |
| 2145 return expression; | 2466 return expression; |
| 2146 } | 2467 } |
| 2147 } | 2468 } |
| 2148 ASSERT(false); | 2469 ASSERT(false); |
| 2149 return this->EmptyExpression(); | 2470 return this->EmptyExpression(); |
| 2150 } | 2471 } |
| 2151 | 2472 |
| 2152 | 2473 |
| 2474 template <class Traits> | |
| 2475 typename ParserBase<Traits>::ExpressionT | |
| 2476 ParserBase<Traits>::ParseArrowFunctionLiteralBody( | |
|
marja
2014/06/26 14:38:13
Nit: reorder the functions here to match the order
| |
| 2477 FunctionState* function_state, | |
| 2478 typename Traits::Type::ScopePtr scope, | |
| 2479 int num_parameters, | |
| 2480 const Scanner::Location& eval_args_error_loc, | |
| 2481 const Scanner::Location& dupe_error_loc, | |
| 2482 const Scanner::Location& reserved_loc, | |
| 2483 FunctionLiteral::IsParenthesizedFlag parenthesized, | |
| 2484 int start_pos, | |
| 2485 bool* ok) { | |
| 2486 | |
| 2487 typename Traits::Type::StatementList body; | |
| 2488 int materialized_literal_count = -1; | |
| 2489 int expected_property_count = -1; | |
| 2490 | |
| 2491 Expect(Token::ARROW, CHECK_OK); | |
| 2492 | |
| 2493 if (peek() == Token::LBRACE) { | |
| 2494 // Multiple statemente body | |
| 2495 Consume(Token::LBRACE); | |
| 2496 | |
| 2497 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | |
| 2498 scope_->AllowsLazyCompilation() && | |
| 2499 !parenthesized_function_); | |
| 2500 parenthesized_function_ = false; // This Was set for this funciton only. | |
|
marja
2014/06/26 14:38:13
1) Why do you need to set parenthesized_function_
| |
| 2501 | |
| 2502 if (is_lazily_parsed) { | |
| 2503 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | |
| 2504 &materialized_literal_count, | |
| 2505 &expected_property_count, | |
| 2506 CHECK_OK); | |
| 2507 } else { | |
| 2508 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(), | |
| 2509 RelocInfo::kNoPosition, | |
| 2510 NULL, | |
| 2511 Token::INIT_VAR, | |
| 2512 false, // Not a generator. | |
| 2513 CHECK_OK); | |
| 2514 } | |
| 2515 } else { | |
| 2516 // Single-expression body | |
| 2517 parenthesized_function_ = false; | |
| 2518 ParseAssignmentExpression(true, CHECK_OK); | |
| 2519 } | |
| 2520 | |
| 2521 scope->set_start_position(start_pos); | |
| 2522 scope->set_end_position(scanner()->location().end_pos); | |
| 2523 | |
| 2524 this->CheckStrictFunctionNameAndParameters(this->EmptyIdentifier(), | |
| 2525 false, | |
| 2526 Scanner::Location::invalid(), | |
| 2527 Scanner::Location::invalid(), | |
| 2528 dupe_error_loc, | |
| 2529 Scanner::Location::invalid(), | |
| 2530 CHECK_OK); | |
| 2531 | |
| 2532 // Validate strict mode. | |
| 2533 if (strict_mode() == STRICT) { | |
| 2534 CheckOctalLiteral(start_pos, | |
| 2535 scanner()->location().end_pos, | |
| 2536 CHECK_OK); | |
| 2537 } | |
| 2538 | |
| 2539 if (allow_harmony_scoping() && strict_mode() == STRICT) | |
| 2540 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | |
| 2541 | |
| 2542 return this->EmptyExpression(); | |
| 2543 } | |
| 2544 | |
| 2545 | |
| 2546 template <class Traits> | |
| 2547 typename ParserBase<Traits>::ExpressionT | |
| 2548 ParserBase<Traits>::ParseArrowFunctionLiteral(bool* ok) { | |
| 2549 // TODO(aperez): Change this to use ARROW_SCOPE | |
| 2550 typename Traits::Type::ScopePtr scope = | |
| 2551 this->NewScope(scope_, FUNCTION_SCOPE); | |
| 2552 | |
| 2553 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | |
| 2554 ? FunctionLiteral::kIsParenthesized | |
| 2555 : FunctionLiteral::kNotParenthesized; | |
| 2556 parenthesized_function_ = false; | |
| 2557 | |
| 2558 int start_pos = position(); | |
| 2559 int num_parameters = 0; | |
| 2560 FunctionState function_state(&function_state_, &scope_, &scope, | |
| 2561 zone(), this->ast_value_factory()); | |
| 2562 | |
| 2563 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | |
| 2564 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | |
| 2565 Scanner::Location reserved_loc = Scanner::Location::invalid(); | |
| 2566 | |
| 2567 if (peek() == Token::LPAREN) { | |
| 2568 // Parse a parenthesized parameter list. | |
| 2569 Consume(Token::LPAREN); | |
| 2570 bool done = (peek() == Token::RPAREN); | |
| 2571 while (!done) { | |
| 2572 bool is_strict_reserved = false; | |
| 2573 IdentifierT param_name = | |
| 2574 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, | |
| 2575 CHECK_OK); | |
| 2576 | |
| 2577 // Store locations for possible future error reports. | |
| 2578 if (!eval_args_error_loc.IsValid() && | |
| 2579 this->IsEvalOrArguments(param_name)) { | |
| 2580 eval_args_error_loc = scanner()->location(); | |
| 2581 } | |
| 2582 if (!reserved_loc.IsValid() && is_strict_reserved) { | |
| 2583 reserved_loc = scanner()->location(); | |
| 2584 } | |
| 2585 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
| 2586 dupe_error_loc = scanner()->location(); | |
| 2587 } | |
| 2588 | |
| 2589 scope_->DeclareParameter(param_name, VAR); | |
| 2590 num_parameters++; | |
| 2591 if (num_parameters > Code::kMaxArguments) { | |
| 2592 this->ReportMessageAt(scanner()->location(), "too_many_parameters"); | |
| 2593 *ok = false; | |
| 2594 return this->EmptyExpression(); | |
| 2595 } | |
| 2596 done = (peek() == Token::RPAREN); | |
| 2597 if (!done) Expect(Token::COMMA, CHECK_OK); | |
| 2598 } | |
| 2599 Expect(Token::RPAREN, CHECK_OK); | |
| 2600 } else { | |
| 2601 // Parse a single parameter identifier. | |
| 2602 bool is_strict_reserved = false; | |
| 2603 IdentifierT param_name = | |
| 2604 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | |
| 2605 | |
| 2606 // Store locations for possible future error reports. | |
| 2607 if (this->IsEvalOrArguments(param_name)) | |
| 2608 eval_args_error_loc = scanner()->location(); | |
| 2609 if (is_strict_reserved) | |
| 2610 reserved_loc = scanner()->location(); | |
| 2611 | |
| 2612 scope_->DeclareParameter(param_name, VAR); | |
| 2613 } | |
| 2614 | |
| 2615 return ParseArrowFunctionLiteralBody(&function_state, | |
| 2616 scope, | |
| 2617 num_parameters, | |
| 2618 eval_args_error_loc, | |
| 2619 dupe_error_loc, | |
| 2620 reserved_loc, | |
| 2621 parenthesized, | |
| 2622 start_pos, | |
| 2623 CHECK_OK); | |
| 2624 } | |
| 2625 | |
| 2626 | |
| 2627 template <class Traits> | |
| 2628 typename ParserBase<Traits>::ExpressionT | |
| 2629 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | |
| 2630 ExpressionT params_ast, | |
| 2631 bool* ok) { | |
| 2632 if (!this->IsValidArrowFunctionParameterList(params_ast)) { | |
| 2633 ReportMessageAt( | |
| 2634 Scanner::Location(start_pos, scanner()->location().beg_pos), | |
| 2635 "strict_parameter_list"); | |
| 2636 *ok = false; | |
| 2637 return this->EmptyExpression(); | |
| 2638 } | |
| 2639 | |
| 2640 // TODO(aperez): Change this to use ARROW_SCOPE | |
| 2641 typename Traits::Type::ScopePtr scope = | |
| 2642 this->NewScope(scope_, FUNCTION_SCOPE); | |
| 2643 | |
| 2644 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | |
| 2645 ? FunctionLiteral::kIsParenthesized | |
| 2646 : FunctionLiteral::kNotParenthesized; | |
| 2647 parenthesized_function_ = false; | |
| 2648 FunctionState function_state(&function_state_, &scope_, &scope, | |
| 2649 zone(), this->ast_value_factory()); | |
| 2650 typename Traits::Type::ParameterIdentifierVector params = | |
| 2651 Traits::ParameterListFromExpression(params_ast); | |
| 2652 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | |
| 2653 | |
| 2654 if (params.length() > Code::kMaxArguments) { | |
| 2655 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
| 2656 "too_many_parameters"); | |
| 2657 *ok = false; | |
| 2658 return this->EmptyExpression(); | |
| 2659 } | |
| 2660 | |
| 2661 // The vector has the items in reverse order. | |
| 2662 for (int i = params.length() - 1; i >= 0; --i) { | |
| 2663 const IdentifierT param_name = params.at(i)->raw_name(); | |
| 2664 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
| 2665 int param_pos = params.at(i)->position(); | |
| 2666 dupe_error_loc = Scanner::Location(param_pos, | |
| 2667 param_pos + param_name->length()); | |
| 2668 } | |
| 2669 scope_->DeclareParameter(param_name, VAR); | |
| 2670 } | |
| 2671 | |
| 2672 return ParseArrowFunctionLiteralBody(&function_state, | |
| 2673 scope, | |
| 2674 params.length(), | |
| 2675 Scanner::Location::invalid(), | |
| 2676 dupe_error_loc, | |
| 2677 Scanner::Location::invalid(), | |
| 2678 parenthesized, | |
| 2679 start_pos, | |
| 2680 CHECK_OK); | |
| 2681 } | |
| 2682 | |
| 2683 | |
| 2153 template <typename Traits> | 2684 template <typename Traits> |
| 2154 typename ParserBase<Traits>::ExpressionT | 2685 typename ParserBase<Traits>::ExpressionT |
| 2155 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2686 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
| 2156 ExpressionT expression, | 2687 ExpressionT expression, |
| 2157 Scanner::Location location, const char* message, bool* ok) { | 2688 Scanner::Location location, const char* message, bool* ok) { |
| 2158 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2689 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
| 2159 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2690 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
| 2160 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2691 this->ReportMessageAt(location, "strict_eval_arguments", false); |
| 2161 *ok = false; | 2692 *ok = false; |
| 2162 return this->EmptyExpression(); | 2693 return this->EmptyExpression(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2206 parser()->ReportMessage("accessor_get_set"); | 2737 parser()->ReportMessage("accessor_get_set"); |
| 2207 } | 2738 } |
| 2208 *ok = false; | 2739 *ok = false; |
| 2209 } | 2740 } |
| 2210 } | 2741 } |
| 2211 | 2742 |
| 2212 | 2743 |
| 2213 } } // v8::internal | 2744 } } // v8::internal |
| 2214 | 2745 |
| 2215 #endif // V8_PREPARSER_H | 2746 #endif // V8_PREPARSER_H |
| OLD | NEW |