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_scoping() const { return scanner()->HarmonyScoping(); } | 104 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
104 bool allow_harmony_numeric_literals() const { | 105 bool allow_harmony_numeric_literals() const { |
105 return scanner()->HarmonyNumericLiterals(); | 106 return scanner()->HarmonyNumericLiterals(); |
106 } | 107 } |
107 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } | 108 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } |
108 bool allow_harmony_object_literals() const { | 109 bool allow_harmony_object_literals() const { |
109 return allow_harmony_object_literals_; | 110 return allow_harmony_object_literals_; |
110 } | 111 } |
111 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } | 112 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } |
112 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 113 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
113 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 114 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
114 bool allow_harmony_computed_property_names() const { | 115 bool allow_harmony_computed_property_names() const { |
115 return allow_harmony_computed_property_names_; | 116 return allow_harmony_computed_property_names_; |
116 } | 117 } |
117 bool allow_harmony_rest_params() const { | 118 bool allow_harmony_rest_params() const { |
118 return allow_harmony_rest_params_; | 119 return allow_harmony_rest_params_; |
119 } | 120 } |
121 bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; } | |
120 | 122 |
121 bool allow_strong_mode() const { return allow_strong_mode_; } | 123 bool allow_strong_mode() const { return allow_strong_mode_; } |
122 | 124 |
123 // Setters that determine whether certain syntactical constructs are | 125 // Setters that determine whether certain syntactical constructs are |
124 // allowed to be parsed by this instance of the parser. | 126 // allowed to be parsed by this instance of the parser. |
125 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 127 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
126 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 128 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
127 void set_allow_harmony_arrow_functions(bool allow) { | 129 void set_allow_harmony_arrow_functions(bool allow) { |
128 allow_harmony_arrow_functions_ = allow; | 130 allow_harmony_arrow_functions_ = allow; |
129 } | 131 } |
(...skipping 20 matching lines...) Expand all Loading... | |
150 } | 152 } |
151 void set_allow_harmony_unicode(bool allow) { | 153 void set_allow_harmony_unicode(bool allow) { |
152 scanner()->SetHarmonyUnicode(allow); | 154 scanner()->SetHarmonyUnicode(allow); |
153 } | 155 } |
154 void set_allow_harmony_computed_property_names(bool allow) { | 156 void set_allow_harmony_computed_property_names(bool allow) { |
155 allow_harmony_computed_property_names_ = allow; | 157 allow_harmony_computed_property_names_ = allow; |
156 } | 158 } |
157 void set_allow_harmony_rest_params(bool allow) { | 159 void set_allow_harmony_rest_params(bool allow) { |
158 allow_harmony_rest_params_ = allow; | 160 allow_harmony_rest_params_ = allow; |
159 } | 161 } |
162 void set_allow_harmony_spreadcalls(bool allow) { | |
163 allow_harmony_spreadcalls_ = allow; | |
164 } | |
160 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 165 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
161 | 166 |
162 protected: | 167 protected: |
163 enum AllowEvalOrArgumentsAsIdentifier { | 168 enum AllowEvalOrArgumentsAsIdentifier { |
164 kAllowEvalOrArguments, | 169 kAllowEvalOrArguments, |
165 kDontAllowEvalOrArguments | 170 kDontAllowEvalOrArguments |
166 }; | 171 }; |
167 | 172 |
168 enum Mode { | 173 enum Mode { |
169 PARSE_LAZILY, | 174 PARSE_LAZILY, |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 572 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
568 ExpressionT ParseArrayLiteral(bool* ok); | 573 ExpressionT ParseArrayLiteral(bool* ok); |
569 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 574 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
570 bool* is_static, bool* is_computed_name, | 575 bool* is_static, bool* is_computed_name, |
571 bool* ok); | 576 bool* ok); |
572 ExpressionT ParseObjectLiteral(bool* ok); | 577 ExpressionT ParseObjectLiteral(bool* ok); |
573 ObjectLiteralPropertyT ParsePropertyDefinition( | 578 ObjectLiteralPropertyT ParsePropertyDefinition( |
574 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 579 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
575 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 580 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
576 bool* ok); | 581 bool* ok); |
577 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 582 typename Traits::Type::ExpressionList ParseArguments( |
583 Scanner::Location* first_spread_pos, bool* ok); | |
578 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 584 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
579 ExpressionT ParseYieldExpression(bool* ok); | 585 ExpressionT ParseYieldExpression(bool* ok); |
580 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 586 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
581 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 587 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
582 ExpressionT ParseUnaryExpression(bool* ok); | 588 ExpressionT ParseUnaryExpression(bool* ok); |
583 ExpressionT ParsePostfixExpression(bool* ok); | 589 ExpressionT ParsePostfixExpression(bool* ok); |
584 ExpressionT ParseLeftHandSideExpression(bool* ok); | 590 ExpressionT ParseLeftHandSideExpression(bool* ok); |
585 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 591 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
586 ExpressionT ParseMemberExpression(bool* ok); | 592 ExpressionT ParseMemberExpression(bool* ok); |
587 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 593 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
679 Scanner* scanner_; | 685 Scanner* scanner_; |
680 bool stack_overflow_; | 686 bool stack_overflow_; |
681 | 687 |
682 bool allow_lazy_; | 688 bool allow_lazy_; |
683 bool allow_natives_; | 689 bool allow_natives_; |
684 bool allow_harmony_arrow_functions_; | 690 bool allow_harmony_arrow_functions_; |
685 bool allow_harmony_object_literals_; | 691 bool allow_harmony_object_literals_; |
686 bool allow_harmony_sloppy_; | 692 bool allow_harmony_sloppy_; |
687 bool allow_harmony_computed_property_names_; | 693 bool allow_harmony_computed_property_names_; |
688 bool allow_harmony_rest_params_; | 694 bool allow_harmony_rest_params_; |
695 bool allow_harmony_spreadcalls_; | |
689 bool allow_strong_mode_; | 696 bool allow_strong_mode_; |
690 }; | 697 }; |
691 | 698 |
692 | 699 |
693 class PreParserIdentifier { | 700 class PreParserIdentifier { |
694 public: | 701 public: |
695 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 702 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
696 static PreParserIdentifier Default() { | 703 static PreParserIdentifier Default() { |
697 return PreParserIdentifier(kUnknownIdentifier); | 704 return PreParserIdentifier(kUnknownIdentifier); |
698 } | 705 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
771 friend class PreParserExpression; | 778 friend class PreParserExpression; |
772 }; | 779 }; |
773 | 780 |
774 | 781 |
775 class PreParserExpression { | 782 class PreParserExpression { |
776 public: | 783 public: |
777 static PreParserExpression Default() { | 784 static PreParserExpression Default() { |
778 return PreParserExpression(TypeField::encode(kExpression)); | 785 return PreParserExpression(TypeField::encode(kExpression)); |
779 } | 786 } |
780 | 787 |
788 static PreParserExpression Spread(PreParserExpression expression) { | |
789 return PreParserExpression(TypeField::encode(kSpreadExpression)); | |
790 } | |
791 | |
781 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 792 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
782 return PreParserExpression(TypeField::encode(kIdentifierExpression) | | 793 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
783 IdentifierTypeField::encode(id.type_)); | 794 IdentifierTypeField::encode(id.type_)); |
784 } | 795 } |
785 | 796 |
786 static PreParserExpression BinaryOperation(PreParserExpression left, | 797 static PreParserExpression BinaryOperation(PreParserExpression left, |
787 Token::Value op, | 798 Token::Value op, |
788 PreParserExpression right) { | 799 PreParserExpression right) { |
789 bool valid_arrow_param_list = | 800 bool valid_arrow_param_list = |
790 op == Token::COMMA && !left.is_parenthesized() && | 801 op == Token::COMMA && !left.is_parenthesized() && |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
904 | 915 |
905 // At the moment PreParser doesn't track these expression types. | 916 // At the moment PreParser doesn't track these expression types. |
906 bool IsFunctionLiteral() const { return false; } | 917 bool IsFunctionLiteral() const { return false; } |
907 bool IsCallNew() const { return false; } | 918 bool IsCallNew() const { return false; } |
908 | 919 |
909 bool IsNoTemplateTag() const { | 920 bool IsNoTemplateTag() const { |
910 return TypeField::decode(code_) == kExpression && | 921 return TypeField::decode(code_) == kExpression && |
911 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 922 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
912 } | 923 } |
913 | 924 |
925 bool IsSpreadExpression() const { | |
926 return TypeField::decode(code_) == kSpreadExpression; | |
927 } | |
928 | |
914 PreParserExpression AsFunctionLiteral() { return *this; } | 929 PreParserExpression AsFunctionLiteral() { return *this; } |
915 | 930 |
916 bool IsBinaryOperation() const { | 931 bool IsBinaryOperation() const { |
917 return TypeField::decode(code_) == kBinaryOperationExpression; | 932 return TypeField::decode(code_) == kBinaryOperationExpression; |
918 } | 933 } |
919 | 934 |
920 bool is_parenthesized() const { | 935 bool is_parenthesized() const { |
921 return ParenthesizationField::decode(code_) != kNotParenthesized; | 936 return ParenthesizationField::decode(code_) != kNotParenthesized; |
922 } | 937 } |
923 | 938 |
(...skipping 12 matching lines...) Expand all Loading... | |
936 void set_parenthesized() {} | 951 void set_parenthesized() {} |
937 | 952 |
938 int position() const { return RelocInfo::kNoPosition; } | 953 int position() const { return RelocInfo::kNoPosition; } |
939 void set_function_token_position(int position) {} | 954 void set_function_token_position(int position) {} |
940 | 955 |
941 private: | 956 private: |
942 enum Type { | 957 enum Type { |
943 kExpression, | 958 kExpression, |
944 kIdentifierExpression, | 959 kIdentifierExpression, |
945 kStringLiteralExpression, | 960 kStringLiteralExpression, |
946 kBinaryOperationExpression | 961 kBinaryOperationExpression, |
962 kSpreadExpression | |
947 }; | 963 }; |
948 | 964 |
949 enum Parenthesization { | 965 enum Parenthesization { |
950 kNotParenthesized, | 966 kNotParenthesized, |
951 kParanthesizedExpression, | 967 kParanthesizedExpression, |
952 kMultiParenthesizedExpression | 968 kMultiParenthesizedExpression |
953 }; | 969 }; |
954 | 970 |
955 enum ExpressionType { | 971 enum ExpressionType { |
956 kThisExpression, | 972 kThisExpression, |
957 kThisPropertyExpression, | 973 kThisPropertyExpression, |
958 kPropertyExpression, | 974 kPropertyExpression, |
959 kCallExpression, | 975 kCallExpression, |
960 kSuperExpression, | 976 kSuperExpression, |
961 kNoTemplateTagExpression | 977 kNoTemplateTagExpression |
962 }; | 978 }; |
963 | 979 |
964 explicit PreParserExpression(uint32_t expression_code) | 980 explicit PreParserExpression(uint32_t expression_code) |
965 : code_(expression_code) {} | 981 : code_(expression_code) {} |
966 | 982 |
967 V8_INLINE bool IsValidArrowParams() const { | 983 V8_INLINE bool IsValidArrowParams() const { |
968 return IsBinaryOperation() | 984 return IsBinaryOperation() |
969 ? IsValidArrowParamListField::decode(code_) | 985 ? IsValidArrowParamListField::decode(code_) |
970 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 986 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); |
971 } | 987 } |
972 | 988 |
973 // The first four bits are for the Type and Parenthesization. | 989 // The first five bits are for the Type and Parenthesization. |
974 typedef BitField<Type, 0, 2> TypeField; | 990 typedef BitField<Type, 0, 3> TypeField; |
975 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 991 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
976 | 992 |
977 // The rest of the bits are interpreted depending on the value | 993 // The rest of the bits are interpreted depending on the value |
978 // of the Type field, so they can share the storage. | 994 // of the Type field, so they can share the storage. |
979 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 995 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
980 ExpressionTypeField; | 996 ExpressionTypeField; |
981 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 997 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
982 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 998 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
983 typedef BitField<bool, ParenthesizationField::kNext, 1> | 999 typedef BitField<bool, ParenthesizationField::kNext, 1> |
984 IsValidArrowParamListField; | 1000 IsValidArrowParamListField; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1165 PreParserExpression NewCall(PreParserExpression expression, | 1181 PreParserExpression NewCall(PreParserExpression expression, |
1166 PreParserExpressionList arguments, | 1182 PreParserExpressionList arguments, |
1167 int pos) { | 1183 int pos) { |
1168 return PreParserExpression::Call(); | 1184 return PreParserExpression::Call(); |
1169 } | 1185 } |
1170 PreParserExpression NewCallNew(PreParserExpression expression, | 1186 PreParserExpression NewCallNew(PreParserExpression expression, |
1171 PreParserExpressionList arguments, | 1187 PreParserExpressionList arguments, |
1172 int pos) { | 1188 int pos) { |
1173 return PreParserExpression::Default(); | 1189 return PreParserExpression::Default(); |
1174 } | 1190 } |
1191 PreParserExpression NewCallRuntime(const AstRawString* name, | |
1192 const Runtime::Function* function, | |
1193 PreParserExpressionList arguments, | |
1194 int pos) { | |
1195 return PreParserExpression::Default(); | |
1196 } | |
1175 PreParserStatement NewReturnStatement(PreParserExpression expression, | 1197 PreParserStatement NewReturnStatement(PreParserExpression expression, |
1176 int pos) { | 1198 int pos) { |
1177 return PreParserStatement::Default(); | 1199 return PreParserStatement::Default(); |
1178 } | 1200 } |
1179 PreParserExpression NewFunctionLiteral( | 1201 PreParserExpression NewFunctionLiteral( |
1180 PreParserIdentifier name, AstValueFactory* ast_value_factory, | 1202 PreParserIdentifier name, AstValueFactory* ast_value_factory, |
1181 Scope* scope, PreParserStatementList body, int materialized_literal_count, | 1203 Scope* scope, PreParserStatementList body, int materialized_literal_count, |
1182 int expected_property_count, int handler_count, int parameter_count, | 1204 int expected_property_count, int handler_count, int parameter_count, |
1183 FunctionLiteral::ParameterFlag has_duplicate_parameters, | 1205 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
1184 FunctionLiteral::FunctionType function_type, | 1206 FunctionLiteral::FunctionType function_type, |
1185 FunctionLiteral::IsFunctionFlag is_function, | 1207 FunctionLiteral::IsFunctionFlag is_function, |
1186 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, | 1208 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, |
1187 int position) { | 1209 int position) { |
1188 return PreParserExpression::Default(); | 1210 return PreParserExpression::Default(); |
1189 } | 1211 } |
1190 | 1212 |
1213 PreParserExpression NewSpreadOperation(PreParserExpression expression, | |
1214 int pos) { | |
1215 return PreParserExpression::Spread(expression); | |
1216 } | |
1217 | |
1191 // Return the object itself as AstVisitor and implement the needed | 1218 // Return the object itself as AstVisitor and implement the needed |
1192 // dummy method right in this class. | 1219 // dummy method right in this class. |
1193 PreParserFactory* visitor() { return this; } | 1220 PreParserFactory* visitor() { return this; } |
1194 int* ast_properties() { | 1221 int* ast_properties() { |
1195 static int dummy = 42; | 1222 static int dummy = 42; |
1196 return &dummy; | 1223 return &dummy; |
1197 } | 1224 } |
1198 }; | 1225 }; |
1199 | 1226 |
1200 | 1227 |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1493 PreParserIdentifier name, Scanner::Location function_name_location, | 1520 PreParserIdentifier name, Scanner::Location function_name_location, |
1494 bool name_is_strict_reserved, FunctionKind kind, | 1521 bool name_is_strict_reserved, FunctionKind kind, |
1495 int function_token_position, FunctionLiteral::FunctionType type, | 1522 int function_token_position, FunctionLiteral::FunctionType type, |
1496 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1523 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1497 | 1524 |
1498 PreParserExpression ParseClassLiteral(PreParserIdentifier name, | 1525 PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
1499 Scanner::Location class_name_location, | 1526 Scanner::Location class_name_location, |
1500 bool name_is_strict_reserved, int pos, | 1527 bool name_is_strict_reserved, int pos, |
1501 bool* ok); | 1528 bool* ok); |
1502 | 1529 |
1530 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) { | |
1531 return list; | |
1532 } | |
1533 | |
1534 inline void MaterializeUnspreadArgumentsLiterals(int count); | |
1535 | |
1536 inline PreParserExpression SpreadCall(PreParserExpression function, | |
1537 PreParserExpressionList args, int pos); | |
1538 | |
1539 inline PreParserExpression SpreadCallNew(PreParserExpression function, | |
1540 PreParserExpressionList args, | |
1541 int pos); | |
1542 | |
1503 private: | 1543 private: |
1504 PreParser* pre_parser_; | 1544 PreParser* pre_parser_; |
1505 }; | 1545 }; |
1506 | 1546 |
1507 | 1547 |
1508 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1548 // Preparsing checks a JavaScript program and emits preparse-data that helps |
1509 // a later parsing to be faster. | 1549 // a later parsing to be faster. |
1510 // See preparse-data-format.h for the data format. | 1550 // See preparse-data-format.h for the data format. |
1511 | 1551 |
1512 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1552 // The PreParser checks that the syntax follows the grammar for JavaScript, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1632 bool* ok); | 1672 bool* ok); |
1633 }; | 1673 }; |
1634 | 1674 |
1635 | 1675 |
1636 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { | 1676 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { |
1637 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1677 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
1638 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1678 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
1639 } | 1679 } |
1640 | 1680 |
1641 | 1681 |
1682 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { | |
1683 for (int i = 0; i < count; ++i) { | |
1684 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | |
1685 } | |
1686 } | |
1687 | |
1688 | |
1689 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, | |
1690 PreParserExpressionList args, | |
1691 int pos) { | |
1692 return pre_parser_->factory()->NewCall(function, args, pos); | |
1693 } | |
1694 | |
1695 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, | |
1696 PreParserExpressionList args, | |
1697 int pos) { | |
1698 return pre_parser_->factory()->NewCallNew(function, args, pos); | |
1699 } | |
1700 | |
1701 | |
1642 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1702 PreParserStatementList PreParser::ParseEagerFunctionBody( |
1643 PreParserIdentifier function_name, int pos, Variable* fvar, | 1703 PreParserIdentifier function_name, int pos, Variable* fvar, |
1644 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1704 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
1645 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1705 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1646 | 1706 |
1647 ParseStatementList(Token::RBRACE, ok); | 1707 ParseStatementList(Token::RBRACE, ok); |
1648 if (!*ok) return PreParserStatementList(); | 1708 if (!*ok) return PreParserStatementList(); |
1649 | 1709 |
1650 Expect(Token::RBRACE, ok); | 1710 Expect(Token::RBRACE, ok); |
1651 return PreParserStatementList(); | 1711 return PreParserStatementList(); |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2278 return factory()->NewObjectLiteral(properties, | 2338 return factory()->NewObjectLiteral(properties, |
2279 literal_index, | 2339 literal_index, |
2280 number_of_boilerplate_properties, | 2340 number_of_boilerplate_properties, |
2281 has_function, | 2341 has_function, |
2282 pos); | 2342 pos); |
2283 } | 2343 } |
2284 | 2344 |
2285 | 2345 |
2286 template <class Traits> | 2346 template <class Traits> |
2287 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2347 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
2288 bool* ok) { | 2348 Scanner::Location* first_spread_arg_loc, bool* ok) { |
2289 // Arguments :: | 2349 // Arguments :: |
2290 // '(' (AssignmentExpression)*[','] ')' | 2350 // '(' (AssignmentExpression)*[','] ')' |
2291 | 2351 |
2352 Scanner::Location spread_arg = Scanner::Location::invalid(); | |
2292 typename Traits::Type::ExpressionList result = | 2353 typename Traits::Type::ExpressionList result = |
2293 this->NewExpressionList(4, zone_); | 2354 this->NewExpressionList(4, zone_); |
2294 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2355 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2295 bool done = (peek() == Token::RPAREN); | 2356 bool done = (peek() == Token::RPAREN); |
2357 bool was_unspread = false; | |
2358 int unspread_sequences_count = 0; | |
rossberg
2015/02/25 14:28:18
A brief comment explaining what this actually coun
caitp (gmail)
2015/02/25 14:49:08
That's right --- will add a comment
| |
2296 while (!done) { | 2359 while (!done) { |
2360 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); | |
2361 int start_pos = peek_position(); | |
2362 if (is_spread) Consume(Token::ELLIPSIS); | |
2363 | |
2297 ExpressionT argument = this->ParseAssignmentExpression( | 2364 ExpressionT argument = this->ParseAssignmentExpression( |
2298 true, CHECK_OK_CUSTOM(NullExpressionList)); | 2365 true, CHECK_OK_CUSTOM(NullExpressionList)); |
2366 if (is_spread) { | |
2367 if (!spread_arg.IsValid()) { | |
2368 spread_arg.beg_pos = start_pos; | |
2369 spread_arg.end_pos = peek_position(); | |
2370 } | |
2371 argument = factory()->NewSpreadOperation(argument, start_pos); | |
2372 } | |
2299 result->Add(argument, zone_); | 2373 result->Add(argument, zone_); |
2374 | |
2375 if (is_spread) { | |
2376 was_unspread = false; | |
2377 } else if (!was_unspread) { | |
2378 was_unspread = true; | |
2379 unspread_sequences_count++; | |
2380 } | |
2381 | |
2300 if (result->length() > Code::kMaxArguments) { | 2382 if (result->length() > Code::kMaxArguments) { |
2301 ReportMessage("too_many_arguments"); | 2383 ReportMessage("too_many_arguments"); |
2302 *ok = false; | 2384 *ok = false; |
2303 return this->NullExpressionList(); | 2385 return this->NullExpressionList(); |
2304 } | 2386 } |
2305 done = (peek() == Token::RPAREN); | 2387 done = (peek() == Token::RPAREN); |
2306 if (!done) { | 2388 if (!done) { |
2307 // Need {} because of the CHECK_OK_CUSTOM macro. | 2389 // Need {} because of the CHECK_OK_CUSTOM macro. |
2308 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); | 2390 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); |
2309 } | 2391 } |
2310 } | 2392 } |
2311 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2393 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2394 *first_spread_arg_loc = spread_arg; | |
2395 | |
2396 if (spread_arg.IsValid()) { | |
2397 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | |
2398 } | |
2399 | |
2312 return result; | 2400 return result; |
2313 } | 2401 } |
2314 | 2402 |
2315 // Precedence = 2 | 2403 // Precedence = 2 |
2316 template <class Traits> | 2404 template <class Traits> |
2317 typename ParserBase<Traits>::ExpressionT | 2405 typename ParserBase<Traits>::ExpressionT |
2318 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2406 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
2319 // AssignmentExpression :: | 2407 // AssignmentExpression :: |
2320 // ConditionalExpression | 2408 // ConditionalExpression |
2321 // ArrowFunction | 2409 // ArrowFunction |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2616 // should not point to the closing brace otherwise it will intersect | 2704 // should not point to the closing brace otherwise it will intersect |
2617 // with positions recorded for function literal and confuse debugger. | 2705 // with positions recorded for function literal and confuse debugger. |
2618 pos = peek_position(); | 2706 pos = peek_position(); |
2619 // Also the trailing parenthesis are a hint that the function will | 2707 // Also the trailing parenthesis are a hint that the function will |
2620 // be called immediately. If we happen to have parsed a preceding | 2708 // be called immediately. If we happen to have parsed a preceding |
2621 // function literal eagerly, we can also compile it eagerly. | 2709 // function literal eagerly, we can also compile it eagerly. |
2622 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2710 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2623 result->AsFunctionLiteral()->set_parenthesized(); | 2711 result->AsFunctionLiteral()->set_parenthesized(); |
2624 } | 2712 } |
2625 } | 2713 } |
2626 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); | 2714 Scanner::Location spread_pos; |
2715 typename Traits::Type::ExpressionList args = | |
2716 ParseArguments(&spread_pos, CHECK_OK); | |
2627 | 2717 |
2628 // Keep track of eval() calls since they disable all local variable | 2718 // Keep track of eval() calls since they disable all local variable |
2629 // optimizations. | 2719 // optimizations. |
2630 // The calls that need special treatment are the | 2720 // The calls that need special treatment are the |
2631 // direct eval calls. These calls are all of the form eval(...), with | 2721 // direct eval calls. These calls are all of the form eval(...), with |
2632 // no explicit receiver. | 2722 // no explicit receiver. |
2633 // These calls are marked as potentially direct eval calls. Whether | 2723 // These calls are marked as potentially direct eval calls. Whether |
2634 // they are actually direct calls to eval is determined at run time. | 2724 // they are actually direct calls to eval is determined at run time. |
2635 this->CheckPossibleEvalCall(result, scope_); | 2725 this->CheckPossibleEvalCall(result, scope_); |
2636 result = factory()->NewCall(result, args, pos); | 2726 |
2727 if (spread_pos.IsValid()) { | |
2728 args = Traits::PrepareSpreadArguments(args); | |
2729 result = Traits::SpreadCall(result, args, pos); | |
2730 } else { | |
2731 result = factory()->NewCall(result, args, pos); | |
2732 } | |
2637 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2733 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2638 break; | 2734 break; |
2639 } | 2735 } |
2640 | 2736 |
2641 case Token::TEMPLATE_SPAN: | 2737 case Token::TEMPLATE_SPAN: |
2642 case Token::TEMPLATE_TAIL: { | 2738 case Token::TEMPLATE_TAIL: { |
2643 int pos; | 2739 int pos; |
2644 if (scanner()->current_token() == Token::IDENTIFIER) { | 2740 if (scanner()->current_token() == Token::IDENTIFIER) { |
2645 pos = position(); | 2741 pos = position(); |
2646 } else { | 2742 } else { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2697 int new_pos = position(); | 2793 int new_pos = position(); |
2698 ExpressionT result = this->EmptyExpression(); | 2794 ExpressionT result = this->EmptyExpression(); |
2699 if (peek() == Token::SUPER) { | 2795 if (peek() == Token::SUPER) { |
2700 const bool is_new = true; | 2796 const bool is_new = true; |
2701 result = ParseSuperExpression(is_new, CHECK_OK); | 2797 result = ParseSuperExpression(is_new, CHECK_OK); |
2702 } else { | 2798 } else { |
2703 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2799 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
2704 } | 2800 } |
2705 if (peek() == Token::LPAREN) { | 2801 if (peek() == Token::LPAREN) { |
2706 // NewExpression with arguments. | 2802 // NewExpression with arguments. |
2803 Scanner::Location spread_pos; | |
2707 typename Traits::Type::ExpressionList args = | 2804 typename Traits::Type::ExpressionList args = |
2708 this->ParseArguments(CHECK_OK); | 2805 this->ParseArguments(&spread_pos, CHECK_OK); |
2709 result = factory()->NewCallNew(result, args, new_pos); | 2806 |
2807 if (spread_pos.IsValid()) { | |
2808 args = Traits::PrepareSpreadArguments(args); | |
2809 result = Traits::SpreadCallNew(result, args, new_pos); | |
2810 } else { | |
2811 result = factory()->NewCallNew(result, args, new_pos); | |
2812 } | |
2710 // The expression can still continue with . or [ after the arguments. | 2813 // The expression can still continue with . or [ after the arguments. |
2711 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2814 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
2712 return result; | 2815 return result; |
2713 } | 2816 } |
2714 // NewExpression without arguments. | 2817 // NewExpression without arguments. |
2715 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2818 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
2716 new_pos); | 2819 new_pos); |
2717 } | 2820 } |
2718 // No 'new' or 'super' keyword. | 2821 // No 'new' or 'super' keyword. |
2719 return this->ParseMemberExpression(ok); | 2822 return this->ParseMemberExpression(ok); |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3109 *ok = false; | 3212 *ok = false; |
3110 return; | 3213 return; |
3111 } | 3214 } |
3112 has_seen_constructor_ = true; | 3215 has_seen_constructor_ = true; |
3113 return; | 3216 return; |
3114 } | 3217 } |
3115 } | 3218 } |
3116 } } // v8::internal | 3219 } } // v8::internal |
3117 | 3220 |
3118 #endif // V8_PREPARSER_H | 3221 #endif // V8_PREPARSER_H |
OLD | NEW |