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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 return Statement::Default(); | 271 return Statement::Default(); |
272 } | 272 } |
273 return ParseSubStatement(allow_function, ok); | 273 return ParseSubStatement(allow_function, ok); |
274 } | 274 } |
275 | 275 |
276 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { | 276 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { |
277 if (is_strict(language_mode()) || peek() != Token::FUNCTION || | 277 if (is_strict(language_mode()) || peek() != Token::FUNCTION || |
278 (legacy && allow_harmony_restrictive_declarations())) { | 278 (legacy && allow_harmony_restrictive_declarations())) { |
279 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok); | 279 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok); |
280 } else { | 280 } else { |
| 281 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); |
| 282 BlockState block_state(&scope_, body_scope); |
281 return ParseFunctionDeclaration(CHECK_OK); | 283 return ParseFunctionDeclaration(CHECK_OK); |
282 } | 284 } |
283 } | 285 } |
284 | 286 |
285 PreParser::Statement PreParser::ParseSubStatement( | 287 PreParser::Statement PreParser::ParseSubStatement( |
286 AllowLabelledFunctionStatement allow_function, bool* ok) { | 288 AllowLabelledFunctionStatement allow_function, bool* ok) { |
287 // Statement :: | 289 // Statement :: |
288 // Block | 290 // Block |
289 // VariableStatement | 291 // VariableStatement |
290 // EmptyStatement | 292 // EmptyStatement |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, | 410 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, |
409 CHECK_OK); | 411 CHECK_OK); |
410 return Statement::Default(); | 412 return Statement::Default(); |
411 } | 413 } |
412 | 414 |
413 | 415 |
414 PreParser::Statement PreParser::ParseBlock(bool* ok) { | 416 PreParser::Statement PreParser::ParseBlock(bool* ok) { |
415 // Block :: | 417 // Block :: |
416 // '{' StatementList '}' | 418 // '{' StatementList '}' |
417 | 419 |
| 420 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
418 Expect(Token::LBRACE, CHECK_OK); | 421 Expect(Token::LBRACE, CHECK_OK); |
419 Statement final = Statement::Default(); | 422 Statement final = Statement::Default(); |
420 while (peek() != Token::RBRACE) { | 423 { |
421 final = ParseStatementListItem(CHECK_OK); | 424 BlockState block_state(&scope_, block_scope); |
| 425 while (peek() != Token::RBRACE) { |
| 426 final = ParseStatementListItem(CHECK_OK); |
| 427 } |
422 } | 428 } |
423 Expect(Token::RBRACE, ok); | 429 Expect(Token::RBRACE, ok); |
424 return final; | 430 return final; |
425 } | 431 } |
426 | 432 |
427 | 433 |
428 PreParser::Statement PreParser::ParseVariableStatement( | 434 PreParser::Statement PreParser::ParseVariableStatement( |
429 VariableDeclarationContext var_context, | 435 VariableDeclarationContext var_context, |
430 bool* ok) { | 436 bool* ok) { |
431 // VariableStatement :: | 437 // VariableStatement :: |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 | 713 |
708 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { | 714 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { |
709 // SwitchStatement :: | 715 // SwitchStatement :: |
710 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 716 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
711 | 717 |
712 Expect(Token::SWITCH, CHECK_OK); | 718 Expect(Token::SWITCH, CHECK_OK); |
713 Expect(Token::LPAREN, CHECK_OK); | 719 Expect(Token::LPAREN, CHECK_OK); |
714 ParseExpression(true, CHECK_OK); | 720 ParseExpression(true, CHECK_OK); |
715 Expect(Token::RPAREN, CHECK_OK); | 721 Expect(Token::RPAREN, CHECK_OK); |
716 | 722 |
717 Expect(Token::LBRACE, CHECK_OK); | 723 Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE); |
718 Token::Value token = peek(); | 724 { |
719 while (token != Token::RBRACE) { | 725 BlockState cases_block_state(&scope_, cases_scope); |
720 if (token == Token::CASE) { | 726 Expect(Token::LBRACE, CHECK_OK); |
721 Expect(Token::CASE, CHECK_OK); | 727 Token::Value token = peek(); |
722 ParseExpression(true, CHECK_OK); | 728 while (token != Token::RBRACE) { |
723 } else { | 729 if (token == Token::CASE) { |
724 Expect(Token::DEFAULT, CHECK_OK); | 730 Expect(Token::CASE, CHECK_OK); |
725 } | 731 ParseExpression(true, CHECK_OK); |
726 Expect(Token::COLON, CHECK_OK); | 732 } else { |
727 token = peek(); | 733 Expect(Token::DEFAULT, CHECK_OK); |
728 Statement statement = Statement::Jump(); | 734 } |
729 while (token != Token::CASE && | 735 Expect(Token::COLON, CHECK_OK); |
730 token != Token::DEFAULT && | |
731 token != Token::RBRACE) { | |
732 statement = ParseStatementListItem(CHECK_OK); | |
733 token = peek(); | 736 token = peek(); |
| 737 Statement statement = Statement::Jump(); |
| 738 while (token != Token::CASE && |
| 739 token != Token::DEFAULT && |
| 740 token != Token::RBRACE) { |
| 741 statement = ParseStatementListItem(CHECK_OK); |
| 742 token = peek(); |
| 743 } |
734 } | 744 } |
735 } | 745 } |
736 Expect(Token::RBRACE, ok); | 746 Expect(Token::RBRACE, ok); |
737 return Statement::Default(); | 747 return Statement::Default(); |
738 } | 748 } |
739 | 749 |
740 | 750 |
741 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { | 751 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { |
742 // DoStatement :: | 752 // DoStatement :: |
743 // 'do' Statement 'while' '(' Expression ')' ';' | 753 // 'do' Statement 'while' '(' Expression ')' ';' |
(...skipping 19 matching lines...) Expand all Loading... |
763 Expect(Token::RPAREN, CHECK_OK); | 773 Expect(Token::RPAREN, CHECK_OK); |
764 ParseScopedStatement(true, ok); | 774 ParseScopedStatement(true, ok); |
765 return Statement::Default(); | 775 return Statement::Default(); |
766 } | 776 } |
767 | 777 |
768 | 778 |
769 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 779 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
770 // ForStatement :: | 780 // ForStatement :: |
771 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 781 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
772 | 782 |
| 783 // Create an in-between scope for let-bound iteration variables. |
| 784 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 785 bool has_lexical = false; |
| 786 |
| 787 BlockState block_state(&scope_, for_scope); |
773 Expect(Token::FOR, CHECK_OK); | 788 Expect(Token::FOR, CHECK_OK); |
774 Expect(Token::LPAREN, CHECK_OK); | 789 Expect(Token::LPAREN, CHECK_OK); |
775 if (peek() != Token::SEMICOLON) { | 790 if (peek() != Token::SEMICOLON) { |
776 ForEachStatement::VisitMode mode; | 791 ForEachStatement::VisitMode mode; |
777 if (peek() == Token::VAR || peek() == Token::CONST || | 792 if (peek() == Token::VAR || peek() == Token::CONST || |
778 (peek() == Token::LET && IsNextLetKeyword())) { | 793 (peek() == Token::LET && IsNextLetKeyword())) { |
779 int decl_count; | 794 int decl_count; |
780 bool is_lexical; | 795 bool is_lexical; |
781 bool is_binding_pattern; | 796 bool is_binding_pattern; |
782 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); | 797 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); |
783 Scanner::Location bindings_loc = Scanner::Location::invalid(); | 798 Scanner::Location bindings_loc = Scanner::Location::invalid(); |
784 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical, | 799 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical, |
785 &is_binding_pattern, &first_initializer_loc, | 800 &is_binding_pattern, &first_initializer_loc, |
786 &bindings_loc, CHECK_OK); | 801 &bindings_loc, CHECK_OK); |
| 802 if (is_lexical) has_lexical = true; |
787 if (CheckInOrOf(&mode, ok)) { | 803 if (CheckInOrOf(&mode, ok)) { |
788 if (!*ok) return Statement::Default(); | 804 if (!*ok) return Statement::Default(); |
789 if (decl_count != 1) { | 805 if (decl_count != 1) { |
790 PreParserTraits::ReportMessageAt( | 806 PreParserTraits::ReportMessageAt( |
791 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings, | 807 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings, |
792 ForEachStatement::VisitModeString(mode)); | 808 ForEachStatement::VisitModeString(mode)); |
793 *ok = false; | 809 *ok = false; |
794 return Statement::Default(); | 810 return Statement::Default(); |
795 } | 811 } |
796 if (first_initializer_loc.IsValid() && | 812 if (first_initializer_loc.IsValid() && |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
840 | 856 |
841 if (mode == ForEachStatement::ITERATE) { | 857 if (mode == ForEachStatement::ITERATE) { |
842 ExpressionClassifier classifier(this); | 858 ExpressionClassifier classifier(this); |
843 ParseAssignmentExpression(true, &classifier, CHECK_OK); | 859 ParseAssignmentExpression(true, &classifier, CHECK_OK); |
844 RewriteNonPattern(&classifier, CHECK_OK); | 860 RewriteNonPattern(&classifier, CHECK_OK); |
845 } else { | 861 } else { |
846 ParseExpression(true, CHECK_OK); | 862 ParseExpression(true, CHECK_OK); |
847 } | 863 } |
848 | 864 |
849 Expect(Token::RPAREN, CHECK_OK); | 865 Expect(Token::RPAREN, CHECK_OK); |
850 ParseScopedStatement(true, CHECK_OK); | 866 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); |
| 867 { |
| 868 BlockState block_state(&scope_, body_scope); |
| 869 ParseScopedStatement(true, CHECK_OK); |
| 870 } |
851 return Statement::Default(); | 871 return Statement::Default(); |
852 } | 872 } |
853 } | 873 } |
854 } | 874 } |
855 | 875 |
856 // Parsed initializer at this point. | 876 // Parsed initializer at this point. |
857 Expect(Token::SEMICOLON, CHECK_OK); | 877 Expect(Token::SEMICOLON, CHECK_OK); |
858 | 878 |
859 if (peek() != Token::SEMICOLON) { | 879 // If there are let bindings, then condition and the next statement of the |
860 ParseExpression(true, CHECK_OK); | 880 // for loop must be parsed in a new scope. |
| 881 Scope* inner_scope = scope_; |
| 882 if (has_lexical) inner_scope = NewScope(for_scope, BLOCK_SCOPE); |
| 883 |
| 884 { |
| 885 BlockState block_state(&scope_, inner_scope); |
| 886 |
| 887 if (peek() != Token::SEMICOLON) { |
| 888 ParseExpression(true, CHECK_OK); |
| 889 } |
| 890 Expect(Token::SEMICOLON, CHECK_OK); |
| 891 |
| 892 if (peek() != Token::RPAREN) { |
| 893 ParseExpression(true, CHECK_OK); |
| 894 } |
| 895 Expect(Token::RPAREN, CHECK_OK); |
| 896 |
| 897 ParseScopedStatement(true, ok); |
861 } | 898 } |
862 Expect(Token::SEMICOLON, CHECK_OK); | |
863 | |
864 if (peek() != Token::RPAREN) { | |
865 ParseExpression(true, CHECK_OK); | |
866 } | |
867 Expect(Token::RPAREN, CHECK_OK); | |
868 | |
869 ParseScopedStatement(true, ok); | |
870 return Statement::Default(); | 899 return Statement::Default(); |
871 } | 900 } |
872 | 901 |
873 | 902 |
874 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { | 903 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { |
875 // ThrowStatement :: | 904 // ThrowStatement :: |
876 // 'throw' [no line terminator] Expression ';' | 905 // 'throw' [no line terminator] Expression ';' |
877 | 906 |
878 Expect(Token::THROW, CHECK_OK); | 907 Expect(Token::THROW, CHECK_OK); |
879 if (scanner()->HasAnyLineTerminatorBeforeNext()) { | 908 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
(...skipping 25 matching lines...) Expand all Loading... |
905 | 934 |
906 Token::Value tok = peek(); | 935 Token::Value tok = peek(); |
907 if (tok != Token::CATCH && tok != Token::FINALLY) { | 936 if (tok != Token::CATCH && tok != Token::FINALLY) { |
908 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); | 937 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); |
909 *ok = false; | 938 *ok = false; |
910 return Statement::Default(); | 939 return Statement::Default(); |
911 } | 940 } |
912 if (tok == Token::CATCH) { | 941 if (tok == Token::CATCH) { |
913 Consume(Token::CATCH); | 942 Consume(Token::CATCH); |
914 Expect(Token::LPAREN, CHECK_OK); | 943 Expect(Token::LPAREN, CHECK_OK); |
| 944 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE); |
915 ExpressionClassifier pattern_classifier(this); | 945 ExpressionClassifier pattern_classifier(this); |
916 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); | 946 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); |
917 ValidateBindingPattern(&pattern_classifier, CHECK_OK); | 947 ValidateBindingPattern(&pattern_classifier, CHECK_OK); |
918 Expect(Token::RPAREN, CHECK_OK); | 948 Expect(Token::RPAREN, CHECK_OK); |
919 { | 949 { |
920 // TODO(adamk): Make this CATCH_SCOPE | 950 BlockState block_state(&scope_, catch_scope); |
921 Scope* with_scope = NewScope(scope_, WITH_SCOPE); | 951 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
922 BlockState block_state(&scope_, with_scope); | 952 { |
923 ParseBlock(CHECK_OK); | 953 BlockState block_state(&scope_, block_scope); |
| 954 ParseBlock(CHECK_OK); |
| 955 } |
924 } | 956 } |
925 tok = peek(); | 957 tok = peek(); |
926 } | 958 } |
927 if (tok == Token::FINALLY) { | 959 if (tok == Token::FINALLY) { |
928 Consume(Token::FINALLY); | 960 Consume(Token::FINALLY); |
929 ParseBlock(CHECK_OK); | 961 ParseBlock(CHECK_OK); |
930 } | 962 } |
931 return Statement::Default(); | 963 return Statement::Default(); |
932 } | 964 } |
933 | 965 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 | 1139 |
1108 return Expression::Default(); | 1140 return Expression::Default(); |
1109 } | 1141 } |
1110 | 1142 |
1111 | 1143 |
1112 PreParserExpression PreParser::ParseDoExpression(bool* ok) { | 1144 PreParserExpression PreParser::ParseDoExpression(bool* ok) { |
1113 // AssignmentExpression :: | 1145 // AssignmentExpression :: |
1114 // do '{' StatementList '}' | 1146 // do '{' StatementList '}' |
1115 Expect(Token::DO, CHECK_OK); | 1147 Expect(Token::DO, CHECK_OK); |
1116 Expect(Token::LBRACE, CHECK_OK); | 1148 Expect(Token::LBRACE, CHECK_OK); |
1117 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1149 while (peek() != Token::RBRACE) { |
1118 { | 1150 ParseStatementListItem(CHECK_OK); |
1119 BlockState block_state(&scope_, block_scope); | |
1120 while (peek() != Token::RBRACE) { | |
1121 ParseStatementListItem(CHECK_OK); | |
1122 } | |
1123 Expect(Token::RBRACE, CHECK_OK); | |
1124 return PreParserExpression::Default(); | |
1125 } | 1151 } |
| 1152 Expect(Token::RBRACE, CHECK_OK); |
| 1153 return PreParserExpression::Default(); |
1126 } | 1154 } |
1127 | 1155 |
1128 #undef CHECK_OK | 1156 #undef CHECK_OK |
1129 | 1157 |
1130 | 1158 |
1131 } // namespace internal | 1159 } // namespace internal |
1132 } // namespace v8 | 1160 } // namespace v8 |
OLD | NEW |