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

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: 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
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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 } 139 }
140 void set_allow_harmony_computed_property_names(bool allow) { 140 void set_allow_harmony_computed_property_names(bool allow) {
141 allow_harmony_computed_property_names_ = allow; 141 allow_harmony_computed_property_names_ = allow;
142 } 142 }
143 void set_allow_harmony_rest_params(bool allow) { 143 void set_allow_harmony_rest_params(bool allow) {
144 allow_harmony_rest_params_ = allow; 144 allow_harmony_rest_params_ = allow;
145 } 145 }
146 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } 146 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
147 147
148 protected: 148 protected:
149 enum AllowEvalOrArgumentsAsIdentifier { 149 enum AllowRestrictedIdentifiers {
rossberg 2015/04/08 11:30:11 That's nicer indeed.
conradw 2015/04/09 12:24:17 Acknowledged.
150 kAllowEvalOrArguments, 150 kAllowRestrictedIdentifiers,
151 kDontAllowEvalOrArguments 151 kDontAllowRestrictedIdentifiers
152 }; 152 };
153 153
154 enum Mode { 154 enum Mode {
155 PARSE_LAZILY, 155 PARSE_LAZILY,
156 PARSE_EAGERLY 156 PARSE_EAGERLY
157 }; 157 };
158 158
159 enum VariableDeclarationContext { 159 enum VariableDeclarationContext {
160 kStatementListItem, 160 kStatementListItem,
161 kStatement, 161 kStatement,
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 if (this->IsEvalOrArguments(function_name)) { 472 if (this->IsEvalOrArguments(function_name)) {
473 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments"); 473 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments");
474 *ok = false; 474 *ok = false;
475 return; 475 return;
476 } 476 }
477 if (function_name_is_strict_reserved) { 477 if (function_name_is_strict_reserved) {
478 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved"); 478 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved");
479 *ok = false; 479 *ok = false;
480 return; 480 return;
481 } 481 }
482 if (is_strong(language_mode) && this->IsUndefined(function_name)) {
483 Traits::ReportMessageAt(function_name_loc, "strong_undefined");
484 *ok = false;
485 return;
486 }
482 } 487 }
483 488
484 // Checking the parameter names of a function literal. This has to be done 489 // Checking the parameter names of a function literal. This has to be done
485 // after parsing the function, since the function can declare itself strict. 490 // after parsing the function, since the function can declare itself strict.
486 void CheckFunctionParameterNames(LanguageMode language_mode, 491 void CheckFunctionParameterNames(LanguageMode language_mode,
487 bool strict_params, 492 bool strict_params,
488 const Scanner::Location& eval_args_error_loc, 493 const Scanner::Location& eval_args_error_loc,
494 const Scanner::Location& undefined_error_loc,
489 const Scanner::Location& dupe_error_loc, 495 const Scanner::Location& dupe_error_loc,
490 const Scanner::Location& reserved_loc, 496 const Scanner::Location& reserved_loc,
491 bool* ok) { 497 bool* ok) {
492 if (is_sloppy(language_mode) && !strict_params) return; 498 if (is_sloppy(language_mode) && !strict_params) return;
493 499
494 if (is_strict(language_mode) && eval_args_error_loc.IsValid()) { 500 if (is_strict(language_mode) && eval_args_error_loc.IsValid()) {
495 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); 501 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
496 *ok = false; 502 *ok = false;
497 return; 503 return;
498 } 504 }
505 if (is_strong(language_mode) && undefined_error_loc.IsValid()) {
506 Traits::ReportMessageAt(eval_args_error_loc, "strong_undefined");
507 *ok = false;
508 return;
509 }
499 // TODO(arv): When we add support for destructuring in setters we also need 510 // TODO(arv): When we add support for destructuring in setters we also need
500 // to check for duplicate names. 511 // to check for duplicate names.
501 if (dupe_error_loc.IsValid()) { 512 if (dupe_error_loc.IsValid()) {
502 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe"); 513 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe");
503 *ok = false; 514 *ok = false;
504 return; 515 return;
505 } 516 }
506 if (reserved_loc.IsValid()) { 517 if (reserved_loc.IsValid()) {
507 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); 518 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
508 *ok = false; 519 *ok = false;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 void ReportUnexpectedToken(Token::Value token); 551 void ReportUnexpectedToken(Token::Value token);
541 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); 552 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token);
542 553
543 // Recursive descent functions: 554 // Recursive descent functions:
544 555
545 // Parses an identifier that is valid for the current scope, in particular it 556 // Parses an identifier that is valid for the current scope, in particular it
546 // fails on strict mode future reserved keywords in a strict scope. If 557 // fails on strict mode future reserved keywords in a strict scope. If
547 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 558 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
548 // "arguments" as identifier even in strict mode (this is needed in cases like 559 // "arguments" as identifier even in strict mode (this is needed in cases like
549 // "var foo = eval;"). 560 // "var foo = eval;").
550 IdentifierT ParseIdentifier( 561 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
551 AllowEvalOrArgumentsAsIdentifier,
552 bool* ok);
553 // Parses an identifier or a strict mode future reserved word, and indicate 562 // Parses an identifier or a strict mode future reserved word, and indicate
554 // whether it is strict mode future reserved. 563 // whether it is strict mode future reserved.
555 IdentifierT ParseIdentifierOrStrictReservedWord( 564 IdentifierT ParseIdentifierOrStrictReservedWord(
556 bool* is_strict_reserved, 565 bool* is_strict_reserved,
557 bool* ok); 566 bool* ok);
558 IdentifierT ParseIdentifierName(bool* ok); 567 IdentifierT ParseIdentifierName(bool* ok);
559 // Parses an identifier and determines whether or not it is 'get' or 'set'. 568 // Parses an identifier and determines whether or not it is 'get' or 'set'.
560 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, 569 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
561 bool* is_set, 570 bool* is_set,
562 bool* ok); 571 bool* ok);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 PreParserIdentifier() : type_(kUnknownIdentifier) {} 704 PreParserIdentifier() : type_(kUnknownIdentifier) {}
696 static PreParserIdentifier Default() { 705 static PreParserIdentifier Default() {
697 return PreParserIdentifier(kUnknownIdentifier); 706 return PreParserIdentifier(kUnknownIdentifier);
698 } 707 }
699 static PreParserIdentifier Eval() { 708 static PreParserIdentifier Eval() {
700 return PreParserIdentifier(kEvalIdentifier); 709 return PreParserIdentifier(kEvalIdentifier);
701 } 710 }
702 static PreParserIdentifier Arguments() { 711 static PreParserIdentifier Arguments() {
703 return PreParserIdentifier(kArgumentsIdentifier); 712 return PreParserIdentifier(kArgumentsIdentifier);
704 } 713 }
714 static PreParserIdentifier Undefined() {
715 return PreParserIdentifier(kUndefinedIdentifier);
716 }
705 static PreParserIdentifier FutureReserved() { 717 static PreParserIdentifier FutureReserved() {
706 return PreParserIdentifier(kFutureReservedIdentifier); 718 return PreParserIdentifier(kFutureReservedIdentifier);
707 } 719 }
708 static PreParserIdentifier FutureStrictReserved() { 720 static PreParserIdentifier FutureStrictReserved() {
709 return PreParserIdentifier(kFutureStrictReservedIdentifier); 721 return PreParserIdentifier(kFutureStrictReservedIdentifier);
710 } 722 }
711 static PreParserIdentifier Let() { 723 static PreParserIdentifier Let() {
712 return PreParserIdentifier(kLetIdentifier); 724 return PreParserIdentifier(kLetIdentifier);
713 } 725 }
714 static PreParserIdentifier Static() { 726 static PreParserIdentifier Static() {
715 return PreParserIdentifier(kStaticIdentifier); 727 return PreParserIdentifier(kStaticIdentifier);
716 } 728 }
717 static PreParserIdentifier Yield() { 729 static PreParserIdentifier Yield() {
718 return PreParserIdentifier(kYieldIdentifier); 730 return PreParserIdentifier(kYieldIdentifier);
719 } 731 }
720 static PreParserIdentifier Prototype() { 732 static PreParserIdentifier Prototype() {
721 return PreParserIdentifier(kPrototypeIdentifier); 733 return PreParserIdentifier(kPrototypeIdentifier);
722 } 734 }
723 static PreParserIdentifier Constructor() { 735 static PreParserIdentifier Constructor() {
724 return PreParserIdentifier(kConstructorIdentifier); 736 return PreParserIdentifier(kConstructorIdentifier);
725 } 737 }
726 bool IsEval() const { return type_ == kEvalIdentifier; } 738 bool IsEval() const { return type_ == kEvalIdentifier; }
727 bool IsArguments() const { return type_ == kArgumentsIdentifier; } 739 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
728 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } 740 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
741 bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
729 bool IsLet() const { return type_ == kLetIdentifier; } 742 bool IsLet() const { return type_ == kLetIdentifier; }
730 bool IsStatic() const { return type_ == kStaticIdentifier; } 743 bool IsStatic() const { return type_ == kStaticIdentifier; }
731 bool IsYield() const { return type_ == kYieldIdentifier; } 744 bool IsYield() const { return type_ == kYieldIdentifier; }
732 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } 745 bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
733 bool IsConstructor() const { return type_ == kConstructorIdentifier; } 746 bool IsConstructor() const { return type_ == kConstructorIdentifier; }
734 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } 747 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
735 bool IsFutureStrictReserved() const { 748 bool IsFutureStrictReserved() const {
736 return type_ == kFutureStrictReservedIdentifier || 749 return type_ == kFutureStrictReservedIdentifier ||
737 type_ == kLetIdentifier || type_ == kStaticIdentifier || 750 type_ == kLetIdentifier || type_ == kStaticIdentifier ||
738 type_ == kYieldIdentifier; 751 type_ == kYieldIdentifier;
739 } 752 }
740 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; }
741 V8_INLINE bool IsValidArrowParam() const { 753 V8_INLINE bool IsValidArrowParam() const {
742 // A valid identifier can be an arrow function parameter 754 // A valid identifier can be an arrow function parameter
743 // except for eval, arguments, yield, and reserved keywords. 755 // except for eval, arguments, yield, and reserved keywords.
744 return !(IsEval() || IsArguments() || IsFutureStrictReserved()); 756 return !(IsEval() || IsArguments() || IsFutureStrictReserved());
745 } 757 }
746 758
747 // Allow identifier->name()[->length()] to work. The preparser 759 // Allow identifier->name()[->length()] to work. The preparser
748 // does not need the actual positions/lengths of the identifiers. 760 // does not need the actual positions/lengths of the identifiers.
749 const PreParserIdentifier* operator->() const { return this; } 761 const PreParserIdentifier* operator->() const { return this; }
750 const PreParserIdentifier raw_name() const { return *this; } 762 const PreParserIdentifier raw_name() const { return *this; }
751 763
752 int position() const { return 0; } 764 int position() const { return 0; }
753 int length() const { return 0; } 765 int length() const { return 0; }
754 766
755 private: 767 private:
756 enum Type { 768 enum Type {
757 kUnknownIdentifier, 769 kUnknownIdentifier,
758 kFutureReservedIdentifier, 770 kFutureReservedIdentifier,
759 kFutureStrictReservedIdentifier, 771 kFutureStrictReservedIdentifier,
760 kLetIdentifier, 772 kLetIdentifier,
761 kStaticIdentifier, 773 kStaticIdentifier,
762 kYieldIdentifier, 774 kYieldIdentifier,
763 kEvalIdentifier, 775 kEvalIdentifier,
764 kArgumentsIdentifier, 776 kArgumentsIdentifier,
777 kUndefinedIdentifier,
765 kPrototypeIdentifier, 778 kPrototypeIdentifier,
766 kConstructorIdentifier 779 kConstructorIdentifier
767 }; 780 };
768 explicit PreParserIdentifier(Type type) : type_(type) {} 781 explicit PreParserIdentifier(Type type) : type_(type) {}
769 Type type_; 782 Type type_;
770 783
771 friend class PreParserExpression; 784 friend class PreParserExpression;
772 }; 785 };
773 786
774 787
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 } 1243 }
1231 1244
1232 static bool IsArguments(PreParserIdentifier identifier) { 1245 static bool IsArguments(PreParserIdentifier identifier) {
1233 return identifier.IsArguments(); 1246 return identifier.IsArguments();
1234 } 1247 }
1235 1248
1236 static bool IsEvalOrArguments(PreParserIdentifier identifier) { 1249 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
1237 return identifier.IsEvalOrArguments(); 1250 return identifier.IsEvalOrArguments();
1238 } 1251 }
1239 1252
1253 static bool IsUndefined(PreParserIdentifier identifier) {
1254 return identifier.IsUndefined();
1255 }
1256
1240 static bool IsPrototype(PreParserIdentifier identifier) { 1257 static bool IsPrototype(PreParserIdentifier identifier) {
1241 return identifier.IsPrototype(); 1258 return identifier.IsPrototype();
1242 } 1259 }
1243 1260
1244 static bool IsConstructor(PreParserIdentifier identifier) { 1261 static bool IsConstructor(PreParserIdentifier identifier) {
1245 return identifier.IsConstructor(); 1262 return identifier.IsConstructor();
1246 } 1263 }
1247 1264
1248 // Returns true if the expression is of type "this.foo". 1265 // Returns true if the expression is of type "this.foo".
1249 static bool IsThisProperty(PreParserExpression expression) { 1266 static bool IsThisProperty(PreParserExpression expression) {
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 return Traits::ReportMessageAt(source_location, 1735 return Traits::ReportMessageAt(source_location,
1719 "unexpected_template_string"); 1736 "unexpected_template_string");
1720 default: 1737 default:
1721 const char* name = Token::String(token); 1738 const char* name = Token::String(token);
1722 DCHECK(name != NULL); 1739 DCHECK(name != NULL);
1723 Traits::ReportMessageAt(source_location, "unexpected_token", name); 1740 Traits::ReportMessageAt(source_location, "unexpected_token", name);
1724 } 1741 }
1725 } 1742 }
1726 1743
1727 1744
1728 template<class Traits> 1745 template <class Traits>
1729 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1746 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1730 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1747 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1731 bool* ok) {
1732 Token::Value next = Next(); 1748 Token::Value next = Next();
1733 if (next == Token::IDENTIFIER) { 1749 if (next == Token::IDENTIFIER) {
1734 IdentifierT name = this->GetSymbol(scanner()); 1750 IdentifierT name = this->GetSymbol(scanner());
1735 if (allow_eval_or_arguments == kDontAllowEvalOrArguments) { 1751 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1736 if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) { 1752 if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) {
1737 ReportMessage("strict_eval_arguments"); 1753 ReportMessage("strict_eval_arguments");
1738 *ok = false; 1754 *ok = false;
1739 } 1755 }
1756 if (is_strong(language_mode()) && this->IsUndefined(name)) {
1757 ReportMessage("strong_undefined");
1758 *ok = false;
1759 }
1740 } else { 1760 } else {
1741 if (is_strong(language_mode()) && this->IsArguments(name)) { 1761 if (is_strong(language_mode()) && this->IsArguments(name)) {
1742 ReportMessage("strong_arguments"); 1762 ReportMessage("strong_arguments");
1743 *ok = false; 1763 *ok = false;
1744 } 1764 }
1745 } 1765 }
1746 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1766 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1747 return name; 1767 return name;
1748 } else if (is_sloppy(language_mode()) && 1768 } else if (is_sloppy(language_mode()) &&
1749 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1769 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1750 next == Token::LET || next == Token::STATIC || 1770 next == Token::LET || next == Token::STATIC ||
1751 (next == Token::YIELD && !is_generator()))) { 1771 (next == Token::YIELD && !is_generator()))) {
1752 return this->GetSymbol(scanner()); 1772 return this->GetSymbol(scanner());
1753 } else { 1773 } else {
1754 this->ReportUnexpectedToken(next); 1774 this->ReportUnexpectedToken(next);
1755 *ok = false; 1775 *ok = false;
1756 return Traits::EmptyIdentifier(); 1776 return Traits::EmptyIdentifier();
1757 } 1777 }
1758 } 1778 }
1759 1779
1760
1761 template <class Traits> 1780 template <class Traits>
1762 typename ParserBase<Traits>::IdentifierT ParserBase< 1781 typename ParserBase<Traits>::IdentifierT ParserBase<
1763 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, 1782 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1764 bool* ok) { 1783 bool* ok) {
1765 Token::Value next = Next(); 1784 Token::Value next = Next();
1766 if (next == Token::IDENTIFIER) { 1785 if (next == Token::IDENTIFIER) {
1767 *is_strict_reserved = false; 1786 *is_strict_reserved = false;
1768 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 1787 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1769 next == Token::STATIC || 1788 next == Token::STATIC ||
1770 (next == Token::YIELD && !this->is_generator())) { 1789 (next == Token::YIELD && !this->is_generator())) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 result = 1908 result =
1890 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); 1909 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
1891 break; 1910 break;
1892 1911
1893 case Token::IDENTIFIER: 1912 case Token::IDENTIFIER:
1894 case Token::LET: 1913 case Token::LET:
1895 case Token::STATIC: 1914 case Token::STATIC:
1896 case Token::YIELD: 1915 case Token::YIELD:
1897 case Token::FUTURE_STRICT_RESERVED_WORD: { 1916 case Token::FUTURE_STRICT_RESERVED_WORD: {
1898 // Using eval or arguments in this context is OK even in strict mode. 1917 // Using eval or arguments in this context is OK even in strict mode.
1899 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1918 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1900 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, 1919 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
1901 factory()); 1920 factory());
1902 break; 1921 break;
1903 } 1922 }
1904 1923
1905 case Token::STRING: { 1924 case Token::STRING: {
1906 Consume(Token::STRING); 1925 Consume(Token::STRING);
1907 result = this->ExpressionFromString(beg_pos, scanner(), factory()); 1926 result = this->ExpressionFromString(beg_pos, scanner(), factory());
1908 break; 1927 break;
1909 } 1928 }
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
2944 materialized_literal_count = function_state.materialized_literal_count(); 2963 materialized_literal_count = function_state.materialized_literal_count();
2945 expected_property_count = function_state.expected_property_count(); 2964 expected_property_count = function_state.expected_property_count();
2946 handler_count = function_state.handler_count(); 2965 handler_count = function_state.handler_count();
2947 } 2966 }
2948 super_loc = function_state.super_call_location(); 2967 super_loc = function_state.super_call_location();
2949 2968
2950 scope->set_start_position(start_pos); 2969 scope->set_start_position(start_pos);
2951 scope->set_end_position(scanner()->location().end_pos); 2970 scope->set_end_position(scanner()->location().end_pos);
2952 2971
2953 // Arrow function *parameter lists* are always checked as in strict mode. 2972 // Arrow function *parameter lists* are always checked as in strict mode.
2954 // TODO(arv): eval_args_error_loc and reserved_loc needs to be set by 2973 // TODO(arv): eval_args_error_loc, undefined_error_loc, and reserved_loc
2955 // DeclareArrowParametersFromExpression. 2974 // needs to be set by DeclareArrowParametersFromExpression.
2956 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); 2975 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2976 Scanner::Location undefined_error_loc = Scanner::Location::invalid();
2957 Scanner::Location reserved_loc = Scanner::Location::invalid(); 2977 Scanner::Location reserved_loc = Scanner::Location::invalid();
2958 const bool use_strict_params = true; 2978 const bool use_strict_params = true;
2959 this->CheckFunctionParameterNames(language_mode(), use_strict_params, 2979 this->CheckFunctionParameterNames(language_mode(), use_strict_params,
2960 eval_args_error_loc, dupe_error_loc, reserved_loc, CHECK_OK); 2980 eval_args_error_loc, undefined_error_loc,
2981 dupe_error_loc, reserved_loc, CHECK_OK);
2961 2982
2962 // Validate strict mode. 2983 // Validate strict mode.
2963 if (is_strict(language_mode())) { 2984 if (is_strict(language_mode())) {
2964 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, 2985 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos,
2965 CHECK_OK); 2986 CHECK_OK);
2966 this->CheckConflictingVarDeclarations(scope, CHECK_OK); 2987 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2967 } 2988 }
2968 } 2989 }
2969 2990
2970 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( 2991 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3074 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. 3095 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3075 return Traits::CloseTemplateLiteral(&ts, start, tag); 3096 return Traits::CloseTemplateLiteral(&ts, start, tag);
3076 } 3097 }
3077 3098
3078 3099
3079 template <typename Traits> 3100 template <typename Traits>
3080 typename ParserBase<Traits>::ExpressionT ParserBase< 3101 typename ParserBase<Traits>::ExpressionT ParserBase<
3081 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, 3102 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression,
3082 Scanner::Location location, 3103 Scanner::Location location,
3083 const char* message, bool* ok) { 3104 const char* message, bool* ok) {
3084 if (is_strict(language_mode()) && this->IsIdentifier(expression) && 3105 if (this->IsIdentifier(expression)) {
3085 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 3106 if (is_strict(language_mode()) &&
3086 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); 3107 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3087 *ok = false; 3108 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError);
3088 return this->EmptyExpression(); 3109 *ok = false;
3089 } else if (expression->IsValidReferenceExpression()) { 3110 return this->EmptyExpression();
3111 }
3112 if (is_strong(language_mode()) &&
3113 this->IsUndefined(this->AsIdentifier(expression))) {
3114 this->ReportMessageAt(location, "strong_undefined", kSyntaxError);
3115 *ok = false;
3116 return this->EmptyExpression();
3117 }
3118 }
3119 if (expression->IsValidReferenceExpression()) {
3090 return expression; 3120 return expression;
3091 } else if (expression->IsCall()) { 3121 } else if (expression->IsCall()) {
3092 // If it is a call, make it a runtime error for legacy web compatibility. 3122 // If it is a call, make it a runtime error for legacy web compatibility.
3093 // Rewrite `expr' to `expr[throw ReferenceError]'. 3123 // Rewrite `expr' to `expr[throw ReferenceError]'.
3094 int pos = location.beg_pos; 3124 int pos = location.beg_pos;
3095 ExpressionT error = this->NewThrowReferenceError(message, pos); 3125 ExpressionT error = this->NewThrowReferenceError(message, pos);
3096 return factory()->NewProperty(expression, error, pos); 3126 return factory()->NewProperty(expression, error, pos);
3097 } else { 3127 } else {
3098 this->ReportMessageAt(location, message, kReferenceError); 3128 this->ReportMessageAt(location, message, kReferenceError);
3099 *ok = false; 3129 *ok = false;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3154 *ok = false; 3184 *ok = false;
3155 return; 3185 return;
3156 } 3186 }
3157 has_seen_constructor_ = true; 3187 has_seen_constructor_ = true;
3158 return; 3188 return;
3159 } 3189 }
3160 } 3190 }
3161 } } // v8::internal 3191 } } // v8::internal
3162 3192
3163 #endif // V8_PREPARSER_H 3193 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698