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

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: improve tests (rebase, only undefined.js has changed) 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 {
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 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 return Traits::ReportMessageAt(source_location, 1736 return Traits::ReportMessageAt(source_location,
1720 "unexpected_template_string"); 1737 "unexpected_template_string");
1721 default: 1738 default:
1722 const char* name = Token::String(token); 1739 const char* name = Token::String(token);
1723 DCHECK(name != NULL); 1740 DCHECK(name != NULL);
1724 Traits::ReportMessageAt(source_location, "unexpected_token", name); 1741 Traits::ReportMessageAt(source_location, "unexpected_token", name);
1725 } 1742 }
1726 } 1743 }
1727 1744
1728 1745
1729 template<class Traits> 1746 template <class Traits>
1730 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1747 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1731 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1748 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1732 bool* ok) {
1733 Token::Value next = Next(); 1749 Token::Value next = Next();
1734 if (next == Token::IDENTIFIER) { 1750 if (next == Token::IDENTIFIER) {
1735 IdentifierT name = this->GetSymbol(scanner()); 1751 IdentifierT name = this->GetSymbol(scanner());
1736 if (allow_eval_or_arguments == kDontAllowEvalOrArguments) { 1752 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1737 if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) { 1753 if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) {
1738 ReportMessage("strict_eval_arguments"); 1754 ReportMessage("strict_eval_arguments");
1739 *ok = false; 1755 *ok = false;
1740 } 1756 }
1757 if (is_strong(language_mode()) && this->IsUndefined(name)) {
1758 ReportMessage("strong_undefined");
1759 *ok = false;
1760 }
1741 } else { 1761 } else {
1742 if (is_strong(language_mode()) && this->IsArguments(name)) { 1762 if (is_strong(language_mode()) && this->IsArguments(name)) {
1743 ReportMessage("strong_arguments"); 1763 ReportMessage("strong_arguments");
1744 *ok = false; 1764 *ok = false;
1745 } 1765 }
1746 } 1766 }
1747 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1767 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1748 return name; 1768 return name;
1749 } else if (is_sloppy(language_mode()) && 1769 } else if (is_sloppy(language_mode()) &&
1750 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1770 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1751 next == Token::LET || next == Token::STATIC || 1771 next == Token::LET || next == Token::STATIC ||
1752 (next == Token::YIELD && !is_generator()))) { 1772 (next == Token::YIELD && !is_generator()))) {
1753 return this->GetSymbol(scanner()); 1773 return this->GetSymbol(scanner());
1754 } else { 1774 } else {
1755 this->ReportUnexpectedToken(next); 1775 this->ReportUnexpectedToken(next);
1756 *ok = false; 1776 *ok = false;
1757 return Traits::EmptyIdentifier(); 1777 return Traits::EmptyIdentifier();
1758 } 1778 }
1759 } 1779 }
1760 1780
1761
1762 template <class Traits> 1781 template <class Traits>
1763 typename ParserBase<Traits>::IdentifierT ParserBase< 1782 typename ParserBase<Traits>::IdentifierT ParserBase<
1764 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, 1783 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1765 bool* ok) { 1784 bool* ok) {
1766 Token::Value next = Next(); 1785 Token::Value next = Next();
1767 if (next == Token::IDENTIFIER) { 1786 if (next == Token::IDENTIFIER) {
1768 *is_strict_reserved = false; 1787 *is_strict_reserved = false;
1769 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 1788 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1770 next == Token::STATIC || 1789 next == Token::STATIC ||
1771 (next == Token::YIELD && !this->is_generator())) { 1790 (next == Token::YIELD && !this->is_generator())) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1890 result = 1909 result =
1891 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); 1910 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
1892 break; 1911 break;
1893 1912
1894 case Token::IDENTIFIER: 1913 case Token::IDENTIFIER:
1895 case Token::LET: 1914 case Token::LET:
1896 case Token::STATIC: 1915 case Token::STATIC:
1897 case Token::YIELD: 1916 case Token::YIELD:
1898 case Token::FUTURE_STRICT_RESERVED_WORD: { 1917 case Token::FUTURE_STRICT_RESERVED_WORD: {
1899 // Using eval or arguments in this context is OK even in strict mode. 1918 // Using eval or arguments in this context is OK even in strict mode.
1900 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1919 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1901 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, 1920 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
1902 factory()); 1921 factory());
1903 break; 1922 break;
1904 } 1923 }
1905 1924
1906 case Token::STRING: { 1925 case Token::STRING: {
1907 Consume(Token::STRING); 1926 Consume(Token::STRING);
1908 result = this->ExpressionFromString(beg_pos, scanner(), factory()); 1927 result = this->ExpressionFromString(beg_pos, scanner(), factory());
1909 break; 1928 break;
1910 } 1929 }
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
2945 materialized_literal_count = function_state.materialized_literal_count(); 2964 materialized_literal_count = function_state.materialized_literal_count();
2946 expected_property_count = function_state.expected_property_count(); 2965 expected_property_count = function_state.expected_property_count();
2947 handler_count = function_state.handler_count(); 2966 handler_count = function_state.handler_count();
2948 } 2967 }
2949 super_loc = function_state.super_call_location(); 2968 super_loc = function_state.super_call_location();
2950 2969
2951 scope->set_start_position(start_pos); 2970 scope->set_start_position(start_pos);
2952 scope->set_end_position(scanner()->location().end_pos); 2971 scope->set_end_position(scanner()->location().end_pos);
2953 2972
2954 // Arrow function *parameter lists* are always checked as in strict mode. 2973 // Arrow function *parameter lists* are always checked as in strict mode.
2955 // TODO(arv): eval_args_error_loc and reserved_loc needs to be set by 2974 // TODO(arv): eval_args_error_loc, undefined_error_loc, and reserved_loc
2956 // DeclareArrowParametersFromExpression. 2975 // needs to be set by DeclareArrowParametersFromExpression.
2957 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); 2976 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2977 Scanner::Location undefined_error_loc = Scanner::Location::invalid();
2958 Scanner::Location reserved_loc = Scanner::Location::invalid(); 2978 Scanner::Location reserved_loc = Scanner::Location::invalid();
2959 const bool use_strict_params = true; 2979 const bool use_strict_params = true;
2960 this->CheckFunctionParameterNames(language_mode(), use_strict_params, 2980 this->CheckFunctionParameterNames(language_mode(), use_strict_params,
2961 eval_args_error_loc, dupe_error_loc, reserved_loc, CHECK_OK); 2981 eval_args_error_loc, undefined_error_loc,
2982 dupe_error_loc, reserved_loc, CHECK_OK);
2962 2983
2963 // Validate strict mode. 2984 // Validate strict mode.
2964 if (is_strict(language_mode())) { 2985 if (is_strict(language_mode())) {
2965 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, 2986 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos,
2966 CHECK_OK); 2987 CHECK_OK);
2967 this->CheckConflictingVarDeclarations(scope, CHECK_OK); 2988 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2968 } 2989 }
2969 } 2990 }
2970 2991
2971 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( 2992 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3075 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. 3096 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3076 return Traits::CloseTemplateLiteral(&ts, start, tag); 3097 return Traits::CloseTemplateLiteral(&ts, start, tag);
3077 } 3098 }
3078 3099
3079 3100
3080 template <typename Traits> 3101 template <typename Traits>
3081 typename ParserBase<Traits>::ExpressionT ParserBase< 3102 typename ParserBase<Traits>::ExpressionT ParserBase<
3082 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, 3103 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression,
3083 Scanner::Location location, 3104 Scanner::Location location,
3084 const char* message, bool* ok) { 3105 const char* message, bool* ok) {
3085 if (is_strict(language_mode()) && this->IsIdentifier(expression) && 3106 if (this->IsIdentifier(expression)) {
3086 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 3107 if (is_strict(language_mode()) &&
3087 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); 3108 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3088 *ok = false; 3109 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError);
3089 return this->EmptyExpression(); 3110 *ok = false;
3090 } else if (expression->IsValidReferenceExpression()) { 3111 return this->EmptyExpression();
3112 }
3113 if (is_strong(language_mode()) &&
3114 this->IsUndefined(this->AsIdentifier(expression))) {
3115 this->ReportMessageAt(location, "strong_undefined", kSyntaxError);
3116 *ok = false;
3117 return this->EmptyExpression();
3118 }
3119 }
3120 if (expression->IsValidReferenceExpression()) {
3091 return expression; 3121 return expression;
3092 } else if (expression->IsCall()) { 3122 } else if (expression->IsCall()) {
3093 // If it is a call, make it a runtime error for legacy web compatibility. 3123 // If it is a call, make it a runtime error for legacy web compatibility.
3094 // Rewrite `expr' to `expr[throw ReferenceError]'. 3124 // Rewrite `expr' to `expr[throw ReferenceError]'.
3095 int pos = location.beg_pos; 3125 int pos = location.beg_pos;
3096 ExpressionT error = this->NewThrowReferenceError(message, pos); 3126 ExpressionT error = this->NewThrowReferenceError(message, pos);
3097 return factory()->NewProperty(expression, error, pos); 3127 return factory()->NewProperty(expression, error, pos);
3098 } else { 3128 } else {
3099 this->ReportMessageAt(location, message, kReferenceError); 3129 this->ReportMessageAt(location, message, kReferenceError);
3100 *ok = false; 3130 *ok = false;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3155 *ok = false; 3185 *ok = false;
3156 return; 3186 return;
3157 } 3187 }
3158 has_seen_constructor_ = true; 3188 has_seen_constructor_ = true;
3159 return; 3189 return;
3160 } 3190 }
3161 } 3191 }
3162 } } // v8::internal 3192 } } // v8::internal
3163 3193
3164 #endif // V8_PREPARSER_H 3194 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | test/mjsunit/strong/undefined.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698