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

Side by Side Diff: src/parser.cc

Issue 1218543003: [es6] Ensure that for-in/of loops have a proper TDZ for their boundnames (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 5 years, 5 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 | « no previous file | test/mjsunit/es6/debug-blockscopes.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/ast-literal-reindexer.h" 9 #include "src/ast-literal-reindexer.h"
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 3537 matching lines...) Expand 10 before | Expand all | Expand 10 after
3548 RelocInfo::kNoPosition), 3548 RelocInfo::kNoPosition),
3549 zone()); 3549 zone());
3550 } 3550 }
3551 3551
3552 // Rewrite a for-in/of statement of the form 3552 // Rewrite a for-in/of statement of the form
3553 // 3553 //
3554 // for (let/const/var x in/of e) b 3554 // for (let/const/var x in/of e) b
3555 // 3555 //
3556 // into 3556 // into
3557 // 3557 //
3558 // <let x' be a temporary variable> 3558 // {
3559 // for (x' in/of e) { 3559 // <let x' be a temporary variable>
3560 // let/const/var x; 3560 // for (x' in/of e) {
3561 // x = x'; 3561 // let/const/var x;
3562 // b; 3562 // x = x';
3563 // b;
3564 // }
3565 // let x; // for TDZ
3563 // } 3566 // }
3564 3567
3565 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3568 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3566 ast_value_factory()->dot_for_string()); 3569 ast_value_factory()->dot_for_string());
3567 ForEachStatement* loop = 3570 ForEachStatement* loop =
3568 factory()->NewForEachStatement(mode, labels, stmt_pos); 3571 factory()->NewForEachStatement(mode, labels, stmt_pos);
3569 Target target(&this->target_stack_, loop); 3572 Target target(&this->target_stack_, loop);
3570 3573
3571 // The expression does not see the lexical loop variables.
3572 scope_ = saved_scope;
3573 Expression* enumerable = ParseExpression(true, CHECK_OK); 3574 Expression* enumerable = ParseExpression(true, CHECK_OK);
3574 scope_ = for_scope; 3575
3575 Expect(Token::RPAREN, CHECK_OK); 3576 Expect(Token::RPAREN, CHECK_OK);
3576 3577
3578 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3579 body_scope->set_start_position(scanner()->location().beg_pos);
3580 scope_ = body_scope;
3581
3577 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3582 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3578 3583
3579 Block* body_block = 3584 Block* body_block =
3580 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3585 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3581 3586
3582 auto each_initialization_block = 3587 auto each_initialization_block =
3583 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); 3588 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3584 { 3589 {
3585 DCHECK(parsing_result.declarations.length() == 1); 3590 DCHECK(parsing_result.declarations.length() == 1);
3586 DeclarationParsingResult::Declaration decl = 3591 DeclarationParsingResult::Declaration decl =
3587 parsing_result.declarations[0]; 3592 parsing_result.declarations[0];
3588 auto descriptor = parsing_result.descriptor; 3593 auto descriptor = parsing_result.descriptor;
3589 descriptor.declaration_pos = RelocInfo::kNoPosition; 3594 descriptor.declaration_pos = RelocInfo::kNoPosition;
3590 decl.initializer = factory()->NewVariableProxy(temp); 3595 decl.initializer = factory()->NewVariableProxy(temp);
3591 3596
3592 PatternRewriter::DeclareAndInitializeVariables( 3597 PatternRewriter::DeclareAndInitializeVariables(
3593 each_initialization_block, &descriptor, &decl, 3598 each_initialization_block, &descriptor, &decl,
3594 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3599 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3595 : nullptr, 3600 : nullptr,
3596 CHECK_OK); 3601 CHECK_OK);
3597 } 3602 }
3598 3603
3599 body_block->AddStatement(each_initialization_block, zone()); 3604 body_block->AddStatement(each_initialization_block, zone());
3600 body_block->AddStatement(body, zone()); 3605 body_block->AddStatement(body, zone());
3601 VariableProxy* temp_proxy = 3606 VariableProxy* temp_proxy =
3602 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3607 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3603 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); 3608 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3609 scope_ = for_scope;
3610 body_scope->set_end_position(scanner()->location().end_pos);
3611 body_scope = body_scope->FinalizeBlockScope();
3612 if (body_scope != nullptr) {
3613 body_block->set_scope(body_scope);
3614 }
3615
3616 // Create a TDZ for any lexically-bound names.
3617 if (is_strict(language_mode()) &&
3618 IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3619 DCHECK_NULL(init_block);
3620
3621 init_block =
3622 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3623
3624 for (int i = 0; i < lexical_bindings.length(); ++i) {
3625 // TODO(adamk): This needs to be some sort of special
3626 // INTERNAL variable that's invisible to the debugger
3627 // but visible to everything else.
3628 VariableProxy* tdz_proxy = NewUnresolved(lexical_bindings[i], LET);
3629 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3630 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3631 Variable* tdz_var = Declare(tdz_decl, DeclarationDescriptor::NORMAL,
3632 true, CHECK_OK);
3633 tdz_var->set_initializer_position(position());
3634 }
3635 }
3636
3604 scope_ = saved_scope; 3637 scope_ = saved_scope;
3605 for_scope->set_end_position(scanner()->location().end_pos); 3638 for_scope->set_end_position(scanner()->location().end_pos);
3606 for_scope = for_scope->FinalizeBlockScope(); 3639 for_scope = for_scope->FinalizeBlockScope();
3607 if (for_scope != nullptr) {
3608 body_block->set_scope(for_scope);
3609 }
3610 // Parsed for-in loop w/ variable declarations. 3640 // Parsed for-in loop w/ variable declarations.
3611 if (init_block != nullptr) { 3641 if (init_block != nullptr) {
3612 init_block->AddStatement(loop, zone()); 3642 init_block->AddStatement(loop, zone());
3643 if (for_scope != nullptr) {
3644 init_block->set_scope(for_scope);
3645 }
3613 return init_block; 3646 return init_block;
3614 } else { 3647 } else {
3648 DCHECK_NULL(for_scope);
3615 return loop; 3649 return loop;
3616 } 3650 }
3617 } else { 3651 } else {
3618 init = parsing_result.BuildInitializationBlock( 3652 init = parsing_result.BuildInitializationBlock(
3619 IsLexicalVariableMode(parsing_result.descriptor.mode) 3653 IsLexicalVariableMode(parsing_result.descriptor.mode)
3620 ? &lexical_bindings 3654 ? &lexical_bindings
3621 : nullptr, 3655 : nullptr,
3622 CHECK_OK); 3656 CHECK_OK);
3623 } 3657 }
3624 } else { 3658 } else {
(...skipping 2280 matching lines...) Expand 10 before | Expand all | Expand 10 after
5905 Expression* Parser::SpreadCallNew(Expression* function, 5939 Expression* Parser::SpreadCallNew(Expression* function,
5906 ZoneList<v8::internal::Expression*>* args, 5940 ZoneList<v8::internal::Expression*>* args,
5907 int pos) { 5941 int pos) {
5908 args->InsertAt(0, function, zone()); 5942 args->InsertAt(0, function, zone());
5909 5943
5910 return factory()->NewCallRuntime( 5944 return factory()->NewCallRuntime(
5911 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5945 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5912 } 5946 }
5913 } // namespace internal 5947 } // namespace internal
5914 } // namespace v8 5948 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/es6/debug-blockscopes.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698