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

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: Add more variations to evaluation order tests Created 5 years, 10 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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698