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 |