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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 scanner_(scanner), | 107 scanner_(scanner), |
108 stack_overflow_(false), | 108 stack_overflow_(false), |
109 allow_lazy_(false), | 109 allow_lazy_(false), |
110 allow_natives_(false), | 110 allow_natives_(false), |
111 allow_harmony_sloppy_(false), | 111 allow_harmony_sloppy_(false), |
112 allow_harmony_sloppy_function_(false), | 112 allow_harmony_sloppy_function_(false), |
113 allow_harmony_sloppy_let_(false), | 113 allow_harmony_sloppy_let_(false), |
114 allow_harmony_rest_parameters_(false), | 114 allow_harmony_rest_parameters_(false), |
115 allow_harmony_default_parameters_(false), | 115 allow_harmony_default_parameters_(false), |
116 allow_harmony_destructuring_(false), | 116 allow_harmony_destructuring_(false), |
117 allow_harmony_destructuring_assignment_(false), | |
117 allow_strong_mode_(false), | 118 allow_strong_mode_(false), |
118 allow_legacy_const_(true), | 119 allow_legacy_const_(true), |
119 allow_harmony_do_expressions_(false) {} | 120 allow_harmony_do_expressions_(false) {} |
120 | 121 |
121 #define ALLOW_ACCESSORS(name) \ | 122 #define ALLOW_ACCESSORS(name) \ |
122 bool allow_##name() const { return allow_##name##_; } \ | 123 bool allow_##name() const { return allow_##name##_; } \ |
123 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 124 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
124 | 125 |
125 ALLOW_ACCESSORS(lazy); | 126 ALLOW_ACCESSORS(lazy); |
126 ALLOW_ACCESSORS(natives); | 127 ALLOW_ACCESSORS(natives); |
127 ALLOW_ACCESSORS(harmony_sloppy); | 128 ALLOW_ACCESSORS(harmony_sloppy); |
128 ALLOW_ACCESSORS(harmony_sloppy_function); | 129 ALLOW_ACCESSORS(harmony_sloppy_function); |
129 ALLOW_ACCESSORS(harmony_sloppy_let); | 130 ALLOW_ACCESSORS(harmony_sloppy_let); |
130 ALLOW_ACCESSORS(harmony_rest_parameters); | 131 ALLOW_ACCESSORS(harmony_rest_parameters); |
131 ALLOW_ACCESSORS(harmony_default_parameters); | 132 ALLOW_ACCESSORS(harmony_default_parameters); |
132 ALLOW_ACCESSORS(harmony_destructuring); | 133 ALLOW_ACCESSORS(harmony_destructuring); |
134 ALLOW_ACCESSORS(harmony_destructuring_assignment); | |
133 ALLOW_ACCESSORS(strong_mode); | 135 ALLOW_ACCESSORS(strong_mode); |
134 ALLOW_ACCESSORS(legacy_const); | 136 ALLOW_ACCESSORS(legacy_const); |
135 ALLOW_ACCESSORS(harmony_do_expressions); | 137 ALLOW_ACCESSORS(harmony_do_expressions); |
136 #undef ALLOW_ACCESSORS | 138 #undef ALLOW_ACCESSORS |
137 | 139 |
138 uintptr_t stack_limit() const { return stack_limit_; } | 140 uintptr_t stack_limit() const { return stack_limit_; } |
139 | 141 |
140 protected: | 142 protected: |
141 enum AllowRestrictedIdentifiers { | 143 enum AllowRestrictedIdentifiers { |
142 kAllowRestrictedIdentifiers, | 144 kAllowRestrictedIdentifiers, |
(...skipping 25 matching lines...) Expand all Loading... | |
168 : scope_stack_(scope_stack), outer_scope_(*scope_stack) { | 170 : scope_stack_(scope_stack), outer_scope_(*scope_stack) { |
169 *scope_stack_ = scope; | 171 *scope_stack_ = scope; |
170 } | 172 } |
171 ~BlockState() { *scope_stack_ = outer_scope_; } | 173 ~BlockState() { *scope_stack_ = outer_scope_; } |
172 | 174 |
173 private: | 175 private: |
174 Scope** scope_stack_; | 176 Scope** scope_stack_; |
175 Scope* outer_scope_; | 177 Scope* outer_scope_; |
176 }; | 178 }; |
177 | 179 |
180 struct DestructuringAssignment { | |
181 public: | |
182 DestructuringAssignment(ExpressionT expression, Scope* scope) | |
183 : assignment(expression), scope(scope) {} | |
184 | |
185 ExpressionT assignment; | |
186 Scope* scope; | |
187 }; | |
188 | |
178 class FunctionState BASE_EMBEDDED { | 189 class FunctionState BASE_EMBEDDED { |
179 public: | 190 public: |
180 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, | 191 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
181 Scope* scope, FunctionKind kind, | 192 Scope* scope, FunctionKind kind, |
182 typename Traits::Type::Factory* factory); | 193 typename Traits::Type::Factory* factory); |
183 ~FunctionState(); | 194 ~FunctionState(); |
184 | 195 |
185 int NextMaterializedLiteralIndex() { | 196 int NextMaterializedLiteralIndex() { |
186 return next_materialized_literal_index_++; | 197 return next_materialized_literal_index_++; |
187 } | 198 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 DCHECK(is_generator()); | 231 DCHECK(is_generator()); |
221 generator_object_variable_ = variable; | 232 generator_object_variable_ = variable; |
222 } | 233 } |
223 typename Traits::Type::GeneratorVariable* generator_object_variable() | 234 typename Traits::Type::GeneratorVariable* generator_object_variable() |
224 const { | 235 const { |
225 return generator_object_variable_; | 236 return generator_object_variable_; |
226 } | 237 } |
227 | 238 |
228 typename Traits::Type::Factory* factory() { return factory_; } | 239 typename Traits::Type::Factory* factory() { return factory_; } |
229 | 240 |
241 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | |
242 const { | |
243 return destructuring_assignments_to_rewrite_; | |
244 } | |
245 | |
246 void AddDestructuringAssignment(DestructuringAssignment pair) { | |
247 destructuring_assignments_to_rewrite_.Add(pair); | |
248 } | |
249 | |
230 private: | 250 private: |
231 // Used to assign an index to each literal that needs materialization in | 251 // Used to assign an index to each literal that needs materialization in |
232 // the function. Includes regexp literals, and boilerplate for object and | 252 // the function. Includes regexp literals, and boilerplate for object and |
233 // array literals. | 253 // array literals. |
234 int next_materialized_literal_index_; | 254 int next_materialized_literal_index_; |
235 | 255 |
236 // Properties count estimation. | 256 // Properties count estimation. |
237 int expected_property_count_; | 257 int expected_property_count_; |
238 | 258 |
239 // Location of most recent use of 'this' (invalid if none). | 259 // Location of most recent use of 'this' (invalid if none). |
240 Scanner::Location this_location_; | 260 Scanner::Location this_location_; |
241 | 261 |
242 // Location of most recent 'return' statement (invalid if none). | 262 // Location of most recent 'return' statement (invalid if none). |
243 Scanner::Location return_location_; | 263 Scanner::Location return_location_; |
244 | 264 |
245 // Location of call to the "super" constructor (invalid if none). | 265 // Location of call to the "super" constructor (invalid if none). |
246 Scanner::Location super_location_; | 266 Scanner::Location super_location_; |
247 | 267 |
248 FunctionKind kind_; | 268 FunctionKind kind_; |
249 // For generators, this variable may hold the generator object. It variable | 269 // For generators, this variable may hold the generator object. It variable |
250 // is used by yield expressions and return statements. It is not necessary | 270 // is used by yield expressions and return statements. It is not necessary |
251 // for generator functions to have this variable set. | 271 // for generator functions to have this variable set. |
252 Variable* generator_object_variable_; | 272 Variable* generator_object_variable_; |
253 | 273 |
254 FunctionState** function_state_stack_; | 274 FunctionState** function_state_stack_; |
255 FunctionState* outer_function_state_; | 275 FunctionState* outer_function_state_; |
256 Scope** scope_stack_; | 276 Scope** scope_stack_; |
257 Scope* outer_scope_; | 277 Scope* outer_scope_; |
278 | |
279 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; | |
adamk
2015/11/20 22:42:59
Why does ParserBase need this List? Couldn't it ju
| |
280 | |
281 void RewriteDestructuringAssignments(); | |
282 | |
258 typename Traits::Type::Factory* factory_; | 283 typename Traits::Type::Factory* factory_; |
259 | 284 |
260 friend class ParserTraits; | 285 friend class ParserTraits; |
261 friend class Checkpoint; | 286 friend class Checkpoint; |
262 }; | 287 }; |
263 | 288 |
264 // Annoyingly, arrow functions first parse as comma expressions, then when we | 289 // Annoyingly, arrow functions first parse as comma expressions, then when we |
265 // see the => we have to go back and reinterpret the arguments as being formal | 290 // see the => we have to go back and reinterpret the arguments as being formal |
266 // parameters. To do so we need to reset some of the parser state back to | 291 // parameters. To do so we need to reset some of the parser state back to |
267 // what it was before the arguments were first seen. | 292 // what it was before the arguments were first seen. |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
453 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 478 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
454 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, | 479 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, |
455 ok); | 480 ok); |
456 } | 481 } |
457 | 482 |
458 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 483 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
459 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, | 484 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, |
460 ok); | 485 ok); |
461 } | 486 } |
462 | 487 |
488 void CheckDestructuringElement(ExpressionT element, | |
489 ExpressionClassifier* classifier, int beg_pos, | |
490 int end_pos); | |
491 | |
463 // Checking the name of a function literal. This has to be done after parsing | 492 // Checking the name of a function literal. This has to be done after parsing |
464 // the function, since the function can declare itself strict. | 493 // the function, since the function can declare itself strict. |
465 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, | 494 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, |
466 FunctionNameValidity function_name_validity, | 495 FunctionNameValidity function_name_validity, |
467 const Scanner::Location& function_name_loc, bool* ok) { | 496 const Scanner::Location& function_name_loc, bool* ok) { |
468 if (function_name_validity == kSkipFunctionNameCheck) return; | 497 if (function_name_validity == kSkipFunctionNameCheck) return; |
469 // The function name needs to be checked in strict mode. | 498 // The function name needs to be checked in strict mode. |
470 if (is_sloppy(language_mode)) return; | 499 if (is_sloppy(language_mode)) return; |
471 | 500 |
472 if (this->IsEvalOrArguments(function_name)) { | 501 if (this->IsEvalOrArguments(function_name)) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
535 Scanner::Location location, Token::Value token, | 564 Scanner::Location location, Token::Value token, |
536 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 565 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
537 | 566 |
538 | 567 |
539 void ReportClassifierError(const ExpressionClassifier::Error& error) { | 568 void ReportClassifierError(const ExpressionClassifier::Error& error) { |
540 Traits::ReportMessageAt(error.location, error.message, error.arg, | 569 Traits::ReportMessageAt(error.location, error.message, error.arg, |
541 kSyntaxError); | 570 kSyntaxError); |
542 } | 571 } |
543 | 572 |
544 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 573 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
545 if (!classifier->is_valid_expression()) { | 574 if (!classifier->is_valid_expression() || |
546 ReportClassifierError(classifier->expression_error()); | 575 classifier->has_cover_initialized_name()) { |
576 const Scanner::Location& a = classifier->expression_error().location; | |
577 const Scanner::Location& b = | |
578 classifier->cover_initialized_name_error().location; | |
579 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) { | |
580 ReportClassifierError(classifier->cover_initialized_name_error()); | |
581 } else { | |
582 ReportClassifierError(classifier->expression_error()); | |
583 } | |
547 *ok = false; | 584 *ok = false; |
548 } | 585 } |
549 } | 586 } |
550 | 587 |
551 void ValidateFormalParameterInitializer( | 588 void ValidateFormalParameterInitializer( |
552 const ExpressionClassifier* classifier, bool* ok) { | 589 const ExpressionClassifier* classifier, bool* ok) { |
553 if (!classifier->is_valid_formal_parameter_initializer()) { | 590 if (!classifier->is_valid_formal_parameter_initializer()) { |
554 ReportClassifierError(classifier->formal_parameter_initializer_error()); | 591 ReportClassifierError(classifier->formal_parameter_initializer_error()); |
555 *ok = false; | 592 *ok = false; |
556 } | 593 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 bool* is_static, bool* is_computed_name, | 723 bool* is_static, bool* is_computed_name, |
687 ExpressionClassifier* classifier, bool* ok); | 724 ExpressionClassifier* classifier, bool* ok); |
688 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 725 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
689 ObjectLiteralPropertyT ParsePropertyDefinition( | 726 ObjectLiteralPropertyT ParsePropertyDefinition( |
690 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 727 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
691 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 728 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
692 ExpressionClassifier* classifier, bool* ok); | 729 ExpressionClassifier* classifier, bool* ok); |
693 typename Traits::Type::ExpressionList ParseArguments( | 730 typename Traits::Type::ExpressionList ParseArguments( |
694 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 731 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
695 bool* ok); | 732 bool* ok); |
733 | |
734 enum AssignmentExpressionFlags { | |
735 kIsLeftHandSide = 0, | |
736 kIsRightHandSide = 1 << 0, | |
737 kIsPatternElement = 1 << 1 | |
738 }; | |
739 | |
740 ExpressionT ParseAssignmentExpression(bool accept_IN, int flags, | |
741 ExpressionClassifier* classifier, | |
742 bool* ok); | |
696 ExpressionT ParseAssignmentExpression(bool accept_IN, | 743 ExpressionT ParseAssignmentExpression(bool accept_IN, |
697 ExpressionClassifier* classifier, | 744 ExpressionClassifier* classifier, |
698 bool* ok); | 745 bool* ok) { |
746 return ParseAssignmentExpression(accept_IN, kIsLeftHandSide, classifier, | |
747 ok); | |
748 } | |
699 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); | 749 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
700 ExpressionT ParseConditionalExpression(bool accept_IN, | 750 ExpressionT ParseConditionalExpression(bool accept_IN, |
701 ExpressionClassifier* classifier, | 751 ExpressionClassifier* classifier, |
702 bool* ok); | 752 bool* ok); |
703 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 753 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
704 ExpressionClassifier* classifier, bool* ok); | 754 ExpressionClassifier* classifier, bool* ok); |
705 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 755 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
706 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 756 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
707 bool* ok); | 757 bool* ok); |
708 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 758 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
740 // Checks if the expression is a valid reference expression (e.g., on the | 790 // Checks if the expression is a valid reference expression (e.g., on the |
741 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 791 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
742 // we allow calls for web compatibility and rewrite them to a runtime throw. | 792 // we allow calls for web compatibility and rewrite them to a runtime throw. |
743 ExpressionT CheckAndRewriteReferenceExpression( | 793 ExpressionT CheckAndRewriteReferenceExpression( |
744 ExpressionT expression, int beg_pos, int end_pos, | 794 ExpressionT expression, int beg_pos, int end_pos, |
745 MessageTemplate::Template message, bool* ok); | 795 MessageTemplate::Template message, bool* ok); |
746 ExpressionT CheckAndRewriteReferenceExpression( | 796 ExpressionT CheckAndRewriteReferenceExpression( |
747 ExpressionT expression, int beg_pos, int end_pos, | 797 ExpressionT expression, int beg_pos, int end_pos, |
748 MessageTemplate::Template message, ParseErrorType type, bool* ok); | 798 MessageTemplate::Template message, ParseErrorType type, bool* ok); |
749 | 799 |
800 bool IsValidReferenceExpression(ExpressionT expression); | |
801 | |
802 bool IsAssignableIdentifier(ExpressionT expression) { | |
803 if (!Traits::IsIdentifier(expression)) return false; | |
804 if (is_strict(language_mode()) && | |
805 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { | |
806 return false; | |
807 } | |
808 if (is_strong(language_mode()) && | |
809 Traits::IsUndefined(Traits::AsIdentifier(expression))) { | |
810 return false; | |
811 } | |
812 return true; | |
813 } | |
814 | |
750 // Used to validate property names in object literals and class literals | 815 // Used to validate property names in object literals and class literals |
751 enum PropertyKind { | 816 enum PropertyKind { |
752 kAccessorProperty, | 817 kAccessorProperty, |
753 kValueProperty, | 818 kValueProperty, |
754 kMethodProperty | 819 kMethodProperty |
755 }; | 820 }; |
756 | 821 |
757 class ObjectLiteralCheckerBase { | 822 class ObjectLiteralCheckerBase { |
758 public: | 823 public: |
759 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | 824 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
828 bool stack_overflow_; | 893 bool stack_overflow_; |
829 | 894 |
830 bool allow_lazy_; | 895 bool allow_lazy_; |
831 bool allow_natives_; | 896 bool allow_natives_; |
832 bool allow_harmony_sloppy_; | 897 bool allow_harmony_sloppy_; |
833 bool allow_harmony_sloppy_function_; | 898 bool allow_harmony_sloppy_function_; |
834 bool allow_harmony_sloppy_let_; | 899 bool allow_harmony_sloppy_let_; |
835 bool allow_harmony_rest_parameters_; | 900 bool allow_harmony_rest_parameters_; |
836 bool allow_harmony_default_parameters_; | 901 bool allow_harmony_default_parameters_; |
837 bool allow_harmony_destructuring_; | 902 bool allow_harmony_destructuring_; |
903 bool allow_harmony_destructuring_assignment_; | |
838 bool allow_strong_mode_; | 904 bool allow_strong_mode_; |
839 bool allow_legacy_const_; | 905 bool allow_legacy_const_; |
840 bool allow_harmony_do_expressions_; | 906 bool allow_harmony_do_expressions_; |
841 }; | 907 }; |
842 | 908 |
843 | 909 |
844 class PreParserIdentifier { | 910 class PreParserIdentifier { |
845 public: | 911 public: |
846 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 912 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
847 static PreParserIdentifier Default() { | 913 static PreParserIdentifier Default() { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
940 | 1006 |
941 static PreParserExpression BinaryOperation(PreParserExpression left, | 1007 static PreParserExpression BinaryOperation(PreParserExpression left, |
942 Token::Value op, | 1008 Token::Value op, |
943 PreParserExpression right) { | 1009 PreParserExpression right) { |
944 return PreParserExpression( | 1010 return PreParserExpression( |
945 TypeField::encode(kBinaryOperationExpression) | | 1011 TypeField::encode(kBinaryOperationExpression) | |
946 HasRestField::encode(op == Token::COMMA && | 1012 HasRestField::encode(op == Token::COMMA && |
947 right->IsSpreadExpression())); | 1013 right->IsSpreadExpression())); |
948 } | 1014 } |
949 | 1015 |
1016 static PreParserExpression AssignmentPattern() { | |
1017 return PreParserExpression(TypeField::encode(kExpression) | | |
1018 ExpressionTypeField::encode(kAssignmentPattern)); | |
1019 } | |
1020 | |
950 static PreParserExpression ObjectLiteral() { | 1021 static PreParserExpression ObjectLiteral() { |
951 return PreParserExpression(TypeField::encode(kObjectLiteralExpression)); | 1022 return PreParserExpression(TypeField::encode(kObjectLiteralExpression)); |
952 } | 1023 } |
953 | 1024 |
954 static PreParserExpression ArrayLiteral() { | 1025 static PreParserExpression ArrayLiteral() { |
955 return PreParserExpression(TypeField::encode(kArrayLiteralExpression)); | 1026 return PreParserExpression(TypeField::encode(kArrayLiteralExpression)); |
956 } | 1027 } |
957 | 1028 |
958 static PreParserExpression StringLiteral() { | 1029 static PreParserExpression StringLiteral() { |
959 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 1030 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1005 | 1076 |
1006 bool IsIdentifier() const { | 1077 bool IsIdentifier() const { |
1007 return TypeField::decode(code_) == kIdentifierExpression; | 1078 return TypeField::decode(code_) == kIdentifierExpression; |
1008 } | 1079 } |
1009 | 1080 |
1010 PreParserIdentifier AsIdentifier() const { | 1081 PreParserIdentifier AsIdentifier() const { |
1011 DCHECK(IsIdentifier()); | 1082 DCHECK(IsIdentifier()); |
1012 return PreParserIdentifier(IdentifierTypeField::decode(code_)); | 1083 return PreParserIdentifier(IdentifierTypeField::decode(code_)); |
1013 } | 1084 } |
1014 | 1085 |
1086 bool IsAssignmentPattern() const { | |
1087 return TypeField::decode(code_) == kExpression && | |
1088 ExpressionTypeField::decode(code_) == kAssignmentPattern; | |
1089 } | |
1090 | |
1015 bool IsObjectLiteral() const { | 1091 bool IsObjectLiteral() const { |
1016 return TypeField::decode(code_) == kObjectLiteralExpression; | 1092 return TypeField::decode(code_) == kObjectLiteralExpression; |
1017 } | 1093 } |
1018 | 1094 |
1019 bool IsArrayLiteral() const { | 1095 bool IsArrayLiteral() const { |
1020 return TypeField::decode(code_) == kArrayLiteralExpression; | 1096 return TypeField::decode(code_) == kArrayLiteralExpression; |
1021 } | 1097 } |
1022 | 1098 |
1023 bool IsStringLiteral() const { | 1099 bool IsStringLiteral() const { |
1024 return TypeField::decode(code_) == kStringLiteralExpression; | 1100 return TypeField::decode(code_) == kStringLiteralExpression; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1112 kObjectLiteralExpression, | 1188 kObjectLiteralExpression, |
1113 kArrayLiteralExpression | 1189 kArrayLiteralExpression |
1114 }; | 1190 }; |
1115 | 1191 |
1116 enum ExpressionType { | 1192 enum ExpressionType { |
1117 kThisExpression, | 1193 kThisExpression, |
1118 kThisPropertyExpression, | 1194 kThisPropertyExpression, |
1119 kPropertyExpression, | 1195 kPropertyExpression, |
1120 kCallExpression, | 1196 kCallExpression, |
1121 kSuperCallReference, | 1197 kSuperCallReference, |
1122 kNoTemplateTagExpression | 1198 kNoTemplateTagExpression, |
1199 kAssignmentPattern | |
1123 }; | 1200 }; |
1124 | 1201 |
1125 explicit PreParserExpression(uint32_t expression_code) | 1202 explicit PreParserExpression(uint32_t expression_code) |
1126 : code_(expression_code) {} | 1203 : code_(expression_code) {} |
1127 | 1204 |
1128 // The first three bits are for the Type. | 1205 // The first three bits are for the Type. |
1129 typedef BitField<Type, 0, 3> TypeField; | 1206 typedef BitField<Type, 0, 3> TypeField; |
1130 | 1207 |
1131 // The rest of the bits are interpreted depending on the value | 1208 // The rest of the bits are interpreted depending on the value |
1132 // of the Type field, so they can share the storage. | 1209 // of the Type field, so they can share the storage. |
1133 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; | 1210 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; |
1134 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; | 1211 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; |
1135 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1212 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
1136 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> | 1213 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> |
1137 IdentifierTypeField; | 1214 IdentifierTypeField; |
1138 typedef BitField<bool, TypeField::kNext, 1> HasRestField; | 1215 typedef BitField<bool, TypeField::kNext, 1> HasRestField; |
1216 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField; | |
1139 | 1217 |
1140 uint32_t code_; | 1218 uint32_t code_; |
1141 }; | 1219 }; |
1142 | 1220 |
1143 | 1221 |
1144 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1222 // The pre-parser doesn't need to build lists of expressions, identifiers, or |
1145 // the like. | 1223 // the like. |
1146 template <typename T> | 1224 template <typename T> |
1147 class PreParserList { | 1225 class PreParserList { |
1148 public: | 1226 public: |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1301 PreParserExpression left, | 1379 PreParserExpression left, |
1302 PreParserExpression right, int pos) { | 1380 PreParserExpression right, int pos) { |
1303 return PreParserExpression::Default(); | 1381 return PreParserExpression::Default(); |
1304 } | 1382 } |
1305 PreParserExpression NewAssignment(Token::Value op, | 1383 PreParserExpression NewAssignment(Token::Value op, |
1306 PreParserExpression left, | 1384 PreParserExpression left, |
1307 PreParserExpression right, | 1385 PreParserExpression right, |
1308 int pos) { | 1386 int pos) { |
1309 return PreParserExpression::Default(); | 1387 return PreParserExpression::Default(); |
1310 } | 1388 } |
1389 PreParserExpression NewAssignmentPattern(PreParserExpression pattern, | |
1390 int pos) { | |
1391 DCHECK(pattern->IsObjectLiteral() || pattern->IsArrayLiteral()); | |
1392 return PreParserExpression::AssignmentPattern(); | |
1393 } | |
1311 PreParserExpression NewYield(PreParserExpression generator_object, | 1394 PreParserExpression NewYield(PreParserExpression generator_object, |
1312 PreParserExpression expression, | 1395 PreParserExpression expression, |
1313 Yield::Kind yield_kind, | 1396 Yield::Kind yield_kind, |
1314 int pos) { | 1397 int pos) { |
1315 return PreParserExpression::Default(); | 1398 return PreParserExpression::Default(); |
1316 } | 1399 } |
1317 PreParserExpression NewConditional(PreParserExpression condition, | 1400 PreParserExpression NewConditional(PreParserExpression condition, |
1318 PreParserExpression then_expression, | 1401 PreParserExpression then_expression, |
1319 PreParserExpression else_expression, | 1402 PreParserExpression else_expression, |
1320 int pos) { | 1403 int pos) { |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1731 | 1814 |
1732 inline void MaterializeUnspreadArgumentsLiterals(int count); | 1815 inline void MaterializeUnspreadArgumentsLiterals(int count); |
1733 | 1816 |
1734 inline PreParserExpression SpreadCall(PreParserExpression function, | 1817 inline PreParserExpression SpreadCall(PreParserExpression function, |
1735 PreParserExpressionList args, int pos); | 1818 PreParserExpressionList args, int pos); |
1736 | 1819 |
1737 inline PreParserExpression SpreadCallNew(PreParserExpression function, | 1820 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
1738 PreParserExpressionList args, | 1821 PreParserExpressionList args, |
1739 int pos); | 1822 int pos); |
1740 | 1823 |
1824 inline PreParserExpression RewriteDestructuringAssignmentExpression( | |
1825 PreParserExpression expr) { | |
1826 return expr; | |
1827 } | |
1828 | |
1829 inline void RewriteDestructuringAssignments() {} | |
1830 | |
1831 inline void ShouldRewriteDestructuringAssignment(PreParserExpression) {} | |
1832 | |
1741 private: | 1833 private: |
1742 PreParser* pre_parser_; | 1834 PreParser* pre_parser_; |
1743 }; | 1835 }; |
1744 | 1836 |
1745 | 1837 |
1746 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1838 // Preparsing checks a JavaScript program and emits preparse-data that helps |
1747 // a later parsing to be faster. | 1839 // a later parsing to be faster. |
1748 // See preparse-data-format.h for the data format. | 1840 // See preparse-data-format.h for the data format. |
1749 | 1841 |
1750 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1842 // The PreParser checks that the syntax follows the grammar for JavaScript, |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2362 return this->EmptyExpression(); | 2454 return this->EmptyExpression(); |
2363 } | 2455 } |
2364 Expect(Token::RPAREN, CHECK_OK); | 2456 Expect(Token::RPAREN, CHECK_OK); |
2365 return factory()->NewSpread(expr, ellipsis_pos); | 2457 return factory()->NewSpread(expr, ellipsis_pos); |
2366 } | 2458 } |
2367 // Heuristically try to detect immediately called functions before | 2459 // Heuristically try to detect immediately called functions before |
2368 // seeing the call parentheses. | 2460 // seeing the call parentheses. |
2369 parenthesized_function_ = (peek() == Token::FUNCTION); | 2461 parenthesized_function_ = (peek() == Token::FUNCTION); |
2370 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); | 2462 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); |
2371 Expect(Token::RPAREN, CHECK_OK); | 2463 Expect(Token::RPAREN, CHECK_OK); |
2464 if (peek() != Token::ARROW) { | |
2465 ValidateExpression(classifier, CHECK_OK); | |
2466 } | |
2372 return expr; | 2467 return expr; |
2373 } | 2468 } |
2374 | 2469 |
2375 case Token::CLASS: { | 2470 case Token::CLASS: { |
2376 BindingPatternUnexpectedToken(classifier); | 2471 BindingPatternUnexpectedToken(classifier); |
2377 Consume(Token::CLASS); | 2472 Consume(Token::CLASS); |
2378 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2473 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2379 ReportMessage(MessageTemplate::kSloppyLexical); | 2474 ReportMessage(MessageTemplate::kSloppyLexical); |
2380 *ok = false; | 2475 *ok = false; |
2381 return this->EmptyExpression(); | 2476 return this->EmptyExpression(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2429 template <class Traits> | 2524 template <class Traits> |
2430 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2525 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2431 bool accept_IN, bool* ok) { | 2526 bool accept_IN, bool* ok) { |
2432 ExpressionClassifier classifier; | 2527 ExpressionClassifier classifier; |
2433 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 2528 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
2434 ValidateExpression(&classifier, CHECK_OK); | 2529 ValidateExpression(&classifier, CHECK_OK); |
2435 return result; | 2530 return result; |
2436 } | 2531 } |
2437 | 2532 |
2438 | 2533 |
2439 // Precedence = 1 | |
2440 template <class Traits> | 2534 template <class Traits> |
2441 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2535 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2442 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2536 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
2443 // Expression :: | 2537 // Expression :: |
2444 // AssignmentExpression | 2538 // AssignmentExpression |
2445 // Expression ',' AssignmentExpression | 2539 // Expression ',' AssignmentExpression |
2446 | 2540 |
2447 ExpressionClassifier binding_classifier; | 2541 ExpressionClassifier binding_classifier; |
2448 ExpressionT result = | 2542 ExpressionT result = |
2449 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 2543 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
(...skipping 25 matching lines...) Expand all Loading... | |
2475 if (is_rest) right = factory()->NewSpread(right, pos); | 2569 if (is_rest) right = factory()->NewSpread(right, pos); |
2476 is_simple_parameter_list = | 2570 is_simple_parameter_list = |
2477 is_simple_parameter_list && this->IsIdentifier(right); | 2571 is_simple_parameter_list && this->IsIdentifier(right); |
2478 classifier->Accumulate(binding_classifier, | 2572 classifier->Accumulate(binding_classifier, |
2479 ExpressionClassifier::AllProductions); | 2573 ExpressionClassifier::AllProductions); |
2480 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2574 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
2481 } | 2575 } |
2482 if (!is_simple_parameter_list || seen_rest) { | 2576 if (!is_simple_parameter_list || seen_rest) { |
2483 classifier->RecordNonSimpleParameter(); | 2577 classifier->RecordNonSimpleParameter(); |
2484 } | 2578 } |
2579 | |
2485 return result; | 2580 return result; |
2486 } | 2581 } |
2487 | 2582 |
2488 | 2583 |
2489 template <class Traits> | 2584 template <class Traits> |
2490 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2585 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
2491 ExpressionClassifier* classifier, bool* ok) { | 2586 ExpressionClassifier* classifier, bool* ok) { |
2492 // ArrayLiteral :: | 2587 // ArrayLiteral :: |
2493 // '[' Expression? (',' Expression?)* ']' | 2588 // '[' Expression? (',' Expression?)* ']' |
2494 | 2589 |
(...skipping 16 matching lines...) Expand all Loading... | |
2511 } else if (peek() == Token::ELLIPSIS) { | 2606 } else if (peek() == Token::ELLIPSIS) { |
2512 int start_pos = peek_position(); | 2607 int start_pos = peek_position(); |
2513 Consume(Token::ELLIPSIS); | 2608 Consume(Token::ELLIPSIS); |
2514 ExpressionT argument = | 2609 ExpressionT argument = |
2515 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2610 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
2516 elem = factory()->NewSpread(argument, start_pos); | 2611 elem = factory()->NewSpread(argument, start_pos); |
2517 seen_spread = true; | 2612 seen_spread = true; |
2518 if (first_spread_index < 0) { | 2613 if (first_spread_index < 0) { |
2519 first_spread_index = values->length(); | 2614 first_spread_index = values->length(); |
2520 } | 2615 } |
2616 | |
2617 CheckDestructuringElement(argument, classifier, start_pos, | |
2618 scanner()->location().end_pos); | |
2619 | |
2620 if (peek() == Token::COMMA) { | |
2621 classifier->RecordPatternError( | |
2622 Scanner::Location(start_pos, scanner()->location().end_pos), | |
2623 MessageTemplate::kElementAfterRest); | |
2624 } | |
2521 } else { | 2625 } else { |
2522 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2626 elem = this->ParseAssignmentExpression(true, kIsPatternElement, |
2627 classifier, CHECK_OK); | |
2628 if (!this->IsValidReferenceExpression(elem) && | |
2629 !classifier->is_valid_assignment_pattern()) { | |
2630 classifier->RecordPatternError( | |
2631 Scanner::Location(pos, scanner()->location().end_pos), | |
2632 MessageTemplate::kInvalidDestructuringTarget); | |
2633 } | |
2523 } | 2634 } |
2524 values->Add(elem, zone_); | 2635 values->Add(elem, zone_); |
2525 if (peek() != Token::RBRACK) { | 2636 if (peek() != Token::RBRACK) { |
2526 if (seen_spread) { | |
2527 BindingPatternUnexpectedToken(classifier); | |
2528 } | |
2529 Expect(Token::COMMA, CHECK_OK); | 2637 Expect(Token::COMMA, CHECK_OK); |
2530 } | 2638 } |
2531 } | 2639 } |
2532 Expect(Token::RBRACK, CHECK_OK); | 2640 Expect(Token::RBRACK, CHECK_OK); |
2533 | 2641 |
2534 // Update the scope information before the pre-parsing bailout. | 2642 // Update the scope information before the pre-parsing bailout. |
2535 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2643 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2536 | 2644 |
2537 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, | 2645 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, |
2538 is_strong(language_mode()), pos); | 2646 is_strong(language_mode()), pos); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2628 DCHECK(!is_static); | 2736 DCHECK(!is_static); |
2629 | 2737 |
2630 if (peek() == Token::COLON) { | 2738 if (peek() == Token::COLON) { |
2631 // PropertyDefinition | 2739 // PropertyDefinition |
2632 // PropertyName ':' AssignmentExpression | 2740 // PropertyName ':' AssignmentExpression |
2633 if (!*is_computed_name) { | 2741 if (!*is_computed_name) { |
2634 checker->CheckProperty(name_token, kValueProperty, false, false, | 2742 checker->CheckProperty(name_token, kValueProperty, false, false, |
2635 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2743 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2636 } | 2744 } |
2637 Consume(Token::COLON); | 2745 Consume(Token::COLON); |
2746 int pos = peek_position(); | |
2638 value = this->ParseAssignmentExpression( | 2747 value = this->ParseAssignmentExpression( |
2639 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2748 true, kIsPatternElement, classifier, |
2749 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2750 | |
2751 if (!this->IsValidReferenceExpression(value) && | |
2752 !classifier->is_valid_assignment_pattern()) { | |
2753 classifier->RecordPatternError( | |
2754 Scanner::Location(pos, scanner()->location().end_pos), | |
2755 MessageTemplate::kInvalidDestructuringTarget); | |
2756 } | |
2757 | |
2640 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 2758 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
2641 *is_computed_name); | 2759 *is_computed_name); |
2642 } | 2760 } |
2643 | 2761 |
2644 if (Token::IsIdentifier(name_token, language_mode(), | 2762 if (Token::IsIdentifier(name_token, language_mode(), |
2645 this->is_generator()) && | 2763 this->is_generator()) && |
2646 (peek() == Token::COMMA || peek() == Token::RBRACE || | 2764 (peek() == Token::COMMA || peek() == Token::RBRACE || |
2647 peek() == Token::ASSIGN)) { | 2765 peek() == Token::ASSIGN)) { |
2648 // PropertyDefinition | 2766 // PropertyDefinition |
2649 // IdentifierReference | 2767 // IdentifierReference |
2650 // CoverInitializedName | 2768 // CoverInitializedName |
2651 // | 2769 // |
2652 // CoverInitializedName | 2770 // CoverInitializedName |
2653 // IdentifierReference Initializer? | 2771 // IdentifierReference Initializer? |
2654 if (classifier->duplicate_finder() != nullptr && | 2772 if (classifier->duplicate_finder() != nullptr && |
2655 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 2773 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
2656 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 2774 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
2657 } | 2775 } |
2658 if (name_token == Token::LET) { | 2776 if (name_token == Token::LET) { |
2659 classifier->RecordLetPatternError( | 2777 classifier->RecordLetPatternError( |
2660 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 2778 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
2661 } | 2779 } |
2662 | 2780 |
2663 ExpressionT lhs = this->ExpressionFromIdentifier( | 2781 ExpressionT lhs = this->ExpressionFromIdentifier( |
2664 name, next_beg_pos, next_end_pos, scope_, factory()); | 2782 name, next_beg_pos, next_end_pos, scope_, factory()); |
2665 | 2783 |
2666 if (peek() == Token::ASSIGN) { | 2784 if (peek() == Token::ASSIGN) { |
2667 this->ExpressionUnexpectedToken(classifier); | |
2668 Consume(Token::ASSIGN); | 2785 Consume(Token::ASSIGN); |
2669 ExpressionClassifier rhs_classifier; | 2786 ExpressionClassifier rhs_classifier; |
2670 ExpressionT rhs = this->ParseAssignmentExpression( | 2787 ExpressionT rhs = this->ParseAssignmentExpression( |
2671 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2788 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2672 classifier->Accumulate(rhs_classifier, | 2789 classifier->Accumulate(rhs_classifier, |
2673 ExpressionClassifier::ExpressionProductions); | 2790 ExpressionClassifier::ExpressionProductions); |
2674 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2791 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
2675 RelocInfo::kNoPosition); | 2792 RelocInfo::kNoPosition); |
2793 classifier->RecordCoverInitializedNameError( | |
2794 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | |
2795 MessageTemplate::kInvalidCoverInitializedName); | |
2676 } else { | 2796 } else { |
2677 value = lhs; | 2797 value = lhs; |
2678 } | 2798 } |
2679 | 2799 |
2680 return factory()->NewObjectLiteralProperty( | 2800 return factory()->NewObjectLiteralProperty( |
2681 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 2801 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
2682 false); | 2802 false); |
2683 } | 2803 } |
2684 } | 2804 } |
2685 | 2805 |
2806 // Method definitions are never valid in patterns. | |
2807 classifier->RecordPatternError( | |
2808 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | |
2809 MessageTemplate::kInvalidDestructuringTarget); | |
2810 | |
2686 | 2811 |
2687 if (is_generator || peek() == Token::LPAREN) { | 2812 if (is_generator || peek() == Token::LPAREN) { |
2688 // MethodDefinition | 2813 // MethodDefinition |
2689 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2814 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2690 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2815 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2691 if (!*is_computed_name) { | 2816 if (!*is_computed_name) { |
2692 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2817 checker->CheckProperty(name_token, kMethodProperty, is_static, |
2693 is_generator, | 2818 is_generator, |
2694 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2819 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2695 } | 2820 } |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2899 // the parser and preparser | 3024 // the parser and preparser |
2900 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 3025 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
2901 } | 3026 } |
2902 | 3027 |
2903 return result; | 3028 return result; |
2904 } | 3029 } |
2905 | 3030 |
2906 // Precedence = 2 | 3031 // Precedence = 2 |
2907 template <class Traits> | 3032 template <class Traits> |
2908 typename ParserBase<Traits>::ExpressionT | 3033 typename ParserBase<Traits>::ExpressionT |
2909 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 3034 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, |
2910 ExpressionClassifier* classifier, | 3035 ExpressionClassifier* classifier, |
2911 bool* ok) { | 3036 bool* ok) { |
2912 // AssignmentExpression :: | 3037 // AssignmentExpression :: |
2913 // ConditionalExpression | 3038 // ConditionalExpression |
2914 // ArrowFunction | 3039 // ArrowFunction |
2915 // YieldExpression | 3040 // YieldExpression |
2916 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 3041 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2917 | 3042 bool is_rhs = flags & kIsRightHandSide; |
3043 bool is_pattern_element = flags & kIsPatternElement; | |
2918 int lhs_beg_pos = peek_position(); | 3044 int lhs_beg_pos = peek_position(); |
2919 | 3045 |
2920 if (peek() == Token::YIELD && is_generator()) { | 3046 if (peek() == Token::YIELD && is_generator()) { |
2921 return this->ParseYieldExpression(classifier, ok); | 3047 return this->ParseYieldExpression(classifier, ok); |
2922 } | 3048 } |
2923 | 3049 |
2924 if (fni_ != NULL) fni_->Enter(); | 3050 if (fni_ != NULL) fni_->Enter(); |
2925 ParserBase<Traits>::Checkpoint checkpoint(this); | 3051 ParserBase<Traits>::Checkpoint checkpoint(this); |
2926 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); | 3052 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); |
2927 bool parenthesized_formals = peek() == Token::LPAREN; | 3053 bool parenthesized_formals = peek() == Token::LPAREN; |
(...skipping 25 matching lines...) Expand all Loading... | |
2953 | 3079 |
2954 checkpoint.Restore(¶meters.materialized_literals_count); | 3080 checkpoint.Restore(¶meters.materialized_literals_count); |
2955 | 3081 |
2956 scope->set_start_position(lhs_beg_pos); | 3082 scope->set_start_position(lhs_beg_pos); |
2957 if (duplicate_loc.IsValid()) { | 3083 if (duplicate_loc.IsValid()) { |
2958 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 3084 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
2959 duplicate_loc); | 3085 duplicate_loc); |
2960 } | 3086 } |
2961 expression = this->ParseArrowFunctionLiteral( | 3087 expression = this->ParseArrowFunctionLiteral( |
2962 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); | 3088 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); |
3089 if (is_pattern_element) { | |
3090 classifier->RecordPatternError( | |
3091 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), | |
3092 MessageTemplate::kInvalidDestructuringTarget); | |
3093 } | |
2963 return expression; | 3094 return expression; |
2964 } | 3095 } |
2965 | 3096 |
3097 if (this->IsValidReferenceExpression(expression)) { | |
3098 arrow_formals_classifier.ForgiveAssignmentPatternError(); | |
3099 } | |
3100 | |
2966 // "expression" was not itself an arrow function parameter list, but it might | 3101 // "expression" was not itself an arrow function parameter list, but it might |
2967 // form part of one. Propagate speculative formal parameter error locations. | 3102 // form part of one. Propagate speculative formal parameter error locations. |
2968 classifier->Accumulate(arrow_formals_classifier, | 3103 classifier->Accumulate( |
2969 ExpressionClassifier::StandardProductions | | 3104 arrow_formals_classifier, |
2970 ExpressionClassifier::FormalParametersProductions); | 3105 ExpressionClassifier::StandardProductions | |
3106 ExpressionClassifier::FormalParametersProductions | | |
3107 ExpressionClassifier::CoverInitializedNameProduction); | |
3108 | |
3109 bool maybe_pattern = | |
3110 expression->IsObjectLiteral() || expression->IsArrayLiteral(); | |
3111 bool binding_pattern = | |
3112 allow_harmony_destructuring() && maybe_pattern && !is_rhs; | |
2971 | 3113 |
2972 if (!Token::IsAssignmentOp(peek())) { | 3114 if (!Token::IsAssignmentOp(peek())) { |
2973 if (fni_ != NULL) fni_->Leave(); | 3115 if (fni_ != NULL) fni_->Leave(); |
2974 // Parsed conditional expression only (no assignment). | 3116 // Parsed conditional expression only (no assignment). |
3117 if (is_pattern_element && !this->IsValidReferenceExpression(expression) && | |
3118 !maybe_pattern) { | |
3119 classifier->RecordPatternError( | |
3120 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), | |
3121 MessageTemplate::kInvalidDestructuringTarget); | |
3122 } else if (is_rhs && maybe_pattern) { | |
3123 ValidateExpression(classifier, CHECK_OK); | |
3124 } | |
3125 | |
2975 return expression; | 3126 return expression; |
2976 } | 3127 } |
2977 | 3128 |
2978 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) { | 3129 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) { |
2979 BindingPatternUnexpectedToken(classifier); | 3130 BindingPatternUnexpectedToken(classifier); |
2980 } | 3131 } |
2981 | 3132 |
2982 expression = this->CheckAndRewriteReferenceExpression( | 3133 if (allow_harmony_destructuring_assignment() && maybe_pattern && |
2983 expression, lhs_beg_pos, scanner()->location().end_pos, | 3134 peek() == Token::ASSIGN) { |
2984 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 3135 classifier->ForgiveCoverInitializedNameError(); |
3136 ValidateAssignmentPattern(classifier, CHECK_OK); | |
3137 expression = factory()->NewAssignmentPattern(expression, lhs_beg_pos); | |
3138 } else if (!binding_pattern) { | |
3139 expression = this->CheckAndRewriteReferenceExpression( | |
3140 expression, lhs_beg_pos, scanner()->location().end_pos, | |
3141 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | |
3142 } | |
3143 | |
2985 expression = this->MarkExpressionAsAssigned(expression); | 3144 expression = this->MarkExpressionAsAssigned(expression); |
2986 | 3145 |
2987 Token::Value op = Next(); // Get assignment operator. | 3146 Token::Value op = Next(); // Get assignment operator. |
2988 if (op != Token::ASSIGN) { | 3147 if (op != Token::ASSIGN) { |
2989 classifier->RecordBindingPatternError(scanner()->location(), | 3148 classifier->RecordBindingPatternError(scanner()->location(), |
2990 MessageTemplate::kUnexpectedToken, | 3149 MessageTemplate::kUnexpectedToken, |
2991 Token::String(op)); | 3150 Token::String(op)); |
2992 } | 3151 } |
2993 int pos = position(); | 3152 int pos = position(); |
2994 | 3153 |
2995 ExpressionClassifier rhs_classifier; | 3154 ExpressionClassifier rhs_classifier; |
2996 ExpressionT right = | 3155 |
2997 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 3156 int rhs_flags = flags; |
2998 classifier->Accumulate(rhs_classifier, | 3157 rhs_flags &= ~kIsPatternElement; |
2999 ExpressionClassifier::ExpressionProductions); | 3158 rhs_flags |= kIsRightHandSide; |
3159 ExpressionT right = this->ParseAssignmentExpression( | |
3160 accept_IN, rhs_flags, &rhs_classifier, CHECK_OK); | |
3161 classifier->Accumulate( | |
3162 rhs_classifier, ExpressionClassifier::ExpressionProductions | | |
3163 ExpressionClassifier::CoverInitializedNameProduction); | |
3000 | 3164 |
3001 // TODO(1231235): We try to estimate the set of properties set by | 3165 // TODO(1231235): We try to estimate the set of properties set by |
3002 // constructors. We define a new property whenever there is an | 3166 // constructors. We define a new property whenever there is an |
3003 // assignment to a property of 'this'. We should probably only add | 3167 // assignment to a property of 'this'. We should probably only add |
3004 // properties if we haven't seen them before. Otherwise we'll | 3168 // properties if we haven't seen them before. Otherwise we'll |
3005 // probably overestimate the number of properties. | 3169 // probably overestimate the number of properties. |
3006 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 3170 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
3007 function_state_->AddProperty(); | 3171 function_state_->AddProperty(); |
3008 } | 3172 } |
3009 | 3173 |
3010 this->CheckAssigningFunctionLiteralToProperty(expression, right); | 3174 this->CheckAssigningFunctionLiteralToProperty(expression, right); |
3011 | 3175 |
3012 if (fni_ != NULL) { | 3176 if (fni_ != NULL) { |
3013 // Check if the right hand side is a call to avoid inferring a | 3177 // Check if the right hand side is a call to avoid inferring a |
3014 // name if we're dealing with "a = function(){...}();"-like | 3178 // name if we're dealing with "a = function(){...}();"-like |
3015 // expression. | 3179 // expression. |
3016 if ((op == Token::INIT_VAR | 3180 if ((op == Token::INIT_VAR |
3017 || op == Token::INIT_CONST_LEGACY | 3181 || op == Token::INIT_CONST_LEGACY |
3018 || op == Token::ASSIGN) | 3182 || op == Token::ASSIGN) |
3019 && (!right->IsCall() && !right->IsCallNew())) { | 3183 && (!right->IsCall() && !right->IsCallNew())) { |
3020 fni_->Infer(); | 3184 fni_->Infer(); |
3021 } else { | 3185 } else { |
3022 fni_->RemoveLastFunction(); | 3186 fni_->RemoveLastFunction(); |
3023 } | 3187 } |
3024 fni_->Leave(); | 3188 fni_->Leave(); |
3025 } | 3189 } |
3026 | 3190 |
3027 return factory()->NewAssignment(op, expression, right, pos); | 3191 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
3192 | |
3193 if (expression->IsAssignmentPattern()) { | |
3194 Traits::ShouldRewriteDestructuringAssignment(result); | |
3195 } | |
3196 | |
3197 return result; | |
3028 } | 3198 } |
3029 | 3199 |
3030 template <class Traits> | 3200 template <class Traits> |
3031 typename ParserBase<Traits>::ExpressionT | 3201 typename ParserBase<Traits>::ExpressionT |
3032 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 3202 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
3033 bool* ok) { | 3203 bool* ok) { |
3034 // YieldExpression :: | 3204 // YieldExpression :: |
3035 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 3205 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
3036 int pos = peek_position(); | 3206 int pos = peek_position(); |
3037 BindingPatternUnexpectedToken(classifier); | 3207 BindingPatternUnexpectedToken(classifier); |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3974 allow_duplicate_parameters, CHECK_OK); | 4144 allow_duplicate_parameters, CHECK_OK); |
3975 | 4145 |
3976 // Validate strict mode. | 4146 // Validate strict mode. |
3977 if (is_strict(language_mode())) { | 4147 if (is_strict(language_mode())) { |
3978 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 4148 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
3979 scanner()->location().end_pos, CHECK_OK); | 4149 scanner()->location().end_pos, CHECK_OK); |
3980 } | 4150 } |
3981 if (is_strict(language_mode()) || allow_harmony_sloppy()) { | 4151 if (is_strict(language_mode()) || allow_harmony_sloppy()) { |
3982 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 4152 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3983 } | 4153 } |
4154 | |
4155 Traits::RewriteDestructuringAssignments(); | |
3984 } | 4156 } |
3985 | 4157 |
3986 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 4158 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3987 this->EmptyIdentifierString(), ast_value_factory(), | 4159 this->EmptyIdentifierString(), ast_value_factory(), |
3988 formal_parameters.scope, body, materialized_literal_count, | 4160 formal_parameters.scope, body, materialized_literal_count, |
3989 expected_property_count, num_parameters, | 4161 expected_property_count, num_parameters, |
3990 FunctionLiteral::kNoDuplicateParameters, | 4162 FunctionLiteral::kNoDuplicateParameters, |
3991 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | 4163 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
3992 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 4164 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, |
3993 formal_parameters.scope->start_position()); | 4165 formal_parameters.scope->start_position()); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4122 return this->EmptyExpression(); | 4294 return this->EmptyExpression(); |
4123 } | 4295 } |
4124 if (is_strong(language_mode()) && | 4296 if (is_strong(language_mode()) && |
4125 this->IsUndefined(this->AsIdentifier(expression))) { | 4297 this->IsUndefined(this->AsIdentifier(expression))) { |
4126 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined, | 4298 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined, |
4127 kSyntaxError); | 4299 kSyntaxError); |
4128 *ok = false; | 4300 *ok = false; |
4129 return this->EmptyExpression(); | 4301 return this->EmptyExpression(); |
4130 } | 4302 } |
4131 } | 4303 } |
4132 if (expression->IsValidReferenceExpression()) { | 4304 if (expression->IsValidReferenceExpression() || |
4305 expression->IsAssignmentPattern()) { | |
4133 return expression; | 4306 return expression; |
4134 } else if (expression->IsCall()) { | 4307 } else if (expression->IsCall()) { |
4135 // If it is a call, make it a runtime error for legacy web compatibility. | 4308 // If it is a call, make it a runtime error for legacy web compatibility. |
4136 // Rewrite `expr' to `expr[throw ReferenceError]'. | 4309 // Rewrite `expr' to `expr[throw ReferenceError]'. |
4137 int pos = location.beg_pos; | 4310 int pos = location.beg_pos; |
4138 ExpressionT error = this->NewThrowReferenceError(message, pos); | 4311 ExpressionT error = this->NewThrowReferenceError(message, pos); |
4139 return factory()->NewProperty(expression, error, pos); | 4312 return factory()->NewProperty(expression, error, pos); |
4140 } else { | 4313 } else { |
4141 this->ReportMessageAt(location, message, type); | 4314 this->ReportMessageAt(location, message, type); |
4142 *ok = false; | 4315 *ok = false; |
4143 return this->EmptyExpression(); | 4316 return this->EmptyExpression(); |
4144 } | 4317 } |
4145 } | 4318 } |
4146 | 4319 |
4147 | 4320 |
4321 template <typename Traits> | |
4322 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { | |
4323 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); | |
4324 } | |
4325 | |
4326 | |
4327 template <typename Traits> | |
4328 void ParserBase<Traits>::CheckDestructuringElement( | |
4329 ExpressionT expression, ExpressionClassifier* classifier, int begin, | |
4330 int end) { | |
4331 static const MessageTemplate::Template message = | |
4332 MessageTemplate::kInvalidDestructuringTarget; | |
4333 if (!this->IsAssignableIdentifier(expression)) { | |
4334 const Scanner::Location location(begin, end); | |
4335 classifier->RecordBindingPatternError(location, message); | |
4336 if (!expression->IsProperty()) { | |
4337 classifier->RecordAssignmentPatternError(location, message); | |
4338 } | |
4339 } | |
4340 } | |
4341 | |
4342 | |
4148 #undef CHECK_OK | 4343 #undef CHECK_OK |
4149 #undef CHECK_OK_CUSTOM | 4344 #undef CHECK_OK_CUSTOM |
4150 | 4345 |
4151 | 4346 |
4152 template <typename Traits> | 4347 template <typename Traits> |
4153 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 4348 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
4154 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 4349 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
4155 bool* ok) { | 4350 bool* ok) { |
4156 DCHECK(!is_static); | 4351 DCHECK(!is_static); |
4157 DCHECK(!is_generator || type == kMethodProperty); | 4352 DCHECK(!is_generator || type == kMethodProperty); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4199 return; | 4394 return; |
4200 } | 4395 } |
4201 has_seen_constructor_ = true; | 4396 has_seen_constructor_ = true; |
4202 return; | 4397 return; |
4203 } | 4398 } |
4204 } | 4399 } |
4205 } // namespace internal | 4400 } // namespace internal |
4206 } // namespace v8 | 4401 } // namespace v8 |
4207 | 4402 |
4208 #endif // V8_PREPARSER_H | 4403 #endif // V8_PREPARSER_H |
OLD | NEW |