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 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 return !tag.IsNoTemplateTag(); | 1632 return !tag.IsNoTemplateTag(); |
1633 } | 1633 } |
1634 | 1634 |
1635 void AddFormalParameter( | 1635 void AddFormalParameter( |
1636 PreParserFormalParameters* parameters, PreParserExpression pattern, | 1636 PreParserFormalParameters* parameters, PreParserExpression pattern, |
1637 bool is_rest) { | 1637 bool is_rest) { |
1638 ++parameters->arity; | 1638 ++parameters->arity; |
1639 } | 1639 } |
1640 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter, | 1640 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter, |
1641 bool is_simple, | 1641 bool is_simple, |
1642 ExpressionClassifier* classifier) {} | 1642 ExpressionClassifier* classifier) { |
| 1643 if (!is_simple) scope->SetHasNonSimpleParameters(); |
| 1644 } |
1643 | 1645 |
1644 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} | 1646 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
1645 | 1647 |
1646 // Temporary glue; these functions will move to ParserBase. | 1648 // Temporary glue; these functions will move to ParserBase. |
1647 PreParserExpression ParseV8Intrinsic(bool* ok); | 1649 PreParserExpression ParseV8Intrinsic(bool* ok); |
1648 PreParserExpression ParseFunctionLiteral( | 1650 PreParserExpression ParseFunctionLiteral( |
1649 PreParserIdentifier name, Scanner::Location function_name_location, | 1651 PreParserIdentifier name, Scanner::Location function_name_location, |
1650 FunctionNameValidity function_name_validity, FunctionKind kind, | 1652 FunctionNameValidity function_name_validity, FunctionKind kind, |
1651 int function_token_position, FunctionLiteral::FunctionType type, | 1653 int function_token_position, FunctionLiteral::FunctionType type, |
1652 FunctionLiteral::ArityRestriction arity_restriction, | 1654 FunctionLiteral::ArityRestriction arity_restriction, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1730 | 1732 |
1731 // Parses a single function literal, from the opening parentheses before | 1733 // Parses a single function literal, from the opening parentheses before |
1732 // parameters to the closing brace after the body. | 1734 // parameters to the closing brace after the body. |
1733 // Returns a FunctionEntry describing the body of the function in enough | 1735 // Returns a FunctionEntry describing the body of the function in enough |
1734 // detail that it can be lazily compiled. | 1736 // detail that it can be lazily compiled. |
1735 // The scanner is expected to have matched the "function" or "function*" | 1737 // The scanner is expected to have matched the "function" or "function*" |
1736 // keyword and parameters, and have consumed the initial '{'. | 1738 // keyword and parameters, and have consumed the initial '{'. |
1737 // At return, unless an error occurred, the scanner is positioned before the | 1739 // At return, unless an error occurred, the scanner is positioned before the |
1738 // the final '}'. | 1740 // the final '}'. |
1739 PreParseResult PreParseLazyFunction( | 1741 PreParseResult PreParseLazyFunction( |
1740 LanguageMode language_mode, FunctionKind kind, ParserRecorder* log, | 1742 LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters, |
1741 Scanner::BookmarkScope* bookmark = nullptr); | 1743 ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr); |
1742 | 1744 |
1743 private: | 1745 private: |
1744 friend class PreParserTraits; | 1746 friend class PreParserTraits; |
1745 | 1747 |
1746 static const int kLazyParseTrialLimit = 200; | 1748 static const int kLazyParseTrialLimit = 200; |
1747 | 1749 |
1748 // These types form an algebra over syntactic categories that is just | 1750 // These types form an algebra over syntactic categories that is just |
1749 // rich enough to let us recognize and propagate the constructs that | 1751 // rich enough to let us recognize and propagate the constructs that |
1750 // are either being counted in the preparser data, or is important | 1752 // are either being counted in the preparser data, or is important |
1751 // to throw the correct syntax error exceptions. | 1753 // to throw the correct syntax error exceptions. |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 } | 2299 } |
2298 Expect(Token::RPAREN, CHECK_OK); | 2300 Expect(Token::RPAREN, CHECK_OK); |
2299 result = this->ParseArrowFunctionLiteral(formals, formals_classifier, | 2301 result = this->ParseArrowFunctionLiteral(formals, formals_classifier, |
2300 CHECK_OK); | 2302 CHECK_OK); |
2301 } else { | 2303 } else { |
2302 // Heuristically try to detect immediately called functions before | 2304 // Heuristically try to detect immediately called functions before |
2303 // seeing the call parentheses. | 2305 // seeing the call parentheses. |
2304 parenthesized_function_ = (peek() == Token::FUNCTION); | 2306 parenthesized_function_ = (peek() == Token::FUNCTION); |
2305 result = this->ParseExpression(true, classifier, CHECK_OK); | 2307 result = this->ParseExpression(true, classifier, CHECK_OK); |
2306 Expect(Token::RPAREN, CHECK_OK); | 2308 Expect(Token::RPAREN, CHECK_OK); |
| 2309 if (peek() == Token::ARROW) { |
| 2310 int x = 5; |
| 2311 USE(x); |
| 2312 } |
2307 } | 2313 } |
2308 break; | 2314 break; |
2309 | 2315 |
2310 case Token::CLASS: { | 2316 case Token::CLASS: { |
2311 BindingPatternUnexpectedToken(classifier); | 2317 BindingPatternUnexpectedToken(classifier); |
2312 Consume(Token::CLASS); | 2318 Consume(Token::CLASS); |
2313 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2319 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2314 ReportMessage(MessageTemplate::kSloppyLexical); | 2320 ReportMessage(MessageTemplate::kSloppyLexical); |
2315 *ok = false; | 2321 *ok = false; |
2316 break; | 2322 break; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 template <class Traits> | 2378 template <class Traits> |
2373 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2379 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2374 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2380 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
2375 // Expression :: | 2381 // Expression :: |
2376 // AssignmentExpression | 2382 // AssignmentExpression |
2377 // Expression ',' AssignmentExpression | 2383 // Expression ',' AssignmentExpression |
2378 | 2384 |
2379 ExpressionClassifier binding_classifier; | 2385 ExpressionClassifier binding_classifier; |
2380 ExpressionT result = | 2386 ExpressionT result = |
2381 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 2387 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
| 2388 bool is_simple_parameter_list = this->IsIdentifier(result); |
2382 classifier->Accumulate(binding_classifier, | 2389 classifier->Accumulate(binding_classifier, |
2383 ExpressionClassifier::AllProductions); | 2390 ExpressionClassifier::AllProductions); |
2384 bool seen_rest = false; | 2391 bool seen_rest = false; |
2385 while (peek() == Token::COMMA) { | 2392 while (peek() == Token::COMMA) { |
2386 if (seen_rest) { | 2393 if (seen_rest) { |
2387 // At this point the production can't possibly be valid, but we don't know | 2394 // At this point the production can't possibly be valid, but we don't know |
2388 // which error to signal. | 2395 // which error to signal. |
2389 classifier->RecordArrowFormalParametersError( | 2396 classifier->RecordArrowFormalParametersError( |
2390 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 2397 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
2391 } | 2398 } |
2392 Consume(Token::COMMA); | 2399 Consume(Token::COMMA); |
2393 bool is_rest = false; | 2400 bool is_rest = false; |
2394 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { | 2401 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { |
2395 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 2402 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
2396 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 2403 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
2397 // valid expression or binding pattern. | 2404 // valid expression or binding pattern. |
2398 ExpressionUnexpectedToken(classifier); | 2405 ExpressionUnexpectedToken(classifier); |
2399 BindingPatternUnexpectedToken(classifier); | 2406 BindingPatternUnexpectedToken(classifier); |
2400 Consume(Token::ELLIPSIS); | 2407 Consume(Token::ELLIPSIS); |
2401 seen_rest = is_rest = true; | 2408 seen_rest = is_rest = true; |
2402 } | 2409 } |
2403 int pos = position(); | 2410 int pos = position(); |
2404 ExpressionT right = this->ParseAssignmentExpression( | 2411 ExpressionT right = this->ParseAssignmentExpression( |
2405 accept_IN, &binding_classifier, CHECK_OK); | 2412 accept_IN, &binding_classifier, CHECK_OK); |
2406 if (is_rest) right = factory()->NewSpread(right, pos); | 2413 if (is_rest) right = factory()->NewSpread(right, pos); |
| 2414 if (is_simple_parameter_list) { |
| 2415 is_simple_parameter_list = this->IsIdentifier(result); |
| 2416 } |
2407 classifier->Accumulate(binding_classifier, | 2417 classifier->Accumulate(binding_classifier, |
2408 ExpressionClassifier::AllProductions); | 2418 ExpressionClassifier::AllProductions); |
2409 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2419 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
2410 } | 2420 } |
| 2421 if (!is_simple_parameter_list) { |
| 2422 classifier->RecordNonSimpleParameter(); |
| 2423 } |
2411 return result; | 2424 return result; |
2412 } | 2425 } |
2413 | 2426 |
2414 | 2427 |
2415 template <class Traits> | 2428 template <class Traits> |
2416 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2429 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
2417 ExpressionClassifier* classifier, bool* ok) { | 2430 ExpressionClassifier* classifier, bool* ok) { |
2418 // ArrayLiteral :: | 2431 // ArrayLiteral :: |
2419 // '[' Expression? (',' Expression?)* ']' | 2432 // '[' Expression? (',' Expression?)* ']' |
2420 | 2433 |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2836 ExpressionT expression = this->ParseConditionalExpression( | 2849 ExpressionT expression = this->ParseConditionalExpression( |
2837 accept_IN, &arrow_formals_classifier, CHECK_OK); | 2850 accept_IN, &arrow_formals_classifier, CHECK_OK); |
2838 | 2851 |
2839 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2852 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
2840 BindingPatternUnexpectedToken(classifier); | 2853 BindingPatternUnexpectedToken(classifier); |
2841 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2854 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
2842 parenthesized_formals, CHECK_OK); | 2855 parenthesized_formals, CHECK_OK); |
2843 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); | 2856 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
2844 Scope* scope = | 2857 Scope* scope = |
2845 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 2858 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
| 2859 bool is_simple = arrow_formals_classifier.is_simple_parameter_list(); |
| 2860 if (!is_simple) scope->SetHasNonSimpleParameters(); |
2846 FormalParametersT parameters(scope); | 2861 FormalParametersT parameters(scope); |
| 2862 parameters.is_simple = is_simple; |
2847 checkpoint.Restore(¶meters.materialized_literals_count); | 2863 checkpoint.Restore(¶meters.materialized_literals_count); |
2848 | 2864 |
2849 scope->set_start_position(lhs_location.beg_pos); | 2865 scope->set_start_position(lhs_location.beg_pos); |
2850 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2866 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
2851 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, | 2867 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, |
2852 &duplicate_loc, CHECK_OK); | 2868 &duplicate_loc, CHECK_OK); |
2853 if (duplicate_loc.IsValid()) { | 2869 if (duplicate_loc.IsValid()) { |
2854 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 2870 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
2855 duplicate_loc); | 2871 duplicate_loc); |
2856 } | 2872 } |
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3758 formal_parameters.scope, kArrowFunction, | 3774 formal_parameters.scope, kArrowFunction, |
3759 &function_factory); | 3775 &function_factory); |
3760 | 3776 |
3761 function_state.SkipMaterializedLiterals( | 3777 function_state.SkipMaterializedLiterals( |
3762 formal_parameters.materialized_literals_count); | 3778 formal_parameters.materialized_literals_count); |
3763 | 3779 |
3764 this->ReindexLiterals(formal_parameters); | 3780 this->ReindexLiterals(formal_parameters); |
3765 | 3781 |
3766 Expect(Token::ARROW, CHECK_OK); | 3782 Expect(Token::ARROW, CHECK_OK); |
3767 | 3783 |
| 3784 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
| 3785 // which is not the same as "parameters of a strict function"; it only means |
| 3786 // that duplicates are not allowed. Of course, the arrow function may |
| 3787 // itself be strict as well. |
| 3788 const bool allow_duplicate_parameters = false; |
| 3789 this->ValidateFormalParameters(&formals_classifier, language_mode(), |
| 3790 allow_duplicate_parameters, CHECK_OK); |
| 3791 |
3768 if (peek() == Token::LBRACE) { | 3792 if (peek() == Token::LBRACE) { |
3769 // Multiple statement body | 3793 // Multiple statement body |
3770 Consume(Token::LBRACE); | 3794 Consume(Token::LBRACE); |
3771 bool is_lazily_parsed = | 3795 bool is_lazily_parsed = |
3772 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3796 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
3773 if (is_lazily_parsed) { | 3797 if (is_lazily_parsed) { |
3774 body = this->NewStatementList(0, zone()); | 3798 body = this->NewStatementList(0, zone()); |
3775 this->SkipLazyFunctionBody(&materialized_literal_count, | 3799 this->SkipLazyFunctionBody(&materialized_literal_count, |
3776 &expected_property_count, CHECK_OK); | 3800 &expected_property_count, CHECK_OK); |
3777 } else { | 3801 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
3793 body = this->NewStatementList(1, zone()); | 3817 body = this->NewStatementList(1, zone()); |
3794 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3818 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); |
3795 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3819 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3796 materialized_literal_count = function_state.materialized_literal_count(); | 3820 materialized_literal_count = function_state.materialized_literal_count(); |
3797 expected_property_count = function_state.expected_property_count(); | 3821 expected_property_count = function_state.expected_property_count(); |
3798 } | 3822 } |
3799 super_loc = function_state.super_location(); | 3823 super_loc = function_state.super_location(); |
3800 | 3824 |
3801 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3825 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
3802 | 3826 |
3803 // Arrow function formal parameters are parsed as StrictFormalParameterList, | |
3804 // which is not the same as "parameters of a strict function"; it only means | |
3805 // that duplicates are not allowed. Of course, the arrow function may | |
3806 // itself be strict as well. | |
3807 const bool allow_duplicate_parameters = false; | |
3808 this->ValidateFormalParameters(&formals_classifier, language_mode(), | |
3809 allow_duplicate_parameters, CHECK_OK); | |
3810 | |
3811 // Validate strict mode. | 3827 // Validate strict mode. |
3812 if (is_strict(language_mode())) { | 3828 if (is_strict(language_mode())) { |
3813 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3829 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
3814 scanner()->location().end_pos, CHECK_OK); | 3830 scanner()->location().end_pos, CHECK_OK); |
3815 } | 3831 } |
3816 if (is_strict(language_mode()) || allow_harmony_sloppy()) { | 3832 if (is_strict(language_mode()) || allow_harmony_sloppy()) { |
3817 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3833 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3818 } | 3834 } |
3819 } | 3835 } |
3820 | 3836 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4022 *ok = false; | 4038 *ok = false; |
4023 return; | 4039 return; |
4024 } | 4040 } |
4025 has_seen_constructor_ = true; | 4041 has_seen_constructor_ = true; |
4026 return; | 4042 return; |
4027 } | 4043 } |
4028 } | 4044 } |
4029 } } // v8::internal | 4045 } } // v8::internal |
4030 | 4046 |
4031 #endif // V8_PREPARSER_H | 4047 #endif // V8_PREPARSER_H |
OLD | NEW |