| 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/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 zone_(zone), | 83 zone_(zone), |
| 84 scanner_(scanner), | 84 scanner_(scanner), |
| 85 stack_overflow_(false), | 85 stack_overflow_(false), |
| 86 allow_lazy_(false), | 86 allow_lazy_(false), |
| 87 allow_natives_(false), | 87 allow_natives_(false), |
| 88 allow_harmony_arrow_functions_(false), | 88 allow_harmony_arrow_functions_(false), |
| 89 allow_harmony_object_literals_(false), | 89 allow_harmony_object_literals_(false), |
| 90 allow_harmony_sloppy_(false), | 90 allow_harmony_sloppy_(false), |
| 91 allow_harmony_computed_property_names_(false), | 91 allow_harmony_computed_property_names_(false), |
| 92 allow_harmony_rest_params_(false), | 92 allow_harmony_rest_params_(false), |
| 93 allow_harmony_new_target_(false), |
| 93 allow_strong_mode_(false) {} | 94 allow_strong_mode_(false) {} |
| 94 | 95 |
| 95 // Getters that indicate whether certain syntactical constructs are | 96 // Getters that indicate whether certain syntactical constructs are |
| 96 // allowed to be parsed by this instance of the parser. | 97 // allowed to be parsed by this instance of the parser. |
| 97 bool allow_lazy() const { return allow_lazy_; } | 98 bool allow_lazy() const { return allow_lazy_; } |
| 98 bool allow_natives() const { return allow_natives_; } | 99 bool allow_natives() const { return allow_natives_; } |
| 99 bool allow_harmony_arrow_functions() const { | 100 bool allow_harmony_arrow_functions() const { |
| 100 return allow_harmony_arrow_functions_; | 101 return allow_harmony_arrow_functions_; |
| 101 } | 102 } |
| 102 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } | 103 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } |
| 103 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 104 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
| 104 bool allow_harmony_numeric_literals() const { | 105 bool allow_harmony_numeric_literals() const { |
| 105 return scanner()->HarmonyNumericLiterals(); | 106 return scanner()->HarmonyNumericLiterals(); |
| 106 } | 107 } |
| 107 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } | 108 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } |
| 108 bool allow_harmony_object_literals() const { | 109 bool allow_harmony_object_literals() const { |
| 109 return allow_harmony_object_literals_; | 110 return allow_harmony_object_literals_; |
| 110 } | 111 } |
| 111 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } | 112 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } |
| 112 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 113 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
| 113 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 114 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
| 114 bool allow_harmony_computed_property_names() const { | 115 bool allow_harmony_computed_property_names() const { |
| 115 return allow_harmony_computed_property_names_; | 116 return allow_harmony_computed_property_names_; |
| 116 } | 117 } |
| 117 bool allow_harmony_rest_params() const { | 118 bool allow_harmony_rest_params() const { |
| 118 return allow_harmony_rest_params_; | 119 return allow_harmony_rest_params_; |
| 119 } | 120 } |
| 121 bool allow_harmony_new_target() const { return allow_harmony_new_target_; } |
| 120 | 122 |
| 121 bool allow_strong_mode() const { return allow_strong_mode_; } | 123 bool allow_strong_mode() const { return allow_strong_mode_; } |
| 122 | 124 |
| 123 // Setters that determine whether certain syntactical constructs are | 125 // Setters that determine whether certain syntactical constructs are |
| 124 // allowed to be parsed by this instance of the parser. | 126 // allowed to be parsed by this instance of the parser. |
| 125 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 127 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
| 126 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 128 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
| 127 void set_allow_harmony_arrow_functions(bool allow) { | 129 void set_allow_harmony_arrow_functions(bool allow) { |
| 128 allow_harmony_arrow_functions_ = allow; | 130 allow_harmony_arrow_functions_ = allow; |
| 129 } | 131 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 150 } | 152 } |
| 151 void set_allow_harmony_unicode(bool allow) { | 153 void set_allow_harmony_unicode(bool allow) { |
| 152 scanner()->SetHarmonyUnicode(allow); | 154 scanner()->SetHarmonyUnicode(allow); |
| 153 } | 155 } |
| 154 void set_allow_harmony_computed_property_names(bool allow) { | 156 void set_allow_harmony_computed_property_names(bool allow) { |
| 155 allow_harmony_computed_property_names_ = allow; | 157 allow_harmony_computed_property_names_ = allow; |
| 156 } | 158 } |
| 157 void set_allow_harmony_rest_params(bool allow) { | 159 void set_allow_harmony_rest_params(bool allow) { |
| 158 allow_harmony_rest_params_ = allow; | 160 allow_harmony_rest_params_ = allow; |
| 159 } | 161 } |
| 162 void set_allow_harmony_new_target(bool allow) { |
| 163 allow_harmony_new_target_ = allow; |
| 164 } |
| 160 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 165 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
| 161 | 166 |
| 162 protected: | 167 protected: |
| 163 enum AllowEvalOrArgumentsAsIdentifier { | 168 enum AllowEvalOrArgumentsAsIdentifier { |
| 164 kAllowEvalOrArguments, | 169 kAllowEvalOrArguments, |
| 165 kDontAllowEvalOrArguments | 170 kDontAllowEvalOrArguments |
| 166 }; | 171 }; |
| 167 | 172 |
| 168 enum Mode { | 173 enum Mode { |
| 169 PARSE_LAZILY, | 174 PARSE_LAZILY, |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 ExpressionT ParseLeftHandSideExpression(bool* ok); | 589 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 585 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 590 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 586 ExpressionT ParseMemberExpression(bool* ok); | 591 ExpressionT ParseMemberExpression(bool* ok); |
| 587 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 592 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 588 bool* ok); | 593 bool* ok); |
| 589 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 594 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 590 bool* ok); | 595 bool* ok); |
| 591 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 596 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 592 void AddTemplateExpression(ExpressionT); | 597 void AddTemplateExpression(ExpressionT); |
| 593 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 598 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| 599 ExpressionT ParseNewTargetExpression(bool* ok); |
| 594 | 600 |
| 595 // Checks if the expression is a valid reference expression (e.g., on the | 601 // Checks if the expression is a valid reference expression (e.g., on the |
| 596 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 602 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 597 // we allow calls for web compatibility and rewrite them to a runtime throw. | 603 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 598 ExpressionT CheckAndRewriteReferenceExpression( | 604 ExpressionT CheckAndRewriteReferenceExpression( |
| 599 ExpressionT expression, | 605 ExpressionT expression, |
| 600 Scanner::Location location, const char* message, bool* ok); | 606 Scanner::Location location, const char* message, bool* ok); |
| 601 | 607 |
| 602 // Used to validate property names in object literals and class literals | 608 // Used to validate property names in object literals and class literals |
| 603 enum PropertyKind { | 609 enum PropertyKind { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 Scanner* scanner_; | 685 Scanner* scanner_; |
| 680 bool stack_overflow_; | 686 bool stack_overflow_; |
| 681 | 687 |
| 682 bool allow_lazy_; | 688 bool allow_lazy_; |
| 683 bool allow_natives_; | 689 bool allow_natives_; |
| 684 bool allow_harmony_arrow_functions_; | 690 bool allow_harmony_arrow_functions_; |
| 685 bool allow_harmony_object_literals_; | 691 bool allow_harmony_object_literals_; |
| 686 bool allow_harmony_sloppy_; | 692 bool allow_harmony_sloppy_; |
| 687 bool allow_harmony_computed_property_names_; | 693 bool allow_harmony_computed_property_names_; |
| 688 bool allow_harmony_rest_params_; | 694 bool allow_harmony_rest_params_; |
| 695 bool allow_harmony_new_target_; |
| 689 bool allow_strong_mode_; | 696 bool allow_strong_mode_; |
| 690 }; | 697 }; |
| 691 | 698 |
| 692 | 699 |
| 693 class PreParserIdentifier { | 700 class PreParserIdentifier { |
| 694 public: | 701 public: |
| 695 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 702 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 696 static PreParserIdentifier Default() { | 703 static PreParserIdentifier Default() { |
| 697 return PreParserIdentifier(kUnknownIdentifier); | 704 return PreParserIdentifier(kUnknownIdentifier); |
| 698 } | 705 } |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1390 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { | 1397 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { |
| 1391 return PreParserIdentifier::Default(); | 1398 return PreParserIdentifier::Default(); |
| 1392 } | 1399 } |
| 1393 | 1400 |
| 1394 static PreParserExpression ThisExpression(Scope* scope, | 1401 static PreParserExpression ThisExpression(Scope* scope, |
| 1395 PreParserFactory* factory, | 1402 PreParserFactory* factory, |
| 1396 int pos) { | 1403 int pos) { |
| 1397 return PreParserExpression::This(); | 1404 return PreParserExpression::This(); |
| 1398 } | 1405 } |
| 1399 | 1406 |
| 1407 static PreParserExpression NewTargetExpression(Scope* scope, |
| 1408 PreParserFactory* factory) { |
| 1409 return PreParserExpression::Default(); |
| 1410 } |
| 1411 |
| 1400 static PreParserExpression SuperReference(Scope* scope, | 1412 static PreParserExpression SuperReference(Scope* scope, |
| 1401 PreParserFactory* factory) { | 1413 PreParserFactory* factory) { |
| 1402 return PreParserExpression::Super(); | 1414 return PreParserExpression::Super(); |
| 1403 } | 1415 } |
| 1404 | 1416 |
| 1405 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope, | 1417 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope, |
| 1406 int pos, int end_pos) { | 1418 int pos, int end_pos) { |
| 1407 return PreParserExpression::Default(); | 1419 return PreParserExpression::Default(); |
| 1408 } | 1420 } |
| 1409 | 1421 |
| (...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2671 } | 2683 } |
| 2672 } | 2684 } |
| 2673 | 2685 |
| 2674 | 2686 |
| 2675 template <class Traits> | 2687 template <class Traits> |
| 2676 typename ParserBase<Traits>::ExpressionT | 2688 typename ParserBase<Traits>::ExpressionT |
| 2677 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { | 2689 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { |
| 2678 // NewExpression :: | 2690 // NewExpression :: |
| 2679 // ('new')+ MemberExpression | 2691 // ('new')+ MemberExpression |
| 2680 | 2692 |
| 2693 // NewTarget :: |
| 2694 // 'new' '.' 'target' |
| 2695 |
| 2681 // The grammar for new expressions is pretty warped. We can have several 'new' | 2696 // The grammar for new expressions is pretty warped. We can have several 'new' |
| 2682 // keywords following each other, and then a MemberExpression. When we see '(' | 2697 // keywords following each other, and then a MemberExpression. When we see '(' |
| 2683 // after the MemberExpression, it's associated with the rightmost unassociated | 2698 // after the MemberExpression, it's associated with the rightmost unassociated |
| 2684 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2699 // 'new' to create a NewExpression with arguments. However, a NewExpression |
| 2685 // can also occur without arguments. | 2700 // can also occur without arguments. |
| 2686 | 2701 |
| 2687 // Examples of new expression: | 2702 // Examples of new expression: |
| 2688 // new foo.bar().baz means (new (foo.bar)()).baz | 2703 // new foo.bar().baz means (new (foo.bar)()).baz |
| 2689 // new foo()() means (new foo())() | 2704 // new foo()() means (new foo())() |
| 2690 // new new foo()() means (new (new foo())()) | 2705 // new new foo()() means (new (new foo())()) |
| 2691 // new new foo means new (new foo) | 2706 // new new foo means new (new foo) |
| 2692 // new new foo() means new (new foo()) | 2707 // new new foo() means new (new foo()) |
| 2693 // new new foo().bar().baz means (new (new foo()).bar()).baz | 2708 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 2694 | 2709 |
| 2695 if (peek() == Token::NEW) { | 2710 if (peek() == Token::NEW) { |
| 2696 Consume(Token::NEW); | 2711 Consume(Token::NEW); |
| 2697 int new_pos = position(); | 2712 int new_pos = position(); |
| 2698 ExpressionT result = this->EmptyExpression(); | 2713 ExpressionT result = this->EmptyExpression(); |
| 2699 if (peek() == Token::SUPER) { | 2714 if (peek() == Token::SUPER) { |
| 2700 const bool is_new = true; | 2715 const bool is_new = true; |
| 2701 result = ParseSuperExpression(is_new, CHECK_OK); | 2716 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2717 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) { |
| 2718 return ParseNewTargetExpression(CHECK_OK); |
| 2702 } else { | 2719 } else { |
| 2703 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2720 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| 2704 } | 2721 } |
| 2705 if (peek() == Token::LPAREN) { | 2722 if (peek() == Token::LPAREN) { |
| 2706 // NewExpression with arguments. | 2723 // NewExpression with arguments. |
| 2707 typename Traits::Type::ExpressionList args = | 2724 typename Traits::Type::ExpressionList args = |
| 2708 this->ParseArguments(CHECK_OK); | 2725 this->ParseArguments(CHECK_OK); |
| 2709 result = factory()->NewCallNew(result, args, new_pos); | 2726 result = factory()->NewCallNew(result, args, new_pos); |
| 2710 // The expression can still continue with . or [ after the arguments. | 2727 // The expression can still continue with . or [ after the arguments. |
| 2711 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2728 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2792 } | 2809 } |
| 2793 | 2810 |
| 2794 ReportMessageAt(scanner()->location(), "unexpected_super"); | 2811 ReportMessageAt(scanner()->location(), "unexpected_super"); |
| 2795 *ok = false; | 2812 *ok = false; |
| 2796 return this->EmptyExpression(); | 2813 return this->EmptyExpression(); |
| 2797 } | 2814 } |
| 2798 | 2815 |
| 2799 | 2816 |
| 2800 template <class Traits> | 2817 template <class Traits> |
| 2801 typename ParserBase<Traits>::ExpressionT | 2818 typename ParserBase<Traits>::ExpressionT |
| 2819 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) { |
| 2820 Consume(Token::PERIOD); |
| 2821 ExpectContextualKeyword(CStrVector("target"), CHECK_OK); |
| 2822 |
| 2823 Scope* scope = scope_; |
| 2824 while (scope->is_eval_scope() || scope->is_arrow_scope()) { |
| 2825 scope = scope->outer_scope(); |
| 2826 DCHECK_NOT_NULL(scope); |
| 2827 scope = scope->DeclarationScope(); |
| 2828 } |
| 2829 |
| 2830 if (scope->is_script_scope() || scope->is_module_scope()) { |
| 2831 ReportMessageAt(scanner()->location(), "unexpected_new_target"); |
| 2832 *ok = false; |
| 2833 return this->EmptyExpression(); |
| 2834 } |
| 2835 |
| 2836 scope_->RecordNewTargetUsage(); |
| 2837 return this->NewTargetExpression(scope_, factory()); |
| 2838 } |
| 2839 |
| 2840 |
| 2841 template <class Traits> |
| 2842 typename ParserBase<Traits>::ExpressionT |
| 2802 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, | 2843 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, |
| 2803 bool* ok) { | 2844 bool* ok) { |
| 2804 // Parses this part of MemberExpression: | 2845 // Parses this part of MemberExpression: |
| 2805 // ('[' Expression ']' | '.' Identifier)* | 2846 // ('[' Expression ']' | '.' Identifier)* |
| 2806 while (true) { | 2847 while (true) { |
| 2807 switch (peek()) { | 2848 switch (peek()) { |
| 2808 case Token::LBRACK: { | 2849 case Token::LBRACK: { |
| 2809 Consume(Token::LBRACK); | 2850 Consume(Token::LBRACK); |
| 2810 int pos = position(); | 2851 int pos = position(); |
| 2811 ExpressionT index = this->ParseExpression(true, CHECK_OK); | 2852 ExpressionT index = this->ParseExpression(true, CHECK_OK); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3109 *ok = false; | 3150 *ok = false; |
| 3110 return; | 3151 return; |
| 3111 } | 3152 } |
| 3112 has_seen_constructor_ = true; | 3153 has_seen_constructor_ = true; |
| 3113 return; | 3154 return; |
| 3114 } | 3155 } |
| 3115 } | 3156 } |
| 3116 } } // v8::internal | 3157 } } // v8::internal |
| 3117 | 3158 |
| 3118 #endif // V8_PREPARSER_H | 3159 #endif // V8_PREPARSER_H |
| OLD | NEW |