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

Side by Side Diff: src/preparser.cc

Issue 1471973003: Disallow destructuring in legacy sloppy for-in loop parsing (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix copyright on test Created 5 years 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/preparser.h ('k') | test/message/for-in-loop-initializers-destructuring.js » ('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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 return final; 488 return final;
489 } 489 }
490 490
491 491
492 PreParser::Statement PreParser::ParseVariableStatement( 492 PreParser::Statement PreParser::ParseVariableStatement(
493 VariableDeclarationContext var_context, 493 VariableDeclarationContext var_context,
494 bool* ok) { 494 bool* ok) {
495 // VariableStatement :: 495 // VariableStatement ::
496 // VariableDeclarations ';' 496 // VariableDeclarations ';'
497 497
498 Statement result = ParseVariableDeclarations(var_context, nullptr, nullptr, 498 Statement result = ParseVariableDeclarations(
499 nullptr, CHECK_OK); 499 var_context, nullptr, nullptr, nullptr, nullptr, nullptr, CHECK_OK);
500 ExpectSemicolon(CHECK_OK); 500 ExpectSemicolon(CHECK_OK);
501 return result; 501 return result;
502 } 502 }
503 503
504 504
505 // If the variable declaration declares exactly one non-const 505 // If the variable declaration declares exactly one non-const
506 // variable, then *var is set to that variable. In all other cases, 506 // variable, then *var is set to that variable. In all other cases,
507 // *var is untouched; in particular, it is the caller's responsibility 507 // *var is untouched; in particular, it is the caller's responsibility
508 // to initialize it properly. This mechanism is also used for the parsing 508 // to initialize it properly. This mechanism is also used for the parsing
509 // of 'for-in' loops. 509 // of 'for-in' loops.
510 PreParser::Statement PreParser::ParseVariableDeclarations( 510 PreParser::Statement PreParser::ParseVariableDeclarations(
511 VariableDeclarationContext var_context, int* num_decl, 511 VariableDeclarationContext var_context, int* num_decl, bool* is_lexical,
512 Scanner::Location* first_initializer_loc, Scanner::Location* bindings_loc, 512 bool* is_binding_pattern, Scanner::Location* first_initializer_loc,
513 bool* ok) { 513 Scanner::Location* bindings_loc, bool* ok) {
514 // VariableDeclarations :: 514 // VariableDeclarations ::
515 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 515 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
516 // 516 //
517 // The ES6 Draft Rev3 specifies the following grammar for const declarations 517 // The ES6 Draft Rev3 specifies the following grammar for const declarations
518 // 518 //
519 // ConstDeclaration :: 519 // ConstDeclaration ::
520 // const ConstBinding (',' ConstBinding)* ';' 520 // const ConstBinding (',' ConstBinding)* ';'
521 // ConstBinding :: 521 // ConstBinding ::
522 // Identifier '=' AssignmentExpression 522 // Identifier '=' AssignmentExpression
523 // 523 //
524 // TODO(ES6): 524 // TODO(ES6):
525 // ConstBinding :: 525 // ConstBinding ::
526 // BindingPattern '=' AssignmentExpression 526 // BindingPattern '=' AssignmentExpression
527 bool require_initializer = false; 527 bool require_initializer = false;
528 bool lexical = false; 528 bool lexical = false;
529 bool is_pattern = false;
Dan Ehrenberg 2015/11/25 01:02:58 Nit: Not sure why you moved the initialization up
adamk 2015/11/25 01:13:12 I moved this up to put the passing to the out-para
529 if (peek() == Token::VAR) { 530 if (peek() == Token::VAR) {
530 if (is_strong(language_mode())) { 531 if (is_strong(language_mode())) {
531 Scanner::Location location = scanner()->peek_location(); 532 Scanner::Location location = scanner()->peek_location();
532 ReportMessageAt(location, MessageTemplate::kStrongVar); 533 ReportMessageAt(location, MessageTemplate::kStrongVar);
533 *ok = false; 534 *ok = false;
534 return Statement::Default(); 535 return Statement::Default();
535 } 536 }
536 Consume(Token::VAR); 537 Consume(Token::VAR);
537 } else if (peek() == Token::CONST && allow_const()) { 538 } else if (peek() == Token::CONST && allow_const()) {
538 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 539 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 ValidateLetPattern(&pattern_classifier, CHECK_OK); 583 ValidateLetPattern(&pattern_classifier, CHECK_OK);
583 } 584 }
584 585
585 if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) { 586 if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) {
586 ReportUnexpectedToken(next); 587 ReportUnexpectedToken(next);
587 *ok = false; 588 *ok = false;
588 return Statement::Default(); 589 return Statement::Default();
589 } 590 }
590 } 591 }
591 592
592 bool is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral(); 593 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral();
593 594
594 bool is_for_iteration_variable = 595 bool is_for_iteration_variable =
595 var_context == kForStatement && 596 var_context == kForStatement &&
596 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); 597 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
597 598
598 Scanner::Location variable_loc = scanner()->location(); 599 Scanner::Location variable_loc = scanner()->location();
599 nvars++; 600 nvars++;
600 if (Check(Token::ASSIGN)) { 601 if (Check(Token::ASSIGN)) {
601 ExpressionClassifier classifier; 602 ExpressionClassifier classifier;
602 ParseAssignmentExpression(var_context != kForStatement, &classifier, 603 ParseAssignmentExpression(var_context != kForStatement, &classifier,
(...skipping 13 matching lines...) Expand all
616 *ok = false; 617 *ok = false;
617 return Statement::Default(); 618 return Statement::Default();
618 } 619 }
619 } while (peek() == Token::COMMA); 620 } while (peek() == Token::COMMA);
620 621
621 if (bindings_loc) { 622 if (bindings_loc) {
622 *bindings_loc = 623 *bindings_loc =
623 Scanner::Location(bindings_start, scanner()->location().end_pos); 624 Scanner::Location(bindings_start, scanner()->location().end_pos);
624 } 625 }
625 626
626 if (num_decl != NULL) *num_decl = nvars; 627 if (num_decl != nullptr) *num_decl = nvars;
628 if (is_lexical != nullptr) *is_lexical = lexical;
629 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern;
627 return Statement::Default(); 630 return Statement::Default();
628 } 631 }
629 632
630 633
631 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 634 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
632 // ExpressionStatement | LabelledStatement :: 635 // ExpressionStatement | LabelledStatement ::
633 // Expression ';' 636 // Expression ';'
634 // Identifier ':' Statement 637 // Identifier ':' Statement
635 638
636 switch (peek()) { 639 switch (peek()) {
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 908 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
906 909
907 Expect(Token::FOR, CHECK_OK); 910 Expect(Token::FOR, CHECK_OK);
908 Expect(Token::LPAREN, CHECK_OK); 911 Expect(Token::LPAREN, CHECK_OK);
909 bool is_let_identifier_expression = false; 912 bool is_let_identifier_expression = false;
910 if (peek() != Token::SEMICOLON) { 913 if (peek() != Token::SEMICOLON) {
911 ForEachStatement::VisitMode mode; 914 ForEachStatement::VisitMode mode;
912 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || 915 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) ||
913 (peek() == Token::LET && IsNextLetKeyword())) { 916 (peek() == Token::LET && IsNextLetKeyword())) {
914 int decl_count; 917 int decl_count;
918 bool is_lexical;
919 bool is_binding_pattern;
915 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); 920 Scanner::Location first_initializer_loc = Scanner::Location::invalid();
916 Scanner::Location bindings_loc = Scanner::Location::invalid(); 921 Scanner::Location bindings_loc = Scanner::Location::invalid();
917 ParseVariableDeclarations(kForStatement, &decl_count, 922 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical,
918 &first_initializer_loc, &bindings_loc, 923 &is_binding_pattern, &first_initializer_loc,
919 CHECK_OK); 924 &bindings_loc, CHECK_OK);
920 bool accept_IN = decl_count >= 1; 925 bool accept_IN = decl_count >= 1;
921 if (accept_IN && CheckInOrOf(&mode, ok)) { 926 if (accept_IN && CheckInOrOf(&mode, ok)) {
922 if (!*ok) return Statement::Default(); 927 if (!*ok) return Statement::Default();
923 if (decl_count != 1) { 928 if (decl_count != 1) {
924 const char* loop_type = 929 const char* loop_type =
925 mode == ForEachStatement::ITERATE ? "for-of" : "for-in"; 930 mode == ForEachStatement::ITERATE ? "for-of" : "for-in";
926 PreParserTraits::ReportMessageAt( 931 PreParserTraits::ReportMessageAt(
927 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings, 932 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings,
928 loop_type); 933 loop_type);
929 *ok = false; 934 *ok = false;
930 return Statement::Default(); 935 return Statement::Default();
931 } 936 }
932 if (first_initializer_loc.IsValid() && 937 if (first_initializer_loc.IsValid() &&
933 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) { 938 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
939 is_lexical || is_binding_pattern)) {
934 if (mode == ForEachStatement::ITERATE) { 940 if (mode == ForEachStatement::ITERATE) {
935 ReportMessageAt(first_initializer_loc, 941 ReportMessageAt(first_initializer_loc,
936 MessageTemplate::kForOfLoopInitializer); 942 MessageTemplate::kForOfLoopInitializer);
937 } else { 943 } else {
938 // TODO(caitp): This should be an error in sloppy mode, too. 944 // TODO(caitp): This should be an error in sloppy mode, too.
939 ReportMessageAt(first_initializer_loc, 945 ReportMessageAt(first_initializer_loc,
940 MessageTemplate::kForInLoopInitializer); 946 MessageTemplate::kForInLoopInitializer);
941 } 947 }
942 *ok = false; 948 *ok = false;
943 return Statement::Default(); 949 return Statement::Default();
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 Expect(Token::RBRACE, CHECK_OK); 1266 Expect(Token::RBRACE, CHECK_OK);
1261 return PreParserExpression::Default(); 1267 return PreParserExpression::Default();
1262 } 1268 }
1263 } 1269 }
1264 1270
1265 #undef CHECK_OK 1271 #undef CHECK_OK
1266 1272
1267 1273
1268 } // namespace internal 1274 } // namespace internal
1269 } // namespace v8 1275 } // namespace v8
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | test/message/for-in-loop-initializers-destructuring.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698