| 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 |