Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(633)

Side by Side Diff: src/preparser.h

Issue 1070633002: [strong] Implement static restrictions on binding/assignment to 'undefined' identifier. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698