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

Side by Side Diff: src/parsing/parser.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. 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 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-rewriter.h" 9 #include "src/ast/ast-expression-rewriter.h"
10 #include "src/ast/ast-expression-visitor.h" 10 #include "src/ast/ast-expression-visitor.h"
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 case Token::VAR: 1254 case Token::VAR:
1255 return ParseVariableStatement(kStatementListItem, NULL, ok); 1255 return ParseVariableStatement(kStatementListItem, NULL, ok);
1256 case Token::LET: 1256 case Token::LET:
1257 if (IsNextLetKeyword()) { 1257 if (IsNextLetKeyword()) {
1258 return ParseVariableStatement(kStatementListItem, NULL, ok); 1258 return ParseVariableStatement(kStatementListItem, NULL, ok);
1259 } 1259 }
1260 break; 1260 break;
1261 default: 1261 default:
1262 break; 1262 break;
1263 } 1263 }
1264 return ParseStatement(NULL, ok); 1264 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok);
1265 } 1265 }
1266 1266
1267 1267
1268 Statement* Parser::ParseModuleItem(bool* ok) { 1268 Statement* Parser::ParseModuleItem(bool* ok) {
1269 // (Ecma 262 6th Edition, 15.2): 1269 // (Ecma 262 6th Edition, 15.2):
1270 // ModuleItem : 1270 // ModuleItem :
1271 // ImportDeclaration 1271 // ImportDeclaration
1272 // ExportDeclaration 1272 // ExportDeclaration
1273 // StatementListItem 1273 // StatementListItem
1274 1274
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 // TODO(adamk): Possibly report this error at the right place. 1704 // TODO(adamk): Possibly report this error at the right place.
1705 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]); 1705 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]);
1706 return NULL; 1706 return NULL;
1707 } 1707 }
1708 } 1708 }
1709 1709
1710 DCHECK_NOT_NULL(result); 1710 DCHECK_NOT_NULL(result);
1711 return result; 1711 return result;
1712 } 1712 }
1713 1713
1714 1714 Statement* Parser::ParseStatement(
1715 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, 1715 ZoneList<const AstRawString*>* labels,
1716 bool* ok) { 1716 AllowLabelledFunctionStatement allow_labelled_function_statement,
1717 bool* ok) {
1717 // Statement :: 1718 // Statement ::
1718 // EmptyStatement 1719 // EmptyStatement
1719 // ... 1720 // ...
1720 1721
1721 if (peek() == Token::SEMICOLON) { 1722 if (peek() == Token::SEMICOLON) {
1722 Next(); 1723 Next();
1723 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1724 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1724 } 1725 }
1725 return ParseSubStatement(labels, ok); 1726 return ParseSubStatement(labels, allow_labelled_function_statement, ok);
1726 } 1727 }
1727 1728
1728 1729 Statement* Parser::ParseSubStatement(
1729 Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels, 1730 ZoneList<const AstRawString*>* labels,
1730 bool* ok) { 1731 AllowLabelledFunctionStatement allow_labelled_function_statement,
1732 bool* ok) {
1731 // Statement :: 1733 // Statement ::
1732 // Block 1734 // Block
1733 // VariableStatement 1735 // VariableStatement
1734 // EmptyStatement 1736 // EmptyStatement
1735 // ExpressionStatement 1737 // ExpressionStatement
1736 // IfStatement 1738 // IfStatement
1737 // IterationStatement 1739 // IterationStatement
1738 // ContinueStatement 1740 // ContinueStatement
1739 // BreakStatement 1741 // BreakStatement
1740 // ReturnStatement 1742 // ReturnStatement
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 case Token::CONST: 1820 case Token::CONST:
1819 // In ES6 CONST is not allowed as a Statement, only as a 1821 // In ES6 CONST is not allowed as a Statement, only as a
1820 // LexicalDeclaration, however we continue to allow it in sloppy mode for 1822 // LexicalDeclaration, however we continue to allow it in sloppy mode for
1821 // backwards compatibility. 1823 // backwards compatibility.
1822 if (is_sloppy(language_mode()) && allow_legacy_const()) { 1824 if (is_sloppy(language_mode()) && allow_legacy_const()) {
1823 return ParseVariableStatement(kStatement, NULL, ok); 1825 return ParseVariableStatement(kStatement, NULL, ok);
1824 } 1826 }
1825 1827
1826 // Fall through. 1828 // Fall through.
1827 default: 1829 default:
1828 return ParseExpressionOrLabelledStatement(labels, ok); 1830 return ParseExpressionOrLabelledStatement(
1831 labels, allow_labelled_function_statement, ok);
1829 } 1832 }
1830 } 1833 }
1831 1834
1832 Statement* Parser::ParseStatementAsUnlabelled( 1835 Statement* Parser::ParseStatementAsUnlabelled(
1833 ZoneList<const AstRawString*>* labels, bool* ok) { 1836 ZoneList<const AstRawString*>* labels, bool* ok) {
1834 switch (peek()) { 1837 switch (peek()) {
1835 case Token::CONTINUE: 1838 case Token::CONTINUE:
1836 return ParseContinueStatement(ok); 1839 return ParseContinueStatement(ok);
1837 1840
1838 case Token::BREAK: 1841 case Token::BREAK:
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 if (labels != NULL) { 2422 if (labels != NULL) {
2420 for (int i = labels->length(); i-- > 0; ) { 2423 for (int i = labels->length(); i-- > 0; ) {
2421 if (labels->at(i) == label) { 2424 if (labels->at(i) == label) {
2422 return true; 2425 return true;
2423 } 2426 }
2424 } 2427 }
2425 } 2428 }
2426 return false; 2429 return false;
2427 } 2430 }
2428 2431
2429
2430 Statement* Parser::ParseExpressionOrLabelledStatement( 2432 Statement* Parser::ParseExpressionOrLabelledStatement(
2431 ZoneList<const AstRawString*>* labels, bool* ok) { 2433 ZoneList<const AstRawString*>* labels,
2434 AllowLabelledFunctionStatement allow_labelled_function_statement,
adamk 2016/03/24 01:15:52 How about "allow_function" for this name (here and
2435 bool* ok) {
2432 // ExpressionStatement | LabelledStatement :: 2436 // ExpressionStatement | LabelledStatement ::
2433 // Expression ';' 2437 // Expression ';'
2434 // Identifier ':' Statement 2438 // Identifier ':' Statement
2435 // 2439 //
2436 // ExpressionStatement[Yield] : 2440 // ExpressionStatement[Yield] :
2437 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ; 2441 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2438 2442
2439 int pos = peek_position(); 2443 int pos = peek_position();
2440 2444
2441 switch (peek()) { 2445 switch (peek()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2474 labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); 2478 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2475 } 2479 }
2476 labels->Add(label, zone()); 2480 labels->Add(label, zone());
2477 // Remove the "ghost" variable that turned out to be a label 2481 // Remove the "ghost" variable that turned out to be a label
2478 // from the top scope. This way, we don't try to resolve it 2482 // from the top scope. This way, we don't try to resolve it
2479 // during the scope processing. 2483 // during the scope processing.
2480 scope_->RemoveUnresolved(var); 2484 scope_->RemoveUnresolved(var);
2481 Expect(Token::COLON, CHECK_OK); 2485 Expect(Token::COLON, CHECK_OK);
2482 // ES#sec-labelled-function-declarations Labelled Function Declarations 2486 // ES#sec-labelled-function-declarations Labelled Function Declarations
2483 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { 2487 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
2484 return ParseFunctionDeclaration(labels, ok); 2488 if (allow_labelled_function_statement ==
2489 kAllowLabelledFunctionStatement) {
2490 return ParseFunctionDeclaration(labels, ok);
2491 } else {
2492 return ParseScopedStatement(labels, true, ok);
2493 }
2485 } 2494 }
2486 return ParseStatement(labels, ok); 2495 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
2487 } 2496 }
2488 2497
2489 // If we have an extension, we allow a native function declaration. 2498 // If we have an extension, we allow a native function declaration.
2490 // A native function declaration starts with "native function" with 2499 // A native function declaration starts with "native function" with
2491 // no line-terminator between the two words. 2500 // no line-terminator between the two words.
2492 if (extension_ != NULL && peek() == Token::FUNCTION && 2501 if (extension_ != NULL && peek() == Token::FUNCTION &&
2493 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && 2502 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2494 expr->AsVariableProxy() != NULL && 2503 expr->AsVariableProxy() != NULL &&
2495 expr->AsVariableProxy()->raw_name() == 2504 expr->AsVariableProxy()->raw_name() ==
2496 ast_value_factory()->native_string() && 2505 ast_value_factory()->native_string() &&
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after
3464 } 3473 }
3465 3474
3466 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3475 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3467 return outer_block; 3476 return outer_block;
3468 } 3477 }
3469 3478
3470 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels, 3479 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels,
3471 bool legacy, bool* ok) { 3480 bool legacy, bool* ok) {
3472 if (is_strict(language_mode()) || peek() != Token::FUNCTION || 3481 if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
3473 (legacy && allow_harmony_restrictive_declarations())) { 3482 (legacy && allow_harmony_restrictive_declarations())) {
3474 return ParseSubStatement(labels, ok); 3483 return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok);
3475 } else { 3484 } else {
3476 if (legacy) { 3485 if (legacy) {
3477 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; 3486 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration];
3478 } 3487 }
3479 // Make a block around the statement for a lexical binding 3488 // Make a block around the statement for a lexical binding
3480 // is introduced by a FunctionDeclaration. 3489 // is introduced by a FunctionDeclaration.
3481 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); 3490 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3482 BlockState block_state(&scope_, body_scope); 3491 BlockState block_state(&scope_, body_scope);
3483 Block* block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3492 Block* block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3484 Statement* body = ParseFunctionDeclaration(NULL, CHECK_OK); 3493 Statement* body = ParseFunctionDeclaration(NULL, CHECK_OK);
(...skipping 3313 matching lines...) Expand 10 before | Expand all | Expand 10 after
6798 try_block, target); 6807 try_block, target);
6799 final_loop = target; 6808 final_loop = target;
6800 } 6809 }
6801 6810
6802 return final_loop; 6811 return final_loop;
6803 } 6812 }
6804 6813
6805 6814
6806 } // namespace internal 6815 } // namespace internal
6807 } // namespace v8 6816 } // namespace v8
OLDNEW
« src/parsing/parser.h ('K') | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698