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; | |
66 | 65 |
67 ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, | 66 ParserBase(Scanner* scanner, uintptr_t stack_limit, |
68 ParserRecorder* log, typename Traits::Type::Zone* zone, | 67 v8::Extension* extension, |
| 68 ParserRecorder* log, |
| 69 typename Traits::Type::Zone* zone, |
69 typename Traits::Type::Parser this_object) | 70 typename Traits::Type::Parser this_object) |
70 : Traits(this_object), | 71 : Traits(this_object), |
71 parenthesized_function_(false), | 72 parenthesized_function_(false), |
72 scope_(NULL), | 73 scope_(NULL), |
73 function_state_(NULL), | 74 function_state_(NULL), |
74 extension_(extension), | 75 extension_(extension), |
75 fni_(NULL), | 76 fni_(NULL), |
76 log_(log), | 77 log_(log), |
77 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
78 scanner_(scanner), | 79 scanner_(scanner), |
79 stack_limit_(stack_limit), | 80 stack_limit_(stack_limit), |
80 stack_overflow_(false), | 81 stack_overflow_(false), |
81 allow_lazy_(false), | 82 allow_lazy_(false), |
82 allow_natives_syntax_(false), | 83 allow_natives_syntax_(false), |
83 allow_generators_(false), | 84 allow_generators_(false), |
84 allow_for_of_(false), | 85 allow_for_of_(false), |
85 allow_arrow_functions_(false), | 86 zone_(zone) { } |
86 zone_(zone) {} | |
87 | 87 |
88 // Getters that indicate whether certain syntactical constructs are | 88 // Getters that indicate whether certain syntactical constructs are |
89 // allowed to be parsed by this instance of the parser. | 89 // allowed to be parsed by this instance of the parser. |
90 bool allow_lazy() const { return allow_lazy_; } | 90 bool allow_lazy() const { return allow_lazy_; } |
91 bool allow_natives_syntax() const { return allow_natives_syntax_; } | 91 bool allow_natives_syntax() const { return allow_natives_syntax_; } |
92 bool allow_generators() const { return allow_generators_; } | 92 bool allow_generators() const { return allow_generators_; } |
93 bool allow_for_of() const { return allow_for_of_; } | 93 bool allow_for_of() const { return allow_for_of_; } |
94 bool allow_arrow_functions() const { return allow_arrow_functions_; } | |
95 bool allow_modules() const { return scanner()->HarmonyModules(); } | 94 bool allow_modules() const { return scanner()->HarmonyModules(); } |
96 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 95 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
97 bool allow_harmony_numeric_literals() const { | 96 bool allow_harmony_numeric_literals() const { |
98 return scanner()->HarmonyNumericLiterals(); | 97 return scanner()->HarmonyNumericLiterals(); |
99 } | 98 } |
100 | 99 |
101 // Setters that determine whether certain syntactical constructs are | 100 // Setters that determine whether certain syntactical constructs are |
102 // allowed to be parsed by this instance of the parser. | 101 // allowed to be parsed by this instance of the parser. |
103 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 102 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
104 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 103 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
105 void set_allow_generators(bool allow) { allow_generators_ = allow; } | 104 void set_allow_generators(bool allow) { allow_generators_ = allow; } |
106 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 105 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
107 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } | |
108 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 106 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
109 void set_allow_harmony_scoping(bool allow) { | 107 void set_allow_harmony_scoping(bool allow) { |
110 scanner()->SetHarmonyScoping(allow); | 108 scanner()->SetHarmonyScoping(allow); |
111 } | 109 } |
112 void set_allow_harmony_numeric_literals(bool allow) { | 110 void set_allow_harmony_numeric_literals(bool allow) { |
113 scanner()->SetHarmonyNumericLiterals(allow); | 111 scanner()->SetHarmonyNumericLiterals(allow); |
114 } | 112 } |
115 | 113 |
116 protected: | 114 protected: |
117 enum AllowEvalOrArgumentsAsIdentifier { | 115 enum AllowEvalOrArgumentsAsIdentifier { |
(...skipping 29 matching lines...) Expand all Loading... |
147 }; | 145 }; |
148 | 146 |
149 class FunctionState BASE_EMBEDDED { | 147 class FunctionState BASE_EMBEDDED { |
150 public: | 148 public: |
151 FunctionState( | 149 FunctionState( |
152 FunctionState** function_state_stack, | 150 FunctionState** function_state_stack, |
153 typename Traits::Type::Scope** scope_stack, | 151 typename Traits::Type::Scope** scope_stack, |
154 typename Traits::Type::Scope* scope, | 152 typename Traits::Type::Scope* scope, |
155 typename Traits::Type::Zone* zone = NULL, | 153 typename Traits::Type::Zone* zone = NULL, |
156 AstValueFactory* ast_value_factory = NULL); | 154 AstValueFactory* ast_value_factory = NULL); |
157 FunctionState(FunctionState** function_state_stack, | |
158 typename Traits::Type::Scope** scope_stack, | |
159 typename Traits::Type::Scope** scope, | |
160 typename Traits::Type::Zone* zone = NULL, | |
161 AstValueFactory* ast_value_factory = NULL); | |
162 ~FunctionState(); | 155 ~FunctionState(); |
163 | 156 |
164 int NextMaterializedLiteralIndex() { | 157 int NextMaterializedLiteralIndex() { |
165 return next_materialized_literal_index_++; | 158 return next_materialized_literal_index_++; |
166 } | 159 } |
167 int materialized_literal_count() { | 160 int materialized_literal_count() { |
168 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; | 161 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
169 } | 162 } |
170 | 163 |
171 int NextHandlerIndex() { return next_handler_index_++; } | 164 int NextHandlerIndex() { return next_handler_index_++; } |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 ExpressionT ParseYieldExpression(bool* ok); | 435 ExpressionT ParseYieldExpression(bool* ok); |
443 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 436 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
444 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 437 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
445 ExpressionT ParseUnaryExpression(bool* ok); | 438 ExpressionT ParseUnaryExpression(bool* ok); |
446 ExpressionT ParsePostfixExpression(bool* ok); | 439 ExpressionT ParsePostfixExpression(bool* ok); |
447 ExpressionT ParseLeftHandSideExpression(bool* ok); | 440 ExpressionT ParseLeftHandSideExpression(bool* ok); |
448 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 441 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
449 ExpressionT ParseMemberExpression(bool* ok); | 442 ExpressionT ParseMemberExpression(bool* ok); |
450 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 443 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
451 bool* ok); | 444 bool* ok); |
452 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | |
453 bool* ok); | |
454 ExpressionT ParseArrowFunctionLiteralBody( | |
455 FunctionState* function_state, typename Traits::Type::ScopePtr scope, | |
456 int num_parameters, const Scanner::Location& eval_args_error_loc, | |
457 const Scanner::Location& dupe_error_loc, | |
458 const Scanner::Location& reserved_loc, | |
459 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos, | |
460 bool* ok); | |
461 | 445 |
462 // Checks if the expression is a valid reference expression (e.g., on the | 446 // Checks if the expression is a valid reference expression (e.g., on the |
463 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 447 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
464 // we allow calls for web compatibility and rewrite them to a runtime throw. | 448 // we allow calls for web compatibility and rewrite them to a runtime throw. |
465 ExpressionT CheckAndRewriteReferenceExpression( | 449 ExpressionT CheckAndRewriteReferenceExpression( |
466 ExpressionT expression, | 450 ExpressionT expression, |
467 Scanner::Location location, const char* message, bool* ok); | 451 Scanner::Location location, const char* message, bool* ok); |
468 | 452 |
469 // Used to detect duplicates in object literals. Each of the values | 453 // Used to detect duplicates in object literals. Each of the values |
470 // kGetterProperty, kSetterProperty and kValueProperty represents | 454 // kGetterProperty, kSetterProperty and kValueProperty represents |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 | 519 |
536 private: | 520 private: |
537 Scanner* scanner_; | 521 Scanner* scanner_; |
538 uintptr_t stack_limit_; | 522 uintptr_t stack_limit_; |
539 bool stack_overflow_; | 523 bool stack_overflow_; |
540 | 524 |
541 bool allow_lazy_; | 525 bool allow_lazy_; |
542 bool allow_natives_syntax_; | 526 bool allow_natives_syntax_; |
543 bool allow_generators_; | 527 bool allow_generators_; |
544 bool allow_for_of_; | 528 bool allow_for_of_; |
545 bool allow_arrow_functions_; | |
546 | 529 |
547 typename Traits::Type::Zone* zone_; // Only used by Parser. | 530 typename Traits::Type::Zone* zone_; // Only used by Parser. |
548 }; | 531 }; |
549 | 532 |
550 | 533 |
551 class PreParserIdentifier { | 534 class PreParserIdentifier { |
552 public: | 535 public: |
553 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 536 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
554 static PreParserIdentifier Default() { | 537 static PreParserIdentifier Default() { |
555 return PreParserIdentifier(kUnknownIdentifier); | 538 return PreParserIdentifier(kUnknownIdentifier); |
556 } | 539 } |
557 static PreParserIdentifier Eval() { | 540 static PreParserIdentifier Eval() { |
558 return PreParserIdentifier(kEvalIdentifier); | 541 return PreParserIdentifier(kEvalIdentifier); |
559 } | 542 } |
560 static PreParserIdentifier Arguments() { | 543 static PreParserIdentifier Arguments() { |
561 return PreParserIdentifier(kArgumentsIdentifier); | 544 return PreParserIdentifier(kArgumentsIdentifier); |
562 } | 545 } |
563 static PreParserIdentifier FutureReserved() { | 546 static PreParserIdentifier FutureReserved() { |
564 return PreParserIdentifier(kFutureReservedIdentifier); | 547 return PreParserIdentifier(kFutureReservedIdentifier); |
565 } | 548 } |
566 static PreParserIdentifier FutureStrictReserved() { | 549 static PreParserIdentifier FutureStrictReserved() { |
567 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 550 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
568 } | 551 } |
569 static PreParserIdentifier Let() { | 552 static PreParserIdentifier Let() { |
570 return PreParserIdentifier(kLetIdentifier); | 553 return PreParserIdentifier(kLetIdentifier); |
571 } | 554 } |
572 static PreParserIdentifier Yield() { | 555 static PreParserIdentifier Yield() { |
573 return PreParserIdentifier(kYieldIdentifier); | 556 return PreParserIdentifier(kYieldIdentifier); |
574 } | 557 } |
575 bool IsEval() const { return type_ == kEvalIdentifier; } | 558 bool IsEval() { return type_ == kEvalIdentifier; } |
576 bool IsArguments() const { return type_ == kArgumentsIdentifier; } | 559 bool IsArguments() { return type_ == kArgumentsIdentifier; } |
577 bool IsEvalOrArguments() const { return type_ >= kEvalIdentifier; } | 560 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } |
578 bool IsLet() const { return type_ == kLetIdentifier; } | 561 bool IsYield() { return type_ == kYieldIdentifier; } |
579 bool IsYield() const { return type_ == kYieldIdentifier; } | 562 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } |
580 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } | 563 bool IsFutureStrictReserved() { |
581 bool IsFutureStrictReserved() const { | |
582 return type_ == kFutureStrictReservedIdentifier; | 564 return type_ == kFutureStrictReservedIdentifier; |
583 } | 565 } |
584 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } | 566 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } |
585 | |
586 // Allow identifier->name()[->length()] to work. The preparser | |
587 // does not need the actual positions/lengths of the identifiers. | |
588 const PreParserIdentifier* operator->() const { return this; } | |
589 const PreParserIdentifier raw_name() const { return *this; } | |
590 | |
591 int position() const { return 0; } | |
592 int length() const { return 0; } | |
593 | 567 |
594 private: | 568 private: |
595 enum Type { | 569 enum Type { |
596 kUnknownIdentifier, | 570 kUnknownIdentifier, |
597 kFutureReservedIdentifier, | 571 kFutureReservedIdentifier, |
598 kFutureStrictReservedIdentifier, | 572 kFutureStrictReservedIdentifier, |
599 kLetIdentifier, | 573 kLetIdentifier, |
600 kYieldIdentifier, | 574 kYieldIdentifier, |
601 kEvalIdentifier, | 575 kEvalIdentifier, |
602 kArgumentsIdentifier | 576 kArgumentsIdentifier |
603 }; | 577 }; |
604 explicit PreParserIdentifier(Type type) : type_(type) {} | 578 explicit PreParserIdentifier(Type type) : type_(type) {} |
605 Type type_; | 579 Type type_; |
606 | 580 |
607 friend class PreParserExpression; | 581 friend class PreParserExpression; |
608 friend class PreParserScope; | |
609 }; | 582 }; |
610 | 583 |
611 | 584 |
612 // Bits 0 and 1 are used to identify the type of expression: | 585 // Bits 0 and 1 are used to identify the type of expression: |
613 // If bit 0 is set, it's an identifier. | 586 // If bit 0 is set, it's an identifier. |
614 // if bit 1 is set, it's a string literal. | 587 // if bit 1 is set, it's a string literal. |
615 // If neither is set, it's no particular type, and both set isn't | 588 // If neither is set, it's no particular type, and both set isn't |
616 // use yet. | 589 // use yet. |
617 class PreParserExpression { | 590 class PreParserExpression { |
618 public: | 591 public: |
619 static PreParserExpression Default() { | 592 static PreParserExpression Default() { |
620 return PreParserExpression(kUnknownExpression); | 593 return PreParserExpression(kUnknownExpression); |
621 } | 594 } |
622 | 595 |
623 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 596 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
624 return PreParserExpression(kTypeIdentifier | | 597 return PreParserExpression(kIdentifierFlag | |
625 (id.type_ << kIdentifierShift)); | 598 (id.type_ << kIdentifierShift)); |
626 } | 599 } |
627 | 600 |
628 static PreParserExpression BinaryOperation(PreParserExpression left, | |
629 Token::Value op, | |
630 PreParserExpression right) { | |
631 int code = ((op == Token::COMMA) && !left.is_parenthesized() && | |
632 !right.is_parenthesized()) | |
633 ? left.ArrowParamListBit() & right.ArrowParamListBit() | |
634 : 0; | |
635 return PreParserExpression(kTypeBinaryOperation | code); | |
636 } | |
637 | |
638 static PreParserExpression EmptyArrowParamList() { | |
639 // Any expression for which IsValidArrowParamList() returns true | |
640 // will work here. | |
641 return FromIdentifier(PreParserIdentifier::Default()); | |
642 } | |
643 | |
644 static PreParserExpression StringLiteral() { | 601 static PreParserExpression StringLiteral() { |
645 return PreParserExpression(kUnknownStringLiteral); | 602 return PreParserExpression(kUnknownStringLiteral); |
646 } | 603 } |
647 | 604 |
648 static PreParserExpression UseStrictStringLiteral() { | 605 static PreParserExpression UseStrictStringLiteral() { |
649 return PreParserExpression(kUseStrictString); | 606 return PreParserExpression(kUseStrictString); |
650 } | 607 } |
651 | 608 |
652 static PreParserExpression This() { | 609 static PreParserExpression This() { |
653 return PreParserExpression(kThisExpression); | 610 return PreParserExpression(kThisExpression); |
654 } | 611 } |
655 | 612 |
656 static PreParserExpression ThisProperty() { | 613 static PreParserExpression ThisProperty() { |
657 return PreParserExpression(kThisPropertyExpression); | 614 return PreParserExpression(kThisPropertyExpression); |
658 } | 615 } |
659 | 616 |
660 static PreParserExpression Property() { | 617 static PreParserExpression Property() { |
661 return PreParserExpression(kPropertyExpression); | 618 return PreParserExpression(kPropertyExpression); |
662 } | 619 } |
663 | 620 |
664 static PreParserExpression Call() { | 621 static PreParserExpression Call() { |
665 return PreParserExpression(kCallExpression); | 622 return PreParserExpression(kCallExpression); |
666 } | 623 } |
667 | 624 |
668 bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; } | 625 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } |
669 | 626 |
670 PreParserIdentifier AsIdentifier() const { | 627 PreParserIdentifier AsIdentifier() { |
671 ASSERT(IsIdentifier()); | 628 ASSERT(IsIdentifier()); |
672 return PreParserIdentifier( | 629 return PreParserIdentifier( |
673 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 630 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); |
674 } | 631 } |
675 | 632 |
676 bool IsStringLiteral() const { | 633 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } |
677 return (code_ & kTypeMask) == kTypeStringLiteral; | |
678 } | |
679 | 634 |
680 bool IsUseStrictLiteral() { | 635 bool IsUseStrictLiteral() { |
681 return (code_ & kUseStrictString) == kUseStrictString; | 636 return (code_ & kStringLiteralMask) == kUseStrictString; |
682 } | 637 } |
683 | 638 |
684 bool IsThis() { return code_ == kThisExpression; } | 639 bool IsThis() { return code_ == kThisExpression; } |
685 | 640 |
686 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 641 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
687 | 642 |
688 bool IsProperty() { | 643 bool IsProperty() { |
689 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 644 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
690 } | 645 } |
691 | 646 |
692 bool IsCall() { return code_ == kCallExpression; } | 647 bool IsCall() { return code_ == kCallExpression; } |
693 | 648 |
694 bool IsValidReferenceExpression() { | 649 bool IsValidReferenceExpression() { |
695 return IsIdentifier() || IsProperty(); | 650 return IsIdentifier() || IsProperty(); |
696 } | 651 } |
697 | 652 |
698 bool IsValidArrowParamList() const { | |
699 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 && | |
700 (code_ & kMultiParenthesizedExpression) == 0; | |
701 } | |
702 | |
703 // At the moment PreParser doesn't track these expression types. | 653 // At the moment PreParser doesn't track these expression types. |
704 bool IsFunctionLiteral() const { return false; } | 654 bool IsFunctionLiteral() const { return false; } |
705 bool IsCallNew() const { return false; } | 655 bool IsCallNew() const { return false; } |
706 | 656 |
707 PreParserExpression AsFunctionLiteral() { return *this; } | 657 PreParserExpression AsFunctionLiteral() { return *this; } |
708 | 658 |
709 bool IsBinaryOperation() const { | |
710 return (code_ & kTypeMask) == kTypeBinaryOperation; | |
711 } | |
712 | |
713 bool is_parenthesized() const { | |
714 return (code_ & kParenthesizedExpression) != 0; | |
715 } | |
716 | |
717 void increase_parenthesization_level() { | |
718 code_ |= is_parenthesized() ? kMultiParenthesizedExpression | |
719 : kParenthesizedExpression; | |
720 } | |
721 | |
722 // Dummy implementation for making expression->somefunc() work in both Parser | 659 // Dummy implementation for making expression->somefunc() work in both Parser |
723 // and PreParser. | 660 // and PreParser. |
724 PreParserExpression* operator->() { return this; } | 661 PreParserExpression* operator->() { return this; } |
725 | 662 |
726 // More dummy implementations of things PreParser doesn't need to track: | 663 // More dummy implementations of things PreParser doesn't need to track: |
727 void set_index(int index) {} // For YieldExpressions | 664 void set_index(int index) {} // For YieldExpressions |
728 void set_parenthesized() {} | 665 void set_parenthesized() {} |
729 | 666 |
730 int position() const { return RelocInfo::kNoPosition; } | |
731 void set_function_token_position(int position) {} | |
732 void set_ast_properties(int* ast_properties) {} | |
733 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} | |
734 | |
735 bool operator==(const PreParserExpression& other) const { | |
736 return code_ == other.code_; | |
737 } | |
738 bool operator!=(const PreParserExpression& other) const { | |
739 return code_ != other.code_; | |
740 } | |
741 | |
742 private: | 667 private: |
743 // Least significant 2 bits are used as expression type. The third least | 668 // Least significant 2 bits are used as flags. Bits 0 and 1 represent |
744 // significant bit tracks whether an expression is parenthesized. If the | 669 // identifiers or strings literals, and are mutually exclusive, but can both |
745 // expression is an identifier or a string literal, the other bits | 670 // be absent. If the expression is an identifier or a string literal, the |
746 // describe the type/ (see PreParserIdentifier::Type and string literal | 671 // other bits describe the type (see PreParserIdentifier::Type and string |
747 // constants below). For binary operations, the other bits are flags | 672 // literal constants below). |
748 // which further describe the contents of the expression. | |
749 enum { | 673 enum { |
750 kUnknownExpression = 0, | 674 kUnknownExpression = 0, |
751 kTypeMask = 1 | 2, | 675 // Identifiers |
752 kParenthesizedExpression = (1 << 2), | 676 kIdentifierFlag = 1, // Used to detect labels. |
753 kMultiParenthesizedExpression = (1 << 3), | 677 kIdentifierShift = 3, |
754 | 678 |
755 // Identifiers | 679 kStringLiteralFlag = 2, // Used to detect directive prologue. |
756 kTypeIdentifier = 1, // Used to detect labels. | 680 kUnknownStringLiteral = kStringLiteralFlag, |
757 kIdentifierShift = 5, | 681 kUseStrictString = kStringLiteralFlag | 8, |
758 kTypeStringLiteral = 2, // Used to detect directive prologue. | |
759 kUnknownStringLiteral = kTypeStringLiteral, | |
760 kUseStrictString = kTypeStringLiteral | 32, | |
761 kStringLiteralMask = kUseStrictString, | 682 kStringLiteralMask = kUseStrictString, |
762 | 683 |
763 // Binary operations. Those are needed to detect certain keywords and | |
764 // duplicated identifier in parameter lists for arrow functions, because | |
765 // they are initially parsed as comma-separated expressions. | |
766 kTypeBinaryOperation = 3, | |
767 kBinaryOperationArrowParamList = (1 << 4), | |
768 | |
769 // Below here applies if neither identifier nor string literal. Reserve the | 684 // Below here applies if neither identifier nor string literal. Reserve the |
770 // 2 least significant bits for flags. | 685 // 2 least significant bits for flags. |
771 kThisExpression = (1 << 4), | 686 kThisExpression = 1 << 2, |
772 kThisPropertyExpression = (2 << 4), | 687 kThisPropertyExpression = 2 << 2, |
773 kPropertyExpression = (3 << 4), | 688 kPropertyExpression = 3 << 2, |
774 kCallExpression = (4 << 4) | 689 kCallExpression = 4 << 2 |
775 }; | 690 }; |
776 | 691 |
777 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 692 explicit PreParserExpression(int expression_code) : code_(expression_code) {} |
778 | 693 |
779 V8_INLINE int ArrowParamListBit() const { | |
780 if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList; | |
781 if (IsIdentifier()) { | |
782 const PreParserIdentifier ident = AsIdentifier(); | |
783 // A valid identifier can be an arrow function parameter list | |
784 // except for eval, arguments, yield, and reserved keywords. | |
785 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() || | |
786 ident.IsFutureStrictReserved()) | |
787 return 0; | |
788 return kBinaryOperationArrowParamList; | |
789 } | |
790 return 0; | |
791 } | |
792 | |
793 int code_; | 694 int code_; |
794 }; | 695 }; |
795 | 696 |
796 | 697 |
797 // PreParserExpressionList doesn't actually store the expressions because | 698 // PreParserExpressionList doesn't actually store the expressions because |
798 // PreParser doesn't need to. | 699 // PreParser doesn't need to. |
799 class PreParserExpressionList { | 700 class PreParserExpressionList { |
800 public: | 701 public: |
801 // These functions make list->Add(some_expression) work (and do nothing). | 702 // These functions make list->Add(some_expression) work (and do nothing). |
802 PreParserExpressionList() : length_(0) {} | 703 PreParserExpressionList() : length_(0) {} |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 public: | 765 public: |
865 // These functions make list->Add(some_expression) work as no-ops. | 766 // These functions make list->Add(some_expression) work as no-ops. |
866 PreParserStatementList() {} | 767 PreParserStatementList() {} |
867 PreParserStatementList* operator->() { return this; } | 768 PreParserStatementList* operator->() { return this; } |
868 void Add(PreParserStatement, void*) {} | 769 void Add(PreParserStatement, void*) {} |
869 }; | 770 }; |
870 | 771 |
871 | 772 |
872 class PreParserScope { | 773 class PreParserScope { |
873 public: | 774 public: |
874 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, | 775 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) |
875 void* = NULL) | |
876 : scope_type_(scope_type) { | 776 : scope_type_(scope_type) { |
877 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 777 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
878 } | 778 } |
879 | 779 |
880 ScopeType type() { return scope_type_; } | 780 ScopeType type() { return scope_type_; } |
881 StrictMode strict_mode() const { return strict_mode_; } | 781 StrictMode strict_mode() const { return strict_mode_; } |
882 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 782 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
883 | 783 |
884 // When PreParser is in use, lazy compilation is already being done, | |
885 // things cannot get lazier than that. | |
886 bool AllowsLazyCompilation() const { return false; } | |
887 | |
888 void set_start_position(int position) {} | |
889 void set_end_position(int position) {} | |
890 | |
891 bool IsDeclared(const PreParserIdentifier& identifier) const { return false; } | |
892 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {} | |
893 | |
894 // Allow scope->Foo() to work. | |
895 PreParserScope* operator->() { return this; } | |
896 | |
897 private: | 784 private: |
898 ScopeType scope_type_; | 785 ScopeType scope_type_; |
899 StrictMode strict_mode_; | 786 StrictMode strict_mode_; |
900 }; | 787 }; |
901 | 788 |
902 | 789 |
903 class PreParserFactory { | 790 class PreParserFactory { |
904 public: | 791 public: |
905 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} | 792 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} |
906 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 793 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 return PreParserExpression::Property(); | 837 return PreParserExpression::Property(); |
951 } | 838 } |
952 PreParserExpression NewUnaryOperation(Token::Value op, | 839 PreParserExpression NewUnaryOperation(Token::Value op, |
953 PreParserExpression expression, | 840 PreParserExpression expression, |
954 int pos) { | 841 int pos) { |
955 return PreParserExpression::Default(); | 842 return PreParserExpression::Default(); |
956 } | 843 } |
957 PreParserExpression NewBinaryOperation(Token::Value op, | 844 PreParserExpression NewBinaryOperation(Token::Value op, |
958 PreParserExpression left, | 845 PreParserExpression left, |
959 PreParserExpression right, int pos) { | 846 PreParserExpression right, int pos) { |
960 return PreParserExpression::BinaryOperation(left, op, right); | 847 return PreParserExpression::Default(); |
961 } | 848 } |
962 PreParserExpression NewCompareOperation(Token::Value op, | 849 PreParserExpression NewCompareOperation(Token::Value op, |
963 PreParserExpression left, | 850 PreParserExpression left, |
964 PreParserExpression right, int pos) { | 851 PreParserExpression right, int pos) { |
965 return PreParserExpression::Default(); | 852 return PreParserExpression::Default(); |
966 } | 853 } |
967 PreParserExpression NewAssignment(Token::Value op, | 854 PreParserExpression NewAssignment(Token::Value op, |
968 PreParserExpression left, | 855 PreParserExpression left, |
969 PreParserExpression right, | 856 PreParserExpression right, |
970 int pos) { | 857 int pos) { |
(...skipping 20 matching lines...) Expand all Loading... |
991 PreParserExpression NewCall(PreParserExpression expression, | 878 PreParserExpression NewCall(PreParserExpression expression, |
992 PreParserExpressionList arguments, | 879 PreParserExpressionList arguments, |
993 int pos) { | 880 int pos) { |
994 return PreParserExpression::Call(); | 881 return PreParserExpression::Call(); |
995 } | 882 } |
996 PreParserExpression NewCallNew(PreParserExpression expression, | 883 PreParserExpression NewCallNew(PreParserExpression expression, |
997 PreParserExpressionList arguments, | 884 PreParserExpressionList arguments, |
998 int pos) { | 885 int pos) { |
999 return PreParserExpression::Default(); | 886 return PreParserExpression::Default(); |
1000 } | 887 } |
1001 PreParserStatement NewReturnStatement(PreParserExpression expression, | |
1002 int pos) { | |
1003 return PreParserStatement::Default(); | |
1004 } | |
1005 PreParserExpression NewFunctionLiteral( | |
1006 PreParserIdentifier name, AstValueFactory* ast_value_factory, | |
1007 const PreParserScope& scope, PreParserStatementList body, | |
1008 int materialized_literal_count, int expected_property_count, | |
1009 int handler_count, int parameter_count, | |
1010 FunctionLiteral::ParameterFlag has_duplicate_parameters, | |
1011 FunctionLiteral::FunctionType function_type, | |
1012 FunctionLiteral::IsFunctionFlag is_function, | |
1013 FunctionLiteral::IsParenthesizedFlag is_parenthesized, | |
1014 FunctionLiteral::IsGeneratorFlag is_generator, int position) { | |
1015 return PreParserExpression::Default(); | |
1016 } | |
1017 | |
1018 // Return the object itself as AstVisitor and implement the needed | |
1019 // dummy method right in this class. | |
1020 PreParserFactory* visitor() { return this; } | |
1021 BailoutReason dont_optimize_reason() { return kNoReason; } | |
1022 int* ast_properties() { | |
1023 static int dummy = 42; | |
1024 return &dummy; | |
1025 } | |
1026 }; | 888 }; |
1027 | 889 |
1028 | 890 |
1029 class PreParser; | 891 class PreParser; |
1030 | 892 |
1031 class PreParserTraits { | 893 class PreParserTraits { |
1032 public: | 894 public: |
1033 struct Type { | 895 struct Type { |
1034 // TODO(marja): To be removed. The Traits object should contain all the data | 896 // TODO(marja): To be removed. The Traits object should contain all the data |
1035 // it needs. | 897 // it needs. |
1036 typedef PreParser* Parser; | 898 typedef PreParser* Parser; |
1037 | 899 |
1038 // Used by FunctionState and BlockState. | 900 // Used by FunctionState and BlockState. |
1039 typedef PreParserScope Scope; | 901 typedef PreParserScope Scope; |
1040 typedef PreParserScope ScopePtr; | |
1041 | |
1042 // PreParser doesn't need to store generator variables. | 902 // PreParser doesn't need to store generator variables. |
1043 typedef void GeneratorVariable; | 903 typedef void GeneratorVariable; |
1044 // No interaction with Zones. | 904 // No interaction with Zones. |
1045 typedef void Zone; | 905 typedef void Zone; |
1046 | 906 |
1047 typedef int AstProperties; | |
1048 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; | |
1049 | |
1050 // Return types for traversing functions. | 907 // Return types for traversing functions. |
1051 typedef PreParserIdentifier Identifier; | 908 typedef PreParserIdentifier Identifier; |
1052 typedef PreParserExpression Expression; | 909 typedef PreParserExpression Expression; |
1053 typedef PreParserExpression YieldExpression; | 910 typedef PreParserExpression YieldExpression; |
1054 typedef PreParserExpression FunctionLiteral; | 911 typedef PreParserExpression FunctionLiteral; |
1055 typedef PreParserExpression ObjectLiteralProperty; | 912 typedef PreParserExpression ObjectLiteralProperty; |
1056 typedef PreParserExpression Literal; | 913 typedef PreParserExpression Literal; |
1057 typedef PreParserExpressionList ExpressionList; | 914 typedef PreParserExpressionList ExpressionList; |
1058 typedef PreParserExpressionList PropertyList; | 915 typedef PreParserExpressionList PropertyList; |
1059 typedef PreParserStatementList StatementList; | 916 typedef PreParserStatementList StatementList; |
(...skipping 22 matching lines...) Expand all Loading... |
1082 } | 939 } |
1083 | 940 |
1084 static bool IsIdentifier(PreParserExpression expression) { | 941 static bool IsIdentifier(PreParserExpression expression) { |
1085 return expression.IsIdentifier(); | 942 return expression.IsIdentifier(); |
1086 } | 943 } |
1087 | 944 |
1088 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { | 945 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
1089 return expression.AsIdentifier(); | 946 return expression.AsIdentifier(); |
1090 } | 947 } |
1091 | 948 |
1092 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { | |
1093 return identifier.IsYield() || identifier.IsFutureStrictReserved(); | |
1094 } | |
1095 | |
1096 static bool IsBoilerplateProperty(PreParserExpression property) { | 949 static bool IsBoilerplateProperty(PreParserExpression property) { |
1097 // PreParser doesn't count boilerplate properties. | 950 // PreParser doesn't count boilerplate properties. |
1098 return false; | 951 return false; |
1099 } | 952 } |
1100 | 953 |
1101 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 954 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
1102 return false; | 955 return false; |
1103 } | 956 } |
1104 | 957 |
1105 // Functions for encapsulating the differences between parsing and preparsing; | 958 // Functions for encapsulating the differences between parsing and preparsing; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 return PreParserExpression::Default(); | 1002 return PreParserExpression::Default(); |
1150 } | 1003 } |
1151 PreParserExpression NewThrowSyntaxError( | 1004 PreParserExpression NewThrowSyntaxError( |
1152 const char* type, Handle<Object> arg, int pos) { | 1005 const char* type, Handle<Object> arg, int pos) { |
1153 return PreParserExpression::Default(); | 1006 return PreParserExpression::Default(); |
1154 } | 1007 } |
1155 PreParserExpression NewThrowTypeError( | 1008 PreParserExpression NewThrowTypeError( |
1156 const char* type, Handle<Object> arg, int pos) { | 1009 const char* type, Handle<Object> arg, int pos) { |
1157 return PreParserExpression::Default(); | 1010 return PreParserExpression::Default(); |
1158 } | 1011 } |
1159 PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) { | |
1160 return PreParserScope(outer_scope, scope_type); | |
1161 } | |
1162 | 1012 |
1163 // Reporting errors. | 1013 // Reporting errors. |
1164 void ReportMessageAt(Scanner::Location location, | 1014 void ReportMessageAt(Scanner::Location location, |
1165 const char* message, | 1015 const char* message, |
1166 const char* arg = NULL, | 1016 const char* arg = NULL, |
1167 bool is_reference_error = false); | 1017 bool is_reference_error = false); |
1168 void ReportMessageAt(int start_pos, | 1018 void ReportMessageAt(int start_pos, |
1169 int end_pos, | 1019 int end_pos, |
1170 const char* message, | 1020 const char* message, |
1171 const char* arg = NULL, | 1021 const char* arg = NULL, |
1172 bool is_reference_error = false); | 1022 bool is_reference_error = false); |
1173 | 1023 |
1174 // "null" return type creators. | 1024 // "null" return type creators. |
1175 static PreParserIdentifier EmptyIdentifier() { | 1025 static PreParserIdentifier EmptyIdentifier() { |
1176 return PreParserIdentifier::Default(); | 1026 return PreParserIdentifier::Default(); |
1177 } | 1027 } |
1178 static PreParserIdentifier EmptyIdentifierString() { | |
1179 return PreParserIdentifier::Default(); | |
1180 } | |
1181 static PreParserExpression EmptyExpression() { | 1028 static PreParserExpression EmptyExpression() { |
1182 return PreParserExpression::Default(); | 1029 return PreParserExpression::Default(); |
1183 } | 1030 } |
1184 static PreParserExpression EmptyArrowParamList() { | |
1185 return PreParserExpression::EmptyArrowParamList(); | |
1186 } | |
1187 static PreParserExpression EmptyLiteral() { | 1031 static PreParserExpression EmptyLiteral() { |
1188 return PreParserExpression::Default(); | 1032 return PreParserExpression::Default(); |
1189 } | 1033 } |
1190 static PreParserExpressionList NullExpressionList() { | 1034 static PreParserExpressionList NullExpressionList() { |
1191 return PreParserExpressionList(); | 1035 return PreParserExpressionList(); |
1192 } | 1036 } |
1193 | 1037 |
1194 // Odd-ball literal creators. | 1038 // Odd-ball literal creators. |
1195 static PreParserExpression GetLiteralTheHole(int position, | 1039 static PreParserExpression GetLiteralTheHole(int position, |
1196 PreParserFactory* factory) { | 1040 PreParserFactory* factory) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 } | 1074 } |
1231 | 1075 |
1232 static PreParserStatementList NewStatementList(int size, void* zone) { | 1076 static PreParserStatementList NewStatementList(int size, void* zone) { |
1233 return PreParserStatementList(); | 1077 return PreParserStatementList(); |
1234 } | 1078 } |
1235 | 1079 |
1236 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1080 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
1237 return PreParserExpressionList(); | 1081 return PreParserExpressionList(); |
1238 } | 1082 } |
1239 | 1083 |
1240 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, | |
1241 int* materialized_literal_count, | |
1242 int* expected_property_count, bool* ok) { | |
1243 UNREACHABLE(); | |
1244 } | |
1245 | |
1246 V8_INLINE PreParserStatementList | |
1247 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | |
1248 Variable* fvar, Token::Value fvar_init_op, | |
1249 bool is_generator, bool* ok); | |
1250 | |
1251 // Utility functions | |
1252 Vector<PreParserIdentifier> ParameterListFromExpression( | |
1253 PreParserExpression expression, bool* ok) { | |
1254 // TODO(aperez): Detect duplicated identifiers in paramlists. | |
1255 *ok = expression.IsValidArrowParamList(); | |
1256 return Vector<PreParserIdentifier>::empty(); | |
1257 } | |
1258 | |
1259 static AstValueFactory* ast_value_factory() { return NULL; } | |
1260 | |
1261 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} | |
1262 | |
1263 // Temporary glue; these functions will move to ParserBase. | 1084 // Temporary glue; these functions will move to ParserBase. |
1264 PreParserExpression ParseV8Intrinsic(bool* ok); | 1085 PreParserExpression ParseV8Intrinsic(bool* ok); |
1265 PreParserExpression ParseFunctionLiteral( | 1086 PreParserExpression ParseFunctionLiteral( |
1266 PreParserIdentifier name, | 1087 PreParserIdentifier name, |
1267 Scanner::Location function_name_location, | 1088 Scanner::Location function_name_location, |
1268 bool name_is_strict_reserved, | 1089 bool name_is_strict_reserved, |
1269 bool is_generator, | 1090 bool is_generator, |
1270 int function_token_position, | 1091 int function_token_position, |
1271 FunctionLiteral::FunctionType type, | 1092 FunctionLiteral::FunctionType type, |
1272 FunctionLiteral::ArityRestriction arity_restriction, | 1093 FunctionLiteral::ArityRestriction arity_restriction, |
(...skipping 30 matching lines...) Expand all Loading... |
1303 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1124 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
1304 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1125 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
1305 this) {} | 1126 this) {} |
1306 | 1127 |
1307 // Pre-parse the program from the character stream; returns true on | 1128 // Pre-parse the program from the character stream; returns true on |
1308 // success (even if parsing failed, the pre-parse data successfully | 1129 // success (even if parsing failed, the pre-parse data successfully |
1309 // captured the syntax error), and false if a stack-overflow happened | 1130 // captured the syntax error), and false if a stack-overflow happened |
1310 // during parsing. | 1131 // during parsing. |
1311 PreParseResult PreParseProgram() { | 1132 PreParseResult PreParseProgram() { |
1312 PreParserScope scope(scope_, GLOBAL_SCOPE); | 1133 PreParserScope scope(scope_, GLOBAL_SCOPE); |
1313 FunctionState top_scope(&function_state_, &scope_, &scope); | 1134 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); |
1314 bool ok = true; | 1135 bool ok = true; |
1315 int start_position = scanner()->peek_location().beg_pos; | 1136 int start_position = scanner()->peek_location().beg_pos; |
1316 ParseSourceElements(Token::EOS, &ok); | 1137 ParseSourceElements(Token::EOS, &ok); |
1317 if (stack_overflow()) return kPreParseStackOverflow; | 1138 if (stack_overflow()) return kPreParseStackOverflow; |
1318 if (!ok) { | 1139 if (!ok) { |
1319 ReportUnexpectedToken(scanner()->current_token()); | 1140 ReportUnexpectedToken(scanner()->current_token()); |
1320 } else if (scope_->strict_mode() == STRICT) { | 1141 } else if (scope_->strict_mode() == STRICT) { |
1321 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 1142 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
1322 } | 1143 } |
1323 return kPreParseSuccess; | 1144 return kPreParseSuccess; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 Statement ParseDoWhileStatement(bool* ok); | 1206 Statement ParseDoWhileStatement(bool* ok); |
1386 Statement ParseWhileStatement(bool* ok); | 1207 Statement ParseWhileStatement(bool* ok); |
1387 Statement ParseForStatement(bool* ok); | 1208 Statement ParseForStatement(bool* ok); |
1388 Statement ParseThrowStatement(bool* ok); | 1209 Statement ParseThrowStatement(bool* ok); |
1389 Statement ParseTryStatement(bool* ok); | 1210 Statement ParseTryStatement(bool* ok); |
1390 Statement ParseDebuggerStatement(bool* ok); | 1211 Statement ParseDebuggerStatement(bool* ok); |
1391 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1212 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1392 Expression ParseObjectLiteral(bool* ok); | 1213 Expression ParseObjectLiteral(bool* ok); |
1393 Expression ParseV8Intrinsic(bool* ok); | 1214 Expression ParseV8Intrinsic(bool* ok); |
1394 | 1215 |
1395 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, | |
1396 int* materialized_literal_count, | |
1397 int* expected_property_count, bool* ok); | |
1398 V8_INLINE PreParserStatementList | |
1399 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | |
1400 Variable* fvar, Token::Value fvar_init_op, | |
1401 bool is_generator, bool* ok); | |
1402 | |
1403 Expression ParseFunctionLiteral( | 1216 Expression ParseFunctionLiteral( |
1404 Identifier name, | 1217 Identifier name, |
1405 Scanner::Location function_name_location, | 1218 Scanner::Location function_name_location, |
1406 bool name_is_strict_reserved, | 1219 bool name_is_strict_reserved, |
1407 bool is_generator, | 1220 bool is_generator, |
1408 int function_token_pos, | 1221 int function_token_pos, |
1409 FunctionLiteral::FunctionType function_type, | 1222 FunctionLiteral::FunctionType function_type, |
1410 FunctionLiteral::ArityRestriction arity_restriction, | 1223 FunctionLiteral::ArityRestriction arity_restriction, |
1411 bool* ok); | 1224 bool* ok); |
1412 void ParseLazyFunctionLiteralBody(bool* ok); | 1225 void ParseLazyFunctionLiteralBody(bool* ok); |
1413 | 1226 |
1414 bool CheckInOrOf(bool accept_OF); | 1227 bool CheckInOrOf(bool accept_OF); |
1415 }; | 1228 }; |
1416 | 1229 |
1417 | |
1418 PreParserStatementList PreParser::ParseEagerFunctionBody( | |
1419 PreParserIdentifier function_name, int pos, Variable* fvar, | |
1420 Token::Value fvar_init_op, bool is_generator, bool* ok) { | |
1421 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | |
1422 | |
1423 ParseSourceElements(Token::RBRACE, ok); | |
1424 if (!*ok) return PreParserStatementList(); | |
1425 | |
1426 Expect(Token::RBRACE, ok); | |
1427 return PreParserStatementList(); | |
1428 } | |
1429 | |
1430 | |
1431 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( | |
1432 PreParserIdentifier function_name, int pos, Variable* fvar, | |
1433 Token::Value fvar_init_op, bool is_generator, bool* ok) { | |
1434 return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar, | |
1435 fvar_init_op, is_generator, ok); | |
1436 } | |
1437 | |
1438 | |
1439 template<class Traits> | 1230 template<class Traits> |
1440 ParserBase<Traits>::FunctionState::FunctionState( | 1231 ParserBase<Traits>::FunctionState::FunctionState( |
1441 FunctionState** function_state_stack, | 1232 FunctionState** function_state_stack, |
1442 typename Traits::Type::Scope** scope_stack, | 1233 typename Traits::Type::Scope** scope_stack, |
1443 typename Traits::Type::Scope* scope, | 1234 typename Traits::Type::Scope* scope, |
1444 typename Traits::Type::Zone* extra_param, | 1235 typename Traits::Type::Zone* extra_param, |
1445 AstValueFactory* ast_value_factory) | 1236 AstValueFactory* ast_value_factory) |
1446 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1237 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
1447 next_handler_index_(0), | 1238 next_handler_index_(0), |
1448 expected_property_count_(0), | 1239 expected_property_count_(0), |
1449 is_generator_(false), | 1240 is_generator_(false), |
1450 generator_object_variable_(NULL), | 1241 generator_object_variable_(NULL), |
1451 function_state_stack_(function_state_stack), | 1242 function_state_stack_(function_state_stack), |
1452 outer_function_state_(*function_state_stack), | 1243 outer_function_state_(*function_state_stack), |
1453 scope_stack_(scope_stack), | 1244 scope_stack_(scope_stack), |
1454 outer_scope_(*scope_stack), | 1245 outer_scope_(*scope_stack), |
1455 saved_ast_node_id_(0), | 1246 saved_ast_node_id_(0), |
1456 extra_param_(extra_param), | 1247 extra_param_(extra_param), |
1457 factory_(extra_param, ast_value_factory) { | 1248 factory_(extra_param, ast_value_factory) { |
1458 *scope_stack_ = scope; | 1249 *scope_stack_ = scope; |
1459 *function_state_stack = this; | 1250 *function_state_stack = this; |
1460 Traits::SetUpFunctionState(this, extra_param); | 1251 Traits::SetUpFunctionState(this, extra_param); |
1461 } | 1252 } |
1462 | 1253 |
1463 | 1254 |
1464 template <class Traits> | 1255 template<class Traits> |
1465 ParserBase<Traits>::FunctionState::FunctionState( | |
1466 FunctionState** function_state_stack, | |
1467 typename Traits::Type::Scope** scope_stack, | |
1468 typename Traits::Type::Scope** scope, | |
1469 typename Traits::Type::Zone* extra_param, | |
1470 AstValueFactory* ast_value_factory) | |
1471 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | |
1472 next_handler_index_(0), | |
1473 expected_property_count_(0), | |
1474 is_generator_(false), | |
1475 generator_object_variable_(NULL), | |
1476 function_state_stack_(function_state_stack), | |
1477 outer_function_state_(*function_state_stack), | |
1478 scope_stack_(scope_stack), | |
1479 outer_scope_(*scope_stack), | |
1480 saved_ast_node_id_(0), | |
1481 extra_param_(extra_param), | |
1482 factory_(extra_param, ast_value_factory) { | |
1483 *scope_stack_ = *scope; | |
1484 *function_state_stack = this; | |
1485 Traits::SetUpFunctionState(this, extra_param); | |
1486 } | |
1487 | |
1488 | |
1489 template <class Traits> | |
1490 ParserBase<Traits>::FunctionState::~FunctionState() { | 1256 ParserBase<Traits>::FunctionState::~FunctionState() { |
1491 *scope_stack_ = outer_scope_; | 1257 *scope_stack_ = outer_scope_; |
1492 *function_state_stack_ = outer_function_state_; | 1258 *function_state_stack_ = outer_function_state_; |
1493 Traits::TearDownFunctionState(this, extra_param_); | 1259 Traits::TearDownFunctionState(this, extra_param_); |
1494 } | 1260 } |
1495 | 1261 |
1496 | 1262 |
1497 template<class Traits> | 1263 template<class Traits> |
1498 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1264 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
1499 Scanner::Location source_location = scanner()->location(); | 1265 Scanner::Location source_location = scanner()->location(); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1696 case Token::LBRACK: | 1462 case Token::LBRACK: |
1697 result = this->ParseArrayLiteral(CHECK_OK); | 1463 result = this->ParseArrayLiteral(CHECK_OK); |
1698 break; | 1464 break; |
1699 | 1465 |
1700 case Token::LBRACE: | 1466 case Token::LBRACE: |
1701 result = this->ParseObjectLiteral(CHECK_OK); | 1467 result = this->ParseObjectLiteral(CHECK_OK); |
1702 break; | 1468 break; |
1703 | 1469 |
1704 case Token::LPAREN: | 1470 case Token::LPAREN: |
1705 Consume(Token::LPAREN); | 1471 Consume(Token::LPAREN); |
1706 if (allow_arrow_functions() && peek() == Token::RPAREN) { | 1472 // Heuristically try to detect immediately called functions before |
1707 // Arrow functions are the only expression type constructions | 1473 // seeing the call parentheses. |
1708 // for which an empty parameter list "()" is valid input. | 1474 parenthesized_function_ = (peek() == Token::FUNCTION); |
1709 Consume(Token::RPAREN); | 1475 result = this->ParseExpression(true, CHECK_OK); |
1710 return this->ParseArrowFunctionLiteral(pos, this->EmptyArrowParamList(), | 1476 Expect(Token::RPAREN, CHECK_OK); |
1711 CHECK_OK); | |
1712 } else { | |
1713 // Heuristically try to detect immediately called functions before | |
1714 // seeing the call parentheses. | |
1715 parenthesized_function_ = (peek() == Token::FUNCTION); | |
1716 result = this->ParseExpression(true, CHECK_OK); | |
1717 result->increase_parenthesization_level(); | |
1718 Expect(Token::RPAREN, CHECK_OK); | |
1719 } | |
1720 break; | 1477 break; |
1721 | 1478 |
1722 case Token::MOD: | 1479 case Token::MOD: |
1723 if (allow_natives_syntax() || extension_ != NULL) { | 1480 if (allow_natives_syntax() || extension_ != NULL) { |
1724 result = this->ParseV8Intrinsic(CHECK_OK); | 1481 result = this->ParseV8Intrinsic(CHECK_OK); |
1725 break; | 1482 break; |
1726 } | 1483 } |
1727 // If we're not allowing special syntax we fall-through to the | 1484 // If we're not allowing special syntax we fall-through to the |
1728 // default case. | 1485 // default case. |
1729 | 1486 |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1738 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1982 return result; | 1739 return result; |
1983 } | 1740 } |
1984 | 1741 |
1985 // Precedence = 2 | 1742 // Precedence = 2 |
1986 template <class Traits> | 1743 template <class Traits> |
1987 typename ParserBase<Traits>::ExpressionT | 1744 typename ParserBase<Traits>::ExpressionT |
1988 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 1745 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
1989 // AssignmentExpression :: | 1746 // AssignmentExpression :: |
1990 // ConditionalExpression | 1747 // ConditionalExpression |
1991 // ArrowFunction | |
1992 // YieldExpression | 1748 // YieldExpression |
1993 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1749 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1994 | 1750 |
1995 Scanner::Location lhs_location = scanner()->peek_location(); | 1751 Scanner::Location lhs_location = scanner()->peek_location(); |
1996 | 1752 |
1997 if (peek() == Token::YIELD && is_generator()) { | 1753 if (peek() == Token::YIELD && is_generator()) { |
1998 return this->ParseYieldExpression(ok); | 1754 return this->ParseYieldExpression(ok); |
1999 } | 1755 } |
2000 | 1756 |
2001 if (fni_ != NULL) fni_->Enter(); | 1757 if (fni_ != NULL) fni_->Enter(); |
2002 ExpressionT expression = | 1758 ExpressionT expression = |
2003 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 1759 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
2004 | 1760 |
2005 if (allow_arrow_functions() && peek() == Token::ARROW) | |
2006 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, expression, | |
2007 CHECK_OK); | |
2008 | |
2009 if (!Token::IsAssignmentOp(peek())) { | 1761 if (!Token::IsAssignmentOp(peek())) { |
2010 if (fni_ != NULL) fni_->Leave(); | 1762 if (fni_ != NULL) fni_->Leave(); |
2011 // Parsed conditional expression only (no assignment). | 1763 // Parsed conditional expression only (no assignment). |
2012 return expression; | 1764 return expression; |
2013 } | 1765 } |
2014 | 1766 |
2015 expression = this->CheckAndRewriteReferenceExpression( | 1767 expression = this->CheckAndRewriteReferenceExpression( |
2016 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 1768 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
2017 expression = this->MarkExpressionAsAssigned(expression); | 1769 expression = this->MarkExpressionAsAssigned(expression); |
2018 | 1770 |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2425 } | 2177 } |
2426 default: | 2178 default: |
2427 return expression; | 2179 return expression; |
2428 } | 2180 } |
2429 } | 2181 } |
2430 ASSERT(false); | 2182 ASSERT(false); |
2431 return this->EmptyExpression(); | 2183 return this->EmptyExpression(); |
2432 } | 2184 } |
2433 | 2185 |
2434 | 2186 |
2435 template <class Traits> | |
2436 typename ParserBase<Traits>::ExpressionT ParserBase< | |
2437 Traits>::ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | |
2438 bool* ok) { | |
2439 typename Traits::Type::ParameterIdentifierVector params = | |
2440 Traits::ParameterListFromExpression(params_ast, ok); | |
2441 | |
2442 if (!*ok) { | |
2443 ReportMessageAt(Scanner::Location(start_pos, scanner()->location().beg_pos), | |
2444 "malformed_arrow_function_parameter_list"); | |
2445 params.Dispose(); | |
2446 return this->EmptyExpression(); | |
2447 } | |
2448 | |
2449 // TODO(aperez): Change this to use ARROW_SCOPE | |
2450 typename Traits::Type::ScopePtr scope = | |
2451 this->NewScope(scope_, FUNCTION_SCOPE); | |
2452 | |
2453 FunctionState function_state(&function_state_, &scope_, &scope, zone(), | |
2454 this->ast_value_factory()); | |
2455 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | |
2456 | |
2457 if (params.length() > Code::kMaxArguments) { | |
2458 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
2459 "too_many_parameters"); | |
2460 *ok = false; | |
2461 params.Dispose(); | |
2462 return this->EmptyExpression(); | |
2463 } | |
2464 | |
2465 for (int i = 0; i < params.length(); ++i) { | |
2466 const IdentifierT param_name = params.at(i)->raw_name(); | |
2467 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
2468 int param_pos = params.at(i)->position(); | |
2469 dupe_error_loc = | |
2470 Scanner::Location(param_pos, param_pos + param_name->length()); | |
2471 } | |
2472 scope_->DeclareParameter(param_name, VAR); | |
2473 } | |
2474 | |
2475 ExpressionT expression = ParseArrowFunctionLiteralBody( | |
2476 &function_state, scope, params.length(), Scanner::Location::invalid(), | |
2477 dupe_error_loc, Scanner::Location::invalid(), | |
2478 FunctionLiteral::kNotParenthesized, start_pos, CHECK_OK); | |
2479 params.Dispose(); | |
2480 return expression; | |
2481 } | |
2482 | |
2483 | |
2484 template <class Traits> | |
2485 typename ParserBase<Traits>::ExpressionT | |
2486 ParserBase<Traits>::ParseArrowFunctionLiteralBody( | |
2487 FunctionState* function_state, typename Traits::Type::ScopePtr scope, | |
2488 int num_parameters, const Scanner::Location& eval_args_error_loc, | |
2489 const Scanner::Location& dupe_error_loc, | |
2490 const Scanner::Location& reserved_loc, | |
2491 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos, | |
2492 bool* ok) { | |
2493 int materialized_literal_count = -1; | |
2494 int expected_property_count = -1; | |
2495 | |
2496 Expect(Token::ARROW, CHECK_OK); | |
2497 | |
2498 if (peek() == Token::LBRACE) { | |
2499 // Multiple statemente body | |
2500 Consume(Token::LBRACE); | |
2501 bool is_lazily_parsed = | |
2502 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | |
2503 if (is_lazily_parsed) { | |
2504 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | |
2505 &materialized_literal_count, | |
2506 &expected_property_count, CHECK_OK); | |
2507 } else { | |
2508 this->ParseEagerFunctionBody(this->EmptyIdentifier(), | |
2509 RelocInfo::kNoPosition, NULL, | |
2510 Token::INIT_VAR, false, // Not a generator. | |
2511 CHECK_OK); | |
2512 } | |
2513 } else { | |
2514 // Single-expression body | |
2515 ParseAssignmentExpression(true, CHECK_OK); | |
2516 } | |
2517 | |
2518 scope->set_start_position(start_pos); | |
2519 scope->set_end_position(scanner()->location().end_pos); | |
2520 | |
2521 // Arrow function *parameter lists* are always checked as in strict mode. | |
2522 this->CheckStrictFunctionNameAndParameters( | |
2523 this->EmptyIdentifier(), false, Scanner::Location::invalid(), | |
2524 Scanner::Location::invalid(), dupe_error_loc, | |
2525 Scanner::Location::invalid(), CHECK_OK); | |
2526 | |
2527 // Validate strict mode. | |
2528 if (strict_mode() == STRICT) { | |
2529 CheckOctalLiteral(start_pos, scanner()->location().end_pos, CHECK_OK); | |
2530 } | |
2531 | |
2532 if (allow_harmony_scoping() && strict_mode() == STRICT) | |
2533 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | |
2534 | |
2535 // TODO(aperez): Generate a proper FunctionLiteral instead of | |
2536 // returning a dummy value. | |
2537 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | |
2538 this->EmptyIdentifierString(), this->ast_value_factory(), scope, | |
2539 this->NewStatementList(0, zone()), 0, 0, 0, num_parameters, | |
2540 FunctionLiteral::kNoDuplicateParameters, | |
2541 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | |
2542 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNotGenerator, | |
2543 start_pos); | |
2544 function_literal->set_function_token_position(start_pos); | |
2545 return function_literal; | |
2546 } | |
2547 | |
2548 | |
2549 template <typename Traits> | 2187 template <typename Traits> |
2550 typename ParserBase<Traits>::ExpressionT | 2188 typename ParserBase<Traits>::ExpressionT |
2551 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2189 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2552 ExpressionT expression, | 2190 ExpressionT expression, |
2553 Scanner::Location location, const char* message, bool* ok) { | 2191 Scanner::Location location, const char* message, bool* ok) { |
2554 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2192 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2555 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2193 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2556 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2194 this->ReportMessageAt(location, "strict_eval_arguments", false); |
2557 *ok = false; | 2195 *ok = false; |
2558 return this->EmptyExpression(); | 2196 return this->EmptyExpression(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2602 parser()->ReportMessage("accessor_get_set"); | 2240 parser()->ReportMessage("accessor_get_set"); |
2603 } | 2241 } |
2604 *ok = false; | 2242 *ok = false; |
2605 } | 2243 } |
2606 } | 2244 } |
2607 | 2245 |
2608 | 2246 |
2609 } } // v8::internal | 2247 } } // v8::internal |
2610 | 2248 |
2611 #endif // V8_PREPARSER_H | 2249 #endif // V8_PREPARSER_H |
OLD | NEW |