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" |
11 #include "src/expression-classifier.h" | 11 #include "src/expression-classifier.h" |
12 #include "src/func-name-inferrer.h" | 12 #include "src/func-name-inferrer.h" |
13 #include "src/hashmap.h" | 13 #include "src/hashmap.h" |
14 #include "src/messages.h" | 14 #include "src/messages.h" |
15 #include "src/scanner.h" | 15 #include "src/scanner.h" |
16 #include "src/scopes.h" | 16 #include "src/scopes.h" |
17 #include "src/token.h" | 17 #include "src/token.h" |
18 | 18 |
19 namespace v8 { | 19 namespace v8 { |
20 namespace internal { | 20 namespace internal { |
21 | 21 |
| 22 |
| 23 enum FunctionNameValidity { |
| 24 kFunctionNameIsStrictReserved, |
| 25 kSkipFunctionNameCheck, |
| 26 kFunctionNameValidityUnknown |
| 27 }; |
| 28 |
| 29 |
22 // Common base class shared between parser and pre-parser. Traits encapsulate | 30 // Common base class shared between parser and pre-parser. Traits encapsulate |
23 // the differences between Parser and PreParser: | 31 // the differences between Parser and PreParser: |
24 | 32 |
25 // - Return types: For example, Parser functions return Expression* and | 33 // - Return types: For example, Parser functions return Expression* and |
26 // PreParser functions return PreParserExpression. | 34 // PreParser functions return PreParserExpression. |
27 | 35 |
28 // - Creating parse tree nodes: Parser generates an AST during the recursive | 36 // - Creating parse tree nodes: Parser generates an AST during the recursive |
29 // descent. PreParser doesn't create a tree. Instead, it passes around minimal | 37 // descent. PreParser doesn't create a tree. Instead, it passes around minimal |
30 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain | 38 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain |
31 // just enough data for the upper layer functions. PreParserFactory is | 39 // just enough data for the upper layer functions. PreParserFactory is |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 ok); | 450 ok); |
443 } | 451 } |
444 | 452 |
445 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 453 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
446 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, | 454 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, |
447 ok); | 455 ok); |
448 } | 456 } |
449 | 457 |
450 // Checking the name of a function literal. This has to be done after parsing | 458 // Checking the name of a function literal. This has to be done after parsing |
451 // the function, since the function can declare itself strict. | 459 // the function, since the function can declare itself strict. |
452 void CheckFunctionName(LanguageMode language_mode, FunctionKind kind, | 460 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, |
453 IdentifierT function_name, | 461 FunctionNameValidity function_name_validity, |
454 bool function_name_is_strict_reserved, | 462 const Scanner::Location& function_name_loc, bool* ok) { |
455 const Scanner::Location& function_name_loc, | 463 if (function_name_validity == kSkipFunctionNameCheck) return; |
456 bool* ok) { | |
457 // Property names are never checked. | |
458 if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return; | |
459 // The function name needs to be checked in strict mode. | 464 // The function name needs to be checked in strict mode. |
460 if (is_sloppy(language_mode)) return; | 465 if (is_sloppy(language_mode)) return; |
461 | 466 |
462 if (this->IsEvalOrArguments(function_name)) { | 467 if (this->IsEvalOrArguments(function_name)) { |
463 Traits::ReportMessageAt(function_name_loc, | 468 Traits::ReportMessageAt(function_name_loc, |
464 MessageTemplate::kStrictEvalArguments); | 469 MessageTemplate::kStrictEvalArguments); |
465 *ok = false; | 470 *ok = false; |
466 return; | 471 return; |
467 } | 472 } |
468 if (function_name_is_strict_reserved) { | 473 if (function_name_validity == kFunctionNameIsStrictReserved) { |
469 Traits::ReportMessageAt(function_name_loc, | 474 Traits::ReportMessageAt(function_name_loc, |
470 MessageTemplate::kUnexpectedStrictReserved); | 475 MessageTemplate::kUnexpectedStrictReserved); |
471 *ok = false; | 476 *ok = false; |
472 return; | 477 return; |
473 } | 478 } |
474 if (is_strong(language_mode) && this->IsUndefined(function_name)) { | 479 if (is_strong(language_mode) && this->IsUndefined(function_name)) { |
475 Traits::ReportMessageAt(function_name_loc, | 480 Traits::ReportMessageAt(function_name_loc, |
476 MessageTemplate::kStrongUndefined); | 481 MessageTemplate::kStrongUndefined); |
477 *ok = false; | 482 *ok = false; |
478 return; | 483 return; |
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 | 1618 |
1614 void DeclareFormalParameter(void* parsing_state, PreParserExpression pattern, | 1619 void DeclareFormalParameter(void* parsing_state, PreParserExpression pattern, |
1615 ExpressionClassifier* classifier, bool is_rest) {} | 1620 ExpressionClassifier* classifier, bool is_rest) {} |
1616 | 1621 |
1617 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} | 1622 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
1618 | 1623 |
1619 // Temporary glue; these functions will move to ParserBase. | 1624 // Temporary glue; these functions will move to ParserBase. |
1620 PreParserExpression ParseV8Intrinsic(bool* ok); | 1625 PreParserExpression ParseV8Intrinsic(bool* ok); |
1621 PreParserExpression ParseFunctionLiteral( | 1626 PreParserExpression ParseFunctionLiteral( |
1622 PreParserIdentifier name, Scanner::Location function_name_location, | 1627 PreParserIdentifier name, Scanner::Location function_name_location, |
1623 bool name_is_strict_reserved, FunctionKind kind, | 1628 FunctionNameValidity function_name_validity, FunctionKind kind, |
1624 int function_token_position, FunctionLiteral::FunctionType type, | 1629 int function_token_position, FunctionLiteral::FunctionType type, |
1625 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1630 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1626 | 1631 |
1627 PreParserExpression ParseClassLiteral(PreParserIdentifier name, | 1632 PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
1628 Scanner::Location class_name_location, | 1633 Scanner::Location class_name_location, |
1629 bool name_is_strict_reserved, int pos, | 1634 bool name_is_strict_reserved, int pos, |
1630 bool* ok); | 1635 bool* ok); |
1631 | 1636 |
1632 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) { | 1637 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) { |
1633 return list; | 1638 return list; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1761 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, | 1766 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, |
1762 int* expected_property_count, bool* ok); | 1767 int* expected_property_count, bool* ok); |
1763 V8_INLINE PreParserStatementList | 1768 V8_INLINE PreParserStatementList |
1764 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1769 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1765 const FormalParameterParsingStateT& formal_parameters, | 1770 const FormalParameterParsingStateT& formal_parameters, |
1766 Variable* fvar, Token::Value fvar_init_op, | 1771 Variable* fvar, Token::Value fvar_init_op, |
1767 FunctionKind kind, bool* ok); | 1772 FunctionKind kind, bool* ok); |
1768 | 1773 |
1769 Expression ParseFunctionLiteral( | 1774 Expression ParseFunctionLiteral( |
1770 Identifier name, Scanner::Location function_name_location, | 1775 Identifier name, Scanner::Location function_name_location, |
1771 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 1776 FunctionNameValidity function_name_validity, FunctionKind kind, |
1772 FunctionLiteral::FunctionType function_type, | 1777 int function_token_pos, FunctionLiteral::FunctionType function_type, |
1773 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1778 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1774 void ParseLazyFunctionLiteralBody(bool* ok, | 1779 void ParseLazyFunctionLiteralBody(bool* ok, |
1775 Scanner::BookmarkScope* bookmark = nullptr); | 1780 Scanner::BookmarkScope* bookmark = nullptr); |
1776 | 1781 |
1777 PreParserExpression ParseClassLiteral(PreParserIdentifier name, | 1782 PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
1778 Scanner::Location class_name_location, | 1783 Scanner::Location class_name_location, |
1779 bool name_is_strict_reserved, int pos, | 1784 bool name_is_strict_reserved, int pos, |
1780 bool* ok); | 1785 bool* ok); |
1781 }; | 1786 }; |
1782 | 1787 |
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2536 | 2541 |
2537 if (in_class && !is_static && this->IsConstructor(name)) { | 2542 if (in_class && !is_static && this->IsConstructor(name)) { |
2538 *has_seen_constructor = true; | 2543 *has_seen_constructor = true; |
2539 kind = has_extends ? FunctionKind::kSubclassConstructor | 2544 kind = has_extends ? FunctionKind::kSubclassConstructor |
2540 : FunctionKind::kBaseConstructor; | 2545 : FunctionKind::kBaseConstructor; |
2541 } | 2546 } |
2542 | 2547 |
2543 if (!in_class) kind = WithObjectLiteralBit(kind); | 2548 if (!in_class) kind = WithObjectLiteralBit(kind); |
2544 | 2549 |
2545 value = this->ParseFunctionLiteral( | 2550 value = this->ParseFunctionLiteral( |
2546 name, scanner()->location(), | 2551 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2547 false, // reserved words are allowed here | 2552 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
2548 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | |
2549 FunctionLiteral::NORMAL_ARITY, | 2553 FunctionLiteral::NORMAL_ARITY, |
2550 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2554 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2551 | 2555 |
2552 return factory()->NewObjectLiteralProperty(name_expression, value, | 2556 return factory()->NewObjectLiteralProperty(name_expression, value, |
2553 ObjectLiteralProperty::COMPUTED, | 2557 ObjectLiteralProperty::COMPUTED, |
2554 is_static, *is_computed_name); | 2558 is_static, *is_computed_name); |
2555 | 2559 |
2556 } else if (in_class && name_is_static && !is_static) { | 2560 } else if (in_class && name_is_static && !is_static) { |
2557 // static MethodDefinition | 2561 // static MethodDefinition |
2558 return ParsePropertyDefinition(checker, true, has_extends, true, | 2562 return ParsePropertyDefinition(checker, true, has_extends, true, |
(...skipping 10 matching lines...) Expand all Loading... |
2569 | 2573 |
2570 if (!*is_computed_name) { | 2574 if (!*is_computed_name) { |
2571 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 2575 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
2572 is_generator, | 2576 is_generator, |
2573 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2577 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2574 } | 2578 } |
2575 | 2579 |
2576 FunctionKind kind = FunctionKind::kAccessorFunction; | 2580 FunctionKind kind = FunctionKind::kAccessorFunction; |
2577 if (!in_class) kind = WithObjectLiteralBit(kind); | 2581 if (!in_class) kind = WithObjectLiteralBit(kind); |
2578 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 2582 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
2579 name, scanner()->location(), | 2583 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2580 false, // reserved words are allowed here | 2584 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
2581 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | |
2582 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, | 2585 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, |
2583 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2586 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2584 | 2587 |
2585 // Make sure the name expression is a string since we need a Name for | 2588 // Make sure the name expression is a string since we need a Name for |
2586 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | 2589 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this |
2587 // statically we can skip the extra runtime check. | 2590 // statically we can skip the extra runtime check. |
2588 if (!*is_computed_name) { | 2591 if (!*is_computed_name) { |
2589 name_expression = | 2592 name_expression = |
2590 factory()->NewStringLiteral(name, name_expression->position()); | 2593 factory()->NewStringLiteral(name, name_expression->position()); |
2591 } | 2594 } |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3286 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3289 Scanner::Location function_name_location = Scanner::Location::invalid(); |
3287 FunctionLiteral::FunctionType function_type = | 3290 FunctionLiteral::FunctionType function_type = |
3288 FunctionLiteral::ANONYMOUS_EXPRESSION; | 3291 FunctionLiteral::ANONYMOUS_EXPRESSION; |
3289 if (peek_any_identifier()) { | 3292 if (peek_any_identifier()) { |
3290 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3293 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
3291 CHECK_OK); | 3294 CHECK_OK); |
3292 function_name_location = scanner()->location(); | 3295 function_name_location = scanner()->location(); |
3293 function_type = FunctionLiteral::NAMED_EXPRESSION; | 3296 function_type = FunctionLiteral::NAMED_EXPRESSION; |
3294 } | 3297 } |
3295 result = this->ParseFunctionLiteral( | 3298 result = this->ParseFunctionLiteral( |
3296 name, function_name_location, is_strict_reserved_name, | 3299 name, function_name_location, |
| 3300 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
| 3301 : kFunctionNameValidityUnknown, |
3297 is_generator ? FunctionKind::kGeneratorFunction | 3302 is_generator ? FunctionKind::kGeneratorFunction |
3298 : FunctionKind::kNormalFunction, | 3303 : FunctionKind::kNormalFunction, |
3299 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | 3304 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, |
3300 CHECK_OK); | 3305 CHECK_OK); |
3301 } else if (peek() == Token::SUPER) { | 3306 } else if (peek() == Token::SUPER) { |
3302 const bool is_new = false; | 3307 const bool is_new = false; |
3303 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 3308 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
3304 } else { | 3309 } else { |
3305 result = ParsePrimaryExpression(classifier, CHECK_OK); | 3310 result = ParsePrimaryExpression(classifier, CHECK_OK); |
3306 } | 3311 } |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3973 *ok = false; | 3978 *ok = false; |
3974 return; | 3979 return; |
3975 } | 3980 } |
3976 has_seen_constructor_ = true; | 3981 has_seen_constructor_ = true; |
3977 return; | 3982 return; |
3978 } | 3983 } |
3979 } | 3984 } |
3980 } } // v8::internal | 3985 } } // v8::internal |
3981 | 3986 |
3982 #endif // V8_PREPARSER_H | 3987 #endif // V8_PREPARSER_H |
OLD | NEW |