| 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 } | 144 } |
| 145 void set_allow_harmony_rest_params(bool allow) { | 145 void set_allow_harmony_rest_params(bool allow) { |
| 146 allow_harmony_rest_params_ = allow; | 146 allow_harmony_rest_params_ = allow; |
| 147 } | 147 } |
| 148 void set_allow_harmony_spreadcalls(bool allow) { | 148 void set_allow_harmony_spreadcalls(bool allow) { |
| 149 allow_harmony_spreadcalls_ = allow; | 149 allow_harmony_spreadcalls_ = allow; |
| 150 } | 150 } |
| 151 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 151 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
| 152 | 152 |
| 153 protected: | 153 protected: |
| 154 enum AllowEvalOrArgumentsAsIdentifier { | 154 enum AllowRestrictedIdentifiers { |
| 155 kAllowEvalOrArguments, | 155 kAllowRestrictedIdentifiers, |
| 156 kDontAllowEvalOrArguments | 156 kDontAllowRestrictedIdentifiers |
| 157 }; | 157 }; |
| 158 | 158 |
| 159 enum Mode { | 159 enum Mode { |
| 160 PARSE_LAZILY, | 160 PARSE_LAZILY, |
| 161 PARSE_EAGERLY | 161 PARSE_EAGERLY |
| 162 }; | 162 }; |
| 163 | 163 |
| 164 enum VariableDeclarationContext { | 164 enum VariableDeclarationContext { |
| 165 kStatementListItem, | 165 kStatementListItem, |
| 166 kStatement, | 166 kStatement, |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 if (this->IsEvalOrArguments(function_name)) { | 477 if (this->IsEvalOrArguments(function_name)) { |
| 478 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments"); | 478 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments"); |
| 479 *ok = false; | 479 *ok = false; |
| 480 return; | 480 return; |
| 481 } | 481 } |
| 482 if (function_name_is_strict_reserved) { | 482 if (function_name_is_strict_reserved) { |
| 483 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved"); | 483 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved"); |
| 484 *ok = false; | 484 *ok = false; |
| 485 return; | 485 return; |
| 486 } | 486 } |
| 487 if (is_strong(language_mode) && this->IsUndefined(function_name)) { |
| 488 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); |
| 489 *ok = false; |
| 490 return; |
| 491 } |
| 487 } | 492 } |
| 488 | 493 |
| 489 // Checking the parameter names of a function literal. This has to be done | 494 // Checking the parameter names of a function literal. This has to be done |
| 490 // after parsing the function, since the function can declare itself strict. | 495 // after parsing the function, since the function can declare itself strict. |
| 491 void CheckFunctionParameterNames(LanguageMode language_mode, | 496 void CheckFunctionParameterNames(LanguageMode language_mode, |
| 492 bool strict_params, | 497 bool strict_params, |
| 493 const Scanner::Location& eval_args_error_loc, | 498 const Scanner::Location& eval_args_error_loc, |
| 499 const Scanner::Location& undefined_error_loc, |
| 494 const Scanner::Location& dupe_error_loc, | 500 const Scanner::Location& dupe_error_loc, |
| 495 const Scanner::Location& reserved_loc, | 501 const Scanner::Location& reserved_loc, |
| 496 bool* ok) { | 502 bool* ok) { |
| 497 if (is_sloppy(language_mode) && !strict_params) return; | 503 if (is_sloppy(language_mode) && !strict_params) return; |
| 498 | 504 |
| 499 if (is_strict(language_mode) && eval_args_error_loc.IsValid()) { | 505 if (is_strict(language_mode) && eval_args_error_loc.IsValid()) { |
| 500 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); | 506 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); |
| 501 *ok = false; | 507 *ok = false; |
| 502 return; | 508 return; |
| 503 } | 509 } |
| 510 if (is_strong(language_mode) && undefined_error_loc.IsValid()) { |
| 511 Traits::ReportMessageAt(eval_args_error_loc, "strong_undefined"); |
| 512 *ok = false; |
| 513 return; |
| 514 } |
| 504 // TODO(arv): When we add support for destructuring in setters we also need | 515 // TODO(arv): When we add support for destructuring in setters we also need |
| 505 // to check for duplicate names. | 516 // to check for duplicate names. |
| 506 if (dupe_error_loc.IsValid()) { | 517 if (dupe_error_loc.IsValid()) { |
| 507 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe"); | 518 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe"); |
| 508 *ok = false; | 519 *ok = false; |
| 509 return; | 520 return; |
| 510 } | 521 } |
| 511 if (reserved_loc.IsValid()) { | 522 if (reserved_loc.IsValid()) { |
| 512 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); | 523 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); |
| 513 *ok = false; | 524 *ok = false; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 void ReportUnexpectedToken(Token::Value token); | 556 void ReportUnexpectedToken(Token::Value token); |
| 546 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); | 557 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); |
| 547 | 558 |
| 548 // Recursive descent functions: | 559 // Recursive descent functions: |
| 549 | 560 |
| 550 // Parses an identifier that is valid for the current scope, in particular it | 561 // Parses an identifier that is valid for the current scope, in particular it |
| 551 // fails on strict mode future reserved keywords in a strict scope. If | 562 // fails on strict mode future reserved keywords in a strict scope. If |
| 552 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 563 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 553 // "arguments" as identifier even in strict mode (this is needed in cases like | 564 // "arguments" as identifier even in strict mode (this is needed in cases like |
| 554 // "var foo = eval;"). | 565 // "var foo = eval;"). |
| 555 IdentifierT ParseIdentifier( | 566 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
| 556 AllowEvalOrArgumentsAsIdentifier, | |
| 557 bool* ok); | |
| 558 // Parses an identifier or a strict mode future reserved word, and indicate | 567 // Parses an identifier or a strict mode future reserved word, and indicate |
| 559 // whether it is strict mode future reserved. | 568 // whether it is strict mode future reserved. |
| 560 IdentifierT ParseIdentifierOrStrictReservedWord( | 569 IdentifierT ParseIdentifierOrStrictReservedWord( |
| 561 bool* is_strict_reserved, | 570 bool* is_strict_reserved, |
| 562 bool* ok); | 571 bool* ok); |
| 563 IdentifierT ParseIdentifierName(bool* ok); | 572 IdentifierT ParseIdentifierName(bool* ok); |
| 564 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 573 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
| 565 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 574 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 566 bool* is_set, | 575 bool* is_set, |
| 567 bool* ok); | 576 bool* ok); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 711 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 703 static PreParserIdentifier Default() { | 712 static PreParserIdentifier Default() { |
| 704 return PreParserIdentifier(kUnknownIdentifier); | 713 return PreParserIdentifier(kUnknownIdentifier); |
| 705 } | 714 } |
| 706 static PreParserIdentifier Eval() { | 715 static PreParserIdentifier Eval() { |
| 707 return PreParserIdentifier(kEvalIdentifier); | 716 return PreParserIdentifier(kEvalIdentifier); |
| 708 } | 717 } |
| 709 static PreParserIdentifier Arguments() { | 718 static PreParserIdentifier Arguments() { |
| 710 return PreParserIdentifier(kArgumentsIdentifier); | 719 return PreParserIdentifier(kArgumentsIdentifier); |
| 711 } | 720 } |
| 721 static PreParserIdentifier Undefined() { |
| 722 return PreParserIdentifier(kUndefinedIdentifier); |
| 723 } |
| 712 static PreParserIdentifier FutureReserved() { | 724 static PreParserIdentifier FutureReserved() { |
| 713 return PreParserIdentifier(kFutureReservedIdentifier); | 725 return PreParserIdentifier(kFutureReservedIdentifier); |
| 714 } | 726 } |
| 715 static PreParserIdentifier FutureStrictReserved() { | 727 static PreParserIdentifier FutureStrictReserved() { |
| 716 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 728 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
| 717 } | 729 } |
| 718 static PreParserIdentifier Let() { | 730 static PreParserIdentifier Let() { |
| 719 return PreParserIdentifier(kLetIdentifier); | 731 return PreParserIdentifier(kLetIdentifier); |
| 720 } | 732 } |
| 721 static PreParserIdentifier Static() { | 733 static PreParserIdentifier Static() { |
| 722 return PreParserIdentifier(kStaticIdentifier); | 734 return PreParserIdentifier(kStaticIdentifier); |
| 723 } | 735 } |
| 724 static PreParserIdentifier Yield() { | 736 static PreParserIdentifier Yield() { |
| 725 return PreParserIdentifier(kYieldIdentifier); | 737 return PreParserIdentifier(kYieldIdentifier); |
| 726 } | 738 } |
| 727 static PreParserIdentifier Prototype() { | 739 static PreParserIdentifier Prototype() { |
| 728 return PreParserIdentifier(kPrototypeIdentifier); | 740 return PreParserIdentifier(kPrototypeIdentifier); |
| 729 } | 741 } |
| 730 static PreParserIdentifier Constructor() { | 742 static PreParserIdentifier Constructor() { |
| 731 return PreParserIdentifier(kConstructorIdentifier); | 743 return PreParserIdentifier(kConstructorIdentifier); |
| 732 } | 744 } |
| 733 bool IsEval() const { return type_ == kEvalIdentifier; } | 745 bool IsEval() const { return type_ == kEvalIdentifier; } |
| 734 bool IsArguments() const { return type_ == kArgumentsIdentifier; } | 746 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
| 735 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } | 747 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } |
| 748 bool IsUndefined() const { return type_ == kUndefinedIdentifier; } |
| 736 bool IsLet() const { return type_ == kLetIdentifier; } | 749 bool IsLet() const { return type_ == kLetIdentifier; } |
| 737 bool IsStatic() const { return type_ == kStaticIdentifier; } | 750 bool IsStatic() const { return type_ == kStaticIdentifier; } |
| 738 bool IsYield() const { return type_ == kYieldIdentifier; } | 751 bool IsYield() const { return type_ == kYieldIdentifier; } |
| 739 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } | 752 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } |
| 740 bool IsConstructor() const { return type_ == kConstructorIdentifier; } | 753 bool IsConstructor() const { return type_ == kConstructorIdentifier; } |
| 741 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } | 754 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
| 742 bool IsFutureStrictReserved() const { | 755 bool IsFutureStrictReserved() const { |
| 743 return type_ == kFutureStrictReservedIdentifier || | 756 return type_ == kFutureStrictReservedIdentifier || |
| 744 type_ == kLetIdentifier || type_ == kStaticIdentifier || | 757 type_ == kLetIdentifier || type_ == kStaticIdentifier || |
| 745 type_ == kYieldIdentifier; | 758 type_ == kYieldIdentifier; |
| 746 } | 759 } |
| 747 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } | |
| 748 V8_INLINE bool IsValidArrowParam() const { | 760 V8_INLINE bool IsValidArrowParam() const { |
| 749 // A valid identifier can be an arrow function parameter | 761 // A valid identifier can be an arrow function parameter |
| 750 // except for eval, arguments, yield, and reserved keywords. | 762 // except for eval, arguments, yield, and reserved keywords. |
| 751 return !(IsEval() || IsArguments() || IsFutureStrictReserved()); | 763 return !(IsEval() || IsArguments() || IsFutureStrictReserved()); |
| 752 } | 764 } |
| 753 | 765 |
| 754 // Allow identifier->name()[->length()] to work. The preparser | 766 // Allow identifier->name()[->length()] to work. The preparser |
| 755 // does not need the actual positions/lengths of the identifiers. | 767 // does not need the actual positions/lengths of the identifiers. |
| 756 const PreParserIdentifier* operator->() const { return this; } | 768 const PreParserIdentifier* operator->() const { return this; } |
| 757 const PreParserIdentifier raw_name() const { return *this; } | 769 const PreParserIdentifier raw_name() const { return *this; } |
| 758 | 770 |
| 759 int position() const { return 0; } | 771 int position() const { return 0; } |
| 760 int length() const { return 0; } | 772 int length() const { return 0; } |
| 761 | 773 |
| 762 private: | 774 private: |
| 763 enum Type { | 775 enum Type { |
| 764 kUnknownIdentifier, | 776 kUnknownIdentifier, |
| 765 kFutureReservedIdentifier, | 777 kFutureReservedIdentifier, |
| 766 kFutureStrictReservedIdentifier, | 778 kFutureStrictReservedIdentifier, |
| 767 kLetIdentifier, | 779 kLetIdentifier, |
| 768 kStaticIdentifier, | 780 kStaticIdentifier, |
| 769 kYieldIdentifier, | 781 kYieldIdentifier, |
| 770 kEvalIdentifier, | 782 kEvalIdentifier, |
| 771 kArgumentsIdentifier, | 783 kArgumentsIdentifier, |
| 784 kUndefinedIdentifier, |
| 772 kPrototypeIdentifier, | 785 kPrototypeIdentifier, |
| 773 kConstructorIdentifier | 786 kConstructorIdentifier |
| 774 }; | 787 }; |
| 775 explicit PreParserIdentifier(Type type) : type_(type) {} | 788 explicit PreParserIdentifier(Type type) : type_(type) {} |
| 776 Type type_; | 789 Type type_; |
| 777 | 790 |
| 778 friend class PreParserExpression; | 791 friend class PreParserExpression; |
| 779 }; | 792 }; |
| 780 | 793 |
| 781 | 794 |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 } | 1269 } |
| 1257 | 1270 |
| 1258 static bool IsArguments(PreParserIdentifier identifier) { | 1271 static bool IsArguments(PreParserIdentifier identifier) { |
| 1259 return identifier.IsArguments(); | 1272 return identifier.IsArguments(); |
| 1260 } | 1273 } |
| 1261 | 1274 |
| 1262 static bool IsEvalOrArguments(PreParserIdentifier identifier) { | 1275 static bool IsEvalOrArguments(PreParserIdentifier identifier) { |
| 1263 return identifier.IsEvalOrArguments(); | 1276 return identifier.IsEvalOrArguments(); |
| 1264 } | 1277 } |
| 1265 | 1278 |
| 1279 static bool IsUndefined(PreParserIdentifier identifier) { |
| 1280 return identifier.IsUndefined(); |
| 1281 } |
| 1282 |
| 1266 static bool IsPrototype(PreParserIdentifier identifier) { | 1283 static bool IsPrototype(PreParserIdentifier identifier) { |
| 1267 return identifier.IsPrototype(); | 1284 return identifier.IsPrototype(); |
| 1268 } | 1285 } |
| 1269 | 1286 |
| 1270 static bool IsConstructor(PreParserIdentifier identifier) { | 1287 static bool IsConstructor(PreParserIdentifier identifier) { |
| 1271 return identifier.IsConstructor(); | 1288 return identifier.IsConstructor(); |
| 1272 } | 1289 } |
| 1273 | 1290 |
| 1274 // Returns true if the expression is of type "this.foo". | 1291 // Returns true if the expression is of type "this.foo". |
| 1275 static bool IsThisProperty(PreParserExpression expression) { | 1292 static bool IsThisProperty(PreParserExpression expression) { |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1778 return Traits::ReportMessageAt(source_location, | 1795 return Traits::ReportMessageAt(source_location, |
| 1779 "unexpected_template_string"); | 1796 "unexpected_template_string"); |
| 1780 default: | 1797 default: |
| 1781 const char* name = Token::String(token); | 1798 const char* name = Token::String(token); |
| 1782 DCHECK(name != NULL); | 1799 DCHECK(name != NULL); |
| 1783 Traits::ReportMessageAt(source_location, "unexpected_token", name); | 1800 Traits::ReportMessageAt(source_location, "unexpected_token", name); |
| 1784 } | 1801 } |
| 1785 } | 1802 } |
| 1786 | 1803 |
| 1787 | 1804 |
| 1788 template<class Traits> | 1805 template <class Traits> |
| 1789 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | 1806 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
| 1790 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, | 1807 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
| 1791 bool* ok) { | |
| 1792 Token::Value next = Next(); | 1808 Token::Value next = Next(); |
| 1793 if (next == Token::IDENTIFIER) { | 1809 if (next == Token::IDENTIFIER) { |
| 1794 IdentifierT name = this->GetSymbol(scanner()); | 1810 IdentifierT name = this->GetSymbol(scanner()); |
| 1795 if (allow_eval_or_arguments == kDontAllowEvalOrArguments) { | 1811 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { |
| 1796 if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) { | 1812 if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) { |
| 1797 ReportMessage("strict_eval_arguments"); | 1813 ReportMessage("strict_eval_arguments"); |
| 1798 *ok = false; | 1814 *ok = false; |
| 1799 } | 1815 } |
| 1816 if (is_strong(language_mode()) && this->IsUndefined(name)) { |
| 1817 ReportMessage("strong_undefined"); |
| 1818 *ok = false; |
| 1819 } |
| 1800 } else { | 1820 } else { |
| 1801 if (is_strong(language_mode()) && this->IsArguments(name)) { | 1821 if (is_strong(language_mode()) && this->IsArguments(name)) { |
| 1802 ReportMessage("strong_arguments"); | 1822 ReportMessage("strong_arguments"); |
| 1803 *ok = false; | 1823 *ok = false; |
| 1804 } | 1824 } |
| 1805 } | 1825 } |
| 1806 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1826 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
| 1807 return name; | 1827 return name; |
| 1808 } else if (is_sloppy(language_mode()) && | 1828 } else if (is_sloppy(language_mode()) && |
| 1809 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1829 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 1810 next == Token::LET || next == Token::STATIC || | 1830 next == Token::LET || next == Token::STATIC || |
| 1811 (next == Token::YIELD && !is_generator()))) { | 1831 (next == Token::YIELD && !is_generator()))) { |
| 1812 return this->GetSymbol(scanner()); | 1832 return this->GetSymbol(scanner()); |
| 1813 } else { | 1833 } else { |
| 1814 this->ReportUnexpectedToken(next); | 1834 this->ReportUnexpectedToken(next); |
| 1815 *ok = false; | 1835 *ok = false; |
| 1816 return Traits::EmptyIdentifier(); | 1836 return Traits::EmptyIdentifier(); |
| 1817 } | 1837 } |
| 1818 } | 1838 } |
| 1819 | 1839 |
| 1820 | |
| 1821 template <class Traits> | 1840 template <class Traits> |
| 1822 typename ParserBase<Traits>::IdentifierT ParserBase< | 1841 typename ParserBase<Traits>::IdentifierT ParserBase< |
| 1823 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, | 1842 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
| 1824 bool* ok) { | 1843 bool* ok) { |
| 1825 Token::Value next = Next(); | 1844 Token::Value next = Next(); |
| 1826 if (next == Token::IDENTIFIER) { | 1845 if (next == Token::IDENTIFIER) { |
| 1827 *is_strict_reserved = false; | 1846 *is_strict_reserved = false; |
| 1828 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1847 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
| 1829 next == Token::STATIC || | 1848 next == Token::STATIC || |
| 1830 (next == Token::YIELD && !this->is_generator())) { | 1849 (next == Token::YIELD && !this->is_generator())) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1949 result = | 1968 result = |
| 1950 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 1969 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
| 1951 break; | 1970 break; |
| 1952 | 1971 |
| 1953 case Token::IDENTIFIER: | 1972 case Token::IDENTIFIER: |
| 1954 case Token::LET: | 1973 case Token::LET: |
| 1955 case Token::STATIC: | 1974 case Token::STATIC: |
| 1956 case Token::YIELD: | 1975 case Token::YIELD: |
| 1957 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1976 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1958 // Using eval or arguments in this context is OK even in strict mode. | 1977 // Using eval or arguments in this context is OK even in strict mode. |
| 1959 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1978 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 1960 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, | 1979 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, |
| 1961 factory()); | 1980 factory()); |
| 1962 break; | 1981 break; |
| 1963 } | 1982 } |
| 1964 | 1983 |
| 1965 case Token::STRING: { | 1984 case Token::STRING: { |
| 1966 Consume(Token::STRING); | 1985 Consume(Token::STRING); |
| 1967 result = this->ExpressionFromString(beg_pos, scanner(), factory()); | 1986 result = this->ExpressionFromString(beg_pos, scanner(), factory()); |
| 1968 break; | 1987 break; |
| 1969 } | 1988 } |
| (...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3052 materialized_literal_count = function_state.materialized_literal_count(); | 3071 materialized_literal_count = function_state.materialized_literal_count(); |
| 3053 expected_property_count = function_state.expected_property_count(); | 3072 expected_property_count = function_state.expected_property_count(); |
| 3054 handler_count = function_state.handler_count(); | 3073 handler_count = function_state.handler_count(); |
| 3055 } | 3074 } |
| 3056 super_loc = function_state.super_call_location(); | 3075 super_loc = function_state.super_call_location(); |
| 3057 | 3076 |
| 3058 scope->set_start_position(start_pos); | 3077 scope->set_start_position(start_pos); |
| 3059 scope->set_end_position(scanner()->location().end_pos); | 3078 scope->set_end_position(scanner()->location().end_pos); |
| 3060 | 3079 |
| 3061 // Arrow function *parameter lists* are always checked as in strict mode. | 3080 // Arrow function *parameter lists* are always checked as in strict mode. |
| 3062 // TODO(arv): eval_args_error_loc and reserved_loc needs to be set by | 3081 // TODO(arv): eval_args_error_loc, undefined_error_loc, and reserved_loc |
| 3063 // DeclareArrowParametersFromExpression. | 3082 // needs to be set by DeclareArrowParametersFromExpression. |
| 3064 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | 3083 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); |
| 3084 Scanner::Location undefined_error_loc = Scanner::Location::invalid(); |
| 3065 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3085 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3066 const bool use_strict_params = true; | 3086 const bool use_strict_params = true; |
| 3067 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3087 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
| 3068 eval_args_error_loc, dupe_error_loc, reserved_loc, CHECK_OK); | 3088 eval_args_error_loc, undefined_error_loc, |
| 3089 dupe_error_loc, reserved_loc, CHECK_OK); |
| 3069 | 3090 |
| 3070 // Validate strict mode. | 3091 // Validate strict mode. |
| 3071 if (is_strict(language_mode())) { | 3092 if (is_strict(language_mode())) { |
| 3072 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 3093 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, |
| 3073 CHECK_OK); | 3094 CHECK_OK); |
| 3074 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3095 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3075 } | 3096 } |
| 3076 } | 3097 } |
| 3077 | 3098 |
| 3078 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3099 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3182 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 3203 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
| 3183 return Traits::CloseTemplateLiteral(&ts, start, tag); | 3204 return Traits::CloseTemplateLiteral(&ts, start, tag); |
| 3184 } | 3205 } |
| 3185 | 3206 |
| 3186 | 3207 |
| 3187 template <typename Traits> | 3208 template <typename Traits> |
| 3188 typename ParserBase<Traits>::ExpressionT ParserBase< | 3209 typename ParserBase<Traits>::ExpressionT ParserBase< |
| 3189 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, | 3210 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, |
| 3190 Scanner::Location location, | 3211 Scanner::Location location, |
| 3191 const char* message, bool* ok) { | 3212 const char* message, bool* ok) { |
| 3192 if (is_strict(language_mode()) && this->IsIdentifier(expression) && | 3213 if (this->IsIdentifier(expression)) { |
| 3193 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3214 if (is_strict(language_mode()) && |
| 3194 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); | 3215 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
| 3195 *ok = false; | 3216 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); |
| 3196 return this->EmptyExpression(); | 3217 *ok = false; |
| 3197 } else if (expression->IsValidReferenceExpression()) { | 3218 return this->EmptyExpression(); |
| 3219 } |
| 3220 if (is_strong(language_mode()) && |
| 3221 this->IsUndefined(this->AsIdentifier(expression))) { |
| 3222 this->ReportMessageAt(location, "strong_undefined", kSyntaxError); |
| 3223 *ok = false; |
| 3224 return this->EmptyExpression(); |
| 3225 } |
| 3226 } |
| 3227 if (expression->IsValidReferenceExpression()) { |
| 3198 return expression; | 3228 return expression; |
| 3199 } else if (expression->IsCall()) { | 3229 } else if (expression->IsCall()) { |
| 3200 // If it is a call, make it a runtime error for legacy web compatibility. | 3230 // If it is a call, make it a runtime error for legacy web compatibility. |
| 3201 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3231 // Rewrite `expr' to `expr[throw ReferenceError]'. |
| 3202 int pos = location.beg_pos; | 3232 int pos = location.beg_pos; |
| 3203 ExpressionT error = this->NewThrowReferenceError(message, pos); | 3233 ExpressionT error = this->NewThrowReferenceError(message, pos); |
| 3204 return factory()->NewProperty(expression, error, pos); | 3234 return factory()->NewProperty(expression, error, pos); |
| 3205 } else { | 3235 } else { |
| 3206 this->ReportMessageAt(location, message, kReferenceError); | 3236 this->ReportMessageAt(location, message, kReferenceError); |
| 3207 *ok = false; | 3237 *ok = false; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3262 *ok = false; | 3292 *ok = false; |
| 3263 return; | 3293 return; |
| 3264 } | 3294 } |
| 3265 has_seen_constructor_ = true; | 3295 has_seen_constructor_ = true; |
| 3266 return; | 3296 return; |
| 3267 } | 3297 } |
| 3268 } | 3298 } |
| 3269 } } // v8::internal | 3299 } } // v8::internal |
| 3270 | 3300 |
| 3271 #endif // V8_PREPARSER_H | 3301 #endif // V8_PREPARSER_H |
| OLD | NEW |