Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: src/preparser.h

Issue 938443002: [es6] implement spread calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Eagerly iterate spread expressions, make parser more complicated, simplify harmony-spread Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 ExpressionT ParseExpression(bool accept_IN, bool* ok); 556 ExpressionT ParseExpression(bool accept_IN, bool* ok);
552 ExpressionT ParseArrayLiteral(bool* ok); 557 ExpressionT ParseArrayLiteral(bool* ok);
553 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, 558 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
554 bool* is_static, bool* is_computed_name, 559 bool* is_static, bool* is_computed_name,
555 bool* ok); 560 bool* ok);
556 ExpressionT ParseObjectLiteral(bool* ok); 561 ExpressionT ParseObjectLiteral(bool* ok);
557 ObjectLiteralPropertyT ParsePropertyDefinition( 562 ObjectLiteralPropertyT ParsePropertyDefinition(
558 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 563 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
559 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 564 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
560 bool* ok); 565 bool* ok);
561 typename Traits::Type::ExpressionList ParseArguments(bool* ok); 566 typename Traits::Type::ExpressionList ParseArguments(
567 Scanner::Location* first_spread_pos, bool* ok);
562 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); 568 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
563 ExpressionT ParseYieldExpression(bool* ok); 569 ExpressionT ParseYieldExpression(bool* ok);
564 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 570 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
565 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 571 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
566 ExpressionT ParseUnaryExpression(bool* ok); 572 ExpressionT ParseUnaryExpression(bool* ok);
567 ExpressionT ParsePostfixExpression(bool* ok); 573 ExpressionT ParsePostfixExpression(bool* ok);
568 ExpressionT ParseLeftHandSideExpression(bool* ok); 574 ExpressionT ParseLeftHandSideExpression(bool* ok);
569 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 575 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
570 ExpressionT ParseMemberExpression(bool* ok); 576 ExpressionT ParseMemberExpression(bool* ok);
571 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 577 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 Scanner* scanner_; 669 Scanner* scanner_;
664 bool stack_overflow_; 670 bool stack_overflow_;
665 671
666 bool allow_lazy_; 672 bool allow_lazy_;
667 bool allow_natives_; 673 bool allow_natives_;
668 bool allow_harmony_arrow_functions_; 674 bool allow_harmony_arrow_functions_;
669 bool allow_harmony_object_literals_; 675 bool allow_harmony_object_literals_;
670 bool allow_harmony_sloppy_; 676 bool allow_harmony_sloppy_;
671 bool allow_harmony_computed_property_names_; 677 bool allow_harmony_computed_property_names_;
672 bool allow_harmony_rest_params_; 678 bool allow_harmony_rest_params_;
679 bool allow_harmony_spreadcalls_;
673 bool allow_strong_mode_; 680 bool allow_strong_mode_;
674 }; 681 };
675 682
676 683
677 class PreParserIdentifier { 684 class PreParserIdentifier {
678 public: 685 public:
679 PreParserIdentifier() : type_(kUnknownIdentifier) {} 686 PreParserIdentifier() : type_(kUnknownIdentifier) {}
680 static PreParserIdentifier Default() { 687 static PreParserIdentifier Default() {
681 return PreParserIdentifier(kUnknownIdentifier); 688 return PreParserIdentifier(kUnknownIdentifier);
682 } 689 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 friend class PreParserExpression; 766 friend class PreParserExpression;
760 }; 767 };
761 768
762 769
763 class PreParserExpression { 770 class PreParserExpression {
764 public: 771 public:
765 static PreParserExpression Default() { 772 static PreParserExpression Default() {
766 return PreParserExpression(TypeField::encode(kExpression)); 773 return PreParserExpression(TypeField::encode(kExpression));
767 } 774 }
768 775
776 static PreParserExpression Spread(PreParserExpression expression) {
777 return PreParserExpression(TypeField::encode(kSpreadExpression));
778 }
779
769 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 780 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
770 return PreParserExpression(TypeField::encode(kIdentifierExpression) | 781 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
771 IdentifierTypeField::encode(id.type_)); 782 IdentifierTypeField::encode(id.type_));
772 } 783 }
773 784
774 static PreParserExpression BinaryOperation(PreParserExpression left, 785 static PreParserExpression BinaryOperation(PreParserExpression left,
775 Token::Value op, 786 Token::Value op,
776 PreParserExpression right) { 787 PreParserExpression right) {
777 bool valid_arrow_param_list = 788 bool valid_arrow_param_list =
778 op == Token::COMMA && !left.is_parenthesized() && 789 op == Token::COMMA && !left.is_parenthesized() &&
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 903
893 // At the moment PreParser doesn't track these expression types. 904 // At the moment PreParser doesn't track these expression types.
894 bool IsFunctionLiteral() const { return false; } 905 bool IsFunctionLiteral() const { return false; }
895 bool IsCallNew() const { return false; } 906 bool IsCallNew() const { return false; }
896 907
897 bool IsNoTemplateTag() const { 908 bool IsNoTemplateTag() const {
898 return TypeField::decode(code_) == kExpression && 909 return TypeField::decode(code_) == kExpression &&
899 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; 910 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
900 } 911 }
901 912
913 bool IsSpreadExpression() const {
914 return TypeField::decode(code_) == kSpreadExpression;
915 }
916
902 PreParserExpression AsFunctionLiteral() { return *this; } 917 PreParserExpression AsFunctionLiteral() { return *this; }
903 918
904 bool IsBinaryOperation() const { 919 bool IsBinaryOperation() const {
905 return TypeField::decode(code_) == kBinaryOperationExpression; 920 return TypeField::decode(code_) == kBinaryOperationExpression;
906 } 921 }
907 922
908 bool is_parenthesized() const { 923 bool is_parenthesized() const {
909 return ParenthesizationField::decode(code_) != kNotParenthesized; 924 return ParenthesizationField::decode(code_) != kNotParenthesized;
910 } 925 }
911 926
(...skipping 12 matching lines...) Expand all
924 void set_parenthesized() {} 939 void set_parenthesized() {}
925 940
926 int position() const { return RelocInfo::kNoPosition; } 941 int position() const { return RelocInfo::kNoPosition; }
927 void set_function_token_position(int position) {} 942 void set_function_token_position(int position) {}
928 943
929 private: 944 private:
930 enum Type { 945 enum Type {
931 kExpression, 946 kExpression,
932 kIdentifierExpression, 947 kIdentifierExpression,
933 kStringLiteralExpression, 948 kStringLiteralExpression,
934 kBinaryOperationExpression 949 kBinaryOperationExpression,
950 kSpreadExpression
935 }; 951 };
936 952
937 enum Parenthesization { 953 enum Parenthesization {
938 kNotParenthesized, 954 kNotParenthesized,
939 kParanthesizedExpression, 955 kParanthesizedExpression,
940 kMultiParenthesizedExpression 956 kMultiParenthesizedExpression
941 }; 957 };
942 958
943 enum ExpressionType { 959 enum ExpressionType {
944 kThisExpression, 960 kThisExpression,
945 kThisPropertyExpression, 961 kThisPropertyExpression,
946 kPropertyExpression, 962 kPropertyExpression,
947 kCallExpression, 963 kCallExpression,
948 kSuperExpression, 964 kSuperExpression,
949 kNoTemplateTagExpression 965 kNoTemplateTagExpression
950 }; 966 };
951 967
952 explicit PreParserExpression(uint32_t expression_code) 968 explicit PreParserExpression(uint32_t expression_code)
953 : code_(expression_code) {} 969 : code_(expression_code) {}
954 970
955 V8_INLINE bool IsValidArrowParams() const { 971 V8_INLINE bool IsValidArrowParams() const {
956 return IsBinaryOperation() 972 return IsBinaryOperation()
957 ? IsValidArrowParamListField::decode(code_) 973 ? IsValidArrowParamListField::decode(code_)
958 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); 974 : (IsIdentifier() && AsIdentifier().IsValidArrowParam());
959 } 975 }
960 976
961 // The first four bits are for the Type and Parenthesization. 977 // The first five bits are for the Type and Parenthesization.
962 typedef BitField<Type, 0, 2> TypeField; 978 typedef BitField<Type, 0, 3> TypeField;
963 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; 979 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField;
964 980
965 // The rest of the bits are interpreted depending on the value 981 // The rest of the bits are interpreted depending on the value
966 // of the Type field, so they can share the storage. 982 // of the Type field, so they can share the storage.
967 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> 983 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3>
968 ExpressionTypeField; 984 ExpressionTypeField;
969 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; 985 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField;
970 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; 986 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
971 typedef BitField<bool, ParenthesizationField::kNext, 1> 987 typedef BitField<bool, ParenthesizationField::kNext, 1>
972 IsValidArrowParamListField; 988 IsValidArrowParamListField;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 PreParserExpression NewCall(PreParserExpression expression, 1169 PreParserExpression NewCall(PreParserExpression expression,
1154 PreParserExpressionList arguments, 1170 PreParserExpressionList arguments,
1155 int pos) { 1171 int pos) {
1156 return PreParserExpression::Call(); 1172 return PreParserExpression::Call();
1157 } 1173 }
1158 PreParserExpression NewCallNew(PreParserExpression expression, 1174 PreParserExpression NewCallNew(PreParserExpression expression,
1159 PreParserExpressionList arguments, 1175 PreParserExpressionList arguments,
1160 int pos) { 1176 int pos) {
1161 return PreParserExpression::Default(); 1177 return PreParserExpression::Default();
1162 } 1178 }
1179 PreParserExpression NewCallRuntime(const AstRawString* name,
1180 const Runtime::Function* function,
1181 PreParserExpressionList arguments,
1182 int pos) {
1183 return PreParserExpression::Default();
1184 }
1163 PreParserStatement NewReturnStatement(PreParserExpression expression, 1185 PreParserStatement NewReturnStatement(PreParserExpression expression,
1164 int pos) { 1186 int pos) {
1165 return PreParserStatement::Default(); 1187 return PreParserStatement::Default();
1166 } 1188 }
1167 PreParserExpression NewFunctionLiteral( 1189 PreParserExpression NewFunctionLiteral(
1168 PreParserIdentifier name, AstValueFactory* ast_value_factory, 1190 PreParserIdentifier name, AstValueFactory* ast_value_factory,
1169 Scope* scope, PreParserStatementList body, int materialized_literal_count, 1191 Scope* scope, PreParserStatementList body, int materialized_literal_count,
1170 int expected_property_count, int handler_count, int parameter_count, 1192 int expected_property_count, int handler_count, int parameter_count,
1171 FunctionLiteral::ParameterFlag has_duplicate_parameters, 1193 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1172 FunctionLiteral::FunctionType function_type, 1194 FunctionLiteral::FunctionType function_type,
1173 FunctionLiteral::IsFunctionFlag is_function, 1195 FunctionLiteral::IsFunctionFlag is_function,
1174 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, 1196 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
1175 int position) { 1197 int position) {
1176 return PreParserExpression::Default(); 1198 return PreParserExpression::Default();
1177 } 1199 }
1178 1200
1201 PreParserExpression NewSpreadOperation(PreParserExpression expression,
1202 int pos) {
1203 return PreParserExpression::Spread(expression);
1204 }
1205
1179 // Return the object itself as AstVisitor and implement the needed 1206 // Return the object itself as AstVisitor and implement the needed
1180 // dummy method right in this class. 1207 // dummy method right in this class.
1181 PreParserFactory* visitor() { return this; } 1208 PreParserFactory* visitor() { return this; }
1182 int* ast_properties() { 1209 int* ast_properties() {
1183 static int dummy = 42; 1210 static int dummy = 42;
1184 return &dummy; 1211 return &dummy;
1185 } 1212 }
1186 }; 1213 };
1187 1214
1188 1215
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 PreParserIdentifier name, Scanner::Location function_name_location, 1502 PreParserIdentifier name, Scanner::Location function_name_location,
1476 bool name_is_strict_reserved, FunctionKind kind, 1503 bool name_is_strict_reserved, FunctionKind kind,
1477 int function_token_position, FunctionLiteral::FunctionType type, 1504 int function_token_position, FunctionLiteral::FunctionType type,
1478 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); 1505 FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
1479 1506
1480 PreParserExpression ParseClassLiteral(PreParserIdentifier name, 1507 PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1481 Scanner::Location class_name_location, 1508 Scanner::Location class_name_location,
1482 bool name_is_strict_reserved, int pos, 1509 bool name_is_strict_reserved, int pos,
1483 bool* ok); 1510 bool* ok);
1484 1511
1512 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
1513 return list;
1514 }
1515
1516 inline void MaterializeUnspreadArgumentsLiterals(int count);
1517
1518 inline PreParserExpression SpreadCall(PreParserExpression function,
1519 PreParserExpressionList args, int pos);
1520
1521 inline PreParserExpression SpreadCallNew(PreParserExpression function,
1522 PreParserExpressionList args,
1523 int pos);
1524
1485 private: 1525 private:
1486 PreParser* pre_parser_; 1526 PreParser* pre_parser_;
1487 }; 1527 };
1488 1528
1489 1529
1490 // Preparsing checks a JavaScript program and emits preparse-data that helps 1530 // Preparsing checks a JavaScript program and emits preparse-data that helps
1491 // a later parsing to be faster. 1531 // a later parsing to be faster.
1492 // See preparse-data-format.h for the data format. 1532 // See preparse-data-format.h for the data format.
1493 1533
1494 // The PreParser checks that the syntax follows the grammar for JavaScript, 1534 // The PreParser checks that the syntax follows the grammar for JavaScript,
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 bool CheckInOrOf(bool accept_OF); 1655 bool CheckInOrOf(bool accept_OF);
1616 }; 1656 };
1617 1657
1618 1658
1619 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { 1659 void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1620 pre_parser_->function_state_->NextMaterializedLiteralIndex(); 1660 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1621 pre_parser_->function_state_->NextMaterializedLiteralIndex(); 1661 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1622 } 1662 }
1623 1663
1624 1664
1665 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
1666 for (int i = 0; i < count; ++i) {
1667 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1668 }
1669 }
1670
1671
1672 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
1673 PreParserExpressionList args,
1674 int pos) {
1675 return pre_parser_->factory()->NewCall(function, args, pos);
1676 }
1677
1678 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1679 PreParserExpressionList args,
1680 int pos) {
1681 return pre_parser_->factory()->NewCallNew(function, args, pos);
1682 }
1683
1684
1625 PreParserStatementList PreParser::ParseEagerFunctionBody( 1685 PreParserStatementList PreParser::ParseEagerFunctionBody(
1626 PreParserIdentifier function_name, int pos, Variable* fvar, 1686 PreParserIdentifier function_name, int pos, Variable* fvar,
1627 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { 1687 Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
1628 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 1688 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1629 1689
1630 ParseStatementList(Token::RBRACE, ok); 1690 ParseStatementList(Token::RBRACE, ok);
1631 if (!*ok) return PreParserStatementList(); 1691 if (!*ok) return PreParserStatementList();
1632 1692
1633 Expect(Token::RBRACE, ok); 1693 Expect(Token::RBRACE, ok);
1634 return PreParserStatementList(); 1694 return PreParserStatementList();
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
2250 return factory()->NewObjectLiteral(properties, 2310 return factory()->NewObjectLiteral(properties,
2251 literal_index, 2311 literal_index,
2252 number_of_boilerplate_properties, 2312 number_of_boilerplate_properties,
2253 has_function, 2313 has_function,
2254 pos); 2314 pos);
2255 } 2315 }
2256 2316
2257 2317
2258 template <class Traits> 2318 template <class Traits>
2259 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( 2319 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
2260 bool* ok) { 2320 Scanner::Location* spread_arg_loc, bool* ok) {
rossberg 2015/02/24 16:22:47 Maybe name this first_spread_arg_loc to clarify th
2261 // Arguments :: 2321 // Arguments ::
2262 // '(' (AssignmentExpression)*[','] ')' 2322 // '(' (AssignmentExpression)*[','] ')'
2263 2323
2324 Scanner::Location spread_arg = Scanner::Location::invalid();
2264 typename Traits::Type::ExpressionList result = 2325 typename Traits::Type::ExpressionList result =
2265 this->NewExpressionList(4, zone_); 2326 this->NewExpressionList(4, zone_);
2266 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 2327 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2267 bool done = (peek() == Token::RPAREN); 2328 bool done = (peek() == Token::RPAREN);
2329 bool was_unspread = false;
2330 int unspread_sequences_count = 0;
2268 while (!done) { 2331 while (!done) {
2332 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS);
2333 int start_pos = peek_position();
2334 if (is_spread) Consume(Token::ELLIPSIS);
2335
2269 ExpressionT argument = this->ParseAssignmentExpression( 2336 ExpressionT argument = this->ParseAssignmentExpression(
2270 true, CHECK_OK_CUSTOM(NullExpressionList)); 2337 true, CHECK_OK_CUSTOM(NullExpressionList));
2338 if (is_spread) {
2339 if (!spread_arg.IsValid()) {
2340 spread_arg.beg_pos = start_pos;
2341 spread_arg.end_pos = peek_position();
2342 }
2343 argument = factory()->NewSpreadOperation(argument, start_pos);
2344 }
2271 result->Add(argument, zone_); 2345 result->Add(argument, zone_);
2346
2347 if (!is_spread && !was_unspread) {
2348 was_unspread = true;
2349 unspread_sequences_count++;
rossberg 2015/02/24 16:22:47 Something seems wrong with the was_unspread logic.
caitp (gmail) 2015/02/25 00:00:24 Yeah, it was broken. Thanks for spotting that
2350 }
2351
2272 if (result->length() > Code::kMaxArguments) { 2352 if (result->length() > Code::kMaxArguments) {
2273 ReportMessage("too_many_arguments"); 2353 ReportMessage("too_many_arguments");
2274 *ok = false; 2354 *ok = false;
2275 return this->NullExpressionList(); 2355 return this->NullExpressionList();
2276 } 2356 }
2277 done = (peek() == Token::RPAREN); 2357 done = (peek() == Token::RPAREN);
2278 if (!done) { 2358 if (!done) {
2279 // Need {} because of the CHECK_OK_CUSTOM macro. 2359 // Need {} because of the CHECK_OK_CUSTOM macro.
2280 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); 2360 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
2281 } 2361 }
2282 } 2362 }
2283 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 2363 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2364 *spread_arg_loc = spread_arg;
2365
2366 if (spread_arg.IsValid()) {
2367 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2368 }
2369
2284 return result; 2370 return result;
2285 } 2371 }
2286 2372
2287 // Precedence = 2 2373 // Precedence = 2
2288 template <class Traits> 2374 template <class Traits>
2289 typename ParserBase<Traits>::ExpressionT 2375 typename ParserBase<Traits>::ExpressionT
2290 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 2376 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2291 // AssignmentExpression :: 2377 // AssignmentExpression ::
2292 // ConditionalExpression 2378 // ConditionalExpression
2293 // ArrowFunction 2379 // ArrowFunction
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 // should not point to the closing brace otherwise it will intersect 2669 // should not point to the closing brace otherwise it will intersect
2584 // with positions recorded for function literal and confuse debugger. 2670 // with positions recorded for function literal and confuse debugger.
2585 pos = peek_position(); 2671 pos = peek_position();
2586 // Also the trailing parenthesis are a hint that the function will 2672 // Also the trailing parenthesis are a hint that the function will
2587 // be called immediately. If we happen to have parsed a preceding 2673 // be called immediately. If we happen to have parsed a preceding
2588 // function literal eagerly, we can also compile it eagerly. 2674 // function literal eagerly, we can also compile it eagerly.
2589 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { 2675 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2590 result->AsFunctionLiteral()->set_parenthesized(); 2676 result->AsFunctionLiteral()->set_parenthesized();
2591 } 2677 }
2592 } 2678 }
2593 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); 2679 Scanner::Location spread_pos;
2680 typename Traits::Type::ExpressionList args =
2681 ParseArguments(&spread_pos, CHECK_OK);
2594 2682
2595 // Keep track of eval() calls since they disable all local variable 2683 // Keep track of eval() calls since they disable all local variable
2596 // optimizations. 2684 // optimizations.
2597 // The calls that need special treatment are the 2685 // The calls that need special treatment are the
2598 // direct eval calls. These calls are all of the form eval(...), with 2686 // direct eval calls. These calls are all of the form eval(...), with
2599 // no explicit receiver. 2687 // no explicit receiver.
2600 // These calls are marked as potentially direct eval calls. Whether 2688 // These calls are marked as potentially direct eval calls. Whether
2601 // they are actually direct calls to eval is determined at run time. 2689 // they are actually direct calls to eval is determined at run time.
2602 this->CheckPossibleEvalCall(result, scope_); 2690 this->CheckPossibleEvalCall(result, scope_);
2603 result = factory()->NewCall(result, args, pos); 2691
2692 if (spread_pos.IsValid()) {
2693 args = Traits::PrepareSpreadArguments(args);
2694 result = Traits::SpreadCall(result, args, pos);
2695 } else {
2696 result = factory()->NewCall(result, args, pos);
2697 }
2604 if (fni_ != NULL) fni_->RemoveLastFunction(); 2698 if (fni_ != NULL) fni_->RemoveLastFunction();
2605 break; 2699 break;
2606 } 2700 }
2607 2701
2608 case Token::TEMPLATE_SPAN: 2702 case Token::TEMPLATE_SPAN:
2609 case Token::TEMPLATE_TAIL: { 2703 case Token::TEMPLATE_TAIL: {
2610 int pos; 2704 int pos;
2611 if (scanner()->current_token() == Token::IDENTIFIER) { 2705 if (scanner()->current_token() == Token::IDENTIFIER) {
2612 pos = position(); 2706 pos = position();
2613 } else { 2707 } else {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2664 int new_pos = position(); 2758 int new_pos = position();
2665 ExpressionT result = this->EmptyExpression(); 2759 ExpressionT result = this->EmptyExpression();
2666 if (peek() == Token::SUPER) { 2760 if (peek() == Token::SUPER) {
2667 const bool is_new = true; 2761 const bool is_new = true;
2668 result = ParseSuperExpression(is_new, CHECK_OK); 2762 result = ParseSuperExpression(is_new, CHECK_OK);
2669 } else { 2763 } else {
2670 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); 2764 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
2671 } 2765 }
2672 if (peek() == Token::LPAREN) { 2766 if (peek() == Token::LPAREN) {
2673 // NewExpression with arguments. 2767 // NewExpression with arguments.
2768 Scanner::Location spread_pos;
2674 typename Traits::Type::ExpressionList args = 2769 typename Traits::Type::ExpressionList args =
2675 this->ParseArguments(CHECK_OK); 2770 this->ParseArguments(&spread_pos, CHECK_OK);
2676 result = factory()->NewCallNew(result, args, new_pos); 2771
2772 if (spread_pos.IsValid()) {
2773 args = Traits::PrepareSpreadArguments(args);
2774 result = Traits::SpreadCallNew(result, args, new_pos);
2775 } else {
2776 result = factory()->NewCallNew(result, args, new_pos);
2777 }
2677 // The expression can still continue with . or [ after the arguments. 2778 // The expression can still continue with . or [ after the arguments.
2678 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); 2779 result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
2679 return result; 2780 return result;
2680 } 2781 }
2681 // NewExpression without arguments. 2782 // NewExpression without arguments.
2682 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), 2783 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2683 new_pos); 2784 new_pos);
2684 } 2785 }
2685 // No 'new' or 'super' keyword. 2786 // No 'new' or 'super' keyword.
2686 return this->ParseMemberExpression(ok); 2787 return this->ParseMemberExpression(ok);
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
3076 *ok = false; 3177 *ok = false;
3077 return; 3178 return;
3078 } 3179 }
3079 has_seen_constructor_ = true; 3180 has_seen_constructor_ = true;
3080 return; 3181 return;
3081 } 3182 }
3082 } 3183 }
3083 } } // v8::internal 3184 } } // v8::internal
3084 3185
3085 #endif // V8_PREPARSER_H 3186 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698