| 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 zone_(zone), | 107 zone_(zone), |
| 108 scanner_(scanner), | 108 scanner_(scanner), |
| 109 stack_overflow_(false), | 109 stack_overflow_(false), |
| 110 allow_lazy_(false), | 110 allow_lazy_(false), |
| 111 allow_natives_(false), | 111 allow_natives_(false), |
| 112 allow_harmony_arrow_functions_(false), | 112 allow_harmony_arrow_functions_(false), |
| 113 allow_harmony_object_literals_(false), | 113 allow_harmony_object_literals_(false), |
| 114 allow_harmony_sloppy_(false), | 114 allow_harmony_sloppy_(false), |
| 115 allow_harmony_computed_property_names_(false), | 115 allow_harmony_computed_property_names_(false), |
| 116 allow_harmony_rest_params_(false), | 116 allow_harmony_rest_params_(false), |
| 117 allow_harmony_new_target_(false), |
| 117 allow_harmony_spreadcalls_(false), | 118 allow_harmony_spreadcalls_(false), |
| 118 allow_strong_mode_(false) {} | 119 allow_strong_mode_(false) {} |
| 119 | 120 |
| 120 // Getters that indicate whether certain syntactical constructs are | 121 // Getters that indicate whether certain syntactical constructs are |
| 121 // allowed to be parsed by this instance of the parser. | 122 // allowed to be parsed by this instance of the parser. |
| 122 bool allow_lazy() const { return allow_lazy_; } | 123 bool allow_lazy() const { return allow_lazy_; } |
| 123 bool allow_natives() const { return allow_natives_; } | 124 bool allow_natives() const { return allow_natives_; } |
| 124 bool allow_harmony_arrow_functions() const { | 125 bool allow_harmony_arrow_functions() const { |
| 125 return allow_harmony_arrow_functions_; | 126 return allow_harmony_arrow_functions_; |
| 126 } | 127 } |
| 127 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } | 128 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } |
| 128 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } | 129 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } |
| 129 bool allow_harmony_object_literals() const { | 130 bool allow_harmony_object_literals() const { |
| 130 return allow_harmony_object_literals_; | 131 return allow_harmony_object_literals_; |
| 131 } | 132 } |
| 132 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 133 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
| 133 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 134 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
| 134 bool allow_harmony_computed_property_names() const { | 135 bool allow_harmony_computed_property_names() const { |
| 135 return allow_harmony_computed_property_names_; | 136 return allow_harmony_computed_property_names_; |
| 136 } | 137 } |
| 137 bool allow_harmony_rest_params() const { | 138 bool allow_harmony_rest_params() const { |
| 138 return allow_harmony_rest_params_; | 139 return allow_harmony_rest_params_; |
| 139 } | 140 } |
| 141 bool allow_harmony_new_target() const { return allow_harmony_new_target_; } |
| 140 bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; } | 142 bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; } |
| 141 | 143 |
| 142 bool allow_strong_mode() const { return allow_strong_mode_; } | 144 bool allow_strong_mode() const { return allow_strong_mode_; } |
| 143 | 145 |
| 144 // Setters that determine whether certain syntactical constructs are | 146 // Setters that determine whether certain syntactical constructs are |
| 145 // allowed to be parsed by this instance of the parser. | 147 // allowed to be parsed by this instance of the parser. |
| 146 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 148 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
| 147 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 149 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
| 148 void set_allow_harmony_arrow_functions(bool allow) { | 150 void set_allow_harmony_arrow_functions(bool allow) { |
| 149 allow_harmony_arrow_functions_ = allow; | 151 allow_harmony_arrow_functions_ = allow; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 162 } | 164 } |
| 163 void set_allow_harmony_unicode(bool allow) { | 165 void set_allow_harmony_unicode(bool allow) { |
| 164 scanner()->SetHarmonyUnicode(allow); | 166 scanner()->SetHarmonyUnicode(allow); |
| 165 } | 167 } |
| 166 void set_allow_harmony_computed_property_names(bool allow) { | 168 void set_allow_harmony_computed_property_names(bool allow) { |
| 167 allow_harmony_computed_property_names_ = allow; | 169 allow_harmony_computed_property_names_ = allow; |
| 168 } | 170 } |
| 169 void set_allow_harmony_rest_params(bool allow) { | 171 void set_allow_harmony_rest_params(bool allow) { |
| 170 allow_harmony_rest_params_ = allow; | 172 allow_harmony_rest_params_ = allow; |
| 171 } | 173 } |
| 174 void set_allow_harmony_new_target(bool allow) { |
| 175 allow_harmony_new_target_ = allow; |
| 176 } |
| 172 void set_allow_harmony_spreadcalls(bool allow) { | 177 void set_allow_harmony_spreadcalls(bool allow) { |
| 173 allow_harmony_spreadcalls_ = allow; | 178 allow_harmony_spreadcalls_ = allow; |
| 174 } | 179 } |
| 175 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 180 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
| 176 | 181 |
| 177 protected: | 182 protected: |
| 178 enum AllowRestrictedIdentifiers { | 183 enum AllowRestrictedIdentifiers { |
| 179 kAllowRestrictedIdentifiers, | 184 kAllowRestrictedIdentifiers, |
| 180 kDontAllowRestrictedIdentifiers | 185 kDontAllowRestrictedIdentifiers |
| 181 }; | 186 }; |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 625 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 621 ExpressionT ParseMemberExpression(bool* ok); | 626 ExpressionT ParseMemberExpression(bool* ok); |
| 622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 627 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 623 bool* ok); | 628 bool* ok); |
| 624 ExpressionT ParseArrowFunctionLiteral( | 629 ExpressionT ParseArrowFunctionLiteral( |
| 625 Scope* function_scope, const FormalParameterErrorLocations& error_locs, | 630 Scope* function_scope, const FormalParameterErrorLocations& error_locs, |
| 626 bool has_rest, bool* ok); | 631 bool has_rest, bool* ok); |
| 627 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 632 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 628 void AddTemplateExpression(ExpressionT); | 633 void AddTemplateExpression(ExpressionT); |
| 629 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 634 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| 635 ExpressionT ParseNewTargetExpression(bool* ok); |
| 630 | 636 |
| 631 void ParseFormalParameter(FormalParameterScopeT* scope, | 637 void ParseFormalParameter(FormalParameterScopeT* scope, |
| 632 FormalParameterErrorLocations* locs, bool is_rest, | 638 FormalParameterErrorLocations* locs, bool is_rest, |
| 633 bool* ok); | 639 bool* ok); |
| 634 int ParseFormalParameterList(FormalParameterScopeT* scope, | 640 int ParseFormalParameterList(FormalParameterScopeT* scope, |
| 635 FormalParameterErrorLocations* locs, | 641 FormalParameterErrorLocations* locs, |
| 636 bool* has_rest, bool* ok); | 642 bool* has_rest, bool* ok); |
| 637 void CheckArityRestrictions( | 643 void CheckArityRestrictions( |
| 638 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 644 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
| 639 int formals_start_pos, int formals_end_pos, bool* ok); | 645 int formals_start_pos, int formals_end_pos, bool* ok); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 Scanner* scanner_; | 731 Scanner* scanner_; |
| 726 bool stack_overflow_; | 732 bool stack_overflow_; |
| 727 | 733 |
| 728 bool allow_lazy_; | 734 bool allow_lazy_; |
| 729 bool allow_natives_; | 735 bool allow_natives_; |
| 730 bool allow_harmony_arrow_functions_; | 736 bool allow_harmony_arrow_functions_; |
| 731 bool allow_harmony_object_literals_; | 737 bool allow_harmony_object_literals_; |
| 732 bool allow_harmony_sloppy_; | 738 bool allow_harmony_sloppy_; |
| 733 bool allow_harmony_computed_property_names_; | 739 bool allow_harmony_computed_property_names_; |
| 734 bool allow_harmony_rest_params_; | 740 bool allow_harmony_rest_params_; |
| 741 bool allow_harmony_new_target_; |
| 735 bool allow_harmony_spreadcalls_; | 742 bool allow_harmony_spreadcalls_; |
| 736 bool allow_strong_mode_; | 743 bool allow_strong_mode_; |
| 737 }; | 744 }; |
| 738 | 745 |
| 739 | 746 |
| 740 class PreParserIdentifier { | 747 class PreParserIdentifier { |
| 741 public: | 748 public: |
| 742 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 749 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 743 static PreParserIdentifier Default() { | 750 static PreParserIdentifier Default() { |
| 744 return PreParserIdentifier(kUnknownIdentifier); | 751 return PreParserIdentifier(kUnknownIdentifier); |
| (...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { | 1505 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { |
| 1499 return PreParserIdentifier::Default(); | 1506 return PreParserIdentifier::Default(); |
| 1500 } | 1507 } |
| 1501 | 1508 |
| 1502 static PreParserExpression ThisExpression(Scope* scope, | 1509 static PreParserExpression ThisExpression(Scope* scope, |
| 1503 PreParserFactory* factory, | 1510 PreParserFactory* factory, |
| 1504 int pos) { | 1511 int pos) { |
| 1505 return PreParserExpression::This(); | 1512 return PreParserExpression::This(); |
| 1506 } | 1513 } |
| 1507 | 1514 |
| 1515 static PreParserExpression NewTargetExpression(Scope* scope, |
| 1516 PreParserFactory* factory, |
| 1517 int start_position, |
| 1518 int end_position) { |
| 1519 return PreParserExpression::Default(); |
| 1520 } |
| 1521 |
| 1508 static PreParserExpression SuperReference(Scope* scope, | 1522 static PreParserExpression SuperReference(Scope* scope, |
| 1509 PreParserFactory* factory) { | 1523 PreParserFactory* factory) { |
| 1510 return PreParserExpression::Default(); | 1524 return PreParserExpression::Default(); |
| 1511 } | 1525 } |
| 1512 | 1526 |
| 1513 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope, | 1527 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope, |
| 1514 int pos, int end_pos) { | 1528 int pos, int end_pos) { |
| 1515 return PreParserExpression::Default(); | 1529 return PreParserExpression::Default(); |
| 1516 } | 1530 } |
| 1517 | 1531 |
| (...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2901 } | 2915 } |
| 2902 } | 2916 } |
| 2903 | 2917 |
| 2904 | 2918 |
| 2905 template <class Traits> | 2919 template <class Traits> |
| 2906 typename ParserBase<Traits>::ExpressionT | 2920 typename ParserBase<Traits>::ExpressionT |
| 2907 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { | 2921 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { |
| 2908 // NewExpression :: | 2922 // NewExpression :: |
| 2909 // ('new')+ MemberExpression | 2923 // ('new')+ MemberExpression |
| 2910 | 2924 |
| 2925 // NewTarget :: |
| 2926 // 'new' '.' 'target' |
| 2927 |
| 2911 // The grammar for new expressions is pretty warped. We can have several 'new' | 2928 // The grammar for new expressions is pretty warped. We can have several 'new' |
| 2912 // keywords following each other, and then a MemberExpression. When we see '(' | 2929 // keywords following each other, and then a MemberExpression. When we see '(' |
| 2913 // after the MemberExpression, it's associated with the rightmost unassociated | 2930 // after the MemberExpression, it's associated with the rightmost unassociated |
| 2914 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2931 // 'new' to create a NewExpression with arguments. However, a NewExpression |
| 2915 // can also occur without arguments. | 2932 // can also occur without arguments. |
| 2916 | 2933 |
| 2917 // Examples of new expression: | 2934 // Examples of new expression: |
| 2918 // new foo.bar().baz means (new (foo.bar)()).baz | 2935 // new foo.bar().baz means (new (foo.bar)()).baz |
| 2919 // new foo()() means (new foo())() | 2936 // new foo()() means (new foo())() |
| 2920 // new new foo()() means (new (new foo())()) | 2937 // new new foo()() means (new (new foo())()) |
| 2921 // new new foo means new (new foo) | 2938 // new new foo means new (new foo) |
| 2922 // new new foo() means new (new foo()) | 2939 // new new foo() means new (new foo()) |
| 2923 // new new foo().bar().baz means (new (new foo()).bar()).baz | 2940 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 2924 | 2941 |
| 2925 if (peek() == Token::NEW) { | 2942 if (peek() == Token::NEW) { |
| 2926 Consume(Token::NEW); | 2943 Consume(Token::NEW); |
| 2927 int new_pos = position(); | 2944 int new_pos = position(); |
| 2928 ExpressionT result = this->EmptyExpression(); | 2945 ExpressionT result = this->EmptyExpression(); |
| 2929 if (peek() == Token::SUPER) { | 2946 if (peek() == Token::SUPER) { |
| 2930 const bool is_new = true; | 2947 const bool is_new = true; |
| 2931 result = ParseSuperExpression(is_new, CHECK_OK); | 2948 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2949 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) { |
| 2950 return ParseNewTargetExpression(CHECK_OK); |
| 2932 } else { | 2951 } else { |
| 2933 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2952 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| 2934 } | 2953 } |
| 2935 if (peek() == Token::LPAREN) { | 2954 if (peek() == Token::LPAREN) { |
| 2936 // NewExpression with arguments. | 2955 // NewExpression with arguments. |
| 2937 Scanner::Location spread_pos; | 2956 Scanner::Location spread_pos; |
| 2938 typename Traits::Type::ExpressionList args = | 2957 typename Traits::Type::ExpressionList args = |
| 2939 this->ParseArguments(&spread_pos, CHECK_OK); | 2958 this->ParseArguments(&spread_pos, CHECK_OK); |
| 2940 | 2959 |
| 2941 if (spread_pos.IsValid()) { | 2960 if (spread_pos.IsValid()) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3029 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); | 3048 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); |
| 3030 *ok = false; | 3049 *ok = false; |
| 3031 return this->EmptyExpression(); | 3050 return this->EmptyExpression(); |
| 3032 } else if (function_state->return_location().IsValid()) { | 3051 } else if (function_state->return_location().IsValid()) { |
| 3033 ReportMessageAt(function_state->return_location(), | 3052 ReportMessageAt(function_state->return_location(), |
| 3034 "strong_constructor_return_misplaced"); | 3053 "strong_constructor_return_misplaced"); |
| 3035 *ok = false; | 3054 *ok = false; |
| 3036 return this->EmptyExpression(); | 3055 return this->EmptyExpression(); |
| 3037 } | 3056 } |
| 3038 } | 3057 } |
| 3058 scope_->RecordNewTargetUsage(); |
| 3039 function_state->set_super_call_location(scanner()->location()); | 3059 function_state->set_super_call_location(scanner()->location()); |
| 3040 return this->SuperReference(scope_, factory()); | 3060 return this->SuperReference(scope_, factory()); |
| 3041 } | 3061 } |
| 3042 } | 3062 } |
| 3043 | 3063 |
| 3044 ReportMessageAt(scanner()->location(), "unexpected_super"); | 3064 ReportMessageAt(scanner()->location(), "unexpected_super"); |
| 3045 *ok = false; | 3065 *ok = false; |
| 3046 return this->EmptyExpression(); | 3066 return this->EmptyExpression(); |
| 3047 } | 3067 } |
| 3048 | 3068 |
| 3049 | 3069 |
| 3050 template <class Traits> | 3070 template <class Traits> |
| 3051 typename ParserBase<Traits>::ExpressionT | 3071 typename ParserBase<Traits>::ExpressionT |
| 3072 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) { |
| 3073 int pos = position(); |
| 3074 Consume(Token::PERIOD); |
| 3075 ExpectContextualKeyword(CStrVector("target"), CHECK_OK); |
| 3076 |
| 3077 Scope* scope = scope_->DeclarationScope(); |
| 3078 while (scope->is_eval_scope() || scope->is_arrow_scope()) { |
| 3079 scope = scope->outer_scope(); |
| 3080 DCHECK_NOT_NULL(scope); |
| 3081 scope = scope->DeclarationScope(); |
| 3082 } |
| 3083 |
| 3084 if (scope->is_script_scope() || scope->is_module_scope()) { |
| 3085 ReportMessageAt(scanner()->location(), "unexpected_new_target"); |
| 3086 *ok = false; |
| 3087 return this->EmptyExpression(); |
| 3088 } |
| 3089 |
| 3090 scope_->RecordNewTargetUsage(); |
| 3091 |
| 3092 // ExpressionT is_construct_call = factory()->NewCallRuntime( |
| 3093 // ast_value_factory()->is_construct_call_string(), |
| 3094 // Runtime::FunctionForId(Runtime::kInlineIsConstructCall), |
| 3095 // this->NewExpressionList(0, zone_), RelocInfo::kNoPosition); |
| 3096 |
| 3097 // ExpressionT void_zero = factory()->NewUnaryOperation( |
| 3098 // Token::VOID, factory()->NewNumberLiteral(0, RelocInfo::kNoPosition), |
| 3099 // RelocInfo::kNoPosition); |
| 3100 |
| 3101 // %_IsConstructCall() ? new.target : void 0 |
| 3102 // return factory()->NewConditional( |
| 3103 // is_construct_call, |
| 3104 // this->NewTargetExpression(scope_, factory(), pos, position()), |
| 3105 // void_zero, |
| 3106 // RelocInfo::kNoPosition); |
| 3107 |
| 3108 return this->NewTargetExpression(scope_, factory(), pos, position()); |
| 3109 } |
| 3110 |
| 3111 |
| 3112 template <class Traits> |
| 3113 typename ParserBase<Traits>::ExpressionT |
| 3052 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, | 3114 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, |
| 3053 bool* ok) { | 3115 bool* ok) { |
| 3054 // Parses this part of MemberExpression: | 3116 // Parses this part of MemberExpression: |
| 3055 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3117 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 3056 while (true) { | 3118 while (true) { |
| 3057 switch (peek()) { | 3119 switch (peek()) { |
| 3058 case Token::LBRACK: { | 3120 case Token::LBRACK: { |
| 3059 Consume(Token::LBRACK); | 3121 Consume(Token::LBRACK); |
| 3060 int pos = position(); | 3122 int pos = position(); |
| 3061 ExpressionT index = this->ParseExpression(true, CHECK_OK); | 3123 ExpressionT index = this->ParseExpression(true, CHECK_OK); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3472 *ok = false; | 3534 *ok = false; |
| 3473 return; | 3535 return; |
| 3474 } | 3536 } |
| 3475 has_seen_constructor_ = true; | 3537 has_seen_constructor_ = true; |
| 3476 return; | 3538 return; |
| 3477 } | 3539 } |
| 3478 } | 3540 } |
| 3479 } } // v8::internal | 3541 } } // v8::internal |
| 3480 | 3542 |
| 3481 #endif // V8_PREPARSER_H | 3543 #endif // V8_PREPARSER_H |
| OLD | NEW |