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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 stack_limit_(stack_limit), | 96 stack_limit_(stack_limit), |
97 zone_(zone), | 97 zone_(zone), |
98 scanner_(scanner), | 98 scanner_(scanner), |
99 stack_overflow_(false), | 99 stack_overflow_(false), |
100 allow_lazy_(false), | 100 allow_lazy_(false), |
101 allow_natives_(false), | 101 allow_natives_(false), |
102 allow_harmony_arrow_functions_(false), | 102 allow_harmony_arrow_functions_(false), |
103 allow_harmony_sloppy_(false), | 103 allow_harmony_sloppy_(false), |
104 allow_harmony_sloppy_let_(false), | 104 allow_harmony_sloppy_let_(false), |
105 allow_harmony_computed_property_names_(false), | 105 allow_harmony_computed_property_names_(false), |
106 allow_harmony_rest_params_(false), | 106 allow_harmony_rest_parameters_(false), |
107 allow_harmony_spreadcalls_(false), | 107 allow_harmony_spreadcalls_(false), |
108 allow_harmony_destructuring_(false), | 108 allow_harmony_destructuring_(false), |
109 allow_harmony_spread_arrays_(false), | 109 allow_harmony_spread_arrays_(false), |
110 allow_harmony_new_target_(false), | 110 allow_harmony_new_target_(false), |
111 allow_strong_mode_(false), | 111 allow_strong_mode_(false), |
112 allow_legacy_const_(true) {} | 112 allow_legacy_const_(true) {} |
113 | 113 |
114 #define ALLOW_ACCESSORS(name) \ | 114 #define ALLOW_ACCESSORS(name) \ |
115 bool allow_##name() const { return allow_##name##_; } \ | 115 bool allow_##name() const { return allow_##name##_; } \ |
116 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 116 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
117 | 117 |
118 ALLOW_ACCESSORS(lazy); | 118 ALLOW_ACCESSORS(lazy); |
119 ALLOW_ACCESSORS(natives); | 119 ALLOW_ACCESSORS(natives); |
120 ALLOW_ACCESSORS(harmony_arrow_functions); | 120 ALLOW_ACCESSORS(harmony_arrow_functions); |
121 ALLOW_ACCESSORS(harmony_sloppy); | 121 ALLOW_ACCESSORS(harmony_sloppy); |
122 ALLOW_ACCESSORS(harmony_sloppy_let); | 122 ALLOW_ACCESSORS(harmony_sloppy_let); |
123 ALLOW_ACCESSORS(harmony_computed_property_names); | 123 ALLOW_ACCESSORS(harmony_computed_property_names); |
124 ALLOW_ACCESSORS(harmony_rest_params); | 124 ALLOW_ACCESSORS(harmony_rest_parameters); |
125 ALLOW_ACCESSORS(harmony_spreadcalls); | 125 ALLOW_ACCESSORS(harmony_spreadcalls); |
126 ALLOW_ACCESSORS(harmony_destructuring); | 126 ALLOW_ACCESSORS(harmony_destructuring); |
127 ALLOW_ACCESSORS(harmony_spread_arrays); | 127 ALLOW_ACCESSORS(harmony_spread_arrays); |
128 ALLOW_ACCESSORS(harmony_new_target); | 128 ALLOW_ACCESSORS(harmony_new_target); |
129 ALLOW_ACCESSORS(strong_mode); | 129 ALLOW_ACCESSORS(strong_mode); |
130 ALLOW_ACCESSORS(legacy_const); | 130 ALLOW_ACCESSORS(legacy_const); |
131 #undef ALLOW_ACCESSORS | 131 #undef ALLOW_ACCESSORS |
132 | 132 |
133 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } | 133 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } |
134 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 134 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 ExpressionClassifier* classifier, bool* ok); | 695 ExpressionClassifier* classifier, bool* ok); |
696 ExpressionT ParseNewTargetExpression(bool* ok); | 696 ExpressionT ParseNewTargetExpression(bool* ok); |
697 ExpressionT ParseStrongInitializationExpression( | 697 ExpressionT ParseStrongInitializationExpression( |
698 ExpressionClassifier* classifier, bool* ok); | 698 ExpressionClassifier* classifier, bool* ok); |
699 ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier, | 699 ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier, |
700 bool* ok); | 700 bool* ok); |
701 | 701 |
702 void ParseFormalParameter(bool is_rest, | 702 void ParseFormalParameter(bool is_rest, |
703 FormalParametersT* parameters, | 703 FormalParametersT* parameters, |
704 ExpressionClassifier* classifier, bool* ok); | 704 ExpressionClassifier* classifier, bool* ok); |
705 int ParseFormalParameterList(FormalParametersT* parameters, | 705 void ParseFormalParameterList(FormalParametersT* parameters, |
706 ExpressionClassifier* classifier, bool* ok); | 706 ExpressionClassifier* classifier, bool* ok); |
707 void CheckArityRestrictions( | 707 void CheckArityRestrictions( |
708 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 708 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
709 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); | 709 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); |
710 | 710 |
711 // Checks if the expression is a valid reference expression (e.g., on the | 711 // Checks if the expression is a valid reference expression (e.g., on the |
712 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 712 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
713 // we allow calls for web compatibility and rewrite them to a runtime throw. | 713 // we allow calls for web compatibility and rewrite them to a runtime throw. |
714 ExpressionT CheckAndRewriteReferenceExpression( | 714 ExpressionT CheckAndRewriteReferenceExpression( |
715 ExpressionT expression, Scanner::Location location, | 715 ExpressionT expression, Scanner::Location location, |
716 MessageTemplate::Template message, bool* ok); | 716 MessageTemplate::Template message, bool* ok); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 | 794 |
795 Scanner* scanner_; | 795 Scanner* scanner_; |
796 bool stack_overflow_; | 796 bool stack_overflow_; |
797 | 797 |
798 bool allow_lazy_; | 798 bool allow_lazy_; |
799 bool allow_natives_; | 799 bool allow_natives_; |
800 bool allow_harmony_arrow_functions_; | 800 bool allow_harmony_arrow_functions_; |
801 bool allow_harmony_sloppy_; | 801 bool allow_harmony_sloppy_; |
802 bool allow_harmony_sloppy_let_; | 802 bool allow_harmony_sloppy_let_; |
803 bool allow_harmony_computed_property_names_; | 803 bool allow_harmony_computed_property_names_; |
804 bool allow_harmony_rest_params_; | 804 bool allow_harmony_rest_parameters_; |
805 bool allow_harmony_spreadcalls_; | 805 bool allow_harmony_spreadcalls_; |
806 bool allow_harmony_destructuring_; | 806 bool allow_harmony_destructuring_; |
807 bool allow_harmony_spread_arrays_; | 807 bool allow_harmony_spread_arrays_; |
808 bool allow_harmony_new_target_; | 808 bool allow_harmony_new_target_; |
809 bool allow_strong_mode_; | 809 bool allow_strong_mode_; |
810 bool allow_legacy_const_; | 810 bool allow_legacy_const_; |
811 }; | 811 }; |
812 | 812 |
813 | 813 |
814 class PreParserIdentifier { | 814 class PreParserIdentifier { |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 int* ast_properties() { | 1308 int* ast_properties() { |
1309 static int dummy = 42; | 1309 static int dummy = 42; |
1310 return &dummy; | 1310 return &dummy; |
1311 } | 1311 } |
1312 }; | 1312 }; |
1313 | 1313 |
1314 | 1314 |
1315 struct PreParserFormalParameters { | 1315 struct PreParserFormalParameters { |
1316 explicit PreParserFormalParameters(Scope* scope) | 1316 explicit PreParserFormalParameters(Scope* scope) |
1317 : scope(scope), | 1317 : scope(scope), |
| 1318 arity(0), |
1318 has_rest(false), | 1319 has_rest(false), |
1319 is_simple(true), | 1320 is_simple(true), |
1320 materialized_literals_count(0) {} | 1321 materialized_literals_count(0) {} |
1321 Scope* scope; | 1322 Scope* scope; |
| 1323 int arity; |
1322 bool has_rest; | 1324 bool has_rest; |
1323 bool is_simple; | 1325 bool is_simple; |
1324 int materialized_literals_count; | 1326 int materialized_literals_count; |
1325 }; | 1327 }; |
1326 | 1328 |
1327 | 1329 |
1328 class PreParser; | 1330 class PreParser; |
1329 | 1331 |
1330 class PreParserTraits { | 1332 class PreParserTraits { |
1331 public: | 1333 public: |
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2267 return this->EmptyExpression(); | 2269 return this->EmptyExpression(); |
2268 } | 2270 } |
2269 Scope* scope = | 2271 Scope* scope = |
2270 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 2272 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
2271 FormalParametersT parameters(scope); | 2273 FormalParametersT parameters(scope); |
2272 scope->set_start_position(beg_pos); | 2274 scope->set_start_position(beg_pos); |
2273 ExpressionClassifier args_classifier; | 2275 ExpressionClassifier args_classifier; |
2274 result = this->ParseArrowFunctionLiteral(parameters, args_classifier, | 2276 result = this->ParseArrowFunctionLiteral(parameters, args_classifier, |
2275 CHECK_OK); | 2277 CHECK_OK); |
2276 } else if (allow_harmony_arrow_functions() && | 2278 } else if (allow_harmony_arrow_functions() && |
2277 allow_harmony_rest_params() && Check(Token::ELLIPSIS)) { | 2279 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) { |
2278 // (...x) => y | 2280 // (...x) => y |
2279 Scope* scope = | 2281 Scope* scope = |
2280 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 2282 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
2281 FormalParametersT parameters(scope); | 2283 FormalParametersT parameters(scope); |
2282 scope->set_start_position(beg_pos); | 2284 scope->set_start_position(beg_pos); |
2283 ExpressionClassifier args_classifier; | 2285 ExpressionClassifier args_classifier; |
2284 const bool is_rest = true; | 2286 const bool is_rest = true; |
2285 this->ParseFormalParameter(is_rest, ¶meters, &args_classifier, | 2287 this->ParseFormalParameter(is_rest, ¶meters, &args_classifier, |
2286 CHECK_OK); | 2288 CHECK_OK); |
2287 if (peek() == Token::COMMA) { | 2289 if (peek() == Token::COMMA) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2379 bool seen_rest = false; | 2381 bool seen_rest = false; |
2380 while (peek() == Token::COMMA) { | 2382 while (peek() == Token::COMMA) { |
2381 if (seen_rest) { | 2383 if (seen_rest) { |
2382 // At this point the production can't possibly be valid, but we don't know | 2384 // At this point the production can't possibly be valid, but we don't know |
2383 // which error to signal. | 2385 // which error to signal. |
2384 classifier->RecordArrowFormalParametersError( | 2386 classifier->RecordArrowFormalParametersError( |
2385 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 2387 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
2386 } | 2388 } |
2387 Consume(Token::COMMA); | 2389 Consume(Token::COMMA); |
2388 bool is_rest = false; | 2390 bool is_rest = false; |
2389 if (allow_harmony_rest_params() && peek() == Token::ELLIPSIS) { | 2391 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { |
2390 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 2392 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
2391 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 2393 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
2392 // valid expression or binding pattern. | 2394 // valid expression or binding pattern. |
2393 ExpressionUnexpectedToken(classifier); | 2395 ExpressionUnexpectedToken(classifier); |
2394 BindingPatternUnexpectedToken(classifier); | 2396 BindingPatternUnexpectedToken(classifier); |
2395 Consume(Token::ELLIPSIS); | 2397 Consume(Token::ELLIPSIS); |
2396 seen_rest = is_rest = true; | 2398 seen_rest = is_rest = true; |
2397 } | 2399 } |
2398 int pos = position(); | 2400 int pos = position(); |
2399 ExpressionT right = this->ParseAssignmentExpression( | 2401 ExpressionT right = this->ParseAssignmentExpression( |
(...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3638 | 3640 |
3639 if (parameters->is_simple) { | 3641 if (parameters->is_simple) { |
3640 parameters->is_simple = !is_rest && Traits::IsIdentifier(pattern); | 3642 parameters->is_simple = !is_rest && Traits::IsIdentifier(pattern); |
3641 } | 3643 } |
3642 parameters->has_rest = is_rest; | 3644 parameters->has_rest = is_rest; |
3643 if (is_rest && !Traits::IsIdentifier(pattern)) { | 3645 if (is_rest && !Traits::IsIdentifier(pattern)) { |
3644 ReportUnexpectedToken(next); | 3646 ReportUnexpectedToken(next); |
3645 *ok = false; | 3647 *ok = false; |
3646 return; | 3648 return; |
3647 } | 3649 } |
| 3650 ++parameters->arity; |
3648 Traits::DeclareFormalParameter(parameters, pattern, is_rest, classifier); | 3651 Traits::DeclareFormalParameter(parameters, pattern, is_rest, classifier); |
3649 } | 3652 } |
3650 | 3653 |
3651 | 3654 |
3652 template <class Traits> | 3655 template <class Traits> |
3653 int ParserBase<Traits>::ParseFormalParameterList( | 3656 void ParserBase<Traits>::ParseFormalParameterList( |
3654 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { | 3657 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { |
3655 // FormalParameters[Yield,GeneratorParameter] : | 3658 // FormalParameters[Yield,GeneratorParameter] : |
3656 // [empty] | 3659 // [empty] |
3657 // FormalParameterList[?Yield, ?GeneratorParameter] | 3660 // FormalParameterList[?Yield, ?GeneratorParameter] |
3658 // | 3661 // |
3659 // FormalParameterList[Yield,GeneratorParameter] : | 3662 // FormalParameterList[Yield,GeneratorParameter] : |
3660 // FunctionRestParameter[?Yield] | 3663 // FunctionRestParameter[?Yield] |
3661 // FormalsList[?Yield, ?GeneratorParameter] | 3664 // FormalsList[?Yield, ?GeneratorParameter] |
3662 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] | 3665 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] |
3663 // | 3666 // |
3664 // FormalsList[Yield,GeneratorParameter] : | 3667 // FormalsList[Yield,GeneratorParameter] : |
3665 // FormalParameter[?Yield, ?GeneratorParameter] | 3668 // FormalParameter[?Yield, ?GeneratorParameter] |
3666 // FormalsList[?Yield, ?GeneratorParameter] , | 3669 // FormalsList[?Yield, ?GeneratorParameter] , |
3667 // FormalParameter[?Yield,?GeneratorParameter] | 3670 // FormalParameter[?Yield,?GeneratorParameter] |
3668 | 3671 |
3669 int arity = 0; | 3672 DCHECK_EQ(0, parameters->arity); |
3670 | 3673 |
3671 if (peek() != Token::RPAREN) { | 3674 if (peek() != Token::RPAREN) { |
3672 do { | 3675 do { |
3673 if (++arity > Code::kMaxArguments) { | 3676 if (parameters->arity > Code::kMaxArguments) { |
3674 ReportMessage(MessageTemplate::kTooManyParameters); | 3677 ReportMessage(MessageTemplate::kTooManyParameters); |
3675 *ok = false; | 3678 *ok = false; |
3676 return -1; | 3679 return; |
3677 } | 3680 } |
3678 bool is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); | 3681 bool is_rest = allow_harmony_rest_parameters() && Check(Token::ELLIPSIS); |
3679 ParseFormalParameter(is_rest, parameters, classifier, ok); | 3682 ParseFormalParameter(is_rest, parameters, classifier, ok); |
3680 if (!*ok) return -1; | 3683 if (!*ok) return; |
3681 } while (!parameters->has_rest && Check(Token::COMMA)); | 3684 } while (!parameters->has_rest && Check(Token::COMMA)); |
3682 | 3685 |
3683 if (parameters->has_rest && peek() == Token::COMMA) { | 3686 if (parameters->has_rest && peek() == Token::COMMA) { |
3684 ReportMessageAt(scanner()->peek_location(), | 3687 ReportMessageAt(scanner()->peek_location(), |
3685 MessageTemplate::kParamAfterRest); | 3688 MessageTemplate::kParamAfterRest); |
3686 *ok = false; | 3689 *ok = false; |
3687 return -1; | |
3688 } | 3690 } |
3689 } | 3691 } |
3690 | |
3691 return arity; | |
3692 } | 3692 } |
3693 | 3693 |
3694 | 3694 |
3695 template <class Traits> | 3695 template <class Traits> |
3696 void ParserBase<Traits>::CheckArityRestrictions( | 3696 void ParserBase<Traits>::CheckArityRestrictions( |
3697 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 3697 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
3698 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) { | 3698 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) { |
3699 switch (arity_restriction) { | 3699 switch (arity_restriction) { |
3700 case FunctionLiteral::GETTER_ARITY: | 3700 case FunctionLiteral::GETTER_ARITY: |
3701 if (param_count != 0) { | 3701 if (param_count != 0) { |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4012 *ok = false; | 4012 *ok = false; |
4013 return; | 4013 return; |
4014 } | 4014 } |
4015 has_seen_constructor_ = true; | 4015 has_seen_constructor_ = true; |
4016 return; | 4016 return; |
4017 } | 4017 } |
4018 } | 4018 } |
4019 } } // v8::internal | 4019 } } // v8::internal |
4020 | 4020 |
4021 #endif // V8_PREPARSER_H | 4021 #endif // V8_PREPARSER_H |
OLD | NEW |