| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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_spread_calls_(false), | 116 allow_harmony_spread_calls_(false), |
| 117 allow_harmony_destructuring_(false), | 117 allow_harmony_destructuring_(false), |
| 118 allow_harmony_destructuring_assignment_(false), |
| 118 allow_harmony_spread_arrays_(false), | 119 allow_harmony_spread_arrays_(false), |
| 119 allow_harmony_new_target_(false), | 120 allow_harmony_new_target_(false), |
| 120 allow_strong_mode_(false), | 121 allow_strong_mode_(false), |
| 121 allow_legacy_const_(true), | 122 allow_legacy_const_(true), |
| 122 allow_harmony_do_expressions_(false) {} | 123 allow_harmony_do_expressions_(false) {} |
| 123 | 124 |
| 124 #define ALLOW_ACCESSORS(name) \ | 125 #define ALLOW_ACCESSORS(name) \ |
| 125 bool allow_##name() const { return allow_##name##_; } \ | 126 bool allow_##name() const { return allow_##name##_; } \ |
| 126 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 127 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
| 127 | 128 |
| 128 ALLOW_ACCESSORS(lazy); | 129 ALLOW_ACCESSORS(lazy); |
| 129 ALLOW_ACCESSORS(natives); | 130 ALLOW_ACCESSORS(natives); |
| 130 ALLOW_ACCESSORS(harmony_sloppy); | 131 ALLOW_ACCESSORS(harmony_sloppy); |
| 131 ALLOW_ACCESSORS(harmony_sloppy_function); | 132 ALLOW_ACCESSORS(harmony_sloppy_function); |
| 132 ALLOW_ACCESSORS(harmony_sloppy_let); | 133 ALLOW_ACCESSORS(harmony_sloppy_let); |
| 133 ALLOW_ACCESSORS(harmony_rest_parameters); | 134 ALLOW_ACCESSORS(harmony_rest_parameters); |
| 134 ALLOW_ACCESSORS(harmony_default_parameters); | 135 ALLOW_ACCESSORS(harmony_default_parameters); |
| 135 ALLOW_ACCESSORS(harmony_spread_calls); | 136 ALLOW_ACCESSORS(harmony_spread_calls); |
| 136 ALLOW_ACCESSORS(harmony_destructuring); | 137 ALLOW_ACCESSORS(harmony_destructuring); |
| 138 ALLOW_ACCESSORS(harmony_destructuring_assignment); |
| 137 ALLOW_ACCESSORS(harmony_spread_arrays); | 139 ALLOW_ACCESSORS(harmony_spread_arrays); |
| 138 ALLOW_ACCESSORS(harmony_new_target); | 140 ALLOW_ACCESSORS(harmony_new_target); |
| 139 ALLOW_ACCESSORS(strong_mode); | 141 ALLOW_ACCESSORS(strong_mode); |
| 140 ALLOW_ACCESSORS(legacy_const); | 142 ALLOW_ACCESSORS(legacy_const); |
| 141 ALLOW_ACCESSORS(harmony_do_expressions); | 143 ALLOW_ACCESSORS(harmony_do_expressions); |
| 142 #undef ALLOW_ACCESSORS | 144 #undef ALLOW_ACCESSORS |
| 143 | 145 |
| 144 uintptr_t stack_limit() const { return stack_limit_; } | 146 uintptr_t stack_limit() const { return stack_limit_; } |
| 145 | 147 |
| 146 protected: | 148 protected: |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 Scanner::Location location, Token::Value token, | 544 Scanner::Location location, Token::Value token, |
| 543 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 545 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
| 544 | 546 |
| 545 | 547 |
| 546 void ReportClassifierError(const ExpressionClassifier::Error& error) { | 548 void ReportClassifierError(const ExpressionClassifier::Error& error) { |
| 547 Traits::ReportMessageAt(error.location, error.message, error.arg, | 549 Traits::ReportMessageAt(error.location, error.message, error.arg, |
| 548 kSyntaxError); | 550 kSyntaxError); |
| 549 } | 551 } |
| 550 | 552 |
| 551 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 553 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
| 552 if (!classifier->is_valid_expression()) { | 554 if (!classifier->is_valid_expression() || |
| 553 ReportClassifierError(classifier->expression_error()); | 555 classifier->has_cover_initialized_name()) { |
| 556 ReportClassifierError(ExpressionClassifier::FirdRecorded( |
| 557 classifier->expression_error(), |
| 558 classifier->cover_initialized_name_error())); |
| 554 *ok = false; | 559 *ok = false; |
| 555 } | 560 } |
| 556 } | 561 } |
| 557 | 562 |
| 558 void ValidateFormalParameterInitializer( | 563 void ValidateFormalParameterInitializer( |
| 559 const ExpressionClassifier* classifier, bool* ok) { | 564 const ExpressionClassifier* classifier, bool* ok) { |
| 560 if (!classifier->is_valid_formal_parameter_initializer()) { | 565 if (!classifier->is_valid_formal_parameter_initializer()) { |
| 561 ReportClassifierError(classifier->formal_parameter_initializer_error()); | 566 ReportClassifierError(classifier->formal_parameter_initializer_error()); |
| 562 *ok = false; | 567 *ok = false; |
| 563 } | 568 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 | 686 |
| 682 | 687 |
| 683 ExpressionT ParseRegExpLiteral(bool seen_equal, | 688 ExpressionT ParseRegExpLiteral(bool seen_equal, |
| 684 ExpressionClassifier* classifier, bool* ok); | 689 ExpressionClassifier* classifier, bool* ok); |
| 685 | 690 |
| 686 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 691 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 687 bool* ok); | 692 bool* ok); |
| 688 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 693 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 689 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 694 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
| 690 bool* ok); | 695 bool* ok); |
| 696 ExpressionT ParseExpression(bool accept_IN, int flags, |
| 697 ExpressionClassifier* classifier, bool* ok); |
| 691 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 698 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
| 692 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 699 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 693 bool* is_static, bool* is_computed_name, | 700 bool* is_static, bool* is_computed_name, |
| 694 ExpressionClassifier* classifier, bool* ok); | 701 ExpressionClassifier* classifier, bool* ok); |
| 695 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 702 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| 696 ObjectLiteralPropertyT ParsePropertyDefinition( | 703 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 697 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 704 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 698 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 705 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 699 ExpressionClassifier* classifier, bool* ok); | 706 ExpressionClassifier* classifier, bool* ok); |
| 700 typename Traits::Type::ExpressionList ParseArguments( | 707 typename Traits::Type::ExpressionList ParseArguments( |
| 701 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 708 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| 702 bool* ok); | 709 bool* ok); |
| 710 |
| 711 enum AssignmentFlags { |
| 712 kIsRightHandSide = 1 << 0, |
| 713 kIsPatternElement = 1 << 1, |
| 714 kMaybeBindingPattern = 1 << 2 |
| 715 }; |
| 703 ExpressionT ParseAssignmentExpression(bool accept_IN, | 716 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 704 ExpressionClassifier* classifier, | 717 ExpressionClassifier* classifier, |
| 718 bool* ok) { |
| 719 bool seen_destructuring = false; |
| 720 return ParseAssignmentExpression(accept_IN, 0, &seen_destructuring, |
| 721 classifier, ok); |
| 722 } |
| 723 ExpressionT ParseAssignmentExpression(bool accept_IN, int flags, |
| 724 ExpressionClassifier* classifier, |
| 725 bool* ok) { |
| 726 bool seen_destructuring = false; |
| 727 return ParseAssignmentExpression(accept_IN, flags, &seen_destructuring, |
| 728 classifier, ok); |
| 729 } |
| 730 ExpressionT ParseAssignmentExpression(bool accept_IN, int flags, |
| 731 bool* seen_destructuring, |
| 732 ExpressionClassifier* classifier, |
| 705 bool* ok); | 733 bool* ok); |
| 706 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); | 734 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
| 707 ExpressionT ParseConditionalExpression(bool accept_IN, | 735 ExpressionT ParseConditionalExpression(bool accept_IN, |
| 708 ExpressionClassifier* classifier, | 736 ExpressionClassifier* classifier, |
| 709 bool* ok); | 737 bool* ok); |
| 710 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 738 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| 711 ExpressionClassifier* classifier, bool* ok); | 739 ExpressionClassifier* classifier, bool* ok); |
| 712 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 740 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
| 713 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 741 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
| 714 bool* ok); | 742 bool* ok); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 // Checks if the expression is a valid reference expression (e.g., on the | 775 // Checks if the expression is a valid reference expression (e.g., on the |
| 748 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 776 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 749 // we allow calls for web compatibility and rewrite them to a runtime throw. | 777 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 750 ExpressionT CheckAndRewriteReferenceExpression( | 778 ExpressionT CheckAndRewriteReferenceExpression( |
| 751 ExpressionT expression, int beg_pos, int end_pos, | 779 ExpressionT expression, int beg_pos, int end_pos, |
| 752 MessageTemplate::Template message, bool* ok); | 780 MessageTemplate::Template message, bool* ok); |
| 753 ExpressionT CheckAndRewriteReferenceExpression( | 781 ExpressionT CheckAndRewriteReferenceExpression( |
| 754 ExpressionT expression, int beg_pos, int end_pos, | 782 ExpressionT expression, int beg_pos, int end_pos, |
| 755 MessageTemplate::Template message, ParseErrorType type, bool* ok); | 783 MessageTemplate::Template message, ParseErrorType type, bool* ok); |
| 756 | 784 |
| 785 bool IsValidReferenceExpression(ExpressionT expression); |
| 786 |
| 757 // Used to validate property names in object literals and class literals | 787 // Used to validate property names in object literals and class literals |
| 758 enum PropertyKind { | 788 enum PropertyKind { |
| 759 kAccessorProperty, | 789 kAccessorProperty, |
| 760 kValueProperty, | 790 kValueProperty, |
| 761 kMethodProperty | 791 kMethodProperty |
| 762 }; | 792 }; |
| 763 | 793 |
| 764 class ObjectLiteralCheckerBase { | 794 class ObjectLiteralCheckerBase { |
| 765 public: | 795 public: |
| 766 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | 796 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 | 866 |
| 837 bool allow_lazy_; | 867 bool allow_lazy_; |
| 838 bool allow_natives_; | 868 bool allow_natives_; |
| 839 bool allow_harmony_sloppy_; | 869 bool allow_harmony_sloppy_; |
| 840 bool allow_harmony_sloppy_function_; | 870 bool allow_harmony_sloppy_function_; |
| 841 bool allow_harmony_sloppy_let_; | 871 bool allow_harmony_sloppy_let_; |
| 842 bool allow_harmony_rest_parameters_; | 872 bool allow_harmony_rest_parameters_; |
| 843 bool allow_harmony_default_parameters_; | 873 bool allow_harmony_default_parameters_; |
| 844 bool allow_harmony_spread_calls_; | 874 bool allow_harmony_spread_calls_; |
| 845 bool allow_harmony_destructuring_; | 875 bool allow_harmony_destructuring_; |
| 876 bool allow_harmony_destructuring_assignment_; |
| 846 bool allow_harmony_spread_arrays_; | 877 bool allow_harmony_spread_arrays_; |
| 847 bool allow_harmony_new_target_; | 878 bool allow_harmony_new_target_; |
| 848 bool allow_strong_mode_; | 879 bool allow_strong_mode_; |
| 849 bool allow_legacy_const_; | 880 bool allow_legacy_const_; |
| 850 bool allow_harmony_do_expressions_; | 881 bool allow_harmony_do_expressions_; |
| 851 }; | 882 }; |
| 852 | 883 |
| 853 | 884 |
| 854 class PreParserIdentifier { | 885 class PreParserIdentifier { |
| 855 public: | 886 public: |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 | 981 |
| 951 static PreParserExpression BinaryOperation(PreParserExpression left, | 982 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 952 Token::Value op, | 983 Token::Value op, |
| 953 PreParserExpression right) { | 984 PreParserExpression right) { |
| 954 return PreParserExpression( | 985 return PreParserExpression( |
| 955 TypeField::encode(kBinaryOperationExpression) | | 986 TypeField::encode(kBinaryOperationExpression) | |
| 956 HasRestField::encode(op == Token::COMMA && | 987 HasRestField::encode(op == Token::COMMA && |
| 957 right->IsSpreadExpression())); | 988 right->IsSpreadExpression())); |
| 958 } | 989 } |
| 959 | 990 |
| 991 static PreParserExpression Assignment() { |
| 992 return PreParserExpression(TypeField::encode(kAssignmentExpression)); |
| 993 } |
| 994 |
| 995 static PreParserExpression ObjectLiteral( |
| 996 bool has_cover_initialized_name = false) { |
| 997 return PreParserExpression( |
| 998 TypeField::encode(kObjectLiteralExpression) | |
| 999 HasCoverInitializedNameField::encode(has_cover_initialized_name)); |
| 1000 } |
| 1001 |
| 960 static PreParserExpression StringLiteral() { | 1002 static PreParserExpression StringLiteral() { |
| 961 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 1003 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
| 962 } | 1004 } |
| 963 | 1005 |
| 964 static PreParserExpression UseStrictStringLiteral() { | 1006 static PreParserExpression UseStrictStringLiteral() { |
| 965 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | | 1007 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
| 966 IsUseStrictField::encode(true)); | 1008 IsUseStrictField::encode(true)); |
| 967 } | 1009 } |
| 968 | 1010 |
| 969 static PreParserExpression UseStrongStringLiteral() { | 1011 static PreParserExpression UseStrongStringLiteral() { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 998 TypeField::encode(kExpression) | | 1040 TypeField::encode(kExpression) | |
| 999 ExpressionTypeField::encode(kSuperCallReference)); | 1041 ExpressionTypeField::encode(kSuperCallReference)); |
| 1000 } | 1042 } |
| 1001 | 1043 |
| 1002 static PreParserExpression NoTemplateTag() { | 1044 static PreParserExpression NoTemplateTag() { |
| 1003 return PreParserExpression( | 1045 return PreParserExpression( |
| 1004 TypeField::encode(kExpression) | | 1046 TypeField::encode(kExpression) | |
| 1005 ExpressionTypeField::encode(kNoTemplateTagExpression)); | 1047 ExpressionTypeField::encode(kNoTemplateTagExpression)); |
| 1006 } | 1048 } |
| 1007 | 1049 |
| 1050 bool IsAssignment() const { |
| 1051 return TypeField::decode(code_) == kAssignmentExpression; |
| 1052 } |
| 1053 |
| 1008 bool IsIdentifier() const { | 1054 bool IsIdentifier() const { |
| 1009 return TypeField::decode(code_) == kIdentifierExpression; | 1055 return TypeField::decode(code_) == kIdentifierExpression; |
| 1010 } | 1056 } |
| 1011 | 1057 |
| 1012 PreParserIdentifier AsIdentifier() const { | 1058 PreParserIdentifier AsIdentifier() const { |
| 1013 DCHECK(IsIdentifier()); | 1059 DCHECK(IsIdentifier()); |
| 1014 return PreParserIdentifier(IdentifierTypeField::decode(code_)); | 1060 return PreParserIdentifier(IdentifierTypeField::decode(code_)); |
| 1015 } | 1061 } |
| 1016 | 1062 |
| 1063 PreParserExpression AsObjectLiteral() const { |
| 1064 DCHECK(IsObjectLiteral()); |
| 1065 return *this; |
| 1066 } |
| 1067 |
| 1068 bool IsObjectLiteral() const { |
| 1069 return TypeField::decode(code_) == kObjectLiteralExpression; |
| 1070 } |
| 1071 |
| 1072 bool IsArrayLiteral() const { |
| 1073 return TypeField::decode(code_) == kObjectLiteralExpression; |
| 1074 } |
| 1075 |
| 1017 bool IsStringLiteral() const { | 1076 bool IsStringLiteral() const { |
| 1018 return TypeField::decode(code_) == kStringLiteralExpression; | 1077 return TypeField::decode(code_) == kStringLiteralExpression; |
| 1019 } | 1078 } |
| 1020 | 1079 |
| 1021 bool IsUseStrictLiteral() const { | 1080 bool IsUseStrictLiteral() const { |
| 1022 return TypeField::decode(code_) == kStringLiteralExpression && | 1081 return TypeField::decode(code_) == kStringLiteralExpression && |
| 1023 IsUseStrictField::decode(code_); | 1082 IsUseStrictField::decode(code_); |
| 1024 } | 1083 } |
| 1025 | 1084 |
| 1026 bool IsUseStrongLiteral() const { | 1085 bool IsUseStrongLiteral() const { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 | 1154 |
| 1096 int position() const { return RelocInfo::kNoPosition; } | 1155 int position() const { return RelocInfo::kNoPosition; } |
| 1097 void set_function_token_position(int position) {} | 1156 void set_function_token_position(int position) {} |
| 1098 | 1157 |
| 1099 private: | 1158 private: |
| 1100 enum Type { | 1159 enum Type { |
| 1101 kExpression, | 1160 kExpression, |
| 1102 kIdentifierExpression, | 1161 kIdentifierExpression, |
| 1103 kStringLiteralExpression, | 1162 kStringLiteralExpression, |
| 1104 kBinaryOperationExpression, | 1163 kBinaryOperationExpression, |
| 1105 kSpreadExpression | 1164 kSpreadExpression, |
| 1165 kObjectLiteralExpression, |
| 1166 kAssignmentExpression |
| 1106 }; | 1167 }; |
| 1107 | 1168 |
| 1108 enum ExpressionType { | 1169 enum ExpressionType { |
| 1109 kThisExpression, | 1170 kThisExpression, |
| 1110 kThisPropertyExpression, | 1171 kThisPropertyExpression, |
| 1111 kPropertyExpression, | 1172 kPropertyExpression, |
| 1112 kCallExpression, | 1173 kCallExpression, |
| 1113 kSuperCallReference, | 1174 kSuperCallReference, |
| 1114 kNoTemplateTagExpression | 1175 kNoTemplateTagExpression |
| 1115 }; | 1176 }; |
| 1116 | 1177 |
| 1117 explicit PreParserExpression(uint32_t expression_code) | 1178 explicit PreParserExpression(uint32_t expression_code) |
| 1118 : code_(expression_code) {} | 1179 : code_(expression_code) {} |
| 1119 | 1180 |
| 1120 // The first three bits are for the Type. | 1181 // The first three bits are for the Type. |
| 1121 typedef BitField<Type, 0, 3> TypeField; | 1182 typedef BitField<Type, 0, 3> TypeField; |
| 1122 | 1183 |
| 1123 // The rest of the bits are interpreted depending on the value | 1184 // The rest of the bits are interpreted depending on the value |
| 1124 // of the Type field, so they can share the storage. | 1185 // of the Type field, so they can share the storage. |
| 1125 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; | 1186 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; |
| 1126 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; | 1187 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; |
| 1127 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1188 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
| 1128 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> | 1189 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> |
| 1129 IdentifierTypeField; | 1190 IdentifierTypeField; |
| 1130 typedef BitField<bool, TypeField::kNext, 1> HasRestField; | 1191 typedef BitField<bool, TypeField::kNext, 1> HasRestField; |
| 1192 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField; |
| 1131 | 1193 |
| 1132 uint32_t code_; | 1194 uint32_t code_; |
| 1133 }; | 1195 }; |
| 1134 | 1196 |
| 1135 | 1197 |
| 1136 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1198 // The pre-parser doesn't need to build lists of expressions, identifiers, or |
| 1137 // the like. | 1199 // the like. |
| 1138 template <typename T> | 1200 template <typename T> |
| 1139 class PreParserList { | 1201 class PreParserList { |
| 1140 public: | 1202 public: |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1233 PreParserIdentifier js_flags, | 1295 PreParserIdentifier js_flags, |
| 1234 int literal_index, | 1296 int literal_index, |
| 1235 bool is_strong, | 1297 bool is_strong, |
| 1236 int pos) { | 1298 int pos) { |
| 1237 return PreParserExpression::Default(); | 1299 return PreParserExpression::Default(); |
| 1238 } | 1300 } |
| 1239 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 1301 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
| 1240 int literal_index, | 1302 int literal_index, |
| 1241 bool is_strong, | 1303 bool is_strong, |
| 1242 int pos) { | 1304 int pos) { |
| 1243 return PreParserExpression::Default(); | 1305 return PreParserExpression::ObjectLiteral(); |
| 1244 } | 1306 } |
| 1245 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 1307 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
| 1246 int first_spread_index, int literal_index, | 1308 int first_spread_index, int literal_index, |
| 1247 bool is_strong, int pos) { | 1309 bool is_strong, int pos) { |
| 1248 return PreParserExpression::Default(); | 1310 return PreParserExpression::ObjectLiteral(); |
| 1249 } | 1311 } |
| 1250 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 1312 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
| 1251 PreParserExpression value, | 1313 PreParserExpression value, |
| 1252 ObjectLiteralProperty::Kind kind, | 1314 ObjectLiteralProperty::Kind kind, |
| 1253 bool is_static, | 1315 bool is_static, |
| 1254 bool is_computed_name) { | 1316 bool is_computed_name) { |
| 1255 return PreParserExpression::Default(); | 1317 return PreParserExpression::Default(); |
| 1256 } | 1318 } |
| 1257 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 1319 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
| 1258 PreParserExpression value, | 1320 PreParserExpression value, |
| 1259 bool is_static, | 1321 bool is_static, |
| 1260 bool is_computed_name) { | 1322 bool is_computed_name) { |
| 1261 return PreParserExpression::Default(); | 1323 return PreParserExpression::Default(); |
| 1262 } | 1324 } |
| 1263 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, | 1325 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
| 1264 int literal_index, | 1326 int literal_index, |
| 1265 int boilerplate_properties, | 1327 int boilerplate_properties, |
| 1266 bool has_function, | 1328 bool has_function, |
| 1267 bool is_strong, | 1329 bool is_strong, |
| 1268 int pos) { | 1330 int pos) { |
| 1269 return PreParserExpression::Default(); | 1331 return PreParserExpression::ObjectLiteral(); |
| 1270 } | 1332 } |
| 1271 PreParserExpression NewVariableProxy(void* variable) { | 1333 PreParserExpression NewVariableProxy(void* variable) { |
| 1272 return PreParserExpression::Default(); | 1334 return PreParserExpression::Default(); |
| 1273 } | 1335 } |
| 1274 PreParserExpression NewProperty(PreParserExpression obj, | 1336 PreParserExpression NewProperty(PreParserExpression obj, |
| 1275 PreParserExpression key, | 1337 PreParserExpression key, |
| 1276 int pos) { | 1338 int pos) { |
| 1277 if (obj.IsThis()) { | 1339 if (obj.IsThis()) { |
| 1278 return PreParserExpression::ThisProperty(); | 1340 return PreParserExpression::ThisProperty(); |
| 1279 } | 1341 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1291 } | 1353 } |
| 1292 PreParserExpression NewCompareOperation(Token::Value op, | 1354 PreParserExpression NewCompareOperation(Token::Value op, |
| 1293 PreParserExpression left, | 1355 PreParserExpression left, |
| 1294 PreParserExpression right, int pos) { | 1356 PreParserExpression right, int pos) { |
| 1295 return PreParserExpression::Default(); | 1357 return PreParserExpression::Default(); |
| 1296 } | 1358 } |
| 1297 PreParserExpression NewAssignment(Token::Value op, | 1359 PreParserExpression NewAssignment(Token::Value op, |
| 1298 PreParserExpression left, | 1360 PreParserExpression left, |
| 1299 PreParserExpression right, | 1361 PreParserExpression right, |
| 1300 int pos) { | 1362 int pos) { |
| 1301 return PreParserExpression::Default(); | 1363 return PreParserExpression::Assignment(); |
| 1302 } | 1364 } |
| 1303 PreParserExpression NewYield(PreParserExpression generator_object, | 1365 PreParserExpression NewYield(PreParserExpression generator_object, |
| 1304 PreParserExpression expression, | 1366 PreParserExpression expression, |
| 1305 Yield::Kind yield_kind, | 1367 Yield::Kind yield_kind, |
| 1306 int pos) { | 1368 int pos) { |
| 1307 return PreParserExpression::Default(); | 1369 return PreParserExpression::Default(); |
| 1308 } | 1370 } |
| 1309 PreParserExpression NewConditional(PreParserExpression condition, | 1371 PreParserExpression NewConditional(PreParserExpression condition, |
| 1310 PreParserExpression then_expression, | 1372 PreParserExpression then_expression, |
| 1311 PreParserExpression else_expression, | 1373 PreParserExpression else_expression, |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1723 | 1785 |
| 1724 inline void MaterializeUnspreadArgumentsLiterals(int count); | 1786 inline void MaterializeUnspreadArgumentsLiterals(int count); |
| 1725 | 1787 |
| 1726 inline PreParserExpression SpreadCall(PreParserExpression function, | 1788 inline PreParserExpression SpreadCall(PreParserExpression function, |
| 1727 PreParserExpressionList args, int pos); | 1789 PreParserExpressionList args, int pos); |
| 1728 | 1790 |
| 1729 inline PreParserExpression SpreadCallNew(PreParserExpression function, | 1791 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
| 1730 PreParserExpressionList args, | 1792 PreParserExpressionList args, |
| 1731 int pos); | 1793 int pos); |
| 1732 | 1794 |
| 1795 inline PreParserExpression RewriteDestructuringAssignmentExpression( |
| 1796 PreParserExpression expr) { |
| 1797 return expr; |
| 1798 } |
| 1799 |
| 1733 private: | 1800 private: |
| 1734 PreParser* pre_parser_; | 1801 PreParser* pre_parser_; |
| 1735 }; | 1802 }; |
| 1736 | 1803 |
| 1737 | 1804 |
| 1738 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1805 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 1739 // a later parsing to be faster. | 1806 // a later parsing to be faster. |
| 1740 // See preparse-data-format.h for the data format. | 1807 // See preparse-data-format.h for the data format. |
| 1741 | 1808 |
| 1742 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1809 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2368 ReportMessageAt(scanner()->peek_location(), | 2435 ReportMessageAt(scanner()->peek_location(), |
| 2369 MessageTemplate::kParamAfterRest); | 2436 MessageTemplate::kParamAfterRest); |
| 2370 *ok = false; | 2437 *ok = false; |
| 2371 return this->EmptyExpression(); | 2438 return this->EmptyExpression(); |
| 2372 } | 2439 } |
| 2373 Expect(Token::RPAREN, CHECK_OK); | 2440 Expect(Token::RPAREN, CHECK_OK); |
| 2374 } else { | 2441 } else { |
| 2375 // Heuristically try to detect immediately called functions before | 2442 // Heuristically try to detect immediately called functions before |
| 2376 // seeing the call parentheses. | 2443 // seeing the call parentheses. |
| 2377 parenthesized_function_ = (peek() == Token::FUNCTION); | 2444 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2378 result = this->ParseExpression(true, classifier, CHECK_OK); | 2445 result = this->ParseExpression(true, kMaybeBindingPattern, classifier, |
| 2446 CHECK_OK); |
| 2379 Expect(Token::RPAREN, CHECK_OK); | 2447 Expect(Token::RPAREN, CHECK_OK); |
| 2448 |
| 2449 if (peek() != Token::ARROW) { |
| 2450 if (allow_harmony_destructuring_assignment()) { |
| 2451 ValidateAssignmentPattern(classifier, CHECK_OK); |
| 2452 } else { |
| 2453 ValidateExpression(classifier, CHECK_OK); |
| 2454 } |
| 2455 } |
| 2380 } | 2456 } |
| 2381 break; | 2457 break; |
| 2382 | 2458 |
| 2383 case Token::CLASS: { | 2459 case Token::CLASS: { |
| 2384 BindingPatternUnexpectedToken(classifier); | 2460 BindingPatternUnexpectedToken(classifier); |
| 2385 Consume(Token::CLASS); | 2461 Consume(Token::CLASS); |
| 2386 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2462 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 2387 ReportMessage(MessageTemplate::kSloppyLexical); | 2463 ReportMessage(MessageTemplate::kSloppyLexical); |
| 2388 *ok = false; | 2464 *ok = false; |
| 2389 break; | 2465 break; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2443 template <class Traits> | 2519 template <class Traits> |
| 2444 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2520 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2445 bool accept_IN, bool* ok) { | 2521 bool accept_IN, bool* ok) { |
| 2446 ExpressionClassifier classifier; | 2522 ExpressionClassifier classifier; |
| 2447 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 2523 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
| 2448 ValidateExpression(&classifier, CHECK_OK); | 2524 ValidateExpression(&classifier, CHECK_OK); |
| 2449 return result; | 2525 return result; |
| 2450 } | 2526 } |
| 2451 | 2527 |
| 2452 | 2528 |
| 2529 template <class Traits> |
| 2530 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2531 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| 2532 ExpressionT result = ParseExpression(accept_IN, 0, classifier, CHECK_OK); |
| 2533 return result; |
| 2534 } |
| 2535 |
| 2536 |
| 2453 // Precedence = 1 | 2537 // Precedence = 1 |
| 2454 template <class Traits> | 2538 template <class Traits> |
| 2455 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2539 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2456 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2540 bool accept_IN, int flags, ExpressionClassifier* classifier, bool* ok) { |
| 2457 // Expression :: | 2541 // Expression :: |
| 2458 // AssignmentExpression | 2542 // AssignmentExpression |
| 2459 // Expression ',' AssignmentExpression | 2543 // Expression ',' AssignmentExpression |
| 2460 | 2544 |
| 2461 ExpressionClassifier binding_classifier; | 2545 ExpressionClassifier binding_classifier; |
| 2462 ExpressionT result = | 2546 bool seen_destructuring = false; |
| 2463 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 2547 ExpressionT result = this->ParseAssignmentExpression( |
| 2548 accept_IN, flags, &seen_destructuring, &binding_classifier, CHECK_OK); |
| 2464 classifier->Accumulate(binding_classifier, | 2549 classifier->Accumulate(binding_classifier, |
| 2465 ExpressionClassifier::AllProductions); | 2550 ExpressionClassifier::AllProductions); |
| 2466 bool is_simple_parameter_list = this->IsIdentifier(result); | 2551 bool is_simple_parameter_list = this->IsIdentifier(result); |
| 2467 bool seen_rest = false; | 2552 bool seen_rest = false; |
| 2468 while (peek() == Token::COMMA) { | 2553 while (peek() == Token::COMMA) { |
| 2469 if (seen_rest) { | 2554 if (seen_rest) { |
| 2470 // At this point the production can't possibly be valid, but we don't know | 2555 // At this point the production can't possibly be valid, but we don't know |
| 2471 // which error to signal. | 2556 // which error to signal. |
| 2472 classifier->RecordArrowFormalParametersError( | 2557 classifier->RecordArrowFormalParametersError( |
| 2473 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 2558 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
| 2474 } | 2559 } |
| 2475 Consume(Token::COMMA); | 2560 Consume(Token::COMMA); |
| 2476 bool is_rest = false; | 2561 bool is_rest = false; |
| 2477 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { | 2562 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { |
| 2478 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 2563 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
| 2479 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 2564 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
| 2480 // valid expression or binding pattern. | 2565 // valid expression or binding pattern. |
| 2481 ExpressionUnexpectedToken(classifier); | 2566 ExpressionUnexpectedToken(classifier); |
| 2482 BindingPatternUnexpectedToken(classifier); | 2567 BindingPatternUnexpectedToken(classifier); |
| 2483 Consume(Token::ELLIPSIS); | 2568 Consume(Token::ELLIPSIS); |
| 2484 seen_rest = is_rest = true; | 2569 seen_rest = is_rest = true; |
| 2485 } | 2570 } |
| 2486 int pos = position(); | 2571 int pos = position(); |
| 2487 ExpressionT right = this->ParseAssignmentExpression( | 2572 ExpressionT right = this->ParseAssignmentExpression( |
| 2488 accept_IN, &binding_classifier, CHECK_OK); | 2573 accept_IN, flags, &seen_destructuring, &binding_classifier, CHECK_OK); |
| 2489 if (is_rest) right = factory()->NewSpread(right, pos); | 2574 if (is_rest) right = factory()->NewSpread(right, pos); |
| 2490 is_simple_parameter_list = | 2575 is_simple_parameter_list = |
| 2491 is_simple_parameter_list && this->IsIdentifier(right); | 2576 is_simple_parameter_list && this->IsIdentifier(right); |
| 2492 classifier->Accumulate(binding_classifier, | 2577 classifier->Accumulate(binding_classifier, |
| 2493 ExpressionClassifier::AllProductions); | 2578 ExpressionClassifier::AllProductions); |
| 2494 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2579 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 2495 } | 2580 } |
| 2496 if (!is_simple_parameter_list || seen_rest) { | 2581 if (!is_simple_parameter_list || seen_rest) { |
| 2497 classifier->RecordNonSimpleParameter(); | 2582 classifier->RecordNonSimpleParameter(); |
| 2498 } | 2583 } |
| 2584 |
| 2499 return result; | 2585 return result; |
| 2500 } | 2586 } |
| 2501 | 2587 |
| 2502 | 2588 |
| 2503 template <class Traits> | 2589 template <class Traits> |
| 2504 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2590 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| 2505 ExpressionClassifier* classifier, bool* ok) { | 2591 ExpressionClassifier* classifier, bool* ok) { |
| 2506 // ArrayLiteral :: | 2592 // ArrayLiteral :: |
| 2507 // '[' Expression? (',' Expression?)* ']' | 2593 // '[' Expression? (',' Expression?)* ']' |
| 2508 | 2594 |
| 2509 int pos = peek_position(); | 2595 int pos = peek_position(); |
| 2510 typename Traits::Type::ExpressionList values = | 2596 typename Traits::Type::ExpressionList values = |
| 2511 this->NewExpressionList(4, zone_); | 2597 this->NewExpressionList(4, zone_); |
| 2512 int first_spread_index = -1; | 2598 int first_spread_index = -1; |
| 2513 Expect(Token::LBRACK, CHECK_OK); | 2599 Expect(Token::LBRACK, CHECK_OK); |
| 2514 while (peek() != Token::RBRACK) { | 2600 while (peek() != Token::RBRACK) { |
| 2515 bool seen_spread = false; | 2601 bool seen_spread = false; |
| 2516 ExpressionT elem = this->EmptyExpression(); | 2602 ExpressionT elem = this->EmptyExpression(); |
| 2517 if (peek() == Token::COMMA) { | 2603 if (peek() == Token::COMMA) { |
| 2518 if (is_strong(language_mode())) { | 2604 if (is_strong(language_mode())) { |
| 2519 ReportMessageAt(scanner()->peek_location(), | 2605 ReportMessageAt(scanner()->peek_location(), |
| 2520 MessageTemplate::kStrongEllision); | 2606 MessageTemplate::kStrongEllision); |
| 2521 *ok = false; | 2607 *ok = false; |
| 2522 return this->EmptyExpression(); | 2608 return this->EmptyExpression(); |
| 2523 } | 2609 } |
| 2524 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2610 elem = this->GetLiteralTheHole(peek_position(), factory()); |
| 2525 } else if (peek() == Token::ELLIPSIS) { | 2611 } else if (peek() == Token::ELLIPSIS) { |
| 2526 if (!allow_harmony_spread_arrays()) { | 2612 if (!allow_harmony_spread_arrays() && !allow_harmony_destructuring() && |
| 2613 !allow_harmony_destructuring_assignment()) { |
| 2527 ExpressionUnexpectedToken(classifier); | 2614 ExpressionUnexpectedToken(classifier); |
| 2528 } | 2615 } |
| 2529 int start_pos = peek_position(); | 2616 int start_pos = peek_position(); |
| 2530 Consume(Token::ELLIPSIS); | 2617 Consume(Token::ELLIPSIS); |
| 2531 ExpressionT argument = | 2618 ExpressionT argument = |
| 2532 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2619 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 2620 if ((argument->IsArrayLiteral() || argument->IsObjectLiteral()) && |
| 2621 !classifier->is_valid_assignment_pattern()) { |
| 2622 classifier->RecordPatternError( |
| 2623 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 2624 MessageTemplate::kInvalidDestructuringTarget); |
| 2625 } |
| 2533 elem = factory()->NewSpread(argument, start_pos); | 2626 elem = factory()->NewSpread(argument, start_pos); |
| 2534 seen_spread = true; | 2627 seen_spread = true; |
| 2535 if (first_spread_index < 0) { | 2628 if (first_spread_index < 0) { |
| 2536 first_spread_index = values->length(); | 2629 first_spread_index = values->length(); |
| 2537 } | 2630 } |
| 2631 if (argument->IsAssignment()) { |
| 2632 classifier->RecordPatternError( |
| 2633 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 2634 MessageTemplate::kInvalidRestInitializer); |
| 2635 } else if (peek() == Token::COMMA) { |
| 2636 classifier->RecordPatternError( |
| 2637 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 2638 MessageTemplate::kElementAfterRest); |
| 2639 } |
| 2538 } else { | 2640 } else { |
| 2539 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2641 elem = this->ParseAssignmentExpression(true, kIsPatternElement, |
| 2642 classifier, CHECK_OK); |
| 2643 if (!this->IsValidReferenceExpression(elem) && |
| 2644 !classifier->is_valid_assignment_pattern()) { |
| 2645 classifier->RecordPatternError( |
| 2646 Scanner::Location(pos, scanner()->location().end_pos), |
| 2647 MessageTemplate::kInvalidDestructuringTarget); |
| 2648 } |
| 2540 } | 2649 } |
| 2541 values->Add(elem, zone_); | 2650 values->Add(elem, zone_); |
| 2542 if (peek() != Token::RBRACK) { | 2651 if (peek() != Token::RBRACK) { |
| 2543 if (seen_spread) { | 2652 if (seen_spread) { |
| 2544 BindingPatternUnexpectedToken(classifier); | 2653 BindingPatternUnexpectedToken(classifier); |
| 2545 } | 2654 } |
| 2546 Expect(Token::COMMA, CHECK_OK); | 2655 Expect(Token::COMMA, CHECK_OK); |
| 2547 } | 2656 } |
| 2548 } | 2657 } |
| 2549 Expect(Token::RBRACK, CHECK_OK); | 2658 Expect(Token::RBRACK, CHECK_OK); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2645 DCHECK(!is_static); | 2754 DCHECK(!is_static); |
| 2646 | 2755 |
| 2647 if (peek() == Token::COLON) { | 2756 if (peek() == Token::COLON) { |
| 2648 // PropertyDefinition | 2757 // PropertyDefinition |
| 2649 // PropertyName ':' AssignmentExpression | 2758 // PropertyName ':' AssignmentExpression |
| 2650 if (!*is_computed_name) { | 2759 if (!*is_computed_name) { |
| 2651 checker->CheckProperty(name_token, kValueProperty, false, false, | 2760 checker->CheckProperty(name_token, kValueProperty, false, false, |
| 2652 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2761 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2653 } | 2762 } |
| 2654 Consume(Token::COLON); | 2763 Consume(Token::COLON); |
| 2764 int pos = peek_position(); |
| 2655 value = this->ParseAssignmentExpression( | 2765 value = this->ParseAssignmentExpression( |
| 2656 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2766 true, kIsPatternElement, classifier, |
| 2767 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2768 |
| 2769 if (!this->IsValidReferenceExpression(value) && |
| 2770 !classifier->is_valid_assignment_pattern()) { |
| 2771 classifier->RecordPatternError( |
| 2772 Scanner::Location(pos, scanner()->location().end_pos), |
| 2773 MessageTemplate::kInvalidDestructuringTarget); |
| 2774 } |
| 2775 |
| 2657 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 2776 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
| 2658 *is_computed_name); | 2777 *is_computed_name); |
| 2659 } | 2778 } |
| 2660 | 2779 |
| 2661 if (Token::IsIdentifier(name_token, language_mode(), | 2780 if (Token::IsIdentifier(name_token, language_mode(), |
| 2662 this->is_generator()) && | 2781 this->is_generator()) && |
| 2663 (peek() == Token::COMMA || peek() == Token::RBRACE || | 2782 (peek() == Token::COMMA || peek() == Token::RBRACE || |
| 2664 peek() == Token::ASSIGN)) { | 2783 peek() == Token::ASSIGN)) { |
| 2665 // PropertyDefinition | 2784 // PropertyDefinition |
| 2666 // IdentifierReference | 2785 // IdentifierReference |
| 2667 // CoverInitializedName | 2786 // CoverInitializedName |
| 2668 // | 2787 // |
| 2669 // CoverInitializedName | 2788 // CoverInitializedName |
| 2670 // IdentifierReference Initializer? | 2789 // IdentifierReference Initializer? |
| 2671 if (classifier->duplicate_finder() != nullptr && | 2790 if (classifier->duplicate_finder() != nullptr && |
| 2672 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 2791 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
| 2673 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 2792 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
| 2674 } | 2793 } |
| 2675 if (name_token == Token::LET) { | 2794 if (name_token == Token::LET) { |
| 2676 classifier->RecordLetPatternError( | 2795 classifier->RecordLetPatternError( |
| 2677 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 2796 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
| 2678 } | 2797 } |
| 2679 | 2798 |
| 2680 ExpressionT lhs = this->ExpressionFromIdentifier( | 2799 ExpressionT lhs = this->ExpressionFromIdentifier( |
| 2681 name, next_beg_pos, next_end_pos, scope_, factory()); | 2800 name, next_beg_pos, next_end_pos, scope_, factory()); |
| 2682 | 2801 |
| 2683 if (peek() == Token::ASSIGN) { | 2802 if (peek() == Token::ASSIGN) { |
| 2684 this->ExpressionUnexpectedToken(classifier); | |
| 2685 Consume(Token::ASSIGN); | 2803 Consume(Token::ASSIGN); |
| 2686 ExpressionClassifier rhs_classifier; | 2804 ExpressionClassifier rhs_classifier; |
| 2687 ExpressionT rhs = this->ParseAssignmentExpression( | 2805 ExpressionT rhs = this->ParseAssignmentExpression( |
| 2688 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2806 true, kIsRightHandSide, &rhs_classifier, |
| 2807 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2689 classifier->Accumulate(rhs_classifier, | 2808 classifier->Accumulate(rhs_classifier, |
| 2690 ExpressionClassifier::ExpressionProductions); | 2809 ExpressionClassifier::ExpressionProductions); |
| 2691 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2810 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
| 2692 RelocInfo::kNoPosition); | 2811 RelocInfo::kNoPosition); |
| 2812 classifier->RecordCoverInitializedNameError( |
| 2813 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2814 MessageTemplate::kInvalidCoverInitializedName); |
| 2693 } else { | 2815 } else { |
| 2694 value = lhs; | 2816 value = lhs; |
| 2695 } | 2817 } |
| 2696 | 2818 |
| 2697 return factory()->NewObjectLiteralProperty( | 2819 return factory()->NewObjectLiteralProperty( |
| 2698 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 2820 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
| 2699 false); | 2821 false); |
| 2700 } | 2822 } |
| 2701 } | 2823 } |
| 2702 | 2824 |
| 2825 // Method definitions are never valid in patterns. |
| 2826 classifier->RecordPatternError( |
| 2827 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2828 MessageTemplate::kInvalidDestructuringTarget); |
| 2829 |
| 2703 | 2830 |
| 2704 if (is_generator || peek() == Token::LPAREN) { | 2831 if (is_generator || peek() == Token::LPAREN) { |
| 2705 // MethodDefinition | 2832 // MethodDefinition |
| 2706 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2833 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2707 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2834 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2708 if (!*is_computed_name) { | 2835 if (!*is_computed_name) { |
| 2709 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2836 checker->CheckProperty(name_token, kMethodProperty, is_static, |
| 2710 is_generator, | 2837 is_generator, |
| 2711 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2838 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2712 } | 2839 } |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2918 // the parser and preparser | 3045 // the parser and preparser |
| 2919 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 3046 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2920 } | 3047 } |
| 2921 | 3048 |
| 2922 return result; | 3049 return result; |
| 2923 } | 3050 } |
| 2924 | 3051 |
| 2925 // Precedence = 2 | 3052 // Precedence = 2 |
| 2926 template <class Traits> | 3053 template <class Traits> |
| 2927 typename ParserBase<Traits>::ExpressionT | 3054 typename ParserBase<Traits>::ExpressionT |
| 2928 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 3055 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, |
| 3056 bool* seen_destructuring, |
| 2929 ExpressionClassifier* classifier, | 3057 ExpressionClassifier* classifier, |
| 2930 bool* ok) { | 3058 bool* ok) { |
| 2931 // AssignmentExpression :: | 3059 // AssignmentExpression :: |
| 2932 // ConditionalExpression | 3060 // ConditionalExpression |
| 2933 // ArrowFunction | 3061 // ArrowFunction |
| 2934 // YieldExpression | 3062 // YieldExpression |
| 2935 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 3063 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2936 | 3064 |
| 2937 int lhs_beg_pos = peek_position(); | 3065 int lhs_beg_pos = peek_position(); |
| 3066 bool is_rhs = flags & kIsRightHandSide; |
| 3067 bool is_pattern_element = flags & kIsPatternElement; |
| 3068 bool maybe_binding_pattern = flags & kMaybeBindingPattern; |
| 3069 USE(maybe_binding_pattern); |
| 3070 flags = |
| 3071 flags & ~(kIsPatternElement | kMaybeBindingPattern) | kIsRightHandSide; |
| 2938 | 3072 |
| 2939 if (peek() == Token::YIELD && is_generator()) { | 3073 if (peek() == Token::YIELD && is_generator()) { |
| 2940 return this->ParseYieldExpression(classifier, ok); | 3074 return this->ParseYieldExpression(classifier, ok); |
| 2941 } | 3075 } |
| 2942 | 3076 |
| 2943 if (fni_ != NULL) fni_->Enter(); | 3077 if (fni_ != NULL) fni_->Enter(); |
| 2944 ParserBase<Traits>::Checkpoint checkpoint(this); | 3078 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2945 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); | 3079 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); |
| 2946 bool parenthesized_formals = peek() == Token::LPAREN; | 3080 bool parenthesized_formals = peek() == Token::LPAREN; |
| 2947 if (!parenthesized_formals) { | 3081 if (!parenthesized_formals) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2968 | 3102 |
| 2969 checkpoint.Restore(¶meters.materialized_literals_count); | 3103 checkpoint.Restore(¶meters.materialized_literals_count); |
| 2970 | 3104 |
| 2971 scope->set_start_position(lhs_beg_pos); | 3105 scope->set_start_position(lhs_beg_pos); |
| 2972 if (duplicate_loc.IsValid()) { | 3106 if (duplicate_loc.IsValid()) { |
| 2973 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 3107 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
| 2974 duplicate_loc); | 3108 duplicate_loc); |
| 2975 } | 3109 } |
| 2976 expression = this->ParseArrowFunctionLiteral( | 3110 expression = this->ParseArrowFunctionLiteral( |
| 2977 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); | 3111 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); |
| 3112 if (is_pattern_element) { |
| 3113 classifier->RecordPatternError( |
| 3114 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), |
| 3115 MessageTemplate::kInvalidDestructuringTarget); |
| 3116 } |
| 2978 return expression; | 3117 return expression; |
| 2979 } | 3118 } |
| 2980 | 3119 |
| 2981 // "expression" was not itself an arrow function parameter list, but it might | 3120 // "expression" was not itself an arrow function parameter list, but it might |
| 2982 // form part of one. Propagate speculative formal parameter error locations. | 3121 // form part of one. Propagate speculative formal parameter error locations. |
| 2983 classifier->Accumulate(arrow_formals_classifier, | 3122 classifier->Accumulate( |
| 2984 ExpressionClassifier::StandardProductions | | 3123 arrow_formals_classifier, |
| 2985 ExpressionClassifier::FormalParametersProductions); | 3124 ExpressionClassifier::StandardProductions | |
| 3125 ExpressionClassifier::FormalParametersProductions | |
| 3126 ExpressionClassifier::CoverInitializedNameProduction); |
| 3127 |
| 3128 bool maybe_pattern = |
| 3129 expression->IsObjectLiteral() || expression->IsArrayLiteral(); |
| 2986 | 3130 |
| 2987 if (!Token::IsAssignmentOp(peek())) { | 3131 if (!Token::IsAssignmentOp(peek())) { |
| 2988 if (fni_ != NULL) fni_->Leave(); | 3132 if (fni_ != NULL) fni_->Leave(); |
| 2989 // Parsed conditional expression only (no assignment). | 3133 // Parsed conditional expression only (no assignment). |
| 3134 if (is_pattern_element && !this->IsValidReferenceExpression(expression) && |
| 3135 !maybe_pattern) { |
| 3136 classifier->RecordPatternError( |
| 3137 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), |
| 3138 MessageTemplate::kInvalidDestructuringTarget); |
| 3139 } else if (is_rhs && !is_pattern_element && maybe_pattern) { |
| 3140 ValidateExpression(classifier, CHECK_OK); |
| 3141 } |
| 3142 |
| 2990 return expression; | 3143 return expression; |
| 2991 } | 3144 } |
| 2992 | 3145 |
| 2993 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) { | 3146 if (!(allow_harmony_destructuring() || allow_harmony_default_parameters())) { |
| 2994 BindingPatternUnexpectedToken(classifier); | 3147 BindingPatternUnexpectedToken(classifier); |
| 2995 } | 3148 } |
| 2996 | 3149 |
| 2997 expression = this->CheckAndRewriteReferenceExpression( | 3150 bool maybe_destructuring_assignment = |
| 2998 expression, lhs_beg_pos, scanner()->location().end_pos, | 3151 allow_harmony_destructuring_assignment() && maybe_pattern && |
| 2999 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 3152 peek() == Token::ASSIGN; |
| 3153 bool maybe_destructuring_binding = allow_harmony_destructuring() && |
| 3154 maybe_pattern && !is_rhs && |
| 3155 peek() == Token::ASSIGN; |
| 3156 |
| 3157 if (maybe_destructuring_assignment) { |
| 3158 classifier->ForgiveCoverInitializedNameError(); |
| 3159 ValidateAssignmentPattern(classifier, CHECK_OK); |
| 3160 if (!is_pattern_element) *seen_destructuring = true; |
| 3161 } else if (!maybe_destructuring_binding) { |
| 3162 expression = this->CheckAndRewriteReferenceExpression( |
| 3163 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 3164 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
| 3165 } |
| 3000 expression = this->MarkExpressionAsAssigned(expression); | 3166 expression = this->MarkExpressionAsAssigned(expression); |
| 3001 | 3167 |
| 3002 Token::Value op = Next(); // Get assignment operator. | 3168 Token::Value op = Next(); // Get assignment operator. |
| 3003 if (op != Token::ASSIGN) { | 3169 if (op != Token::ASSIGN) { |
| 3004 classifier->RecordBindingPatternError(scanner()->location(), | 3170 classifier->RecordBindingPatternError(scanner()->location(), |
| 3005 MessageTemplate::kUnexpectedToken, | 3171 MessageTemplate::kUnexpectedToken, |
| 3006 Token::String(op)); | 3172 Token::String(op)); |
| 3007 } | 3173 } |
| 3008 int pos = position(); | 3174 int pos = position(); |
| 3009 | 3175 |
| 3010 ExpressionClassifier rhs_classifier; | 3176 ExpressionClassifier rhs_classifier; |
| 3011 ExpressionT right = | 3177 ExpressionT right = this->ParseAssignmentExpression( |
| 3012 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 3178 accept_IN, flags, seen_destructuring, &rhs_classifier, CHECK_OK); |
| 3013 classifier->Accumulate(rhs_classifier, | 3179 classifier->Accumulate( |
| 3014 ExpressionClassifier::ExpressionProductions); | 3180 rhs_classifier, ExpressionClassifier::ExpressionProductions | |
| 3181 ExpressionClassifier::CoverInitializedNameProduction); |
| 3015 | 3182 |
| 3016 // TODO(1231235): We try to estimate the set of properties set by | 3183 // TODO(1231235): We try to estimate the set of properties set by |
| 3017 // constructors. We define a new property whenever there is an | 3184 // constructors. We define a new property whenever there is an |
| 3018 // assignment to a property of 'this'. We should probably only add | 3185 // assignment to a property of 'this'. We should probably only add |
| 3019 // properties if we haven't seen them before. Otherwise we'll | 3186 // properties if we haven't seen them before. Otherwise we'll |
| 3020 // probably overestimate the number of properties. | 3187 // probably overestimate the number of properties. |
| 3021 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 3188 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
| 3022 function_state_->AddProperty(); | 3189 function_state_->AddProperty(); |
| 3023 } | 3190 } |
| 3024 | 3191 |
| 3025 this->CheckAssigningFunctionLiteralToProperty(expression, right); | 3192 this->CheckAssigningFunctionLiteralToProperty(expression, right); |
| 3026 | 3193 |
| 3027 if (fni_ != NULL) { | 3194 if (fni_ != NULL) { |
| 3028 // Check if the right hand side is a call to avoid inferring a | 3195 // Check if the right hand side is a call to avoid inferring a |
| 3029 // name if we're dealing with "a = function(){...}();"-like | 3196 // name if we're dealing with "a = function(){...}();"-like |
| 3030 // expression. | 3197 // expression. |
| 3031 if ((op == Token::INIT_VAR | 3198 if ((op == Token::INIT_VAR |
| 3032 || op == Token::INIT_CONST_LEGACY | 3199 || op == Token::INIT_CONST_LEGACY |
| 3033 || op == Token::ASSIGN) | 3200 || op == Token::ASSIGN) |
| 3034 && (!right->IsCall() && !right->IsCallNew())) { | 3201 && (!right->IsCall() && !right->IsCallNew())) { |
| 3035 fni_->Infer(); | 3202 fni_->Infer(); |
| 3036 } else { | 3203 } else { |
| 3037 fni_->RemoveLastFunction(); | 3204 fni_->RemoveLastFunction(); |
| 3038 } | 3205 } |
| 3039 fni_->Leave(); | 3206 fni_->Leave(); |
| 3040 } | 3207 } |
| 3041 | 3208 |
| 3042 return factory()->NewAssignment(op, expression, right, pos); | 3209 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
| 3210 |
| 3211 if (!is_rhs && *seen_destructuring && !maybe_binding_pattern && |
| 3212 !is_pattern_element) { |
| 3213 return Traits::RewriteDestructuringAssignmentExpression(result); |
| 3214 } |
| 3215 |
| 3216 return result; |
| 3043 } | 3217 } |
| 3044 | 3218 |
| 3045 template <class Traits> | 3219 template <class Traits> |
| 3046 typename ParserBase<Traits>::ExpressionT | 3220 typename ParserBase<Traits>::ExpressionT |
| 3047 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 3221 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
| 3048 bool* ok) { | 3222 bool* ok) { |
| 3049 // YieldExpression :: | 3223 // YieldExpression :: |
| 3050 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 3224 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| 3051 int pos = peek_position(); | 3225 int pos = peek_position(); |
| 3052 BindingPatternUnexpectedToken(classifier); | 3226 BindingPatternUnexpectedToken(classifier); |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4153 ExpressionT error = this->NewThrowReferenceError(message, pos); | 4327 ExpressionT error = this->NewThrowReferenceError(message, pos); |
| 4154 return factory()->NewProperty(expression, error, pos); | 4328 return factory()->NewProperty(expression, error, pos); |
| 4155 } else { | 4329 } else { |
| 4156 this->ReportMessageAt(location, message, type); | 4330 this->ReportMessageAt(location, message, type); |
| 4157 *ok = false; | 4331 *ok = false; |
| 4158 return this->EmptyExpression(); | 4332 return this->EmptyExpression(); |
| 4159 } | 4333 } |
| 4160 } | 4334 } |
| 4161 | 4335 |
| 4162 | 4336 |
| 4337 template <typename Traits> |
| 4338 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { |
| 4339 // TODO(caitp): do this in a less redundant way :( |
| 4340 if (expression->IsValidReferenceExpression()) { |
| 4341 if (this->IsIdentifier(expression)) { |
| 4342 if (is_strict(language_mode()) && |
| 4343 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
| 4344 return false; |
| 4345 } |
| 4346 if (is_strong(language_mode()) && |
| 4347 this->IsUndefined(this->AsIdentifier(expression))) { |
| 4348 return false; |
| 4349 } |
| 4350 } |
| 4351 return true; |
| 4352 } |
| 4353 return false; |
| 4354 } |
| 4355 |
| 4356 |
| 4163 #undef CHECK_OK | 4357 #undef CHECK_OK |
| 4164 #undef CHECK_OK_CUSTOM | 4358 #undef CHECK_OK_CUSTOM |
| 4165 | 4359 |
| 4166 | 4360 |
| 4167 template <typename Traits> | 4361 template <typename Traits> |
| 4168 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 4362 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
| 4169 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 4363 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
| 4170 bool* ok) { | 4364 bool* ok) { |
| 4171 DCHECK(!is_static); | 4365 DCHECK(!is_static); |
| 4172 DCHECK(!is_generator || type == kMethodProperty); | 4366 DCHECK(!is_generator || type == kMethodProperty); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4214 return; | 4408 return; |
| 4215 } | 4409 } |
| 4216 has_seen_constructor_ = true; | 4410 has_seen_constructor_ = true; |
| 4217 return; | 4411 return; |
| 4218 } | 4412 } |
| 4219 } | 4413 } |
| 4220 } // namespace internal | 4414 } // namespace internal |
| 4221 } // namespace v8 | 4415 } // namespace v8 |
| 4222 | 4416 |
| 4223 #endif // V8_PREPARSER_H | 4417 #endif // V8_PREPARSER_H |
| OLD | NEW |