| 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/bailout-reason.h" | 8 #include "src/bailout-reason.h" |
| 9 #include "src/expression-classifier.h" | 9 #include "src/expression-classifier.h" |
| 10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 kSkipFunctionNameCheck, | 23 kSkipFunctionNameCheck, |
| 24 kFunctionNameValidityUnknown | 24 kFunctionNameValidityUnknown |
| 25 }; | 25 }; |
| 26 | 26 |
| 27 | 27 |
| 28 struct FormalParametersBase { | 28 struct FormalParametersBase { |
| 29 explicit FormalParametersBase(Scope* scope) : scope(scope) {} | 29 explicit FormalParametersBase(Scope* scope) : scope(scope) {} |
| 30 Scope* scope; | 30 Scope* scope; |
| 31 bool has_rest = false; | 31 bool has_rest = false; |
| 32 bool is_simple = true; | 32 bool is_simple = true; |
| 33 bool contains_expressions = false; |
| 33 int materialized_literals_count = 0; | 34 int materialized_literals_count = 0; |
| 34 mutable int rest_array_literal_index = -1; | 35 mutable int rest_array_literal_index = -1; |
| 35 }; | 36 }; |
| 36 | 37 |
| 37 | 38 |
| 38 // Common base class shared between parser and pre-parser. Traits encapsulate | 39 // Common base class shared between parser and pre-parser. Traits encapsulate |
| 39 // the differences between Parser and PreParser: | 40 // the differences between Parser and PreParser: |
| 40 | 41 |
| 41 // - Return types: For example, Parser functions return Expression* and | 42 // - Return types: For example, Parser functions return Expression* and |
| 42 // PreParser functions return PreParserExpression. | 43 // PreParser functions return PreParserExpression. |
| (...skipping 1738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1781 // Parses a single function literal, from the opening parentheses before | 1782 // Parses a single function literal, from the opening parentheses before |
| 1782 // parameters to the closing brace after the body. | 1783 // parameters to the closing brace after the body. |
| 1783 // Returns a FunctionEntry describing the body of the function in enough | 1784 // Returns a FunctionEntry describing the body of the function in enough |
| 1784 // detail that it can be lazily compiled. | 1785 // detail that it can be lazily compiled. |
| 1785 // The scanner is expected to have matched the "function" or "function*" | 1786 // The scanner is expected to have matched the "function" or "function*" |
| 1786 // keyword and parameters, and have consumed the initial '{'. | 1787 // keyword and parameters, and have consumed the initial '{'. |
| 1787 // At return, unless an error occurred, the scanner is positioned before the | 1788 // At return, unless an error occurred, the scanner is positioned before the |
| 1788 // the final '}'. | 1789 // the final '}'. |
| 1789 PreParseResult PreParseLazyFunction( | 1790 PreParseResult PreParseLazyFunction( |
| 1790 LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters, | 1791 LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters, |
| 1791 ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr); | 1792 bool has_parameter_expressions, ParserRecorder* log, |
| 1793 Scanner::BookmarkScope* bookmark = nullptr); |
| 1792 | 1794 |
| 1793 private: | 1795 private: |
| 1794 friend class PreParserTraits; | 1796 friend class PreParserTraits; |
| 1795 | 1797 |
| 1796 static const int kLazyParseTrialLimit = 200; | 1798 static const int kLazyParseTrialLimit = 200; |
| 1797 | 1799 |
| 1798 // These types form an algebra over syntactic categories that is just | 1800 // These types form an algebra over syntactic categories that is just |
| 1799 // rich enough to let us recognize and propagate the constructs that | 1801 // rich enough to let us recognize and propagate the constructs that |
| 1800 // are either being counted in the preparser data, or is important | 1802 // are either being counted in the preparser data, or is important |
| 1801 // to throw the correct syntax error exceptions. | 1803 // to throw the correct syntax error exceptions. |
| (...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2604 int next_beg_pos = scanner()->peek_location().beg_pos; | 2606 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 2605 int next_end_pos = scanner()->peek_location().end_pos; | 2607 int next_end_pos = scanner()->peek_location().end_pos; |
| 2606 ExpressionT name_expression = ParsePropertyName( | 2608 ExpressionT name_expression = ParsePropertyName( |
| 2607 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, | 2609 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, |
| 2608 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2610 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2609 | 2611 |
| 2610 if (fni_ != nullptr && !*is_computed_name) { | 2612 if (fni_ != nullptr && !*is_computed_name) { |
| 2611 this->PushLiteralName(fni_, name); | 2613 this->PushLiteralName(fni_, name); |
| 2612 } | 2614 } |
| 2613 | 2615 |
| 2616 if (*is_computed_name) classifier->RecordContainsExpressions(); |
| 2617 |
| 2614 if (!in_class && !is_generator && peek() == Token::COLON) { | 2618 if (!in_class && !is_generator && peek() == Token::COLON) { |
| 2615 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2619 // PropertyDefinition : PropertyName ':' AssignmentExpression |
| 2616 if (!*is_computed_name) { | 2620 if (!*is_computed_name) { |
| 2617 checker->CheckProperty(name_token, kValueProperty, is_static, | 2621 checker->CheckProperty(name_token, kValueProperty, is_static, |
| 2618 is_generator, | 2622 is_generator, |
| 2619 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2623 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2620 } | 2624 } |
| 2621 Consume(Token::COLON); | 2625 Consume(Token::COLON); |
| 2622 value = this->ParseAssignmentExpression( | 2626 value = this->ParseAssignmentExpression( |
| 2623 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2627 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2707 if (peek() == Token::ASSIGN) { | 2711 if (peek() == Token::ASSIGN) { |
| 2708 this->ExpressionUnexpectedToken(classifier); | 2712 this->ExpressionUnexpectedToken(classifier); |
| 2709 Consume(Token::ASSIGN); | 2713 Consume(Token::ASSIGN); |
| 2710 ExpressionClassifier rhs_classifier; | 2714 ExpressionClassifier rhs_classifier; |
| 2711 ExpressionT rhs = this->ParseAssignmentExpression( | 2715 ExpressionT rhs = this->ParseAssignmentExpression( |
| 2712 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2716 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2713 classifier->Accumulate(rhs_classifier, | 2717 classifier->Accumulate(rhs_classifier, |
| 2714 ExpressionClassifier::ExpressionProductions); | 2718 ExpressionClassifier::ExpressionProductions); |
| 2715 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2719 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
| 2716 RelocInfo::kNoPosition); | 2720 RelocInfo::kNoPosition); |
| 2721 classifier->RecordContainsExpressions(); |
| 2717 } else { | 2722 } else { |
| 2718 value = lhs; | 2723 value = lhs; |
| 2719 } | 2724 } |
| 2720 return factory()->NewObjectLiteralProperty( | 2725 return factory()->NewObjectLiteralProperty( |
| 2721 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); | 2726 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); |
| 2722 | 2727 |
| 2723 } else { | 2728 } else { |
| 2724 Token::Value next = Next(); | 2729 Token::Value next = Next(); |
| 2725 ReportUnexpectedToken(next); | 2730 ReportUnexpectedToken(next); |
| 2726 *ok = false; | 2731 *ok = false; |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2897 BindingPatternUnexpectedToken(classifier); | 2902 BindingPatternUnexpectedToken(classifier); |
| 2898 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2903 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
| 2899 parenthesized_formals, CHECK_OK); | 2904 parenthesized_formals, CHECK_OK); |
| 2900 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2905 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
| 2901 Scope* scope = | 2906 Scope* scope = |
| 2902 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 2907 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
| 2903 FormalParametersT parameters(scope); | 2908 FormalParametersT parameters(scope); |
| 2904 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2909 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
| 2905 scope->SetHasNonSimpleParameters(); | 2910 scope->SetHasNonSimpleParameters(); |
| 2906 parameters.is_simple = false; | 2911 parameters.is_simple = false; |
| 2912 |
| 2913 if (arrow_formals_classifier.contains_expressions()) { |
| 2914 parameters.contains_expressions = true; |
| 2915 scope->SetHasParameterExpressions(); |
| 2916 } |
| 2907 } | 2917 } |
| 2908 | 2918 |
| 2909 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2919 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
| 2910 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, | 2920 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, |
| 2911 &duplicate_loc, CHECK_OK); | 2921 &duplicate_loc, CHECK_OK); |
| 2912 | 2922 |
| 2913 checkpoint.Restore(¶meters.materialized_literals_count); | 2923 checkpoint.Restore(¶meters.materialized_literals_count); |
| 2914 | 2924 |
| 2915 scope->set_start_position(lhs_beg_pos); | 2925 scope->set_start_position(lhs_beg_pos); |
| 2916 if (duplicate_loc.IsValid()) { | 2926 if (duplicate_loc.IsValid()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2941 expression = this->CheckAndRewriteReferenceExpression( | 2951 expression = this->CheckAndRewriteReferenceExpression( |
| 2942 expression, lhs_beg_pos, scanner()->location().end_pos, | 2952 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 2943 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 2953 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
| 2944 expression = this->MarkExpressionAsAssigned(expression); | 2954 expression = this->MarkExpressionAsAssigned(expression); |
| 2945 | 2955 |
| 2946 Token::Value op = Next(); // Get assignment operator. | 2956 Token::Value op = Next(); // Get assignment operator. |
| 2947 if (op != Token::ASSIGN) { | 2957 if (op != Token::ASSIGN) { |
| 2948 classifier->RecordBindingPatternError(scanner()->location(), | 2958 classifier->RecordBindingPatternError(scanner()->location(), |
| 2949 MessageTemplate::kUnexpectedToken, | 2959 MessageTemplate::kUnexpectedToken, |
| 2950 Token::String(op)); | 2960 Token::String(op)); |
| 2961 } else { |
| 2962 classifier->RecordContainsExpressions(); |
| 2951 } | 2963 } |
| 2952 int pos = position(); | 2964 int pos = position(); |
| 2953 | 2965 |
| 2954 ExpressionClassifier rhs_classifier; | 2966 ExpressionClassifier rhs_classifier; |
| 2955 ExpressionT right = | 2967 ExpressionT right = |
| 2956 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2968 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
| 2957 classifier->Accumulate(rhs_classifier, | 2969 classifier->Accumulate(rhs_classifier, |
| 2958 ExpressionClassifier::ExpressionProductions); | 2970 ExpressionClassifier::ExpressionProductions); |
| 2959 | 2971 |
| 2960 // TODO(1231235): We try to estimate the set of properties set by | 2972 // TODO(1231235): We try to estimate the set of properties set by |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3736 ExpressionT initializer = Traits::EmptyExpression(); | 3748 ExpressionT initializer = Traits::EmptyExpression(); |
| 3737 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { | 3749 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { |
| 3738 ExpressionClassifier init_classifier; | 3750 ExpressionClassifier init_classifier; |
| 3739 initializer = ParseAssignmentExpression(true, &init_classifier, ok); | 3751 initializer = ParseAssignmentExpression(true, &init_classifier, ok); |
| 3740 if (!*ok) return; | 3752 if (!*ok) return; |
| 3741 ValidateExpression(&init_classifier, ok); | 3753 ValidateExpression(&init_classifier, ok); |
| 3742 ValidateFormalParameterInitializer(&init_classifier, ok); | 3754 ValidateFormalParameterInitializer(&init_classifier, ok); |
| 3743 if (!*ok) return; | 3755 if (!*ok) return; |
| 3744 parameters->is_simple = false; | 3756 parameters->is_simple = false; |
| 3745 classifier->RecordNonSimpleParameter(); | 3757 classifier->RecordNonSimpleParameter(); |
| 3758 classifier->RecordContainsExpressions(); |
| 3746 } | 3759 } |
| 3747 | 3760 |
| 3748 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest); | 3761 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest); |
| 3749 } | 3762 } |
| 3750 | 3763 |
| 3751 | 3764 |
| 3752 template <class Traits> | 3765 template <class Traits> |
| 3753 void ParserBase<Traits>::ParseFormalParameterList( | 3766 void ParserBase<Traits>::ParseFormalParameterList( |
| 3754 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { | 3767 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { |
| 3755 // FormalParameters[Yield,GeneratorParameter] : | 3768 // FormalParameters[Yield,GeneratorParameter] : |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3786 classifier->RecordNonSimpleParameter(); | 3799 classifier->RecordNonSimpleParameter(); |
| 3787 if (peek() == Token::COMMA) { | 3800 if (peek() == Token::COMMA) { |
| 3788 ReportMessageAt(scanner()->peek_location(), | 3801 ReportMessageAt(scanner()->peek_location(), |
| 3789 MessageTemplate::kParamAfterRest); | 3802 MessageTemplate::kParamAfterRest); |
| 3790 *ok = false; | 3803 *ok = false; |
| 3791 return; | 3804 return; |
| 3792 } | 3805 } |
| 3793 } | 3806 } |
| 3794 } | 3807 } |
| 3795 | 3808 |
| 3809 parameters->contains_expressions = classifier->contains_expressions(); |
| 3810 if (parameters->contains_expressions) { |
| 3811 parameters->scope->SetHasParameterExpressions(); |
| 3812 } |
| 3813 |
| 3796 for (int i = 0; i < parameters->Arity(); ++i) { | 3814 for (int i = 0; i < parameters->Arity(); ++i) { |
| 3797 auto parameter = parameters->at(i); | 3815 auto parameter = parameters->at(i); |
| 3798 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); | 3816 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); |
| 3799 } | 3817 } |
| 3800 } | 3818 } |
| 3801 | 3819 |
| 3802 | 3820 |
| 3803 template <class Traits> | 3821 template <class Traits> |
| 3804 void ParserBase<Traits>::CheckArityRestrictions( | 3822 void ParserBase<Traits>::CheckArityRestrictions( |
| 3805 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 3823 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4157 *ok = false; | 4175 *ok = false; |
| 4158 return; | 4176 return; |
| 4159 } | 4177 } |
| 4160 has_seen_constructor_ = true; | 4178 has_seen_constructor_ = true; |
| 4161 return; | 4179 return; |
| 4162 } | 4180 } |
| 4163 } | 4181 } |
| 4164 } } // v8::internal | 4182 } } // v8::internal |
| 4165 | 4183 |
| 4166 #endif // V8_PREPARSER_H | 4184 #endif // V8_PREPARSER_H |
| OLD | NEW |