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 return statement.IsJumpStatement() ? Statement::Default() : statement; |
549 // Preparsing is disabled for extensions (because the extension details | 556 // Preparsing is disabled for extensions (because the extension details |
550 // aren't passed to lazily compiled functions), so we don't | 557 // aren't passed to lazily compiled functions), so we don't |
551 // accept "native function" in the preparser. | 558 // accept "native function" in the preparser. |
552 } | 559 } |
553 // Parsed expression statement. | 560 // Parsed expression statement. |
554 // Detect attempts at 'let' declarations in sloppy mode. | 561 // Detect attempts at 'let' declarations in sloppy mode. |
555 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) && | 562 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) && |
556 expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { | 563 expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { |
557 ReportMessage("sloppy_lexical", NULL); | 564 ReportMessage("sloppy_lexical", NULL); |
558 *ok = false; | 565 *ok = false; |
559 return Statement::Default(); | 566 return Statement::Default(); |
560 } | 567 } |
561 ExpectSemicolon(CHECK_OK); | 568 ExpectSemicolon(CHECK_OK); |
562 return Statement::ExpressionStatement(expr); | 569 return Statement::ExpressionStatement(expr); |
563 } | 570 } |
564 | 571 |
565 | 572 |
566 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { | 573 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { |
567 // IfStatement :: | 574 // IfStatement :: |
568 // 'if' '(' Expression ')' Statement ('else' Statement)? | 575 // 'if' '(' Expression ')' Statement ('else' Statement)? |
569 | 576 |
570 Expect(Token::IF, CHECK_OK); | 577 Expect(Token::IF, CHECK_OK); |
571 Expect(Token::LPAREN, CHECK_OK); | 578 Expect(Token::LPAREN, CHECK_OK); |
572 ParseExpression(true, CHECK_OK); | 579 ParseExpression(true, CHECK_OK); |
573 Expect(Token::RPAREN, CHECK_OK); | 580 Expect(Token::RPAREN, CHECK_OK); |
574 ParseSubStatement(CHECK_OK); | 581 Statement stat = ParseSubStatement(CHECK_OK); |
575 if (peek() == Token::ELSE) { | 582 if (peek() == Token::ELSE) { |
576 Next(); | 583 Next(); |
577 ParseSubStatement(CHECK_OK); | 584 Statement else_stat = ParseSubStatement(CHECK_OK); |
| 585 stat = (stat.IsJumpStatement() && else_stat.IsJumpStatement()) ? |
| 586 Statement::Jump() : Statement::Default(); |
| 587 } else { |
| 588 stat = Statement::Default(); |
578 } | 589 } |
579 return Statement::Default(); | 590 return stat; |
580 } | 591 } |
581 | 592 |
582 | 593 |
583 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { | 594 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { |
584 // ContinueStatement :: | 595 // ContinueStatement :: |
585 // 'continue' [no line terminator] Identifier? ';' | 596 // 'continue' [no line terminator] Identifier? ';' |
586 | 597 |
587 Expect(Token::CONTINUE, CHECK_OK); | 598 Expect(Token::CONTINUE, CHECK_OK); |
588 Token::Value tok = peek(); | 599 Token::Value tok = peek(); |
589 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 600 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
590 tok != Token::SEMICOLON && | 601 tok != Token::SEMICOLON && |
591 tok != Token::RBRACE && | 602 tok != Token::RBRACE && |
592 tok != Token::EOS) { | 603 tok != Token::EOS) { |
593 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 604 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
594 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 605 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
595 } | 606 } |
596 ExpectSemicolon(CHECK_OK); | 607 ExpectSemicolon(CHECK_OK); |
597 return Statement::Default(); | 608 return Statement::Jump(); |
598 } | 609 } |
599 | 610 |
600 | 611 |
601 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 612 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
602 // BreakStatement :: | 613 // BreakStatement :: |
603 // 'break' [no line terminator] Identifier? ';' | 614 // 'break' [no line terminator] Identifier? ';' |
604 | 615 |
605 Expect(Token::BREAK, CHECK_OK); | 616 Expect(Token::BREAK, CHECK_OK); |
606 Token::Value tok = peek(); | 617 Token::Value tok = peek(); |
607 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 618 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
608 tok != Token::SEMICOLON && | 619 tok != Token::SEMICOLON && |
609 tok != Token::RBRACE && | 620 tok != Token::RBRACE && |
610 tok != Token::EOS) { | 621 tok != Token::EOS) { |
611 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 622 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
612 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 623 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
613 } | 624 } |
614 ExpectSemicolon(CHECK_OK); | 625 ExpectSemicolon(CHECK_OK); |
615 return Statement::Default(); | 626 return Statement::Jump(); |
616 } | 627 } |
617 | 628 |
618 | 629 |
619 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 630 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
620 // ReturnStatement :: | 631 // ReturnStatement :: |
621 // 'return' [no line terminator] Expression? ';' | 632 // 'return' [no line terminator] Expression? ';' |
622 | 633 |
623 // Consume the return token. It is necessary to do before | 634 // Consume the return token. It is necessary to do before |
624 // reporting any errors on it, because of the way errors are | 635 // reporting any errors on it, because of the way errors are |
625 // reported (underlining). | 636 // reported (underlining). |
(...skipping 14 matching lines...) Expand all Loading... |
640 i::IsConstructor(function_state_->kind())) { | 651 i::IsConstructor(function_state_->kind())) { |
641 int pos = peek_position(); | 652 int pos = peek_position(); |
642 ReportMessageAt(Scanner::Location(pos, pos + 1), | 653 ReportMessageAt(Scanner::Location(pos, pos + 1), |
643 "strong_constructor_return_value"); | 654 "strong_constructor_return_value"); |
644 *ok = false; | 655 *ok = false; |
645 return Statement::Default(); | 656 return Statement::Default(); |
646 } | 657 } |
647 ParseExpression(true, CHECK_OK); | 658 ParseExpression(true, CHECK_OK); |
648 } | 659 } |
649 ExpectSemicolon(CHECK_OK); | 660 ExpectSemicolon(CHECK_OK); |
650 return Statement::Default(); | 661 return Statement::Jump(); |
651 } | 662 } |
652 | 663 |
653 | 664 |
654 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 665 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
655 // WithStatement :: | 666 // WithStatement :: |
656 // 'with' '(' Expression ')' Statement | 667 // 'with' '(' Expression ')' Statement |
657 Expect(Token::WITH, CHECK_OK); | 668 Expect(Token::WITH, CHECK_OK); |
658 if (is_strict(language_mode())) { | 669 if (is_strict(language_mode())) { |
659 ReportMessageAt(scanner()->location(), "strict_mode_with"); | 670 ReportMessageAt(scanner()->location(), "strict_mode_with"); |
660 *ok = false; | 671 *ok = false; |
(...skipping 23 matching lines...) Expand all Loading... |
684 Token::Value token = peek(); | 695 Token::Value token = peek(); |
685 while (token != Token::RBRACE) { | 696 while (token != Token::RBRACE) { |
686 if (token == Token::CASE) { | 697 if (token == Token::CASE) { |
687 Expect(Token::CASE, CHECK_OK); | 698 Expect(Token::CASE, CHECK_OK); |
688 ParseExpression(true, CHECK_OK); | 699 ParseExpression(true, CHECK_OK); |
689 } else { | 700 } else { |
690 Expect(Token::DEFAULT, CHECK_OK); | 701 Expect(Token::DEFAULT, CHECK_OK); |
691 } | 702 } |
692 Expect(Token::COLON, CHECK_OK); | 703 Expect(Token::COLON, CHECK_OK); |
693 token = peek(); | 704 token = peek(); |
| 705 Statement statement = Statement::Jump(); |
694 while (token != Token::CASE && | 706 while (token != Token::CASE && |
695 token != Token::DEFAULT && | 707 token != Token::DEFAULT && |
696 token != Token::RBRACE) { | 708 token != Token::RBRACE) { |
697 ParseStatementListItem(CHECK_OK); | 709 statement = ParseStatementListItem(CHECK_OK); |
698 token = peek(); | 710 token = peek(); |
699 } | 711 } |
| 712 if (is_strong(language_mode()) && !statement.IsJumpStatement() && |
| 713 token != Token::RBRACE) { |
| 714 ReportMessageAt(scanner()->location(), "strong_switch_fallthrough"); |
| 715 *ok = false; |
| 716 return Statement::Default(); |
| 717 } |
700 } | 718 } |
701 Expect(Token::RBRACE, ok); | 719 Expect(Token::RBRACE, ok); |
702 return Statement::Default(); | 720 return Statement::Default(); |
703 } | 721 } |
704 | 722 |
705 | 723 |
706 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { | 724 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { |
707 // DoStatement :: | 725 // DoStatement :: |
708 // 'do' Statement 'while' '(' Expression ')' ';' | 726 // 'do' Statement 'while' '(' Expression ')' ';' |
709 | 727 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 // 'throw' [no line terminator] Expression ';' | 838 // 'throw' [no line terminator] Expression ';' |
821 | 839 |
822 Expect(Token::THROW, CHECK_OK); | 840 Expect(Token::THROW, CHECK_OK); |
823 if (scanner()->HasAnyLineTerminatorBeforeNext()) { | 841 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
824 ReportMessageAt(scanner()->location(), "newline_after_throw"); | 842 ReportMessageAt(scanner()->location(), "newline_after_throw"); |
825 *ok = false; | 843 *ok = false; |
826 return Statement::Default(); | 844 return Statement::Default(); |
827 } | 845 } |
828 ParseExpression(true, CHECK_OK); | 846 ParseExpression(true, CHECK_OK); |
829 ExpectSemicolon(ok); | 847 ExpectSemicolon(ok); |
830 return Statement::Default(); | 848 return Statement::Jump(); |
831 } | 849 } |
832 | 850 |
833 | 851 |
834 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { | 852 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { |
835 // TryStatement :: | 853 // TryStatement :: |
836 // 'try' Block Catch | 854 // 'try' Block Catch |
837 // 'try' Block Finally | 855 // 'try' Block Finally |
838 // 'try' Block Catch Finally | 856 // 'try' Block Catch Finally |
839 // | 857 // |
840 // Catch :: | 858 // Catch :: |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1045 | 1063 |
1046 DCHECK(!spread_pos.IsValid()); | 1064 DCHECK(!spread_pos.IsValid()); |
1047 | 1065 |
1048 return Expression::Default(); | 1066 return Expression::Default(); |
1049 } | 1067 } |
1050 | 1068 |
1051 #undef CHECK_OK | 1069 #undef CHECK_OK |
1052 | 1070 |
1053 | 1071 |
1054 } } // v8::internal | 1072 } } // v8::internal |
OLD | NEW |