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/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 zone_(zone), | 83 zone_(zone), |
84 scanner_(scanner), | 84 scanner_(scanner), |
85 stack_overflow_(false), | 85 stack_overflow_(false), |
86 allow_lazy_(false), | 86 allow_lazy_(false), |
87 allow_natives_(false), | 87 allow_natives_(false), |
88 allow_harmony_arrow_functions_(false), | 88 allow_harmony_arrow_functions_(false), |
89 allow_harmony_object_literals_(false), | 89 allow_harmony_object_literals_(false), |
90 allow_harmony_sloppy_(false), | 90 allow_harmony_sloppy_(false), |
91 allow_harmony_computed_property_names_(false), | 91 allow_harmony_computed_property_names_(false), |
92 allow_harmony_rest_params_(false), | 92 allow_harmony_rest_params_(false), |
| 93 allow_harmony_spreadcalls_(false), |
93 allow_strong_mode_(false) {} | 94 allow_strong_mode_(false) {} |
94 | 95 |
95 // Getters that indicate whether certain syntactical constructs are | 96 // Getters that indicate whether certain syntactical constructs are |
96 // allowed to be parsed by this instance of the parser. | 97 // allowed to be parsed by this instance of the parser. |
97 bool allow_lazy() const { return allow_lazy_; } | 98 bool allow_lazy() const { return allow_lazy_; } |
98 bool allow_natives() const { return allow_natives_; } | 99 bool allow_natives() const { return allow_natives_; } |
99 bool allow_harmony_arrow_functions() const { | 100 bool allow_harmony_arrow_functions() const { |
100 return allow_harmony_arrow_functions_; | 101 return allow_harmony_arrow_functions_; |
101 } | 102 } |
102 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } | 103 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } |
103 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } | 104 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } |
104 bool allow_harmony_object_literals() const { | 105 bool allow_harmony_object_literals() const { |
105 return allow_harmony_object_literals_; | 106 return allow_harmony_object_literals_; |
106 } | 107 } |
107 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 108 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
108 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 109 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
109 bool allow_harmony_computed_property_names() const { | 110 bool allow_harmony_computed_property_names() const { |
110 return allow_harmony_computed_property_names_; | 111 return allow_harmony_computed_property_names_; |
111 } | 112 } |
112 bool allow_harmony_rest_params() const { | 113 bool allow_harmony_rest_params() const { |
113 return allow_harmony_rest_params_; | 114 return allow_harmony_rest_params_; |
114 } | 115 } |
| 116 bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; } |
115 | 117 |
116 bool allow_strong_mode() const { return allow_strong_mode_; } | 118 bool allow_strong_mode() const { return allow_strong_mode_; } |
117 | 119 |
118 // Setters that determine whether certain syntactical constructs are | 120 // Setters that determine whether certain syntactical constructs are |
119 // allowed to be parsed by this instance of the parser. | 121 // allowed to be parsed by this instance of the parser. |
120 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 122 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
121 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 123 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
122 void set_allow_harmony_arrow_functions(bool allow) { | 124 void set_allow_harmony_arrow_functions(bool allow) { |
123 allow_harmony_arrow_functions_ = allow; | 125 allow_harmony_arrow_functions_ = allow; |
124 } | 126 } |
(...skipping 11 matching lines...) Expand all Loading... |
136 } | 138 } |
137 void set_allow_harmony_unicode(bool allow) { | 139 void set_allow_harmony_unicode(bool allow) { |
138 scanner()->SetHarmonyUnicode(allow); | 140 scanner()->SetHarmonyUnicode(allow); |
139 } | 141 } |
140 void set_allow_harmony_computed_property_names(bool allow) { | 142 void set_allow_harmony_computed_property_names(bool allow) { |
141 allow_harmony_computed_property_names_ = allow; | 143 allow_harmony_computed_property_names_ = allow; |
142 } | 144 } |
143 void set_allow_harmony_rest_params(bool allow) { | 145 void set_allow_harmony_rest_params(bool allow) { |
144 allow_harmony_rest_params_ = allow; | 146 allow_harmony_rest_params_ = allow; |
145 } | 147 } |
| 148 void set_allow_harmony_spreadcalls(bool allow) { |
| 149 allow_harmony_spreadcalls_ = allow; |
| 150 } |
146 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 151 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
147 | 152 |
148 protected: | 153 protected: |
149 enum AllowEvalOrArgumentsAsIdentifier { | 154 enum AllowEvalOrArgumentsAsIdentifier { |
150 kAllowEvalOrArguments, | 155 kAllowEvalOrArguments, |
151 kDontAllowEvalOrArguments | 156 kDontAllowEvalOrArguments |
152 }; | 157 }; |
153 | 158 |
154 enum Mode { | 159 enum Mode { |
155 PARSE_LAZILY, | 160 PARSE_LAZILY, |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 575 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
571 ExpressionT ParseArrayLiteral(bool* ok); | 576 ExpressionT ParseArrayLiteral(bool* ok); |
572 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 577 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
573 bool* is_static, bool* is_computed_name, | 578 bool* is_static, bool* is_computed_name, |
574 bool* ok); | 579 bool* ok); |
575 ExpressionT ParseObjectLiteral(bool* ok); | 580 ExpressionT ParseObjectLiteral(bool* ok); |
576 ObjectLiteralPropertyT ParsePropertyDefinition( | 581 ObjectLiteralPropertyT ParsePropertyDefinition( |
577 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 582 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
578 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 583 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
579 bool* ok); | 584 bool* ok); |
580 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 585 typename Traits::Type::ExpressionList ParseArguments( |
| 586 Scanner::Location* first_spread_pos, bool* ok); |
581 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 587 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
582 ExpressionT ParseYieldExpression(bool* ok); | 588 ExpressionT ParseYieldExpression(bool* ok); |
583 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 589 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
584 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 590 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
585 ExpressionT ParseUnaryExpression(bool* ok); | 591 ExpressionT ParseUnaryExpression(bool* ok); |
586 ExpressionT ParsePostfixExpression(bool* ok); | 592 ExpressionT ParsePostfixExpression(bool* ok); |
587 ExpressionT ParseLeftHandSideExpression(bool* ok); | 593 ExpressionT ParseLeftHandSideExpression(bool* ok); |
588 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 594 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
589 ExpressionT ParseMemberExpression(bool* ok); | 595 ExpressionT ParseMemberExpression(bool* ok); |
590 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 596 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 Scanner* scanner_; | 688 Scanner* scanner_; |
683 bool stack_overflow_; | 689 bool stack_overflow_; |
684 | 690 |
685 bool allow_lazy_; | 691 bool allow_lazy_; |
686 bool allow_natives_; | 692 bool allow_natives_; |
687 bool allow_harmony_arrow_functions_; | 693 bool allow_harmony_arrow_functions_; |
688 bool allow_harmony_object_literals_; | 694 bool allow_harmony_object_literals_; |
689 bool allow_harmony_sloppy_; | 695 bool allow_harmony_sloppy_; |
690 bool allow_harmony_computed_property_names_; | 696 bool allow_harmony_computed_property_names_; |
691 bool allow_harmony_rest_params_; | 697 bool allow_harmony_rest_params_; |
| 698 bool allow_harmony_spreadcalls_; |
692 bool allow_strong_mode_; | 699 bool allow_strong_mode_; |
693 }; | 700 }; |
694 | 701 |
695 | 702 |
696 class PreParserIdentifier { | 703 class PreParserIdentifier { |
697 public: | 704 public: |
698 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 705 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
699 static PreParserIdentifier Default() { | 706 static PreParserIdentifier Default() { |
700 return PreParserIdentifier(kUnknownIdentifier); | 707 return PreParserIdentifier(kUnknownIdentifier); |
701 } | 708 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 friend class PreParserExpression; | 781 friend class PreParserExpression; |
775 }; | 782 }; |
776 | 783 |
777 | 784 |
778 class PreParserExpression { | 785 class PreParserExpression { |
779 public: | 786 public: |
780 static PreParserExpression Default() { | 787 static PreParserExpression Default() { |
781 return PreParserExpression(TypeField::encode(kExpression)); | 788 return PreParserExpression(TypeField::encode(kExpression)); |
782 } | 789 } |
783 | 790 |
| 791 static PreParserExpression Spread(PreParserExpression expression) { |
| 792 return PreParserExpression(TypeField::encode(kSpreadExpression)); |
| 793 } |
| 794 |
784 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 795 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
785 return PreParserExpression(TypeField::encode(kIdentifierExpression) | | 796 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
786 IdentifierTypeField::encode(id.type_)); | 797 IdentifierTypeField::encode(id.type_)); |
787 } | 798 } |
788 | 799 |
789 static PreParserExpression BinaryOperation(PreParserExpression left, | 800 static PreParserExpression BinaryOperation(PreParserExpression left, |
790 Token::Value op, | 801 Token::Value op, |
791 PreParserExpression right) { | 802 PreParserExpression right) { |
792 bool valid_arrow_param_list = | 803 bool valid_arrow_param_list = |
793 op == Token::COMMA && !left.is_parenthesized() && | 804 op == Token::COMMA && !left.is_parenthesized() && |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 | 913 |
903 // At the moment PreParser doesn't track these expression types. | 914 // At the moment PreParser doesn't track these expression types. |
904 bool IsFunctionLiteral() const { return false; } | 915 bool IsFunctionLiteral() const { return false; } |
905 bool IsCallNew() const { return false; } | 916 bool IsCallNew() const { return false; } |
906 | 917 |
907 bool IsNoTemplateTag() const { | 918 bool IsNoTemplateTag() const { |
908 return TypeField::decode(code_) == kExpression && | 919 return TypeField::decode(code_) == kExpression && |
909 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 920 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
910 } | 921 } |
911 | 922 |
| 923 bool IsSpreadExpression() const { |
| 924 return TypeField::decode(code_) == kSpreadExpression; |
| 925 } |
| 926 |
912 PreParserExpression AsFunctionLiteral() { return *this; } | 927 PreParserExpression AsFunctionLiteral() { return *this; } |
913 | 928 |
914 bool IsBinaryOperation() const { | 929 bool IsBinaryOperation() const { |
915 return TypeField::decode(code_) == kBinaryOperationExpression; | 930 return TypeField::decode(code_) == kBinaryOperationExpression; |
916 } | 931 } |
917 | 932 |
918 bool is_parenthesized() const { | 933 bool is_parenthesized() const { |
919 return ParenthesizationField::decode(code_) != kNotParenthesized; | 934 return ParenthesizationField::decode(code_) != kNotParenthesized; |
920 } | 935 } |
921 | 936 |
(...skipping 12 matching lines...) Expand all Loading... |
934 void set_parenthesized() {} | 949 void set_parenthesized() {} |
935 | 950 |
936 int position() const { return RelocInfo::kNoPosition; } | 951 int position() const { return RelocInfo::kNoPosition; } |
937 void set_function_token_position(int position) {} | 952 void set_function_token_position(int position) {} |
938 | 953 |
939 private: | 954 private: |
940 enum Type { | 955 enum Type { |
941 kExpression, | 956 kExpression, |
942 kIdentifierExpression, | 957 kIdentifierExpression, |
943 kStringLiteralExpression, | 958 kStringLiteralExpression, |
944 kBinaryOperationExpression | 959 kBinaryOperationExpression, |
| 960 kSpreadExpression |
945 }; | 961 }; |
946 | 962 |
947 enum Parenthesization { | 963 enum Parenthesization { |
948 kNotParenthesized, | 964 kNotParenthesized, |
949 kParanthesizedExpression, | 965 kParanthesizedExpression, |
950 kMultiParenthesizedExpression | 966 kMultiParenthesizedExpression |
951 }; | 967 }; |
952 | 968 |
953 enum ExpressionType { | 969 enum ExpressionType { |
954 kThisExpression, | 970 kThisExpression, |
955 kThisPropertyExpression, | 971 kThisPropertyExpression, |
956 kPropertyExpression, | 972 kPropertyExpression, |
957 kCallExpression, | 973 kCallExpression, |
958 kNoTemplateTagExpression | 974 kNoTemplateTagExpression |
959 }; | 975 }; |
960 | 976 |
961 explicit PreParserExpression(uint32_t expression_code) | 977 explicit PreParserExpression(uint32_t expression_code) |
962 : code_(expression_code) {} | 978 : code_(expression_code) {} |
963 | 979 |
964 V8_INLINE bool IsValidArrowParams() const { | 980 V8_INLINE bool IsValidArrowParams() const { |
965 return IsBinaryOperation() | 981 return IsBinaryOperation() |
966 ? IsValidArrowParamListField::decode(code_) | 982 ? IsValidArrowParamListField::decode(code_) |
967 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 983 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); |
968 } | 984 } |
969 | 985 |
970 // The first four bits are for the Type and Parenthesization. | 986 // The first five bits are for the Type and Parenthesization. |
971 typedef BitField<Type, 0, 2> TypeField; | 987 typedef BitField<Type, 0, 3> TypeField; |
972 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 988 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
973 | 989 |
974 // The rest of the bits are interpreted depending on the value | 990 // The rest of the bits are interpreted depending on the value |
975 // of the Type field, so they can share the storage. | 991 // of the Type field, so they can share the storage. |
976 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 992 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
977 ExpressionTypeField; | 993 ExpressionTypeField; |
978 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 994 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
979 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 995 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
980 typedef BitField<bool, ParenthesizationField::kNext, 1> | 996 typedef BitField<bool, ParenthesizationField::kNext, 1> |
981 IsValidArrowParamListField; | 997 IsValidArrowParamListField; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 PreParserExpression NewCall(PreParserExpression expression, | 1178 PreParserExpression NewCall(PreParserExpression expression, |
1163 PreParserExpressionList arguments, | 1179 PreParserExpressionList arguments, |
1164 int pos) { | 1180 int pos) { |
1165 return PreParserExpression::Call(); | 1181 return PreParserExpression::Call(); |
1166 } | 1182 } |
1167 PreParserExpression NewCallNew(PreParserExpression expression, | 1183 PreParserExpression NewCallNew(PreParserExpression expression, |
1168 PreParserExpressionList arguments, | 1184 PreParserExpressionList arguments, |
1169 int pos) { | 1185 int pos) { |
1170 return PreParserExpression::Default(); | 1186 return PreParserExpression::Default(); |
1171 } | 1187 } |
| 1188 PreParserExpression NewCallRuntime(const AstRawString* name, |
| 1189 const Runtime::Function* function, |
| 1190 PreParserExpressionList arguments, |
| 1191 int pos) { |
| 1192 return PreParserExpression::Default(); |
| 1193 } |
1172 PreParserStatement NewReturnStatement(PreParserExpression expression, | 1194 PreParserStatement NewReturnStatement(PreParserExpression expression, |
1173 int pos) { | 1195 int pos) { |
1174 return PreParserStatement::Default(); | 1196 return PreParserStatement::Default(); |
1175 } | 1197 } |
1176 PreParserExpression NewFunctionLiteral( | 1198 PreParserExpression NewFunctionLiteral( |
1177 PreParserIdentifier name, AstValueFactory* ast_value_factory, | 1199 PreParserIdentifier name, AstValueFactory* ast_value_factory, |
1178 Scope* scope, PreParserStatementList body, int materialized_literal_count, | 1200 Scope* scope, PreParserStatementList body, int materialized_literal_count, |
1179 int expected_property_count, int handler_count, int parameter_count, | 1201 int expected_property_count, int handler_count, int parameter_count, |
1180 FunctionLiteral::ParameterFlag has_duplicate_parameters, | 1202 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
1181 FunctionLiteral::FunctionType function_type, | 1203 FunctionLiteral::FunctionType function_type, |
1182 FunctionLiteral::IsFunctionFlag is_function, | 1204 FunctionLiteral::IsFunctionFlag is_function, |
1183 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, | 1205 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, |
1184 int position) { | 1206 int position) { |
1185 return PreParserExpression::Default(); | 1207 return PreParserExpression::Default(); |
1186 } | 1208 } |
1187 | 1209 |
| 1210 PreParserExpression NewSpread(PreParserExpression expression, int pos) { |
| 1211 return PreParserExpression::Spread(expression); |
| 1212 } |
| 1213 |
1188 // Return the object itself as AstVisitor and implement the needed | 1214 // Return the object itself as AstVisitor and implement the needed |
1189 // dummy method right in this class. | 1215 // dummy method right in this class. |
1190 PreParserFactory* visitor() { return this; } | 1216 PreParserFactory* visitor() { return this; } |
1191 int* ast_properties() { | 1217 int* ast_properties() { |
1192 static int dummy = 42; | 1218 static int dummy = 42; |
1193 return &dummy; | 1219 return &dummy; |
1194 } | 1220 } |
1195 }; | 1221 }; |
1196 | 1222 |
1197 | 1223 |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1490 PreParserIdentifier name, Scanner::Location function_name_location, | 1516 PreParserIdentifier name, Scanner::Location function_name_location, |
1491 bool name_is_strict_reserved, FunctionKind kind, | 1517 bool name_is_strict_reserved, FunctionKind kind, |
1492 int function_token_position, FunctionLiteral::FunctionType type, | 1518 int function_token_position, FunctionLiteral::FunctionType type, |
1493 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1519 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1494 | 1520 |
1495 PreParserExpression ParseClassLiteral(PreParserIdentifier name, | 1521 PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
1496 Scanner::Location class_name_location, | 1522 Scanner::Location class_name_location, |
1497 bool name_is_strict_reserved, int pos, | 1523 bool name_is_strict_reserved, int pos, |
1498 bool* ok); | 1524 bool* ok); |
1499 | 1525 |
| 1526 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) { |
| 1527 return list; |
| 1528 } |
| 1529 |
| 1530 inline void MaterializeUnspreadArgumentsLiterals(int count); |
| 1531 |
| 1532 inline PreParserExpression SpreadCall(PreParserExpression function, |
| 1533 PreParserExpressionList args, int pos); |
| 1534 |
| 1535 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
| 1536 PreParserExpressionList args, |
| 1537 int pos); |
| 1538 |
1500 private: | 1539 private: |
1501 PreParser* pre_parser_; | 1540 PreParser* pre_parser_; |
1502 }; | 1541 }; |
1503 | 1542 |
1504 | 1543 |
1505 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1544 // Preparsing checks a JavaScript program and emits preparse-data that helps |
1506 // a later parsing to be faster. | 1545 // a later parsing to be faster. |
1507 // See preparse-data-format.h for the data format. | 1546 // See preparse-data-format.h for the data format. |
1508 | 1547 |
1509 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1548 // The PreParser checks that the syntax follows the grammar for JavaScript, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1629 bool* ok); | 1668 bool* ok); |
1630 }; | 1669 }; |
1631 | 1670 |
1632 | 1671 |
1633 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { | 1672 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { |
1634 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1673 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
1635 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1674 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
1636 } | 1675 } |
1637 | 1676 |
1638 | 1677 |
| 1678 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { |
| 1679 for (int i = 0; i < count; ++i) { |
| 1680 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
| 1681 } |
| 1682 } |
| 1683 |
| 1684 |
| 1685 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, |
| 1686 PreParserExpressionList args, |
| 1687 int pos) { |
| 1688 return pre_parser_->factory()->NewCall(function, args, pos); |
| 1689 } |
| 1690 |
| 1691 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
| 1692 PreParserExpressionList args, |
| 1693 int pos) { |
| 1694 return pre_parser_->factory()->NewCallNew(function, args, pos); |
| 1695 } |
| 1696 |
| 1697 |
1639 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1698 PreParserStatementList PreParser::ParseEagerFunctionBody( |
1640 PreParserIdentifier function_name, int pos, Variable* fvar, | 1699 PreParserIdentifier function_name, int pos, Variable* fvar, |
1641 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1700 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
1642 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1701 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1643 | 1702 |
1644 ParseStatementList(Token::RBRACE, ok); | 1703 ParseStatementList(Token::RBRACE, ok); |
1645 if (!*ok) return PreParserStatementList(); | 1704 if (!*ok) return PreParserStatementList(); |
1646 | 1705 |
1647 Expect(Token::RBRACE, ok); | 1706 Expect(Token::RBRACE, ok); |
1648 return PreParserStatementList(); | 1707 return PreParserStatementList(); |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2298 return factory()->NewObjectLiteral(properties, | 2357 return factory()->NewObjectLiteral(properties, |
2299 literal_index, | 2358 literal_index, |
2300 number_of_boilerplate_properties, | 2359 number_of_boilerplate_properties, |
2301 has_function, | 2360 has_function, |
2302 pos); | 2361 pos); |
2303 } | 2362 } |
2304 | 2363 |
2305 | 2364 |
2306 template <class Traits> | 2365 template <class Traits> |
2307 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2366 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
2308 bool* ok) { | 2367 Scanner::Location* first_spread_arg_loc, bool* ok) { |
2309 // Arguments :: | 2368 // Arguments :: |
2310 // '(' (AssignmentExpression)*[','] ')' | 2369 // '(' (AssignmentExpression)*[','] ')' |
2311 | 2370 |
| 2371 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2312 typename Traits::Type::ExpressionList result = | 2372 typename Traits::Type::ExpressionList result = |
2313 this->NewExpressionList(4, zone_); | 2373 this->NewExpressionList(4, zone_); |
2314 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2374 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2315 bool done = (peek() == Token::RPAREN); | 2375 bool done = (peek() == Token::RPAREN); |
| 2376 bool was_unspread = false; |
| 2377 int unspread_sequences_count = 0; |
2316 while (!done) { | 2378 while (!done) { |
| 2379 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); |
| 2380 int start_pos = peek_position(); |
| 2381 if (is_spread) Consume(Token::ELLIPSIS); |
| 2382 |
2317 ExpressionT argument = this->ParseAssignmentExpression( | 2383 ExpressionT argument = this->ParseAssignmentExpression( |
2318 true, CHECK_OK_CUSTOM(NullExpressionList)); | 2384 true, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2385 if (is_spread) { |
| 2386 if (!spread_arg.IsValid()) { |
| 2387 spread_arg.beg_pos = start_pos; |
| 2388 spread_arg.end_pos = peek_position(); |
| 2389 } |
| 2390 argument = factory()->NewSpread(argument, start_pos); |
| 2391 } |
2319 result->Add(argument, zone_); | 2392 result->Add(argument, zone_); |
| 2393 |
| 2394 // unspread_sequences_count is the number of sequences of parameters which |
| 2395 // are not prefixed with a spread '...' operator. |
| 2396 if (is_spread) { |
| 2397 was_unspread = false; |
| 2398 } else if (!was_unspread) { |
| 2399 was_unspread = true; |
| 2400 unspread_sequences_count++; |
| 2401 } |
| 2402 |
2320 if (result->length() > Code::kMaxArguments) { | 2403 if (result->length() > Code::kMaxArguments) { |
2321 ReportMessage("too_many_arguments"); | 2404 ReportMessage("too_many_arguments"); |
2322 *ok = false; | 2405 *ok = false; |
2323 return this->NullExpressionList(); | 2406 return this->NullExpressionList(); |
2324 } | 2407 } |
2325 done = (peek() != Token::COMMA); | 2408 done = (peek() != Token::COMMA); |
2326 if (!done) { | 2409 if (!done) { |
2327 Next(); | 2410 Next(); |
2328 } | 2411 } |
2329 } | 2412 } |
2330 Scanner::Location location = scanner_->location(); | 2413 Scanner::Location location = scanner_->location(); |
2331 if (Token::RPAREN != Next()) { | 2414 if (Token::RPAREN != Next()) { |
2332 ReportMessageAt(location, "unterminated_arg_list"); | 2415 ReportMessageAt(location, "unterminated_arg_list"); |
2333 *ok = false; | 2416 *ok = false; |
2334 return this->NullExpressionList(); | 2417 return this->NullExpressionList(); |
2335 } | 2418 } |
| 2419 *first_spread_arg_loc = spread_arg; |
| 2420 |
| 2421 if (spread_arg.IsValid()) { |
| 2422 // Unspread parameter sequences are translated into array literals in the |
| 2423 // parser. Ensure that the number of materialized literals matches between |
| 2424 // the parser and preparser |
| 2425 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2426 } |
| 2427 |
2336 return result; | 2428 return result; |
2337 } | 2429 } |
2338 | 2430 |
2339 // Precedence = 2 | 2431 // Precedence = 2 |
2340 template <class Traits> | 2432 template <class Traits> |
2341 typename ParserBase<Traits>::ExpressionT | 2433 typename ParserBase<Traits>::ExpressionT |
2342 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2434 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
2343 // AssignmentExpression :: | 2435 // AssignmentExpression :: |
2344 // ConditionalExpression | 2436 // ConditionalExpression |
2345 // ArrowFunction | 2437 // ArrowFunction |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2640 // should not point to the closing brace otherwise it will intersect | 2732 // should not point to the closing brace otherwise it will intersect |
2641 // with positions recorded for function literal and confuse debugger. | 2733 // with positions recorded for function literal and confuse debugger. |
2642 pos = peek_position(); | 2734 pos = peek_position(); |
2643 // Also the trailing parenthesis are a hint that the function will | 2735 // Also the trailing parenthesis are a hint that the function will |
2644 // be called immediately. If we happen to have parsed a preceding | 2736 // be called immediately. If we happen to have parsed a preceding |
2645 // function literal eagerly, we can also compile it eagerly. | 2737 // function literal eagerly, we can also compile it eagerly. |
2646 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2738 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2647 result->AsFunctionLiteral()->set_parenthesized(); | 2739 result->AsFunctionLiteral()->set_parenthesized(); |
2648 } | 2740 } |
2649 } | 2741 } |
2650 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); | 2742 Scanner::Location spread_pos; |
| 2743 typename Traits::Type::ExpressionList args = |
| 2744 ParseArguments(&spread_pos, CHECK_OK); |
2651 | 2745 |
2652 // Keep track of eval() calls since they disable all local variable | 2746 // Keep track of eval() calls since they disable all local variable |
2653 // optimizations. | 2747 // optimizations. |
2654 // The calls that need special treatment are the | 2748 // The calls that need special treatment are the |
2655 // direct eval calls. These calls are all of the form eval(...), with | 2749 // direct eval calls. These calls are all of the form eval(...), with |
2656 // no explicit receiver. | 2750 // no explicit receiver. |
2657 // These calls are marked as potentially direct eval calls. Whether | 2751 // These calls are marked as potentially direct eval calls. Whether |
2658 // they are actually direct calls to eval is determined at run time. | 2752 // they are actually direct calls to eval is determined at run time. |
2659 this->CheckPossibleEvalCall(result, scope_); | 2753 this->CheckPossibleEvalCall(result, scope_); |
2660 result = factory()->NewCall(result, args, pos); | 2754 |
| 2755 if (spread_pos.IsValid()) { |
| 2756 args = Traits::PrepareSpreadArguments(args); |
| 2757 result = Traits::SpreadCall(result, args, pos); |
| 2758 } else { |
| 2759 result = factory()->NewCall(result, args, pos); |
| 2760 } |
2661 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2761 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2662 break; | 2762 break; |
2663 } | 2763 } |
2664 | 2764 |
2665 case Token::PERIOD: { | 2765 case Token::PERIOD: { |
2666 Consume(Token::PERIOD); | 2766 Consume(Token::PERIOD); |
2667 int pos = position(); | 2767 int pos = position(); |
2668 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2768 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2669 result = factory()->NewProperty( | 2769 result = factory()->NewProperty( |
2670 result, factory()->NewStringLiteral(name, pos), pos); | 2770 result, factory()->NewStringLiteral(name, pos), pos); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2704 int new_pos = position(); | 2804 int new_pos = position(); |
2705 ExpressionT result = this->EmptyExpression(); | 2805 ExpressionT result = this->EmptyExpression(); |
2706 if (peek() == Token::SUPER) { | 2806 if (peek() == Token::SUPER) { |
2707 const bool is_new = true; | 2807 const bool is_new = true; |
2708 result = ParseSuperExpression(is_new, CHECK_OK); | 2808 result = ParseSuperExpression(is_new, CHECK_OK); |
2709 } else { | 2809 } else { |
2710 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2810 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
2711 } | 2811 } |
2712 if (peek() == Token::LPAREN) { | 2812 if (peek() == Token::LPAREN) { |
2713 // NewExpression with arguments. | 2813 // NewExpression with arguments. |
| 2814 Scanner::Location spread_pos; |
2714 typename Traits::Type::ExpressionList args = | 2815 typename Traits::Type::ExpressionList args = |
2715 this->ParseArguments(CHECK_OK); | 2816 this->ParseArguments(&spread_pos, CHECK_OK); |
2716 result = factory()->NewCallNew(result, args, new_pos); | 2817 |
| 2818 if (spread_pos.IsValid()) { |
| 2819 args = Traits::PrepareSpreadArguments(args); |
| 2820 result = Traits::SpreadCallNew(result, args, new_pos); |
| 2821 } else { |
| 2822 result = factory()->NewCallNew(result, args, new_pos); |
| 2823 } |
2717 // The expression can still continue with . or [ after the arguments. | 2824 // The expression can still continue with . or [ after the arguments. |
2718 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2825 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
2719 return result; | 2826 return result; |
2720 } | 2827 } |
2721 // NewExpression without arguments. | 2828 // NewExpression without arguments. |
2722 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2829 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
2723 new_pos); | 2830 new_pos); |
2724 } | 2831 } |
2725 // No 'new' or 'super' keyword. | 2832 // No 'new' or 'super' keyword. |
2726 return this->ParseMemberExpression(ok); | 2833 return this->ParseMemberExpression(ok); |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3157 *ok = false; | 3264 *ok = false; |
3158 return; | 3265 return; |
3159 } | 3266 } |
3160 has_seen_constructor_ = true; | 3267 has_seen_constructor_ = true; |
3161 return; | 3268 return; |
3162 } | 3269 } |
3163 } | 3270 } |
3164 } } // v8::internal | 3271 } } // v8::internal |
3165 | 3272 |
3166 #endif // V8_PREPARSER_H | 3273 #endif // V8_PREPARSER_H |
OLD | NEW |