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 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 void ParseFormalParameterList(FormalParametersT* parameters, | 706 void ParseFormalParameterList(FormalParametersT* parameters, |
707 ExpressionClassifier* classifier, bool* ok); | 707 ExpressionClassifier* classifier, bool* ok); |
708 void CheckArityRestrictions( | 708 void CheckArityRestrictions( |
709 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 709 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
710 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); | 710 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); |
711 | 711 |
712 // Checks if the expression is a valid reference expression (e.g., on the | 712 // Checks if the expression is a valid reference expression (e.g., on the |
713 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 713 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
714 // we allow calls for web compatibility and rewrite them to a runtime throw. | 714 // we allow calls for web compatibility and rewrite them to a runtime throw. |
715 ExpressionT CheckAndRewriteReferenceExpression( | 715 ExpressionT CheckAndRewriteReferenceExpression( |
716 ExpressionT expression, Scanner::Location location, | 716 ExpressionT expression, int beg_pos, int end_pos, |
717 MessageTemplate::Template message, bool* ok); | 717 MessageTemplate::Template message, bool* ok); |
718 | 718 |
719 // Used to validate property names in object literals and class literals | 719 // Used to validate property names in object literals and class literals |
720 enum PropertyKind { | 720 enum PropertyKind { |
721 kAccessorProperty, | 721 kAccessorProperty, |
722 kValueProperty, | 722 kValueProperty, |
723 kMethodProperty | 723 kMethodProperty |
724 }; | 724 }; |
725 | 725 |
726 class ObjectLiteralCheckerBase { | 726 class ObjectLiteralCheckerBase { |
(...skipping 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2814 typename ParserBase<Traits>::ExpressionT | 2814 typename ParserBase<Traits>::ExpressionT |
2815 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 2815 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
2816 ExpressionClassifier* classifier, | 2816 ExpressionClassifier* classifier, |
2817 bool* ok) { | 2817 bool* ok) { |
2818 // AssignmentExpression :: | 2818 // AssignmentExpression :: |
2819 // ConditionalExpression | 2819 // ConditionalExpression |
2820 // ArrowFunction | 2820 // ArrowFunction |
2821 // YieldExpression | 2821 // YieldExpression |
2822 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2822 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2823 | 2823 |
2824 Scanner::Location lhs_location = scanner()->peek_location(); | 2824 int lhs_beg_pos = peek_position(); |
2825 | 2825 |
2826 if (peek() == Token::YIELD && is_generator()) { | 2826 if (peek() == Token::YIELD && is_generator()) { |
2827 return this->ParseYieldExpression(classifier, ok); | 2827 return this->ParseYieldExpression(classifier, ok); |
2828 } | 2828 } |
2829 | 2829 |
2830 if (fni_ != NULL) fni_->Enter(); | 2830 if (fni_ != NULL) fni_->Enter(); |
2831 ParserBase<Traits>::Checkpoint checkpoint(this); | 2831 ParserBase<Traits>::Checkpoint checkpoint(this); |
2832 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); | 2832 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); |
2833 bool parenthesized_formals = peek() == Token::LPAREN; | 2833 bool parenthesized_formals = peek() == Token::LPAREN; |
2834 if (!parenthesized_formals) { | 2834 if (!parenthesized_formals) { |
2835 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 2835 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); |
2836 } | 2836 } |
2837 ExpressionT expression = this->ParseConditionalExpression( | 2837 ExpressionT expression = this->ParseConditionalExpression( |
2838 accept_IN, &arrow_formals_classifier, CHECK_OK); | 2838 accept_IN, &arrow_formals_classifier, CHECK_OK); |
2839 | 2839 |
2840 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2840 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
2841 BindingPatternUnexpectedToken(classifier); | 2841 BindingPatternUnexpectedToken(classifier); |
2842 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2842 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
2843 parenthesized_formals, CHECK_OK); | 2843 parenthesized_formals, CHECK_OK); |
2844 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); | 2844 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
2845 Scope* scope = | 2845 Scope* scope = |
2846 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 2846 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
2847 FormalParametersT parameters(scope); | 2847 FormalParametersT parameters(scope); |
2848 checkpoint.Restore(¶meters.materialized_literals_count); | 2848 checkpoint.Restore(¶meters.materialized_literals_count); |
2849 | 2849 |
2850 scope->set_start_position(lhs_location.beg_pos); | 2850 scope->set_start_position(lhs_beg_pos); |
2851 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2851 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
2852 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, | 2852 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, |
2853 &duplicate_loc, CHECK_OK); | 2853 &duplicate_loc, CHECK_OK); |
2854 if (duplicate_loc.IsValid()) { | 2854 if (duplicate_loc.IsValid()) { |
2855 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 2855 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
2856 duplicate_loc); | 2856 duplicate_loc); |
2857 } | 2857 } |
2858 expression = this->ParseArrowFunctionLiteral( | 2858 expression = this->ParseArrowFunctionLiteral( |
2859 parameters, arrow_formals_classifier, CHECK_OK); | 2859 parameters, arrow_formals_classifier, CHECK_OK); |
2860 return expression; | 2860 return expression; |
2861 } | 2861 } |
2862 | 2862 |
2863 // "expression" was not itself an arrow function parameter list, but it might | 2863 // "expression" was not itself an arrow function parameter list, but it might |
2864 // form part of one. Propagate speculative formal parameter error locations. | 2864 // form part of one. Propagate speculative formal parameter error locations. |
2865 classifier->Accumulate(arrow_formals_classifier, | 2865 classifier->Accumulate(arrow_formals_classifier, |
2866 ExpressionClassifier::StandardProductions | | 2866 ExpressionClassifier::StandardProductions | |
2867 ExpressionClassifier::FormalParametersProductions); | 2867 ExpressionClassifier::FormalParametersProductions); |
2868 | 2868 |
2869 if (!Token::IsAssignmentOp(peek())) { | 2869 if (!Token::IsAssignmentOp(peek())) { |
2870 if (fni_ != NULL) fni_->Leave(); | 2870 if (fni_ != NULL) fni_->Leave(); |
2871 // Parsed conditional expression only (no assignment). | 2871 // Parsed conditional expression only (no assignment). |
2872 return expression; | 2872 return expression; |
2873 } | 2873 } |
2874 | 2874 |
2875 if (!allow_harmony_destructuring()) { | 2875 if (!allow_harmony_destructuring()) { |
2876 BindingPatternUnexpectedToken(classifier); | 2876 BindingPatternUnexpectedToken(classifier); |
2877 } | 2877 } |
2878 | 2878 |
2879 expression = this->CheckAndRewriteReferenceExpression( | 2879 expression = this->CheckAndRewriteReferenceExpression( |
2880 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, | 2880 expression, lhs_beg_pos, scanner()->location().end_pos, |
2881 CHECK_OK); | 2881 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
2882 expression = this->MarkExpressionAsAssigned(expression); | 2882 expression = this->MarkExpressionAsAssigned(expression); |
2883 | 2883 |
2884 Token::Value op = Next(); // Get assignment operator. | 2884 Token::Value op = Next(); // Get assignment operator. |
2885 if (op != Token::ASSIGN) { | 2885 if (op != Token::ASSIGN) { |
2886 classifier->RecordBindingPatternError(scanner()->location(), | 2886 classifier->RecordBindingPatternError(scanner()->location(), |
2887 MessageTemplate::kUnexpectedToken, | 2887 MessageTemplate::kUnexpectedToken, |
2888 Token::String(op)); | 2888 Token::String(op)); |
2889 } | 2889 } |
2890 int pos = position(); | 2890 int pos = position(); |
2891 | 2891 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3087 *ok = false; | 3087 *ok = false; |
3088 return this->EmptyExpression(); | 3088 return this->EmptyExpression(); |
3089 } | 3089 } |
3090 } | 3090 } |
3091 | 3091 |
3092 // Allow Traits do rewrite the expression. | 3092 // Allow Traits do rewrite the expression. |
3093 return this->BuildUnaryExpression(expression, op, pos, factory()); | 3093 return this->BuildUnaryExpression(expression, op, pos, factory()); |
3094 } else if (Token::IsCountOp(op)) { | 3094 } else if (Token::IsCountOp(op)) { |
3095 BindingPatternUnexpectedToken(classifier); | 3095 BindingPatternUnexpectedToken(classifier); |
3096 op = Next(); | 3096 op = Next(); |
3097 Scanner::Location lhs_location = scanner()->peek_location(); | 3097 int beg_pos = peek_position(); |
3098 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 3098 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
3099 expression = this->CheckAndRewriteReferenceExpression( | 3099 expression = this->CheckAndRewriteReferenceExpression( |
3100 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, | 3100 expression, beg_pos, scanner()->location().end_pos, |
3101 CHECK_OK); | 3101 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
3102 this->MarkExpressionAsAssigned(expression); | 3102 this->MarkExpressionAsAssigned(expression); |
3103 | 3103 |
3104 return factory()->NewCountOperation(op, | 3104 return factory()->NewCountOperation(op, |
3105 true /* prefix */, | 3105 true /* prefix */, |
3106 expression, | 3106 expression, |
3107 position()); | 3107 position()); |
3108 | 3108 |
3109 } else { | 3109 } else { |
3110 return this->ParsePostfixExpression(classifier, ok); | 3110 return this->ParsePostfixExpression(classifier, ok); |
3111 } | 3111 } |
3112 } | 3112 } |
3113 | 3113 |
3114 | 3114 |
3115 template <class Traits> | 3115 template <class Traits> |
3116 typename ParserBase<Traits>::ExpressionT | 3116 typename ParserBase<Traits>::ExpressionT |
3117 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 3117 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
3118 bool* ok) { | 3118 bool* ok) { |
3119 // PostfixExpression :: | 3119 // PostfixExpression :: |
3120 // LeftHandSideExpression ('++' | '--')? | 3120 // LeftHandSideExpression ('++' | '--')? |
3121 | 3121 |
3122 Scanner::Location lhs_location = scanner()->peek_location(); | 3122 int lhs_beg_pos = peek_position(); |
3123 ExpressionT expression = | 3123 ExpressionT expression = |
3124 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 3124 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
3125 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3125 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
3126 Token::IsCountOp(peek())) { | 3126 Token::IsCountOp(peek())) { |
3127 BindingPatternUnexpectedToken(classifier); | 3127 BindingPatternUnexpectedToken(classifier); |
3128 | 3128 |
3129 expression = this->CheckAndRewriteReferenceExpression( | 3129 expression = this->CheckAndRewriteReferenceExpression( |
3130 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, | 3130 expression, lhs_beg_pos, scanner()->location().end_pos, |
3131 CHECK_OK); | 3131 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
3132 expression = this->MarkExpressionAsAssigned(expression); | 3132 expression = this->MarkExpressionAsAssigned(expression); |
3133 | 3133 |
3134 Token::Value next = Next(); | 3134 Token::Value next = Next(); |
3135 expression = | 3135 expression = |
3136 factory()->NewCountOperation(next, | 3136 factory()->NewCountOperation(next, |
3137 false /* postfix */, | 3137 false /* postfix */, |
3138 expression, | 3138 expression, |
3139 position()); | 3139 position()); |
3140 } | 3140 } |
3141 return expression; | 3141 return expression; |
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3929 DCHECK_EQ(next, Token::TEMPLATE_TAIL); | 3929 DCHECK_EQ(next, Token::TEMPLATE_TAIL); |
3930 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3930 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
3931 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 3931 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
3932 return Traits::CloseTemplateLiteral(&ts, start, tag); | 3932 return Traits::CloseTemplateLiteral(&ts, start, tag); |
3933 } | 3933 } |
3934 | 3934 |
3935 | 3935 |
3936 template <typename Traits> | 3936 template <typename Traits> |
3937 typename ParserBase<Traits>::ExpressionT | 3937 typename ParserBase<Traits>::ExpressionT |
3938 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 3938 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
3939 ExpressionT expression, Scanner::Location location, | 3939 ExpressionT expression, int beg_pos, int end_pos, |
3940 MessageTemplate::Template message, bool* ok) { | 3940 MessageTemplate::Template message, bool* ok) { |
| 3941 Scanner::Location location(beg_pos, end_pos); |
3941 if (this->IsIdentifier(expression)) { | 3942 if (this->IsIdentifier(expression)) { |
3942 if (is_strict(language_mode()) && | 3943 if (is_strict(language_mode()) && |
3943 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3944 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
3944 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments, | 3945 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments, |
3945 kSyntaxError); | 3946 kSyntaxError); |
3946 *ok = false; | 3947 *ok = false; |
3947 return this->EmptyExpression(); | 3948 return this->EmptyExpression(); |
3948 } | 3949 } |
3949 if (is_strong(language_mode()) && | 3950 if (is_strong(language_mode()) && |
3950 this->IsUndefined(this->AsIdentifier(expression))) { | 3951 this->IsUndefined(this->AsIdentifier(expression))) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4023 *ok = false; | 4024 *ok = false; |
4024 return; | 4025 return; |
4025 } | 4026 } |
4026 has_seen_constructor_ = true; | 4027 has_seen_constructor_ = true; |
4027 return; | 4028 return; |
4028 } | 4029 } |
4029 } | 4030 } |
4030 } } // v8::internal | 4031 } } // v8::internal |
4031 | 4032 |
4032 #endif // V8_PREPARSER_H | 4033 #endif // V8_PREPARSER_H |
OLD | NEW |