Chromium Code Reviews| 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 |