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

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: Fix rebase merge 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
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/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 3534 matching lines...) Expand 10 before | Expand all | Expand 10 after
3545 RelocInfo::kNoPosition), 3545 RelocInfo::kNoPosition),
3546 zone()); 3546 zone());
3547 } 3547 }
3548 3548
3549 // Rewrite a for-in/of statement of the form 3549 // Rewrite a for-in/of statement of the form
3550 // 3550 //
3551 // for (let/const/var x in/of e) b 3551 // for (let/const/var x in/of e) b
3552 // 3552 //
3553 // into 3553 // into
3554 // 3554 //
3555 // <let x' be a temporary variable> 3555 // {
3556 // for (x' in/of e) { 3556 // <let x' be a temporary variable>
3557 // let/const/var x; 3557 // for (x' in/of e) {
3558 // x = x'; 3558 // let/const/var x;
3559 // b; 3559 // x = x';
3560 // b;
3561 // }
3562 // let x; // for TDZ
3560 // } 3563 // }
3561 3564
3562 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3565 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3563 ast_value_factory()->dot_for_string()); 3566 ast_value_factory()->dot_for_string());
3564 ForEachStatement* loop = 3567 ForEachStatement* loop =
3565 factory()->NewForEachStatement(mode, labels, stmt_pos); 3568 factory()->NewForEachStatement(mode, labels, stmt_pos);
3566 Target target(&this->target_stack_, loop); 3569 Target target(&this->target_stack_, loop);
3567 3570
3568 // The expression does not see the lexical loop variables.
3569 scope_ = saved_scope;
3570 Expression* enumerable = ParseExpression(true, CHECK_OK); 3571 Expression* enumerable = ParseExpression(true, CHECK_OK);
3571 scope_ = for_scope; 3572
3572 Expect(Token::RPAREN, CHECK_OK); 3573 Expect(Token::RPAREN, CHECK_OK);
3573 3574
3575 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3576 body_scope->set_start_position(scanner()->location().beg_pos);
3577 scope_ = body_scope;
3578
3574 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3579 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3575 3580
3576 Block* body_block = 3581 Block* body_block =
3577 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3582 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3578 3583
3579 auto each_initialization_block = 3584 auto each_initialization_block =
3580 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); 3585 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3581 { 3586 {
3582 DCHECK(parsing_result.declarations.length() == 1); 3587 DCHECK(parsing_result.declarations.length() == 1);
3583 DeclarationParsingResult::Declaration decl = 3588 DeclarationParsingResult::Declaration decl =
3584 parsing_result.declarations[0]; 3589 parsing_result.declarations[0];
3585 auto descriptor = parsing_result.descriptor; 3590 auto descriptor = parsing_result.descriptor;
3586 descriptor.declaration_pos = RelocInfo::kNoPosition; 3591 descriptor.declaration_pos = RelocInfo::kNoPosition;
3587 decl.initializer = factory()->NewVariableProxy(temp); 3592 decl.initializer = factory()->NewVariableProxy(temp);
3588 3593
3589 PatternRewriter::DeclareAndInitializeVariables( 3594 PatternRewriter::DeclareAndInitializeVariables(
3590 each_initialization_block, &descriptor, &decl, 3595 each_initialization_block, &descriptor, &decl,
3591 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3596 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3592 : nullptr, 3597 : nullptr,
3593 CHECK_OK); 3598 CHECK_OK);
3594 } 3599 }
3595 3600
3596 body_block->AddStatement(each_initialization_block, zone()); 3601 body_block->AddStatement(each_initialization_block, zone());
3597 body_block->AddStatement(body, zone()); 3602 body_block->AddStatement(body, zone());
3598 VariableProxy* temp_proxy = 3603 VariableProxy* temp_proxy =
3599 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3604 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3600 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); 3605 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3606 scope_ = for_scope;
3607 body_scope->set_end_position(scanner()->location().end_pos);
3608 body_scope = body_scope->FinalizeBlockScope();
3609 if (body_scope != nullptr) {
3610 body_block->set_scope(body_scope);
3611 }
3612
3613 // Create a TDZ for any lexically-bound names.
3614 if (is_strict(language_mode()) &&
3615 IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3616 DCHECK_NULL(init_block);
3617
3618 init_block =
3619 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3620
3621 for (int i = 0; i < lexical_bindings.length(); ++i) {
3622 // TODO(adamk): This needs to be some sort of special
3623 // INTERNAL variable that's invisible to the debugger
3624 // but visible to everything else.
3625 VariableProxy* tdz_proxy = NewUnresolved(lexical_bindings[i], LET);
3626 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3627 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3628 Variable* tdz_var = Declare(tdz_decl, DeclarationDescriptor::NORMAL,
3629 true, CHECK_OK);
3630 tdz_var->set_initializer_position(position());
3631 }
3632 }
3633
3601 scope_ = saved_scope; 3634 scope_ = saved_scope;
3602 for_scope->set_end_position(scanner()->location().end_pos); 3635 for_scope->set_end_position(scanner()->location().end_pos);
3603 for_scope = for_scope->FinalizeBlockScope(); 3636 for_scope = for_scope->FinalizeBlockScope();
3604 if (for_scope != nullptr) {
3605 body_block->set_scope(for_scope);
3606 }
3607 // Parsed for-in loop w/ variable declarations. 3637 // Parsed for-in loop w/ variable declarations.
3608 if (init_block != nullptr) { 3638 if (init_block != nullptr) {
3609 init_block->AddStatement(loop, zone()); 3639 init_block->AddStatement(loop, zone());
3640 if (for_scope != nullptr) {
3641 init_block->set_scope(for_scope);
3642 }
3610 return init_block; 3643 return init_block;
3611 } else { 3644 } else {
3645 DCHECK_NULL(for_scope);
3612 return loop; 3646 return loop;
3613 } 3647 }
3614 } else { 3648 } else {
3615 init = parsing_result.BuildInitializationBlock( 3649 init = parsing_result.BuildInitializationBlock(
3616 IsLexicalVariableMode(parsing_result.descriptor.mode) 3650 IsLexicalVariableMode(parsing_result.descriptor.mode)
3617 ? &lexical_bindings 3651 ? &lexical_bindings
3618 : nullptr, 3652 : nullptr,
3619 CHECK_OK); 3653 CHECK_OK);
3620 } 3654 }
3621 } else { 3655 } else {
(...skipping 2272 matching lines...) Expand 10 before | Expand all | Expand 10 after
5894 Expression* Parser::SpreadCallNew(Expression* function, 5928 Expression* Parser::SpreadCallNew(Expression* function,
5895 ZoneList<v8::internal::Expression*>* args, 5929 ZoneList<v8::internal::Expression*>* args,
5896 int pos) { 5930 int pos) {
5897 args->InsertAt(0, function, zone()); 5931 args->InsertAt(0, function, zone());
5898 5932
5899 return factory()->NewCallRuntime( 5933 return factory()->NewCallRuntime(
5900 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5934 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5901 } 5935 }
5902 } // namespace internal 5936 } // namespace internal
5903 } // namespace v8 5937 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/es6/debug-blockscopes.js » ('j') | test/mjsunit/harmony/destructuring.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698