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

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

Issue 1702063002: Non-pattern rewriting revisited (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix a bug I introduced when rebasing Created 4 years, 10 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') | src/typing-asm.cc » ('j') | 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 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 // of a let declared variable is the scope of the immediately enclosing 566 // of a let declared variable is the scope of the immediately enclosing
567 // block. 567 // block.
568 int nvars = 0; // the number of variables declared 568 int nvars = 0; // the number of variables declared
569 int bindings_start = peek_position(); 569 int bindings_start = peek_position();
570 do { 570 do {
571 // Parse binding pattern. 571 // Parse binding pattern.
572 if (nvars > 0) Consume(Token::COMMA); 572 if (nvars > 0) Consume(Token::COMMA);
573 int decl_pos = peek_position(); 573 int decl_pos = peek_position();
574 PreParserExpression pattern = PreParserExpression::Default(); 574 PreParserExpression pattern = PreParserExpression::Default();
575 { 575 {
576 ExpressionClassifier pattern_classifier; 576 ExpressionClassifier pattern_classifier(this);
577 Token::Value next = peek(); 577 Token::Value next = peek();
578 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); 578 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
579 579
580 ValidateBindingPattern(&pattern_classifier, CHECK_OK); 580 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
581 if (lexical) { 581 if (lexical) {
582 ValidateLetPattern(&pattern_classifier, CHECK_OK); 582 ValidateLetPattern(&pattern_classifier, CHECK_OK);
583 } 583 }
584 584
585 if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) { 585 if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) {
586 ReportUnexpectedToken(next); 586 ReportUnexpectedToken(next);
587 *ok = false; 587 *ok = false;
588 return Statement::Default(); 588 return Statement::Default();
589 } 589 }
590 } 590 }
591 591
592 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral(); 592 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral();
593 593
594 Scanner::Location variable_loc = scanner()->location(); 594 Scanner::Location variable_loc = scanner()->location();
595 nvars++; 595 nvars++;
596 if (Check(Token::ASSIGN)) { 596 if (Check(Token::ASSIGN)) {
597 ExpressionClassifier classifier; 597 ExpressionClassifier classifier(this);
598 ParseAssignmentExpression(var_context != kForStatement, &classifier, 598 ParseAssignmentExpression(var_context != kForStatement, &classifier,
599 CHECK_OK); 599 CHECK_OK);
600 ValidateExpression(&classifier, CHECK_OK); 600 ValidateExpression(&classifier, CHECK_OK);
601 601
602 variable_loc.end_pos = scanner()->location().end_pos; 602 variable_loc.end_pos = scanner()->location().end_pos;
603 if (first_initializer_loc && !first_initializer_loc->IsValid()) { 603 if (first_initializer_loc && !first_initializer_loc->IsValid()) {
604 *first_initializer_loc = variable_loc; 604 *first_initializer_loc = variable_loc;
605 } 605 }
606 } else if ((require_initializer || is_pattern) && 606 } else if ((require_initializer || is_pattern) &&
607 (var_context != kForStatement || !PeekInOrOf())) { 607 (var_context != kForStatement || !PeekInOrOf())) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 return Statement::Default(); 641 return Statement::Default();
642 642
643 case Token::THIS: 643 case Token::THIS:
644 if (!FLAG_strong_this) break; 644 if (!FLAG_strong_this) break;
645 // Fall through. 645 // Fall through.
646 case Token::SUPER: 646 case Token::SUPER:
647 if (is_strong(language_mode()) && 647 if (is_strong(language_mode()) &&
648 IsClassConstructor(function_state_->kind())) { 648 IsClassConstructor(function_state_->kind())) {
649 bool is_this = peek() == Token::THIS; 649 bool is_this = peek() == Token::THIS;
650 Expression expr = Expression::Default(); 650 Expression expr = Expression::Default();
651 ExpressionClassifier classifier; 651 ExpressionClassifier classifier(this);
652 if (is_this) { 652 if (is_this) {
653 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); 653 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
654 } else { 654 } else {
655 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); 655 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
656 } 656 }
657 ValidateExpression(&classifier, CHECK_OK); 657 ValidateExpression(&classifier, CHECK_OK);
658 switch (peek()) { 658 switch (peek()) {
659 case Token::SEMICOLON: 659 case Token::SEMICOLON:
660 Consume(Token::SEMICOLON); 660 Consume(Token::SEMICOLON);
661 break; 661 break;
(...skipping 15 matching lines...) Expand all
677 break; 677 break;
678 678
679 // TODO(arv): Handle `let [` 679 // TODO(arv): Handle `let [`
680 // https://code.google.com/p/v8/issues/detail?id=3847 680 // https://code.google.com/p/v8/issues/detail?id=3847
681 681
682 default: 682 default:
683 break; 683 break;
684 } 684 }
685 685
686 bool starts_with_identifier = peek_any_identifier(); 686 bool starts_with_identifier = peek_any_identifier();
687 ExpressionClassifier classifier; 687 ExpressionClassifier classifier(this);
688 Expression expr = ParseExpression(true, &classifier, CHECK_OK); 688 Expression expr = ParseExpression(true, &classifier, CHECK_OK);
689 ValidateExpression(&classifier, CHECK_OK); 689 ValidateExpression(&classifier, CHECK_OK);
690 690
691 // Even if the expression starts with an identifier, it is not necessarily an 691 // Even if the expression starts with an identifier, it is not necessarily an
692 // identifier. For example, "foo + bar" starts with an identifier but is not 692 // identifier. For example, "foo + bar" starts with an identifier but is not
693 // an identifier. 693 // an identifier.
694 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 694 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
695 // Expression is a single identifier, and not, e.g., a parenthesized 695 // Expression is a single identifier, and not, e.g., a parenthesized
696 // identifier. 696 // identifier.
697 DCHECK(!expr.AsIdentifier().IsFutureReserved()); 697 DCHECK(!expr.AsIdentifier().IsFutureReserved());
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || 930 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
931 is_lexical || is_binding_pattern)) { 931 is_lexical || is_binding_pattern)) {
932 PreParserTraits::ReportMessageAt( 932 PreParserTraits::ReportMessageAt(
933 first_initializer_loc, MessageTemplate::kForInOfLoopInitializer, 933 first_initializer_loc, MessageTemplate::kForInOfLoopInitializer,
934 ForEachStatement::VisitModeString(mode)); 934 ForEachStatement::VisitModeString(mode));
935 *ok = false; 935 *ok = false;
936 return Statement::Default(); 936 return Statement::Default();
937 } 937 }
938 938
939 if (mode == ForEachStatement::ITERATE) { 939 if (mode == ForEachStatement::ITERATE) {
940 ExpressionClassifier classifier; 940 ExpressionClassifier classifier(this);
941 Expression enumerable = 941 ParseAssignmentExpression(true, &classifier, CHECK_OK);
942 ParseAssignmentExpression(true, &classifier, CHECK_OK); 942 RewriteNonPattern(&classifier, CHECK_OK);
943 PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK);
944 } else { 943 } else {
945 ParseExpression(true, CHECK_OK); 944 ParseExpression(true, CHECK_OK);
946 } 945 }
947 946
948 Expect(Token::RPAREN, CHECK_OK); 947 Expect(Token::RPAREN, CHECK_OK);
949 ParseSubStatement(CHECK_OK); 948 ParseSubStatement(CHECK_OK);
950 return Statement::Default(); 949 return Statement::Default();
951 } 950 }
952 } else { 951 } else {
953 int lhs_beg_pos = peek_position(); 952 int lhs_beg_pos = peek_position();
954 ExpressionClassifier classifier; 953 ExpressionClassifier classifier(this);
955 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); 954 Expression lhs = ParseExpression(false, &classifier, CHECK_OK);
956 int lhs_end_pos = scanner()->location().end_pos; 955 int lhs_end_pos = scanner()->location().end_pos;
957 is_let_identifier_expression = 956 is_let_identifier_expression =
958 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); 957 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet();
959 bool is_for_each = CheckInOrOf(&mode, ok); 958 bool is_for_each = CheckInOrOf(&mode, ok);
960 if (!*ok) return Statement::Default(); 959 if (!*ok) return Statement::Default();
961 bool is_destructuring = is_for_each && 960 bool is_destructuring = is_for_each &&
962 allow_harmony_destructuring_assignment() && 961 allow_harmony_destructuring_assignment() &&
963 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); 962 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral());
964 963
965 if (is_destructuring) { 964 if (is_destructuring) {
966 ValidateAssignmentPattern(&classifier, CHECK_OK); 965 ValidateAssignmentPattern(&classifier, CHECK_OK);
967 } else { 966 } else {
968 ValidateExpression(&classifier, CHECK_OK); 967 ValidateExpression(&classifier, CHECK_OK);
969 } 968 }
970 969
971 if (is_for_each) { 970 if (is_for_each) {
972 if (!is_destructuring) { 971 if (!is_destructuring) {
973 lhs = CheckAndRewriteReferenceExpression( 972 lhs = CheckAndRewriteReferenceExpression(
974 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, 973 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
975 kSyntaxError, CHECK_OK); 974 kSyntaxError, CHECK_OK);
976 } 975 }
977 976
978 if (mode == ForEachStatement::ITERATE) { 977 if (mode == ForEachStatement::ITERATE) {
979 ExpressionClassifier classifier; 978 ExpressionClassifier classifier(this);
980 Expression enumerable = 979 ParseAssignmentExpression(true, &classifier, CHECK_OK);
981 ParseAssignmentExpression(true, &classifier, CHECK_OK); 980 RewriteNonPattern(&classifier, CHECK_OK);
982 PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK);
983 } else { 981 } else {
984 ParseExpression(true, CHECK_OK); 982 ParseExpression(true, CHECK_OK);
985 } 983 }
986 984
987 Expect(Token::RPAREN, CHECK_OK); 985 Expect(Token::RPAREN, CHECK_OK);
988 ParseSubStatement(CHECK_OK); 986 ParseSubStatement(CHECK_OK);
989 return Statement::Default(); 987 return Statement::Default();
990 } 988 }
991 } 989 }
992 } 990 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 1048
1051 Token::Value tok = peek(); 1049 Token::Value tok = peek();
1052 if (tok != Token::CATCH && tok != Token::FINALLY) { 1050 if (tok != Token::CATCH && tok != Token::FINALLY) {
1053 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); 1051 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally);
1054 *ok = false; 1052 *ok = false;
1055 return Statement::Default(); 1053 return Statement::Default();
1056 } 1054 }
1057 if (tok == Token::CATCH) { 1055 if (tok == Token::CATCH) {
1058 Consume(Token::CATCH); 1056 Consume(Token::CATCH);
1059 Expect(Token::LPAREN, CHECK_OK); 1057 Expect(Token::LPAREN, CHECK_OK);
1060 ExpressionClassifier pattern_classifier; 1058 ExpressionClassifier pattern_classifier(this);
1061 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); 1059 ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
1062 ValidateBindingPattern(&pattern_classifier, CHECK_OK); 1060 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
1063 Expect(Token::RPAREN, CHECK_OK); 1061 Expect(Token::RPAREN, CHECK_OK);
1064 { 1062 {
1065 // TODO(adamk): Make this CATCH_SCOPE 1063 // TODO(adamk): Make this CATCH_SCOPE
1066 Scope* with_scope = NewScope(scope_, WITH_SCOPE); 1064 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
1067 BlockState block_state(&scope_, with_scope); 1065 BlockState block_state(&scope_, with_scope);
1068 ParseBlock(CHECK_OK); 1066 ParseBlock(CHECK_OK);
1069 } 1067 }
1070 tok = peek(); 1068 tok = peek();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1105 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1108 1106
1109 // Parse function body. 1107 // Parse function body.
1110 bool outer_is_script_scope = scope_->is_script_scope(); 1108 bool outer_is_script_scope = scope_->is_script_scope();
1111 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind); 1109 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
1112 function_scope->SetLanguageMode(language_mode); 1110 function_scope->SetLanguageMode(language_mode);
1113 PreParserFactory factory(NULL); 1111 PreParserFactory factory(NULL);
1114 FunctionState function_state(&function_state_, &scope_, function_scope, kind, 1112 FunctionState function_state(&function_state_, &scope_, function_scope, kind,
1115 &factory); 1113 &factory);
1116 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 1114 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1117 ExpressionClassifier formals_classifier(&duplicate_finder); 1115 ExpressionClassifier formals_classifier(this, &duplicate_finder);
1118 1116
1119 Expect(Token::LPAREN, CHECK_OK); 1117 Expect(Token::LPAREN, CHECK_OK);
1120 int start_position = scanner()->location().beg_pos; 1118 int start_position = scanner()->location().beg_pos;
1121 function_scope->set_start_position(start_position); 1119 function_scope->set_start_position(start_position);
1122 PreParserFormalParameters formals(function_scope); 1120 PreParserFormalParameters formals(function_scope);
1123 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); 1121 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
1124 Expect(Token::RPAREN, CHECK_OK); 1122 Expect(Token::RPAREN, CHECK_OK);
1125 int formals_end_position = scanner()->location().end_pos; 1123 int formals_end_position = scanner()->location().end_pos;
1126 1124
1127 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, 1125 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 1211
1214 Scope* scope = NewScope(scope_, BLOCK_SCOPE); 1212 Scope* scope = NewScope(scope_, BLOCK_SCOPE);
1215 BlockState block_state(&scope_, scope); 1213 BlockState block_state(&scope_, scope);
1216 scope_->SetLanguageMode( 1214 scope_->SetLanguageMode(
1217 static_cast<LanguageMode>(class_language_mode | STRICT)); 1215 static_cast<LanguageMode>(class_language_mode | STRICT));
1218 // TODO(marja): Make PreParser use scope names too. 1216 // TODO(marja): Make PreParser use scope names too.
1219 // scope_->SetScopeName(name); 1217 // scope_->SetScopeName(name);
1220 1218
1221 bool has_extends = Check(Token::EXTENDS); 1219 bool has_extends = Check(Token::EXTENDS);
1222 if (has_extends) { 1220 if (has_extends) {
1223 ExpressionClassifier classifier; 1221 ExpressionClassifier classifier(this);
1224 ParseLeftHandSideExpression(&classifier, CHECK_OK); 1222 ParseLeftHandSideExpression(&classifier, CHECK_OK);
1225 ValidateExpression(&classifier, CHECK_OK); 1223 ValidateExpression(&classifier, CHECK_OK);
1226 } 1224 }
1227 1225
1228 ClassLiteralChecker checker(this); 1226 ClassLiteralChecker checker(this);
1229 bool has_seen_constructor = false; 1227 bool has_seen_constructor = false;
1230 1228
1231 Expect(Token::LBRACE, CHECK_OK); 1229 Expect(Token::LBRACE, CHECK_OK);
1232 while (peek() != Token::RBRACE) { 1230 while (peek() != Token::RBRACE) {
1233 if (Check(Token::SEMICOLON)) continue; 1231 if (Check(Token::SEMICOLON)) continue;
1234 const bool in_class = true; 1232 const bool in_class = true;
1235 const bool is_static = false; 1233 const bool is_static = false;
1236 bool is_computed_name = false; // Classes do not care about computed 1234 bool is_computed_name = false; // Classes do not care about computed
1237 // property names here. 1235 // property names here.
1238 Identifier name; 1236 Identifier name;
1239 ExpressionClassifier classifier; 1237 ExpressionClassifier classifier(this);
1240 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, 1238 ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
1241 &is_computed_name, &has_seen_constructor, 1239 &is_computed_name, &has_seen_constructor,
1242 &classifier, &name, CHECK_OK); 1240 &classifier, &name, CHECK_OK);
1243 ValidateExpression(&classifier, CHECK_OK); 1241 ValidateExpression(&classifier, CHECK_OK);
1244 } 1242 }
1245 1243
1246 Expect(Token::RBRACE, CHECK_OK); 1244 Expect(Token::RBRACE, CHECK_OK);
1247 1245
1248 return Expression::Default(); 1246 return Expression::Default();
1249 } 1247 }
1250 1248
1251 1249
1252 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1250 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1253 // CallRuntime :: 1251 // CallRuntime ::
1254 // '%' Identifier Arguments 1252 // '%' Identifier Arguments
1255 Expect(Token::MOD, CHECK_OK); 1253 Expect(Token::MOD, CHECK_OK);
1256 if (!allow_natives()) { 1254 if (!allow_natives()) {
1257 *ok = false; 1255 *ok = false;
1258 return Expression::Default(); 1256 return Expression::Default();
1259 } 1257 }
1260 // Allow "eval" or "arguments" for backward compatibility. 1258 // Allow "eval" or "arguments" for backward compatibility.
1261 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 1259 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1262 Scanner::Location spread_pos; 1260 Scanner::Location spread_pos;
1263 ExpressionClassifier classifier; 1261 ExpressionClassifier classifier(this);
1264 ParseArguments(&spread_pos, &classifier, ok); 1262 ParseArguments(&spread_pos, &classifier, ok);
1265 ValidateExpression(&classifier, CHECK_OK); 1263 ValidateExpression(&classifier, CHECK_OK);
1266 1264
1267 DCHECK(!spread_pos.IsValid()); 1265 DCHECK(!spread_pos.IsValid());
1268 1266
1269 return Expression::Default(); 1267 return Expression::Default();
1270 } 1268 }
1271 1269
1272 1270
1273 PreParserExpression PreParser::ParseDoExpression(bool* ok) { 1271 PreParserExpression PreParser::ParseDoExpression(bool* ok) {
(...skipping 10 matching lines...) Expand all
1284 Expect(Token::RBRACE, CHECK_OK); 1282 Expect(Token::RBRACE, CHECK_OK);
1285 return PreParserExpression::Default(); 1283 return PreParserExpression::Default();
1286 } 1284 }
1287 } 1285 }
1288 1286
1289 #undef CHECK_OK 1287 #undef CHECK_OK
1290 1288
1291 1289
1292 } // namespace internal 1290 } // namespace internal
1293 } // namespace v8 1291 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | src/typing-asm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698