| 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 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 case Token::VAR: | 1264 case Token::VAR: |
| 1265 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1265 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1266 case Token::LET: | 1266 case Token::LET: |
| 1267 if (IsNextLetKeyword()) { | 1267 if (IsNextLetKeyword()) { |
| 1268 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1268 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1269 } | 1269 } |
| 1270 break; | 1270 break; |
| 1271 default: | 1271 default: |
| 1272 break; | 1272 break; |
| 1273 } | 1273 } |
| 1274 return ParseStatement(NULL, ok); | 1274 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); |
| 1275 } | 1275 } |
| 1276 | 1276 |
| 1277 | 1277 |
| 1278 Statement* Parser::ParseModuleItem(bool* ok) { | 1278 Statement* Parser::ParseModuleItem(bool* ok) { |
| 1279 // (Ecma 262 6th Edition, 15.2): | 1279 // (Ecma 262 6th Edition, 15.2): |
| 1280 // ModuleItem : | 1280 // ModuleItem : |
| 1281 // ImportDeclaration | 1281 // ImportDeclaration |
| 1282 // ExportDeclaration | 1282 // ExportDeclaration |
| 1283 // StatementListItem | 1283 // StatementListItem |
| 1284 | 1284 |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1714 // TODO(adamk): Possibly report this error at the right place. | 1714 // TODO(adamk): Possibly report this error at the right place. |
| 1715 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]); | 1715 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]); |
| 1716 return NULL; | 1716 return NULL; |
| 1717 } | 1717 } |
| 1718 } | 1718 } |
| 1719 | 1719 |
| 1720 DCHECK_NOT_NULL(result); | 1720 DCHECK_NOT_NULL(result); |
| 1721 return result; | 1721 return result; |
| 1722 } | 1722 } |
| 1723 | 1723 |
| 1724 | |
| 1725 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, | 1724 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, |
| 1725 AllowLabelledFunctionStatement allow_function, |
| 1726 bool* ok) { | 1726 bool* ok) { |
| 1727 // Statement :: | 1727 // Statement :: |
| 1728 // EmptyStatement | 1728 // EmptyStatement |
| 1729 // ... | 1729 // ... |
| 1730 | 1730 |
| 1731 if (peek() == Token::SEMICOLON) { | 1731 if (peek() == Token::SEMICOLON) { |
| 1732 Next(); | 1732 Next(); |
| 1733 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1733 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1734 } | 1734 } |
| 1735 return ParseSubStatement(labels, ok); | 1735 return ParseSubStatement(labels, allow_function, ok); |
| 1736 } | 1736 } |
| 1737 | 1737 |
| 1738 | 1738 Statement* Parser::ParseSubStatement( |
| 1739 Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels, | 1739 ZoneList<const AstRawString*>* labels, |
| 1740 bool* ok) { | 1740 AllowLabelledFunctionStatement allow_function, bool* ok) { |
| 1741 // Statement :: | 1741 // Statement :: |
| 1742 // Block | 1742 // Block |
| 1743 // VariableStatement | 1743 // VariableStatement |
| 1744 // EmptyStatement | 1744 // EmptyStatement |
| 1745 // ExpressionStatement | 1745 // ExpressionStatement |
| 1746 // IfStatement | 1746 // IfStatement |
| 1747 // IterationStatement | 1747 // IterationStatement |
| 1748 // ContinueStatement | 1748 // ContinueStatement |
| 1749 // BreakStatement | 1749 // BreakStatement |
| 1750 // ReturnStatement | 1750 // ReturnStatement |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1819 *ok = false; | 1819 *ok = false; |
| 1820 return nullptr; | 1820 return nullptr; |
| 1821 | 1821 |
| 1822 case Token::DEBUGGER: | 1822 case Token::DEBUGGER: |
| 1823 return ParseDebuggerStatement(ok); | 1823 return ParseDebuggerStatement(ok); |
| 1824 | 1824 |
| 1825 case Token::VAR: | 1825 case Token::VAR: |
| 1826 return ParseVariableStatement(kStatement, NULL, ok); | 1826 return ParseVariableStatement(kStatement, NULL, ok); |
| 1827 | 1827 |
| 1828 default: | 1828 default: |
| 1829 return ParseExpressionOrLabelledStatement(labels, ok); | 1829 return ParseExpressionOrLabelledStatement(labels, allow_function, ok); |
| 1830 } | 1830 } |
| 1831 } | 1831 } |
| 1832 | 1832 |
| 1833 Statement* Parser::ParseStatementAsUnlabelled( | 1833 Statement* Parser::ParseStatementAsUnlabelled( |
| 1834 ZoneList<const AstRawString*>* labels, bool* ok) { | 1834 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 1835 switch (peek()) { | 1835 switch (peek()) { |
| 1836 case Token::CONTINUE: | 1836 case Token::CONTINUE: |
| 1837 return ParseContinueStatement(ok); | 1837 return ParseContinueStatement(ok); |
| 1838 | 1838 |
| 1839 case Token::BREAK: | 1839 case Token::BREAK: |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 if (labels != NULL) { | 2408 if (labels != NULL) { |
| 2409 for (int i = labels->length(); i-- > 0; ) { | 2409 for (int i = labels->length(); i-- > 0; ) { |
| 2410 if (labels->at(i) == label) { | 2410 if (labels->at(i) == label) { |
| 2411 return true; | 2411 return true; |
| 2412 } | 2412 } |
| 2413 } | 2413 } |
| 2414 } | 2414 } |
| 2415 return false; | 2415 return false; |
| 2416 } | 2416 } |
| 2417 | 2417 |
| 2418 | |
| 2419 Statement* Parser::ParseExpressionOrLabelledStatement( | 2418 Statement* Parser::ParseExpressionOrLabelledStatement( |
| 2420 ZoneList<const AstRawString*>* labels, bool* ok) { | 2419 ZoneList<const AstRawString*>* labels, |
| 2420 AllowLabelledFunctionStatement allow_function, bool* ok) { |
| 2421 // ExpressionStatement | LabelledStatement :: | 2421 // ExpressionStatement | LabelledStatement :: |
| 2422 // Expression ';' | 2422 // Expression ';' |
| 2423 // Identifier ':' Statement | 2423 // Identifier ':' Statement |
| 2424 // | 2424 // |
| 2425 // ExpressionStatement[Yield] : | 2425 // ExpressionStatement[Yield] : |
| 2426 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ; | 2426 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ; |
| 2427 | 2427 |
| 2428 int pos = peek_position(); | 2428 int pos = peek_position(); |
| 2429 | 2429 |
| 2430 switch (peek()) { | 2430 switch (peek()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2463 labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); | 2463 labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); |
| 2464 } | 2464 } |
| 2465 labels->Add(label, zone()); | 2465 labels->Add(label, zone()); |
| 2466 // Remove the "ghost" variable that turned out to be a label | 2466 // Remove the "ghost" variable that turned out to be a label |
| 2467 // from the top scope. This way, we don't try to resolve it | 2467 // from the top scope. This way, we don't try to resolve it |
| 2468 // during the scope processing. | 2468 // during the scope processing. |
| 2469 scope_->RemoveUnresolved(var); | 2469 scope_->RemoveUnresolved(var); |
| 2470 Expect(Token::COLON, CHECK_OK); | 2470 Expect(Token::COLON, CHECK_OK); |
| 2471 // ES#sec-labelled-function-declarations Labelled Function Declarations | 2471 // ES#sec-labelled-function-declarations Labelled Function Declarations |
| 2472 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { | 2472 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { |
| 2473 return ParseFunctionDeclaration(labels, ok); | 2473 if (allow_function == kAllowLabelledFunctionStatement) { |
| 2474 return ParseFunctionDeclaration(labels, ok); |
| 2475 } else { |
| 2476 return ParseScopedStatement(labels, true, ok); |
| 2477 } |
| 2474 } | 2478 } |
| 2475 return ParseStatement(labels, ok); | 2479 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok); |
| 2476 } | 2480 } |
| 2477 | 2481 |
| 2478 // If we have an extension, we allow a native function declaration. | 2482 // If we have an extension, we allow a native function declaration. |
| 2479 // A native function declaration starts with "native function" with | 2483 // A native function declaration starts with "native function" with |
| 2480 // no line-terminator between the two words. | 2484 // no line-terminator between the two words. |
| 2481 if (extension_ != NULL && peek() == Token::FUNCTION && | 2485 if (extension_ != NULL && peek() == Token::FUNCTION && |
| 2482 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && | 2486 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && |
| 2483 expr->AsVariableProxy() != NULL && | 2487 expr->AsVariableProxy() != NULL && |
| 2484 expr->AsVariableProxy()->raw_name() == | 2488 expr->AsVariableProxy()->raw_name() == |
| 2485 ast_value_factory()->native_string() && | 2489 ast_value_factory()->native_string() && |
| (...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3453 } | 3457 } |
| 3454 | 3458 |
| 3455 outer_loop->Initialize(NULL, NULL, NULL, inner_block); | 3459 outer_loop->Initialize(NULL, NULL, NULL, inner_block); |
| 3456 return outer_block; | 3460 return outer_block; |
| 3457 } | 3461 } |
| 3458 | 3462 |
| 3459 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels, | 3463 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels, |
| 3460 bool legacy, bool* ok) { | 3464 bool legacy, bool* ok) { |
| 3461 if (is_strict(language_mode()) || peek() != Token::FUNCTION || | 3465 if (is_strict(language_mode()) || peek() != Token::FUNCTION || |
| 3462 (legacy && allow_harmony_restrictive_declarations())) { | 3466 (legacy && allow_harmony_restrictive_declarations())) { |
| 3463 return ParseSubStatement(labels, ok); | 3467 return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok); |
| 3464 } else { | 3468 } else { |
| 3465 if (legacy) { | 3469 if (legacy) { |
| 3466 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; | 3470 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; |
| 3467 } | 3471 } |
| 3468 // Make a block around the statement for a lexical binding | 3472 // Make a block around the statement for a lexical binding |
| 3469 // is introduced by a FunctionDeclaration. | 3473 // is introduced by a FunctionDeclaration. |
| 3470 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); | 3474 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); |
| 3471 BlockState block_state(&scope_, body_scope); | 3475 BlockState block_state(&scope_, body_scope); |
| 3472 Block* block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 3476 Block* block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 3473 Statement* body = ParseFunctionDeclaration(NULL, CHECK_OK); | 3477 Statement* body = ParseFunctionDeclaration(NULL, CHECK_OK); |
| (...skipping 3381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6855 try_block, target); | 6859 try_block, target); |
| 6856 final_loop = target; | 6860 final_loop = target; |
| 6857 } | 6861 } |
| 6858 | 6862 |
| 6859 return final_loop; | 6863 return final_loop; |
| 6860 } | 6864 } |
| 6861 | 6865 |
| 6862 | 6866 |
| 6863 } // namespace internal | 6867 } // namespace internal |
| 6864 } // namespace v8 | 6868 } // namespace v8 |
| OLD | NEW |