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 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 546 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
547 ExpressionT ParseArrayLiteral(bool* ok); | 547 ExpressionT ParseArrayLiteral(bool* ok); |
548 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 548 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
549 bool* is_static, bool* is_computed_name, | 549 bool* is_static, bool* is_computed_name, |
550 bool* ok); | 550 bool* ok); |
551 ExpressionT ParseObjectLiteral(bool* ok); | 551 ExpressionT ParseObjectLiteral(bool* ok); |
552 ObjectLiteralPropertyT ParsePropertyDefinition( | 552 ObjectLiteralPropertyT ParsePropertyDefinition( |
553 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 553 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
554 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 554 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
555 bool* ok); | 555 bool* ok); |
556 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 556 typename Traits::Type::ExpressionList ParseArguments( |
| 557 Scanner::Location* first_spread_pos, bool* ok); |
557 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 558 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
558 ExpressionT ParseYieldExpression(bool* ok); | 559 ExpressionT ParseYieldExpression(bool* ok); |
559 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 560 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
560 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 561 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
561 ExpressionT ParseUnaryExpression(bool* ok); | 562 ExpressionT ParseUnaryExpression(bool* ok); |
562 ExpressionT ParsePostfixExpression(bool* ok); | 563 ExpressionT ParsePostfixExpression(bool* ok); |
563 ExpressionT ParseLeftHandSideExpression(bool* ok); | 564 ExpressionT ParseLeftHandSideExpression(bool* ok); |
564 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 565 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
565 ExpressionT ParseMemberExpression(bool* ok); | 566 ExpressionT ParseMemberExpression(bool* ok); |
566 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 567 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
567 bool* ok); | 568 bool* ok); |
568 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 569 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
569 bool* ok); | 570 bool* ok); |
570 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 571 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
571 void AddTemplateExpression(ExpressionT); | 572 void AddTemplateExpression(ExpressionT); |
572 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 573 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
573 | 574 |
574 // Checks if the expression is a valid reference expression (e.g., on the | 575 // Checks if the expression is a valid reference expression (e.g., on the |
575 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 576 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
576 // we allow calls for web compatibility and rewrite them to a runtime throw. | 577 // we allow calls for web compatibility and rewrite them to a runtime throw. |
577 ExpressionT CheckAndRewriteReferenceExpression( | 578 ExpressionT CheckAndRewriteReferenceExpression( |
578 ExpressionT expression, | 579 ExpressionT expression, |
579 Scanner::Location location, const char* message, bool* ok); | 580 Scanner::Location location, const char* message, bool* ok); |
580 | 581 |
| 582 ExpressionT MaybeSpread(ExpressionT expression, bool is_spread, int pos) { |
| 583 if (is_spread) { |
| 584 return factory()->NewSpreadOperation(scope_, expression, pos); |
| 585 } |
| 586 return expression; |
| 587 } |
| 588 |
581 // Used to validate property names in object literals and class literals | 589 // Used to validate property names in object literals and class literals |
582 enum PropertyKind { | 590 enum PropertyKind { |
583 kAccessorProperty, | 591 kAccessorProperty, |
584 kValueProperty, | 592 kValueProperty, |
585 kMethodProperty | 593 kMethodProperty |
586 }; | 594 }; |
587 | 595 |
588 class ObjectLiteralCheckerBase { | 596 class ObjectLiteralCheckerBase { |
589 public: | 597 public: |
590 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | 598 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 friend class PreParserExpression; | 763 friend class PreParserExpression; |
756 }; | 764 }; |
757 | 765 |
758 | 766 |
759 class PreParserExpression { | 767 class PreParserExpression { |
760 public: | 768 public: |
761 static PreParserExpression Default() { | 769 static PreParserExpression Default() { |
762 return PreParserExpression(TypeField::encode(kExpression)); | 770 return PreParserExpression(TypeField::encode(kExpression)); |
763 } | 771 } |
764 | 772 |
| 773 static PreParserExpression Spread(PreParserExpression expression) { |
| 774 DCHECK(!expression.IsSpreadExpression() || expression.is_parenthesized()); |
| 775 return PreParserExpression(TypeField::encode(kSpreadExpression)); |
| 776 } |
| 777 |
765 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 778 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
766 return PreParserExpression(TypeField::encode(kIdentifierExpression) | | 779 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
767 IdentifierTypeField::encode(id.type_)); | 780 IdentifierTypeField::encode(id.type_)); |
768 } | 781 } |
769 | 782 |
770 static PreParserExpression BinaryOperation(PreParserExpression left, | 783 static PreParserExpression BinaryOperation(PreParserExpression left, |
771 Token::Value op, | 784 Token::Value op, |
772 PreParserExpression right) { | 785 PreParserExpression right) { |
773 bool valid_arrow_param_list = | 786 bool valid_arrow_param_list = |
774 op == Token::COMMA && !left.is_parenthesized() && | 787 op == Token::COMMA && !left.is_parenthesized() && |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 | 901 |
889 // At the moment PreParser doesn't track these expression types. | 902 // At the moment PreParser doesn't track these expression types. |
890 bool IsFunctionLiteral() const { return false; } | 903 bool IsFunctionLiteral() const { return false; } |
891 bool IsCallNew() const { return false; } | 904 bool IsCallNew() const { return false; } |
892 | 905 |
893 bool IsNoTemplateTag() const { | 906 bool IsNoTemplateTag() const { |
894 return TypeField::decode(code_) == kExpression && | 907 return TypeField::decode(code_) == kExpression && |
895 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 908 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
896 } | 909 } |
897 | 910 |
| 911 bool IsSpreadExpression() const { |
| 912 return TypeField::decode(code_) == kSpreadExpression; |
| 913 } |
| 914 |
898 PreParserExpression AsFunctionLiteral() { return *this; } | 915 PreParserExpression AsFunctionLiteral() { return *this; } |
899 | 916 |
900 bool IsBinaryOperation() const { | 917 bool IsBinaryOperation() const { |
901 return TypeField::decode(code_) == kBinaryOperationExpression; | 918 return TypeField::decode(code_) == kBinaryOperationExpression; |
902 } | 919 } |
903 | 920 |
904 bool is_parenthesized() const { | 921 bool is_parenthesized() const { |
905 return ParenthesizationField::decode(code_) != kNotParenthesized; | 922 return ParenthesizationField::decode(code_) != kNotParenthesized; |
906 } | 923 } |
907 | 924 |
(...skipping 12 matching lines...) Expand all Loading... |
920 void set_parenthesized() {} | 937 void set_parenthesized() {} |
921 | 938 |
922 int position() const { return RelocInfo::kNoPosition; } | 939 int position() const { return RelocInfo::kNoPosition; } |
923 void set_function_token_position(int position) {} | 940 void set_function_token_position(int position) {} |
924 | 941 |
925 private: | 942 private: |
926 enum Type { | 943 enum Type { |
927 kExpression, | 944 kExpression, |
928 kIdentifierExpression, | 945 kIdentifierExpression, |
929 kStringLiteralExpression, | 946 kStringLiteralExpression, |
930 kBinaryOperationExpression | 947 kBinaryOperationExpression, |
| 948 kSpreadExpression |
931 }; | 949 }; |
932 | 950 |
933 enum Parenthesization { | 951 enum Parenthesization { |
934 kNotParenthesized, | 952 kNotParenthesized, |
935 kParanthesizedExpression, | 953 kParanthesizedExpression, |
936 kMultiParenthesizedExpression | 954 kMultiParenthesizedExpression |
937 }; | 955 }; |
938 | 956 |
939 enum ExpressionType { | 957 enum ExpressionType { |
940 kThisExpression, | 958 kThisExpression, |
941 kThisPropertyExpression, | 959 kThisPropertyExpression, |
942 kPropertyExpression, | 960 kPropertyExpression, |
943 kCallExpression, | 961 kCallExpression, |
944 kSuperExpression, | 962 kSuperExpression, |
945 kNoTemplateTagExpression | 963 kNoTemplateTagExpression |
946 }; | 964 }; |
947 | 965 |
948 explicit PreParserExpression(uint32_t expression_code) | 966 explicit PreParserExpression(uint32_t expression_code) |
949 : code_(expression_code) {} | 967 : code_(expression_code) {} |
950 | 968 |
951 V8_INLINE bool IsValidArrowParams() const { | 969 V8_INLINE bool IsValidArrowParams() const { |
952 return IsBinaryOperation() | 970 return IsBinaryOperation() |
953 ? IsValidArrowParamListField::decode(code_) | 971 ? IsValidArrowParamListField::decode(code_) |
954 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 972 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); |
955 } | 973 } |
956 | 974 |
957 // The first four bits are for the Type and Parenthesization. | 975 // The first four bits are for the Type and Parenthesization. |
958 typedef BitField<Type, 0, 2> TypeField; | 976 typedef BitField<Type, 0, 3> TypeField; |
959 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 977 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
960 | 978 |
961 // The rest of the bits are interpreted depending on the value | 979 // The rest of the bits are interpreted depending on the value |
962 // of the Type field, so they can share the storage. | 980 // of the Type field, so they can share the storage. |
963 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 981 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
964 ExpressionTypeField; | 982 ExpressionTypeField; |
965 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 983 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
966 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 984 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
967 typedef BitField<bool, ParenthesizationField::kNext, 1> | 985 typedef BitField<bool, ParenthesizationField::kNext, 1> |
968 IsValidArrowParamListField; | 986 IsValidArrowParamListField; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 Scope* scope, PreParserStatementList body, int materialized_literal_count, | 1183 Scope* scope, PreParserStatementList body, int materialized_literal_count, |
1166 int expected_property_count, int handler_count, int parameter_count, | 1184 int expected_property_count, int handler_count, int parameter_count, |
1167 FunctionLiteral::ParameterFlag has_duplicate_parameters, | 1185 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
1168 FunctionLiteral::FunctionType function_type, | 1186 FunctionLiteral::FunctionType function_type, |
1169 FunctionLiteral::IsFunctionFlag is_function, | 1187 FunctionLiteral::IsFunctionFlag is_function, |
1170 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, | 1188 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, |
1171 int position) { | 1189 int position) { |
1172 return PreParserExpression::Default(); | 1190 return PreParserExpression::Default(); |
1173 } | 1191 } |
1174 | 1192 |
| 1193 PreParserExpression NewSpreadOperation( |
| 1194 Scope* scope, PreParserExpression expression, int pos) { |
| 1195 return PreParserExpression::Spread(expression); |
| 1196 } |
| 1197 |
1175 // Return the object itself as AstVisitor and implement the needed | 1198 // Return the object itself as AstVisitor and implement the needed |
1176 // dummy method right in this class. | 1199 // dummy method right in this class. |
1177 PreParserFactory* visitor() { return this; } | 1200 PreParserFactory* visitor() { return this; } |
1178 int* ast_properties() { | 1201 int* ast_properties() { |
1179 static int dummy = 42; | 1202 static int dummy = 42; |
1180 return &dummy; | 1203 return &dummy; |
1181 } | 1204 } |
1182 }; | 1205 }; |
1183 | 1206 |
1184 | 1207 |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1472 PreParserIdentifier name, Scanner::Location function_name_location, | 1495 PreParserIdentifier name, Scanner::Location function_name_location, |
1473 bool name_is_strict_reserved, FunctionKind kind, | 1496 bool name_is_strict_reserved, FunctionKind kind, |
1474 int function_token_position, FunctionLiteral::FunctionType type, | 1497 int function_token_position, FunctionLiteral::FunctionType type, |
1475 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1498 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1476 | 1499 |
1477 PreParserExpression ParseClassLiteral(PreParserIdentifier name, | 1500 PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
1478 Scanner::Location class_name_location, | 1501 Scanner::Location class_name_location, |
1479 bool name_is_strict_reserved, int pos, | 1502 bool name_is_strict_reserved, int pos, |
1480 bool* ok); | 1503 bool* ok); |
1481 | 1504 |
| 1505 static void MarkSpreadCall(PreParserExpression call) {} |
| 1506 |
1482 private: | 1507 private: |
1483 PreParser* pre_parser_; | 1508 PreParser* pre_parser_; |
1484 }; | 1509 }; |
1485 | 1510 |
1486 | 1511 |
1487 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1512 // Preparsing checks a JavaScript program and emits preparse-data that helps |
1488 // a later parsing to be faster. | 1513 // a later parsing to be faster. |
1489 // See preparse-data-format.h for the data format. | 1514 // See preparse-data-format.h for the data format. |
1490 | 1515 |
1491 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1516 // The PreParser checks that the syntax follows the grammar for JavaScript, |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2260 return factory()->NewObjectLiteral(properties, | 2285 return factory()->NewObjectLiteral(properties, |
2261 literal_index, | 2286 literal_index, |
2262 number_of_boilerplate_properties, | 2287 number_of_boilerplate_properties, |
2263 has_function, | 2288 has_function, |
2264 pos); | 2289 pos); |
2265 } | 2290 } |
2266 | 2291 |
2267 | 2292 |
2268 template <class Traits> | 2293 template <class Traits> |
2269 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2294 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
2270 bool* ok) { | 2295 Scanner::Location* first_spread, bool* ok) { |
2271 // Arguments :: | 2296 // Arguments :: |
2272 // '(' (AssignmentExpression)*[','] ')' | 2297 // '(' (AssignmentExpression)*[','] ')' |
2273 | 2298 Scanner::Location spread_loc = Scanner::Location::invalid(); |
2274 typename Traits::Type::ExpressionList result = | 2299 typename Traits::Type::ExpressionList result = |
2275 this->NewExpressionList(4, zone_); | 2300 this->NewExpressionList(4, zone_); |
2276 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2301 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2277 bool done = (peek() == Token::RPAREN); | 2302 bool done = (peek() == Token::RPAREN); |
2278 while (!done) { | 2303 while (!done) { |
| 2304 bool is_spread = peek() == Token::ELLIPSIS; |
| 2305 bool first_spread = false; |
| 2306 int spread_pos = -1; |
| 2307 if (is_spread) { |
| 2308 spread_pos = peek_position(); |
| 2309 first_spread = spread_loc.beg_pos < 0; |
| 2310 if (first_spread) { |
| 2311 spread_loc.beg_pos = spread_pos; |
| 2312 } |
| 2313 Consume(Token::ELLIPSIS); |
| 2314 } |
2279 ExpressionT argument = this->ParseAssignmentExpression( | 2315 ExpressionT argument = this->ParseAssignmentExpression( |
2280 true, CHECK_OK_CUSTOM(NullExpressionList)); | 2316 true, CHECK_OK_CUSTOM(NullExpressionList)); |
2281 result->Add(argument, zone_); | 2317 if (first_spread) { |
| 2318 spread_loc.end_pos = peek_position(); |
| 2319 } |
| 2320 result->Add(MaybeSpread(argument, is_spread, spread_pos), zone_); |
2282 if (result->length() > Code::kMaxArguments) { | 2321 if (result->length() > Code::kMaxArguments) { |
2283 ReportMessage("too_many_arguments"); | 2322 ReportMessage("too_many_arguments"); |
2284 *ok = false; | 2323 *ok = false; |
2285 return this->NullExpressionList(); | 2324 return this->NullExpressionList(); |
2286 } | 2325 } |
2287 done = (peek() == Token::RPAREN); | 2326 done = (peek() == Token::RPAREN); |
2288 if (!done) { | 2327 if (!done) { |
2289 // Need {} because of the CHECK_OK_CUSTOM macro. | 2328 // Need {} because of the CHECK_OK_CUSTOM macro. |
2290 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); | 2329 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); |
2291 } | 2330 } |
2292 } | 2331 } |
2293 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2332 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2333 *first_spread = spread_loc; |
2294 return result; | 2334 return result; |
2295 } | 2335 } |
2296 | 2336 |
2297 // Precedence = 2 | 2337 // Precedence = 2 |
2298 template <class Traits> | 2338 template <class Traits> |
2299 typename ParserBase<Traits>::ExpressionT | 2339 typename ParserBase<Traits>::ExpressionT |
2300 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2340 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
2301 // AssignmentExpression :: | 2341 // AssignmentExpression :: |
2302 // ConditionalExpression | 2342 // ConditionalExpression |
2303 // ArrowFunction | 2343 // ArrowFunction |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2587 // should not point to the closing brace otherwise it will intersect | 2627 // should not point to the closing brace otherwise it will intersect |
2588 // with positions recorded for function literal and confuse debugger. | 2628 // with positions recorded for function literal and confuse debugger. |
2589 pos = peek_position(); | 2629 pos = peek_position(); |
2590 // Also the trailing parenthesis are a hint that the function will | 2630 // Also the trailing parenthesis are a hint that the function will |
2591 // be called immediately. If we happen to have parsed a preceding | 2631 // be called immediately. If we happen to have parsed a preceding |
2592 // function literal eagerly, we can also compile it eagerly. | 2632 // function literal eagerly, we can also compile it eagerly. |
2593 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2633 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2594 result->AsFunctionLiteral()->set_parenthesized(); | 2634 result->AsFunctionLiteral()->set_parenthesized(); |
2595 } | 2635 } |
2596 } | 2636 } |
2597 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); | 2637 |
| 2638 Scanner::Location spread_pos; |
| 2639 typename Traits::Type::ExpressionList args = |
| 2640 ParseArguments(&spread_pos, CHECK_OK); |
2598 | 2641 |
2599 // Keep track of eval() calls since they disable all local variable | 2642 // Keep track of eval() calls since they disable all local variable |
2600 // optimizations. | 2643 // optimizations. |
2601 // The calls that need special treatment are the | 2644 // The calls that need special treatment are the |
2602 // direct eval calls. These calls are all of the form eval(...), with | 2645 // direct eval calls. These calls are all of the form eval(...), with |
2603 // no explicit receiver. | 2646 // no explicit receiver. |
2604 // These calls are marked as potentially direct eval calls. Whether | 2647 // These calls are marked as potentially direct eval calls. Whether |
2605 // they are actually direct calls to eval is determined at run time. | 2648 // they are actually direct calls to eval is determined at run time. |
2606 this->CheckPossibleEvalCall(result, scope_); | 2649 this->CheckPossibleEvalCall(result, scope_); |
2607 result = factory()->NewCall(result, args, pos); | 2650 result = factory()->NewCall(result, args, pos); |
| 2651 if (spread_pos.IsValid()) { |
| 2652 Traits::MarkSpreadCall(result); |
| 2653 } |
2608 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2654 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2609 break; | 2655 break; |
2610 } | 2656 } |
2611 | 2657 |
2612 case Token::TEMPLATE_SPAN: | 2658 case Token::TEMPLATE_SPAN: |
2613 case Token::TEMPLATE_TAIL: { | 2659 case Token::TEMPLATE_TAIL: { |
2614 int pos; | 2660 int pos; |
2615 if (scanner()->current_token() == Token::IDENTIFIER) { | 2661 if (scanner()->current_token() == Token::IDENTIFIER) { |
2616 pos = position(); | 2662 pos = position(); |
2617 } else { | 2663 } else { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2668 int new_pos = position(); | 2714 int new_pos = position(); |
2669 ExpressionT result = this->EmptyExpression(); | 2715 ExpressionT result = this->EmptyExpression(); |
2670 if (peek() == Token::SUPER) { | 2716 if (peek() == Token::SUPER) { |
2671 const bool is_new = true; | 2717 const bool is_new = true; |
2672 result = ParseSuperExpression(is_new, CHECK_OK); | 2718 result = ParseSuperExpression(is_new, CHECK_OK); |
2673 } else { | 2719 } else { |
2674 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2720 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
2675 } | 2721 } |
2676 if (peek() == Token::LPAREN) { | 2722 if (peek() == Token::LPAREN) { |
2677 // NewExpression with arguments. | 2723 // NewExpression with arguments. |
| 2724 Scanner::Location spread_pos; |
2678 typename Traits::Type::ExpressionList args = | 2725 typename Traits::Type::ExpressionList args = |
2679 this->ParseArguments(CHECK_OK); | 2726 this->ParseArguments(&spread_pos, CHECK_OK); |
| 2727 |
| 2728 // TODO(caitp): support spread-calls in CallNew() |
| 2729 if (spread_pos.IsValid()) { |
| 2730 Traits::ReportMessageAt(spread_pos, "spreadcall_construct"); |
| 2731 *ok = false; |
| 2732 return Traits::EmptyExpression(); |
| 2733 } |
| 2734 |
2680 result = factory()->NewCallNew(result, args, new_pos); | 2735 result = factory()->NewCallNew(result, args, new_pos); |
2681 // The expression can still continue with . or [ after the arguments. | 2736 // The expression can still continue with . or [ after the arguments. |
2682 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2737 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
2683 return result; | 2738 return result; |
2684 } | 2739 } |
2685 // NewExpression without arguments. | 2740 // NewExpression without arguments. |
2686 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2741 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
2687 new_pos); | 2742 new_pos); |
2688 } | 2743 } |
2689 // No 'new' or 'super' keyword. | 2744 // No 'new' or 'super' keyword. |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3082 *ok = false; | 3137 *ok = false; |
3083 return; | 3138 return; |
3084 } | 3139 } |
3085 has_seen_constructor_ = true; | 3140 has_seen_constructor_ = true; |
3086 return; | 3141 return; |
3087 } | 3142 } |
3088 } | 3143 } |
3089 } } // v8::internal | 3144 } } // v8::internal |
3090 | 3145 |
3091 #endif // V8_PREPARSER_H | 3146 #endif // V8_PREPARSER_H |
OLD | NEW |