Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/parsing/preparser.cc

Issue 1906793002: Synchronize scopes between parser/preparser (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698