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 |