Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 if (!*ok) return Statement::Default(); \ | 228 if (!*ok) return Statement::Default(); \ |
| 229 ((void)0 | 229 ((void)0 |
| 230 #define DUMMY ) // to make indentation work | 230 #define DUMMY ) // to make indentation work |
| 231 #undef DUMMY | 231 #undef DUMMY |
| 232 | 232 |
| 233 | 233 |
| 234 PreParser::Statement PreParser::ParseStatement(bool* ok) { | 234 PreParser::Statement PreParser::ParseStatement(bool* ok) { |
| 235 // Statement :: | 235 // Statement :: |
| 236 // EmptyStatement | 236 // EmptyStatement |
| 237 // ... | 237 // ... |
| 238 | |
| 239 if (peek() == Token::SEMICOLON) { | |
| 240 Next(); | |
| 241 return Statement::Default(); | |
| 242 } | |
| 238 return ParseSubStatement(ok); | 243 return ParseSubStatement(ok); |
| 239 } | 244 } |
| 240 | 245 |
| 241 | 246 |
| 242 PreParser::Statement PreParser::ParseSubStatement(bool* ok) { | 247 PreParser::Statement PreParser::ParseSubStatement(bool* ok) { |
| 243 // Statement :: | 248 // Statement :: |
| 244 // Block | 249 // Block |
| 245 // VariableStatement | 250 // VariableStatement |
| 246 // EmptyStatement | 251 // EmptyStatement |
| 247 // ExpressionStatement | 252 // ExpressionStatement |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 388 | 393 |
| 389 | 394 |
| 390 PreParser::Statement PreParser::ParseBlock(bool* ok) { | 395 PreParser::Statement PreParser::ParseBlock(bool* ok) { |
| 391 // Block :: | 396 // Block :: |
| 392 // '{' Statement* '}' | 397 // '{' Statement* '}' |
| 393 | 398 |
| 394 // Note that a Block does not introduce a new execution scope! | 399 // Note that a Block does not introduce a new execution scope! |
| 395 // (ECMA-262, 3rd, 12.2) | 400 // (ECMA-262, 3rd, 12.2) |
| 396 // | 401 // |
| 397 Expect(Token::LBRACE, CHECK_OK); | 402 Expect(Token::LBRACE, CHECK_OK); |
| 403 Statement final = Statement::Default(); | |
| 398 while (peek() != Token::RBRACE) { | 404 while (peek() != Token::RBRACE) { |
| 399 if (is_strict(language_mode())) { | 405 if (is_strict(language_mode())) { |
| 400 ParseStatementListItem(CHECK_OK); | 406 final = ParseStatementListItem(CHECK_OK); |
| 401 } else { | 407 } else { |
| 402 ParseStatement(CHECK_OK); | 408 final = ParseStatement(CHECK_OK); |
| 403 } | 409 } |
| 404 } | 410 } |
| 405 Expect(Token::RBRACE, ok); | 411 Expect(Token::RBRACE, ok); |
| 406 return Statement::Default(); | 412 return final; |
| 407 } | 413 } |
| 408 | 414 |
| 409 | 415 |
| 410 PreParser::Statement PreParser::ParseVariableStatement( | 416 PreParser::Statement PreParser::ParseVariableStatement( |
| 411 VariableDeclarationContext var_context, | 417 VariableDeclarationContext var_context, |
| 412 bool* ok) { | 418 bool* ok) { |
| 413 // VariableStatement :: | 419 // VariableStatement :: |
| 414 // VariableDeclarations ';' | 420 // VariableDeclarations ';' |
| 415 | 421 |
| 416 Statement result = ParseVariableDeclarations(var_context, nullptr, nullptr, | 422 Statement result = ParseVariableDeclarations(var_context, nullptr, nullptr, |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 // Even if the expression starts with an identifier, it is not necessarily an | 544 // Even if the expression starts with an identifier, it is not necessarily an |
| 539 // identifier. For example, "foo + bar" starts with an identifier but is not | 545 // identifier. For example, "foo + bar" starts with an identifier but is not |
| 540 // an identifier. | 546 // an identifier. |
| 541 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { | 547 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { |
| 542 // Expression is a single identifier, and not, e.g., a parenthesized | 548 // Expression is a single identifier, and not, e.g., a parenthesized |
| 543 // identifier. | 549 // identifier. |
| 544 DCHECK(!expr.AsIdentifier().IsFutureReserved()); | 550 DCHECK(!expr.AsIdentifier().IsFutureReserved()); |
| 545 DCHECK(is_sloppy(language_mode()) || | 551 DCHECK(is_sloppy(language_mode()) || |
| 546 !IsFutureStrictReserved(expr.AsIdentifier())); | 552 !IsFutureStrictReserved(expr.AsIdentifier())); |
| 547 Consume(Token::COLON); | 553 Consume(Token::COLON); |
| 548 return ParseStatement(ok); | 554 Statement statement = ParseStatement(ok); |
| 555 if (statement.IsJumpStatement()) { | |
|
rossberg
2015/04/15 19:56:34
Nit: Use return with ?:
conradw
2015/04/16 10:59:57
Done.
| |
| 556 return Statement::Default(); | |
| 557 } | |
| 558 return statement; | |
| 549 // Preparsing is disabled for extensions (because the extension details | 559 // Preparsing is disabled for extensions (because the extension details |
| 550 // aren't passed to lazily compiled functions), so we don't | 560 // aren't passed to lazily compiled functions), so we don't |
| 551 // accept "native function" in the preparser. | 561 // accept "native function" in the preparser. |
| 552 } | 562 } |
| 553 // Parsed expression statement. | 563 // Parsed expression statement. |
| 554 // Detect attempts at 'let' declarations in sloppy mode. | 564 // Detect attempts at 'let' declarations in sloppy mode. |
| 555 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) && | 565 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) && |
| 556 expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { | 566 expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { |
| 557 ReportMessage("sloppy_lexical", NULL); | 567 ReportMessage("sloppy_lexical", NULL); |
| 558 *ok = false; | 568 *ok = false; |
| 559 return Statement::Default(); | 569 return Statement::Default(); |
| 560 } | 570 } |
| 561 ExpectSemicolon(CHECK_OK); | 571 ExpectSemicolon(CHECK_OK); |
| 562 return Statement::ExpressionStatement(expr); | 572 return Statement::ExpressionStatement(expr); |
| 563 } | 573 } |
| 564 | 574 |
| 565 | 575 |
| 566 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { | 576 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { |
| 567 // IfStatement :: | 577 // IfStatement :: |
| 568 // 'if' '(' Expression ')' Statement ('else' Statement)? | 578 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 569 | 579 |
| 570 Expect(Token::IF, CHECK_OK); | 580 Expect(Token::IF, CHECK_OK); |
| 571 Expect(Token::LPAREN, CHECK_OK); | 581 Expect(Token::LPAREN, CHECK_OK); |
| 572 ParseExpression(true, CHECK_OK); | 582 ParseExpression(true, CHECK_OK); |
| 573 Expect(Token::RPAREN, CHECK_OK); | 583 Expect(Token::RPAREN, CHECK_OK); |
| 574 ParseSubStatement(CHECK_OK); | 584 Statement stat = ParseSubStatement(CHECK_OK); |
| 575 if (peek() == Token::ELSE) { | 585 if (peek() == Token::ELSE) { |
| 576 Next(); | 586 Next(); |
| 577 ParseSubStatement(CHECK_OK); | 587 Statement else_stat = ParseSubStatement(CHECK_OK); |
| 588 stat = (else_stat.IsJumpStatement()) ? stat : Statement::Default(); | |
|
rossberg
2015/04/15 19:56:34
This doesn't seem quite right, since stat may be s
conradw
2015/04/16 10:59:57
Done.
| |
| 589 } else { | |
| 590 stat = Statement::Default(); | |
| 578 } | 591 } |
| 579 return Statement::Default(); | 592 return stat; |
| 580 } | 593 } |
| 581 | 594 |
| 582 | 595 |
| 583 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { | 596 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { |
| 584 // ContinueStatement :: | 597 // ContinueStatement :: |
| 585 // 'continue' [no line terminator] Identifier? ';' | 598 // 'continue' [no line terminator] Identifier? ';' |
| 586 | 599 |
| 587 Expect(Token::CONTINUE, CHECK_OK); | 600 Expect(Token::CONTINUE, CHECK_OK); |
| 588 Token::Value tok = peek(); | 601 Token::Value tok = peek(); |
| 589 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 602 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 590 tok != Token::SEMICOLON && | 603 tok != Token::SEMICOLON && |
| 591 tok != Token::RBRACE && | 604 tok != Token::RBRACE && |
| 592 tok != Token::EOS) { | 605 tok != Token::EOS) { |
| 593 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 606 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 594 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 607 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 595 } | 608 } |
| 596 ExpectSemicolon(CHECK_OK); | 609 ExpectSemicolon(CHECK_OK); |
| 597 return Statement::Default(); | 610 return Statement::Jump(); |
| 598 } | 611 } |
| 599 | 612 |
| 600 | 613 |
| 601 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 614 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
| 602 // BreakStatement :: | 615 // BreakStatement :: |
| 603 // 'break' [no line terminator] Identifier? ';' | 616 // 'break' [no line terminator] Identifier? ';' |
| 604 | 617 |
| 605 Expect(Token::BREAK, CHECK_OK); | 618 Expect(Token::BREAK, CHECK_OK); |
| 606 Token::Value tok = peek(); | 619 Token::Value tok = peek(); |
| 607 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 620 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 608 tok != Token::SEMICOLON && | 621 tok != Token::SEMICOLON && |
| 609 tok != Token::RBRACE && | 622 tok != Token::RBRACE && |
| 610 tok != Token::EOS) { | 623 tok != Token::EOS) { |
| 611 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 624 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 612 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 625 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 613 } | 626 } |
| 614 ExpectSemicolon(CHECK_OK); | 627 ExpectSemicolon(CHECK_OK); |
| 615 return Statement::Default(); | 628 return Statement::Jump(); |
| 616 } | 629 } |
| 617 | 630 |
| 618 | 631 |
| 619 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 632 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
| 620 // ReturnStatement :: | 633 // ReturnStatement :: |
| 621 // 'return' [no line terminator] Expression? ';' | 634 // 'return' [no line terminator] Expression? ';' |
| 622 | 635 |
| 623 // Consume the return token. It is necessary to do before | 636 // Consume the return token. It is necessary to do before |
| 624 // reporting any errors on it, because of the way errors are | 637 // reporting any errors on it, because of the way errors are |
| 625 // reported (underlining). | 638 // reported (underlining). |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 640 i::IsConstructor(function_state_->kind())) { | 653 i::IsConstructor(function_state_->kind())) { |
| 641 int pos = peek_position(); | 654 int pos = peek_position(); |
| 642 ReportMessageAt(Scanner::Location(pos, pos + 1), | 655 ReportMessageAt(Scanner::Location(pos, pos + 1), |
| 643 "strong_constructor_return_value"); | 656 "strong_constructor_return_value"); |
| 644 *ok = false; | 657 *ok = false; |
| 645 return Statement::Default(); | 658 return Statement::Default(); |
| 646 } | 659 } |
| 647 ParseExpression(true, CHECK_OK); | 660 ParseExpression(true, CHECK_OK); |
| 648 } | 661 } |
| 649 ExpectSemicolon(CHECK_OK); | 662 ExpectSemicolon(CHECK_OK); |
| 650 return Statement::Default(); | 663 return Statement::Jump(); |
| 651 } | 664 } |
| 652 | 665 |
| 653 | 666 |
| 654 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 667 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
| 655 // WithStatement :: | 668 // WithStatement :: |
| 656 // 'with' '(' Expression ')' Statement | 669 // 'with' '(' Expression ')' Statement |
| 657 Expect(Token::WITH, CHECK_OK); | 670 Expect(Token::WITH, CHECK_OK); |
| 658 if (is_strict(language_mode())) { | 671 if (is_strict(language_mode())) { |
| 659 ReportMessageAt(scanner()->location(), "strict_mode_with"); | 672 ReportMessageAt(scanner()->location(), "strict_mode_with"); |
| 660 *ok = false; | 673 *ok = false; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 684 Token::Value token = peek(); | 697 Token::Value token = peek(); |
| 685 while (token != Token::RBRACE) { | 698 while (token != Token::RBRACE) { |
| 686 if (token == Token::CASE) { | 699 if (token == Token::CASE) { |
| 687 Expect(Token::CASE, CHECK_OK); | 700 Expect(Token::CASE, CHECK_OK); |
| 688 ParseExpression(true, CHECK_OK); | 701 ParseExpression(true, CHECK_OK); |
| 689 } else { | 702 } else { |
| 690 Expect(Token::DEFAULT, CHECK_OK); | 703 Expect(Token::DEFAULT, CHECK_OK); |
| 691 } | 704 } |
| 692 Expect(Token::COLON, CHECK_OK); | 705 Expect(Token::COLON, CHECK_OK); |
| 693 token = peek(); | 706 token = peek(); |
| 707 Statement statement = Statement::Jump(); | |
| 694 while (token != Token::CASE && | 708 while (token != Token::CASE && |
| 695 token != Token::DEFAULT && | 709 token != Token::DEFAULT && |
| 696 token != Token::RBRACE) { | 710 token != Token::RBRACE) { |
| 697 ParseStatementListItem(CHECK_OK); | 711 statement = ParseStatementListItem(CHECK_OK); |
| 698 token = peek(); | 712 token = peek(); |
| 699 } | 713 } |
| 714 if (is_strong(language_mode()) && | |
| 715 !statement.IsJumpStatement()) { | |
|
rossberg
2015/04/15 19:56:34
Nit: stray line break
But more importantly, don't
conradw
2015/04/16 10:59:57
Done, and I made the same mistake in parser
| |
| 716 ReportMessageAt(scanner()->location(), "strong_switch_fallthrough"); | |
| 717 *ok = false; | |
| 718 return Statement::Default(); | |
| 719 } | |
| 700 } | 720 } |
| 701 Expect(Token::RBRACE, ok); | 721 Expect(Token::RBRACE, ok); |
| 702 return Statement::Default(); | 722 return Statement::Default(); |
| 703 } | 723 } |
| 704 | 724 |
| 705 | 725 |
| 706 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { | 726 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { |
| 707 // DoStatement :: | 727 // DoStatement :: |
| 708 // 'do' Statement 'while' '(' Expression ')' ';' | 728 // 'do' Statement 'while' '(' Expression ')' ';' |
| 709 | 729 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 820 // 'throw' [no line terminator] Expression ';' | 840 // 'throw' [no line terminator] Expression ';' |
| 821 | 841 |
| 822 Expect(Token::THROW, CHECK_OK); | 842 Expect(Token::THROW, CHECK_OK); |
| 823 if (scanner()->HasAnyLineTerminatorBeforeNext()) { | 843 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 824 ReportMessageAt(scanner()->location(), "newline_after_throw"); | 844 ReportMessageAt(scanner()->location(), "newline_after_throw"); |
| 825 *ok = false; | 845 *ok = false; |
| 826 return Statement::Default(); | 846 return Statement::Default(); |
| 827 } | 847 } |
| 828 ParseExpression(true, CHECK_OK); | 848 ParseExpression(true, CHECK_OK); |
| 829 ExpectSemicolon(ok); | 849 ExpectSemicolon(ok); |
| 830 return Statement::Default(); | 850 return Statement::Jump(); |
| 831 } | 851 } |
| 832 | 852 |
| 833 | 853 |
| 834 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { | 854 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { |
| 835 // TryStatement :: | 855 // TryStatement :: |
| 836 // 'try' Block Catch | 856 // 'try' Block Catch |
| 837 // 'try' Block Finally | 857 // 'try' Block Finally |
| 838 // 'try' Block Catch Finally | 858 // 'try' Block Catch Finally |
| 839 // | 859 // |
| 840 // Catch :: | 860 // Catch :: |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1045 | 1065 |
| 1046 DCHECK(!spread_pos.IsValid()); | 1066 DCHECK(!spread_pos.IsValid()); |
| 1047 | 1067 |
| 1048 return Expression::Default(); | 1068 return Expression::Default(); |
| 1049 } | 1069 } |
| 1050 | 1070 |
| 1051 #undef CHECK_OK | 1071 #undef CHECK_OK |
| 1052 | 1072 |
| 1053 | 1073 |
| 1054 } } // v8::internal | 1074 } } // v8::internal |
| OLD | NEW |