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

Side by Side Diff: src/parsing/preparser.cc

Issue 1773653002: [strong] Remove all remainders of strong mode (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Oversight Created 4 years, 9 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/parsing/preparser.h ('k') | src/ppc/builtins-ppc.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 #include <cmath> 5 #include <cmath>
6 6
7 #include "src/allocation.h" 7 #include "src/allocation.h"
8 #include "src/base/logging.h" 8 #include "src/base/logging.h"
9 #include "src/conversions-inl.h" 9 #include "src/conversions-inl.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 71
72 PreParserIdentifier PreParserTraits::GetNumberAsSymbol(Scanner* scanner) { 72 PreParserIdentifier PreParserTraits::GetNumberAsSymbol(Scanner* scanner) {
73 return PreParserIdentifier::Default(); 73 return PreParserIdentifier::Default();
74 } 74 }
75 75
76 76
77 PreParserExpression PreParserTraits::ExpressionFromString( 77 PreParserExpression PreParserTraits::ExpressionFromString(
78 int pos, Scanner* scanner, PreParserFactory* factory) { 78 int pos, Scanner* scanner, PreParserFactory* factory) {
79 if (scanner->UnescapedLiteralMatches("use strict", 10)) { 79 if (scanner->UnescapedLiteralMatches("use strict", 10)) {
80 return PreParserExpression::UseStrictStringLiteral(); 80 return PreParserExpression::UseStrictStringLiteral();
81 } else if (scanner->UnescapedLiteralMatches("use strong", 10)) {
82 return PreParserExpression::UseStrongStringLiteral();
83 } 81 }
84 return PreParserExpression::StringLiteral(); 82 return PreParserExpression::StringLiteral();
85 } 83 }
86 84
87 85
88 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) { 86 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
89 return pre_parser_->ParseV8Intrinsic(ok); 87 return pre_parser_->ParseV8Intrinsic(ok);
90 } 88 }
91 89
92 90
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 } else if (stack_overflow()) { 123 } else if (stack_overflow()) {
126 return kPreParseStackOverflow; 124 return kPreParseStackOverflow;
127 } else if (!ok) { 125 } else if (!ok) {
128 ReportUnexpectedToken(scanner()->current_token()); 126 ReportUnexpectedToken(scanner()->current_token());
129 } else { 127 } else {
130 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 128 DCHECK_EQ(Token::RBRACE, scanner()->peek());
131 if (is_strict(scope_->language_mode())) { 129 if (is_strict(scope_->language_mode())) {
132 int end_pos = scanner()->location().end_pos; 130 int end_pos = scanner()->location().end_pos;
133 CheckStrictOctalLiteral(start_position, end_pos, &ok); 131 CheckStrictOctalLiteral(start_position, end_pos, &ok);
134 if (!ok) return kPreParseSuccess; 132 if (!ok) return kPreParseSuccess;
135
136 if (is_strong(scope_->language_mode()) && IsSubclassConstructor(kind)) {
137 if (!function_state.super_location().IsValid()) {
138 ReportMessageAt(Scanner::Location(start_position, start_position + 1),
139 MessageTemplate::kStrongSuperCallMissing,
140 kReferenceError);
141 return kPreParseSuccess;
142 }
143 }
144 } 133 }
145 } 134 }
146 return kPreParseSuccess; 135 return kPreParseSuccess;
147 } 136 }
148 137
149 138
150 PreParserExpression PreParserTraits::ParseClassLiteral( 139 PreParserExpression PreParserTraits::ParseClassLiteral(
151 PreParserIdentifier name, Scanner::Location class_name_location, 140 PreParserIdentifier name, Scanner::Location class_name_location,
152 bool name_is_strict_reserved, int pos, bool* ok) { 141 bool name_is_strict_reserved, int pos, bool* ok) {
153 return pre_parser_->ParseClassLiteral(name, class_name_location, 142 return pre_parser_->ParseClassLiteral(name, class_name_location,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 bool maybe_reset = bookmark != nullptr; 208 bool maybe_reset = bookmark != nullptr;
220 int count_statements = 0; 209 int count_statements = 0;
221 210
222 bool directive_prologue = true; 211 bool directive_prologue = true;
223 while (peek() != end_token) { 212 while (peek() != end_token) {
224 if (directive_prologue && peek() != Token::STRING) { 213 if (directive_prologue && peek() != Token::STRING) {
225 directive_prologue = false; 214 directive_prologue = false;
226 } 215 }
227 bool starts_with_identifier = peek() == Token::IDENTIFIER; 216 bool starts_with_identifier = peek() == Token::IDENTIFIER;
228 Scanner::Location token_loc = scanner()->peek_location(); 217 Scanner::Location token_loc = scanner()->peek_location();
229 Scanner::Location old_this_loc = function_state_->this_location();
230 Scanner::Location old_super_loc = function_state_->super_location();
231 Statement statement = ParseStatementListItem(ok); 218 Statement statement = ParseStatementListItem(ok);
232 if (!*ok) return; 219 if (!*ok) return;
233 220
234 if (is_strong(language_mode()) && scope_->is_function_scope() &&
235 IsClassConstructor(function_state_->kind())) {
236 Scanner::Location this_loc = function_state_->this_location();
237 Scanner::Location super_loc = function_state_->super_location();
238 if (this_loc.beg_pos != old_this_loc.beg_pos &&
239 this_loc.beg_pos != token_loc.beg_pos) {
240 ReportMessageAt(this_loc, MessageTemplate::kStrongConstructorThis);
241 *ok = false;
242 return;
243 }
244 if (super_loc.beg_pos != old_super_loc.beg_pos &&
245 super_loc.beg_pos != token_loc.beg_pos) {
246 ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper);
247 *ok = false;
248 return;
249 }
250 }
251
252 if (directive_prologue) { 221 if (directive_prologue) {
253 bool use_strict_found = statement.IsUseStrictLiteral(); 222 bool use_strict_found = statement.IsUseStrictLiteral();
254 bool use_strong_found =
255 statement.IsUseStrongLiteral() && allow_strong_mode();
256 223
257 if (use_strict_found) { 224 if (use_strict_found) {
258 scope_->SetLanguageMode( 225 scope_->SetLanguageMode(
259 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); 226 static_cast<LanguageMode>(scope_->language_mode() | STRICT));
260 } else if (use_strong_found) {
261 scope_->SetLanguageMode(static_cast<LanguageMode>(
262 scope_->language_mode() | STRONG));
263 if (IsClassConstructor(function_state_->kind())) {
264 // "use strong" cannot occur in a class constructor body, to avoid
265 // unintuitive strong class object semantics.
266 PreParserTraits::ReportMessageAt(
267 token_loc, MessageTemplate::kStrongConstructorDirective);
268 *ok = false;
269 return;
270 }
271 } else if (!statement.IsStringLiteral()) { 227 } else if (!statement.IsStringLiteral()) {
272 directive_prologue = false; 228 directive_prologue = false;
273 } 229 }
274 230
275 if ((use_strict_found || use_strong_found) && 231 if (use_strict_found && !scope_->HasSimpleParameters()) {
276 !scope_->HasSimpleParameters()) {
277 // TC39 deemed "use strict" directives to be an error when occurring 232 // TC39 deemed "use strict" directives to be an error when occurring
278 // in the body of a function with non-simple parameter list, on 233 // in the body of a function with non-simple parameter list, on
279 // 29/7/2015. https://goo.gl/ueA7Ln 234 // 29/7/2015. https://goo.gl/ueA7Ln
280 //
281 // In V8, this also applies to "use strong " directives.
282 PreParserTraits::ReportMessageAt( 235 PreParserTraits::ReportMessageAt(
283 token_loc, MessageTemplate::kIllegalLanguageModeDirective, 236 token_loc, MessageTemplate::kIllegalLanguageModeDirective,
284 use_strict_found ? "use strict" : "use strong"); 237 "use strict");
285 *ok = false; 238 *ok = false;
286 return; 239 return;
287 } 240 }
288 } 241 }
289 242
290 // If we're allowed to reset to a bookmark, we will do so when we see a long 243 // If we're allowed to reset to a bookmark, we will do so when we see a long
291 // and trivial function. 244 // and trivial function.
292 // Our current definition of 'long and trivial' is: 245 // Our current definition of 'long and trivial' is:
293 // - over 200 statements 246 // - over 200 statements
294 // - all starting with an identifier (i.e., no if, for, while, etc.) 247 // - all starting with an identifier (i.e., no if, for, while, etc.)
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 // labels can be simply ignored in all other cases; except for 309 // labels can be simply ignored in all other cases; except for
357 // trivial labeled break statements 'label: break label' which is 310 // trivial labeled break statements 'label: break label' which is
358 // parsed into an empty statement. 311 // parsed into an empty statement.
359 312
360 // Keep the source position of the statement 313 // Keep the source position of the statement
361 switch (peek()) { 314 switch (peek()) {
362 case Token::LBRACE: 315 case Token::LBRACE:
363 return ParseBlock(ok); 316 return ParseBlock(ok);
364 317
365 case Token::SEMICOLON: 318 case Token::SEMICOLON:
366 if (is_strong(language_mode())) {
367 PreParserTraits::ReportMessageAt(scanner()->peek_location(),
368 MessageTemplate::kStrongEmpty);
369 *ok = false;
370 return Statement::Default();
371 }
372 Next(); 319 Next();
373 return Statement::Default(); 320 return Statement::Default();
374 321
375 case Token::IF: 322 case Token::IF:
376 return ParseIfStatement(ok); 323 return ParseIfStatement(ok);
377 324
378 case Token::DO: 325 case Token::DO:
379 return ParseDoWhileStatement(ok); 326 return ParseDoWhileStatement(ok);
380 327
381 case Token::WHILE: 328 case Token::WHILE:
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 // ConstBinding :: 473 // ConstBinding ::
527 // Identifier '=' AssignmentExpression 474 // Identifier '=' AssignmentExpression
528 // 475 //
529 // TODO(ES6): 476 // TODO(ES6):
530 // ConstBinding :: 477 // ConstBinding ::
531 // BindingPattern '=' AssignmentExpression 478 // BindingPattern '=' AssignmentExpression
532 bool require_initializer = false; 479 bool require_initializer = false;
533 bool lexical = false; 480 bool lexical = false;
534 bool is_pattern = false; 481 bool is_pattern = false;
535 if (peek() == Token::VAR) { 482 if (peek() == Token::VAR) {
536 if (is_strong(language_mode())) {
537 Scanner::Location location = scanner()->peek_location();
538 ReportMessageAt(location, MessageTemplate::kStrongVar);
539 *ok = false;
540 return Statement::Default();
541 }
542 Consume(Token::VAR); 483 Consume(Token::VAR);
543 } else if (peek() == Token::CONST && allow_const()) { 484 } else if (peek() == Token::CONST && allow_const()) {
544 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 485 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
545 // 486 //
546 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 487 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
547 // 488 //
548 // * It is a Syntax Error if the code that matches this production is not 489 // * It is a Syntax Error if the code that matches this production is not
549 // contained in extended code. 490 // contained in extended code.
550 // 491 //
551 // However disallowing const in sloppy mode will break compatibility with 492 // However disallowing const in sloppy mode will break compatibility with
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 580
640 switch (peek()) { 581 switch (peek()) {
641 case Token::FUNCTION: 582 case Token::FUNCTION:
642 case Token::LBRACE: 583 case Token::LBRACE:
643 UNREACHABLE(); // Always handled by the callers. 584 UNREACHABLE(); // Always handled by the callers.
644 case Token::CLASS: 585 case Token::CLASS:
645 ReportUnexpectedToken(Next()); 586 ReportUnexpectedToken(Next());
646 *ok = false; 587 *ok = false;
647 return Statement::Default(); 588 return Statement::Default();
648 589
649 case Token::THIS:
650 if (!FLAG_strong_this) break;
651 // Fall through.
652 case Token::SUPER:
653 if (is_strong(language_mode()) &&
654 IsClassConstructor(function_state_->kind())) {
655 bool is_this = peek() == Token::THIS;
656 Expression expr = Expression::Default();
657 ExpressionClassifier classifier(this);
658 if (is_this) {
659 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
660 } else {
661 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
662 }
663 ValidateExpression(&classifier, CHECK_OK);
664 switch (peek()) {
665 case Token::SEMICOLON:
666 Consume(Token::SEMICOLON);
667 break;
668 case Token::RBRACE:
669 case Token::EOS:
670 break;
671 default:
672 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
673 ReportMessageAt(function_state_->this_location(),
674 is_this
675 ? MessageTemplate::kStrongConstructorThis
676 : MessageTemplate::kStrongConstructorSuper);
677 *ok = false;
678 return Statement::Default();
679 }
680 }
681 return Statement::ExpressionStatement(expr);
682 }
683 break;
684
685 // TODO(arv): Handle `let [`
686 // https://code.google.com/p/v8/issues/detail?id=3847
687
688 default: 590 default:
689 break; 591 break;
690 } 592 }
691 593
692 bool starts_with_identifier = peek_any_identifier(); 594 bool starts_with_identifier = peek_any_identifier();
693 ExpressionClassifier classifier(this); 595 ExpressionClassifier classifier(this);
694 Expression expr = ParseExpression(true, &classifier, CHECK_OK); 596 Expression expr = ParseExpression(true, &classifier, CHECK_OK);
695 ValidateExpression(&classifier, CHECK_OK); 597 ValidateExpression(&classifier, CHECK_OK);
696 598
697 // Even if the expression starts with an identifier, it is not necessarily an 599 // Even if the expression starts with an identifier, it is not necessarily an
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 // An ECMAScript program is considered syntactically incorrect if it 700 // An ECMAScript program is considered syntactically incorrect if it
799 // contains a return statement that is not within the body of a 701 // contains a return statement that is not within the body of a
800 // function. See ECMA-262, section 12.9, page 67. 702 // function. See ECMA-262, section 12.9, page 67.
801 // This is not handled during preparsing. 703 // This is not handled during preparsing.
802 704
803 Token::Value tok = peek(); 705 Token::Value tok = peek();
804 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 706 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
805 tok != Token::SEMICOLON && 707 tok != Token::SEMICOLON &&
806 tok != Token::RBRACE && 708 tok != Token::RBRACE &&
807 tok != Token::EOS) { 709 tok != Token::EOS) {
808 if (is_strong(language_mode()) &&
809 IsClassConstructor(function_state_->kind())) {
810 int pos = peek_position();
811 ReportMessageAt(Scanner::Location(pos, pos + 1),
812 MessageTemplate::kStrongConstructorReturnValue);
813 *ok = false;
814 return Statement::Default();
815 }
816 ParseExpression(true, CHECK_OK); 710 ParseExpression(true, CHECK_OK);
817 } 711 }
818 ExpectSemicolon(CHECK_OK); 712 ExpectSemicolon(CHECK_OK);
819 return Statement::Jump(); 713 return Statement::Jump();
820 } 714 }
821 715
822 716
823 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 717 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
824 // WithStatement :: 718 // WithStatement ::
825 // 'with' '(' Expression ')' Statement 719 // 'with' '(' Expression ')' Statement
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 } 754 }
861 Expect(Token::COLON, CHECK_OK); 755 Expect(Token::COLON, CHECK_OK);
862 token = peek(); 756 token = peek();
863 Statement statement = Statement::Jump(); 757 Statement statement = Statement::Jump();
864 while (token != Token::CASE && 758 while (token != Token::CASE &&
865 token != Token::DEFAULT && 759 token != Token::DEFAULT &&
866 token != Token::RBRACE) { 760 token != Token::RBRACE) {
867 statement = ParseStatementListItem(CHECK_OK); 761 statement = ParseStatementListItem(CHECK_OK);
868 token = peek(); 762 token = peek();
869 } 763 }
870 if (is_strong(language_mode()) && !statement.IsJumpStatement() &&
871 token != Token::RBRACE) {
872 ReportMessageAt(scanner()->location(),
873 MessageTemplate::kStrongSwitchFallthrough);
874 *ok = false;
875 return Statement::Default();
876 }
877 } 764 }
878 Expect(Token::RBRACE, ok); 765 Expect(Token::RBRACE, ok);
879 return Statement::Default(); 766 return Statement::Default();
880 } 767 }
881 768
882 769
883 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { 770 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
884 // DoStatement :: 771 // DoStatement ::
885 // 'do' Statement 'while' '(' Expression ')' ';' 772 // 'do' Statement 'while' '(' Expression ')' ';'
886 773
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 const bool allow_duplicate_parameters = 1046 const bool allow_duplicate_parameters =
1160 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); 1047 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
1161 ValidateFormalParameters(&formals_classifier, language_mode, 1048 ValidateFormalParameters(&formals_classifier, language_mode,
1162 allow_duplicate_parameters, CHECK_OK); 1049 allow_duplicate_parameters, CHECK_OK);
1163 1050
1164 if (is_strict(language_mode)) { 1051 if (is_strict(language_mode)) {
1165 int end_position = scanner()->location().end_pos; 1052 int end_position = scanner()->location().end_pos;
1166 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); 1053 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
1167 } 1054 }
1168 1055
1169 if (is_strong(language_mode) && IsSubclassConstructor(kind)) {
1170 if (!function_state.super_location().IsValid()) {
1171 ReportMessageAt(function_name_location,
1172 MessageTemplate::kStrongSuperCallMissing,
1173 kReferenceError);
1174 *ok = false;
1175 return Expression::Default();
1176 }
1177 }
1178
1179 return Expression::Default(); 1056 return Expression::Default();
1180 } 1057 }
1181 1058
1182 1059
1183 void PreParser::ParseLazyFunctionLiteralBody(bool* ok, 1060 void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
1184 Scanner::BookmarkScope* bookmark) { 1061 Scanner::BookmarkScope* bookmark) {
1185 int body_start = position(); 1062 int body_start = position();
1186 ParseStatementList(Token::RBRACE, ok, bookmark); 1063 ParseStatementList(Token::RBRACE, ok, bookmark);
1187 if (!*ok) return; 1064 if (!*ok) return;
1188 if (bookmark && bookmark->HasBeenReset()) return; 1065 if (bookmark && bookmark->HasBeenReset()) return;
(...skipping 16 matching lines...) Expand all
1205 ReportMessageAt(class_name_location, 1082 ReportMessageAt(class_name_location,
1206 MessageTemplate::kUnexpectedStrictReserved); 1083 MessageTemplate::kUnexpectedStrictReserved);
1207 *ok = false; 1084 *ok = false;
1208 return EmptyExpression(); 1085 return EmptyExpression();
1209 } 1086 }
1210 if (IsEvalOrArguments(name)) { 1087 if (IsEvalOrArguments(name)) {
1211 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); 1088 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
1212 *ok = false; 1089 *ok = false;
1213 return EmptyExpression(); 1090 return EmptyExpression();
1214 } 1091 }
1215 LanguageMode class_language_mode = language_mode();
1216 if (is_strong(class_language_mode) && IsUndefined(name)) {
1217 ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined);
1218 *ok = false;
1219 return EmptyExpression();
1220 }
1221 1092
1093 LanguageMode class_language_mode = language_mode();
1222 Scope* scope = NewScope(scope_, BLOCK_SCOPE); 1094 Scope* scope = NewScope(scope_, BLOCK_SCOPE);
1223 BlockState block_state(&scope_, scope); 1095 BlockState block_state(&scope_, scope);
1224 scope_->SetLanguageMode( 1096 scope_->SetLanguageMode(
1225 static_cast<LanguageMode>(class_language_mode | STRICT)); 1097 static_cast<LanguageMode>(class_language_mode | STRICT));
1226 // TODO(marja): Make PreParser use scope names too. 1098 // TODO(marja): Make PreParser use scope names too.
1227 // scope_->SetScopeName(name); 1099 // scope_->SetScopeName(name);
1228 1100
1229 bool has_extends = Check(Token::EXTENDS); 1101 bool has_extends = Check(Token::EXTENDS);
1230 if (has_extends) { 1102 if (has_extends) {
1231 ExpressionClassifier classifier(this); 1103 ExpressionClassifier classifier(this);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 Expect(Token::RBRACE, CHECK_OK); 1164 Expect(Token::RBRACE, CHECK_OK);
1293 return PreParserExpression::Default(); 1165 return PreParserExpression::Default();
1294 } 1166 }
1295 } 1167 }
1296 1168
1297 #undef CHECK_OK 1169 #undef CHECK_OK
1298 1170
1299 1171
1300 } // namespace internal 1172 } // namespace internal
1301 } // namespace v8 1173 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | src/ppc/builtins-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698