OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |