Chromium Code Reviews

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

Issue 1808373003: Implement ES2015 labelled function declaration restrictions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
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 176 matching lines...)
187 } 187 }
188 break; 188 break;
189 case Token::LET: 189 case Token::LET:
190 if (IsNextLetKeyword()) { 190 if (IsNextLetKeyword()) {
191 return ParseVariableStatement(kStatementListItem, ok); 191 return ParseVariableStatement(kStatementListItem, ok);
192 } 192 }
193 break; 193 break;
194 default: 194 default:
195 break; 195 break;
196 } 196 }
197 return ParseStatement(ok); 197 return ParseStatement(kAllowLabelledFunctionStatement, ok);
198 } 198 }
199 199
200 200
201 void PreParser::ParseStatementList(int end_token, bool* ok, 201 void PreParser::ParseStatementList(int end_token, bool* ok,
202 Scanner::BookmarkScope* bookmark) { 202 Scanner::BookmarkScope* bookmark) {
203 // SourceElements :: 203 // SourceElements ::
204 // (Statement)* <end_token> 204 // (Statement)* <end_token>
205 205
206 // Bookkeeping for trial parse if bookmark is set: 206 // Bookkeeping for trial parse if bookmark is set:
207 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); 207 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
(...skipping 48 matching lines...)
256 } 256 }
257 } 257 }
258 258
259 259
260 #define CHECK_OK ok); \ 260 #define CHECK_OK ok); \
261 if (!*ok) return Statement::Default(); \ 261 if (!*ok) return Statement::Default(); \
262 ((void)0 262 ((void)0
263 #define DUMMY ) // to make indentation work 263 #define DUMMY ) // to make indentation work
264 #undef DUMMY 264 #undef DUMMY
265 265
266 266 PreParser::Statement PreParser::ParseStatement(
267 PreParser::Statement PreParser::ParseStatement(bool* ok) { 267 AllowLabelledFunctionStatement allow_labelled_function_statement,
268 bool* ok) {
268 // Statement :: 269 // Statement ::
269 // EmptyStatement 270 // EmptyStatement
270 // ... 271 // ...
271 272
272 if (peek() == Token::SEMICOLON) { 273 if (peek() == Token::SEMICOLON) {
273 Next(); 274 Next();
274 return Statement::Default(); 275 return Statement::Default();
275 } 276 }
276 return ParseSubStatement(ok); 277 return ParseSubStatement(allow_labelled_function_statement, ok);
277 } 278 }
278 279
279 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { 280 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
280 if (is_strict(language_mode()) || peek() != Token::FUNCTION || 281 if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
281 (legacy && allow_harmony_restrictive_declarations())) { 282 (legacy && allow_harmony_restrictive_declarations())) {
282 return ParseSubStatement(ok); 283 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok);
283 } else { 284 } else {
284 return ParseFunctionDeclaration(CHECK_OK); 285 return ParseFunctionDeclaration(CHECK_OK);
285 } 286 }
286 } 287 }
287 288
288 PreParser::Statement PreParser::ParseSubStatement(bool* ok) { 289 PreParser::Statement PreParser::ParseSubStatement(
290 AllowLabelledFunctionStatement allow_labelled_function_statement,
291 bool* ok) {
289 // Statement :: 292 // Statement ::
290 // Block 293 // Block
291 // VariableStatement 294 // VariableStatement
292 // EmptyStatement 295 // EmptyStatement
293 // ExpressionStatement 296 // ExpressionStatement
294 // IfStatement 297 // IfStatement
295 // IterationStatement 298 // IterationStatement
296 // ContinueStatement 299 // ContinueStatement
297 // BreakStatement 300 // BreakStatement
298 // ReturnStatement 301 // ReturnStatement
(...skipping 75 matching lines...)
374 case Token::CONST: 377 case Token::CONST:
375 // In ES6 CONST is not allowed as a Statement, only as a 378 // In ES6 CONST is not allowed as a Statement, only as a
376 // LexicalDeclaration, however we continue to allow it in sloppy mode for 379 // LexicalDeclaration, however we continue to allow it in sloppy mode for
377 // backwards compatibility. 380 // backwards compatibility.
378 if (is_sloppy(language_mode()) && allow_legacy_const()) { 381 if (is_sloppy(language_mode()) && allow_legacy_const()) {
379 return ParseVariableStatement(kStatement, ok); 382 return ParseVariableStatement(kStatement, ok);
380 } 383 }
381 384
382 // Fall through. 385 // Fall through.
383 default: 386 default:
384 return ParseExpressionOrLabelledStatement(ok); 387 return ParseExpressionOrLabelledStatement(
388 allow_labelled_function_statement, ok);
385 } 389 }
386 } 390 }
387 391
388 392
389 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 393 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
390 // FunctionDeclaration :: 394 // FunctionDeclaration ::
391 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 395 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
392 // GeneratorDeclaration :: 396 // GeneratorDeclaration ::
393 // 'function' '*' Identifier '(' FormalParameterListopt ')' 397 // 'function' '*' Identifier '(' FormalParameterListopt ')'
394 // '{' FunctionBody '}' 398 // '{' FunctionBody '}'
(...skipping 163 matching lines...)
558 *bindings_loc = 562 *bindings_loc =
559 Scanner::Location(bindings_start, scanner()->location().end_pos); 563 Scanner::Location(bindings_start, scanner()->location().end_pos);
560 } 564 }
561 565
562 if (num_decl != nullptr) *num_decl = nvars; 566 if (num_decl != nullptr) *num_decl = nvars;
563 if (is_lexical != nullptr) *is_lexical = lexical; 567 if (is_lexical != nullptr) *is_lexical = lexical;
564 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern; 568 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern;
565 return Statement::Default(); 569 return Statement::Default();
566 } 570 }
567 571
568 572 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
569 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 573 AllowLabelledFunctionStatement allow_labelled_function_statement,
574 bool* ok) {
570 // ExpressionStatement | LabelledStatement :: 575 // ExpressionStatement | LabelledStatement ::
571 // Expression ';' 576 // Expression ';'
572 // Identifier ':' Statement 577 // Identifier ':' Statement
573 578
574 switch (peek()) { 579 switch (peek()) {
575 case Token::FUNCTION: 580 case Token::FUNCTION:
576 case Token::LBRACE: 581 case Token::LBRACE:
577 UNREACHABLE(); // Always handled by the callers. 582 UNREACHABLE(); // Always handled by the callers.
578 case Token::CLASS: 583 case Token::CLASS:
579 ReportUnexpectedToken(Next()); 584 ReportUnexpectedToken(Next());
(...skipping 14 matching lines...)
594 // an identifier. 599 // an identifier.
595 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 600 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
596 // Expression is a single identifier, and not, e.g., a parenthesized 601 // Expression is a single identifier, and not, e.g., a parenthesized
597 // identifier. 602 // identifier.
598 DCHECK(!expr.AsIdentifier().IsFutureReserved()); 603 DCHECK(!expr.AsIdentifier().IsFutureReserved());
599 DCHECK(is_sloppy(language_mode()) || 604 DCHECK(is_sloppy(language_mode()) ||
600 !IsFutureStrictReserved(expr.AsIdentifier())); 605 !IsFutureStrictReserved(expr.AsIdentifier()));
601 Consume(Token::COLON); 606 Consume(Token::COLON);
602 // ES#sec-labelled-function-declarations Labelled Function Declarations 607 // ES#sec-labelled-function-declarations Labelled Function Declarations
603 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { 608 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
604 return ParseFunctionDeclaration(ok); 609 if (allow_labelled_function_statement ==
610 kAllowLabelledFunctionStatement) {
611 return ParseFunctionDeclaration(ok);
612 } else {
613 return ParseScopedStatement(true, ok);
614 }
605 } 615 }
606 Statement statement = ParseStatement(ok); 616 Statement statement =
617 ParseStatement(kDisallowLabelledFunctionStatement, ok);
607 return statement.IsJumpStatement() ? Statement::Default() : statement; 618 return statement.IsJumpStatement() ? Statement::Default() : statement;
608 // Preparsing is disabled for extensions (because the extension details 619 // Preparsing is disabled for extensions (because the extension details
609 // aren't passed to lazily compiled functions), so we don't 620 // aren't passed to lazily compiled functions), so we don't
610 // accept "native function" in the preparser. 621 // accept "native function" in the preparser.
611 } 622 }
612 // Parsed expression statement. 623 // Parsed expression statement.
613 // Detect attempts at 'let' declarations in sloppy mode. 624 // Detect attempts at 'let' declarations in sloppy mode.
614 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER && 625 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
615 is_sloppy(language_mode()) && expr.IsIdentifier() && 626 is_sloppy(language_mode()) && expr.IsIdentifier() &&
616 expr.AsIdentifier().IsLet()) { 627 expr.AsIdentifier().IsLet()) {
(...skipping 539 matching lines...)
1156 Expect(Token::RBRACE, CHECK_OK); 1167 Expect(Token::RBRACE, CHECK_OK);
1157 return PreParserExpression::Default(); 1168 return PreParserExpression::Default();
1158 } 1169 }
1159 } 1170 }
1160 1171
1161 #undef CHECK_OK 1172 #undef CHECK_OK
1162 1173
1163 1174
1164 } // namespace internal 1175 } // namespace internal
1165 } // namespace v8 1176 } // namespace v8
OLDNEW

Powered by Google App Engine