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

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

Issue 1634553002: Fix bug where generators got closed prematurely. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments. Created 4 years, 11 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/js/generator.js ('k') | test/cctest/test-ast-expression-visitor.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 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/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-rewriter.h" 9 #include "src/ast/ast-expression-rewriter.h"
10 #include "src/ast/ast-expression-visitor.h" 10 #include "src/ast/ast-expression-visitor.h"
(...skipping 4637 matching lines...) Expand 10 before | Expand all | Expand 10 after
4648 inner_scope->set_is_declaration_scope(); 4648 inner_scope->set_is_declaration_scope();
4649 inner_scope->set_start_position(scanner()->location().beg_pos); 4649 inner_scope->set_start_position(scanner()->location().beg_pos);
4650 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition); 4650 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4651 inner_block->set_scope(inner_scope); 4651 inner_block->set_scope(inner_scope);
4652 body = inner_block->statements(); 4652 body = inner_block->statements();
4653 } 4653 }
4654 4654
4655 { 4655 {
4656 BlockState block_state(&scope_, inner_scope); 4656 BlockState block_state(&scope_, inner_scope);
4657 4657
4658 // For generators, allocate and yield an iterator on function entry.
4659 if (IsGeneratorFunction(kind)) { 4658 if (IsGeneratorFunction(kind)) {
4660 ZoneList<Expression*>* arguments = 4659 // We produce:
4661 new(zone()) ZoneList<Expression*>(0, zone()); 4660 //
4662 CallRuntime* allocation = factory()->NewCallRuntime( 4661 // try { InitialYield; ...body...; FinalYield }
4663 Runtime::kCreateJSGeneratorObject, arguments, pos); 4662 // finally { %GeneratorClose(generator) }
4664 VariableProxy* init_proxy = factory()->NewVariableProxy( 4663 //
4665 function_state_->generator_object_variable()); 4664 // - InitialYield yields the actual generator object.
4666 Assignment* assignment = factory()->NewAssignment( 4665 // - FinalYield yields {value: foo, done: true} where foo is the
4667 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition); 4666 // completion value of body. (This is needed here in case the body
4668 VariableProxy* get_proxy = factory()->NewVariableProxy( 4667 // falls through without an explicit return.)
4669 function_state_->generator_object_variable()); 4668 // - Any return statement inside the body will be converted into a similar
4670 Yield* yield = factory()->NewYield( 4669 // FinalYield.
4671 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); 4670 // - If the generator terminates for whatever reason, we must close it.
4672 body->Add(factory()->NewExpressionStatement( 4671 // Hence the finally clause.
4673 yield, RelocInfo::kNoPosition), zone());
4674 }
4675 4672
4676 ParseStatementList(body, Token::RBRACE, CHECK_OK); 4673 Block* try_block =
4674 factory()->NewBlock(nullptr, 3, false, RelocInfo::kNoPosition);
4677 4675
4678 if (IsGeneratorFunction(kind)) { 4676 {
4677 ZoneList<Expression*>* arguments =
4678 new (zone()) ZoneList<Expression*>(0, zone());
4679 CallRuntime* allocation = factory()->NewCallRuntime(
4680 Runtime::kCreateJSGeneratorObject, arguments, pos);
4681 VariableProxy* init_proxy = factory()->NewVariableProxy(
4682 function_state_->generator_object_variable());
4683 Assignment* assignment = factory()->NewAssignment(
4684 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition);
4685 VariableProxy* get_proxy = factory()->NewVariableProxy(
4686 function_state_->generator_object_variable());
4687 Yield* yield = factory()->NewYield(
4688 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
4689 try_block->statements()->Add(
4690 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition),
4691 zone());
4692 }
4693
4694 ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK);
4695
4679 VariableProxy* get_proxy = factory()->NewVariableProxy( 4696 VariableProxy* get_proxy = factory()->NewVariableProxy(
4680 function_state_->generator_object_variable()); 4697 function_state_->generator_object_variable());
4681 Expression* undefined = 4698 Expression* undefined =
4682 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 4699 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4683 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, 4700 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
4684 RelocInfo::kNoPosition); 4701 RelocInfo::kNoPosition);
4685 body->Add(factory()->NewExpressionStatement( 4702 try_block->statements()->Add(
4686 yield, RelocInfo::kNoPosition), zone()); 4703 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition),
4704 zone());
4705
4706 Block* finally_block =
4707 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
4708 ZoneList<Expression*>* args =
4709 new (zone()) ZoneList<Expression*>(1, zone());
4710 VariableProxy* call_proxy = factory()->NewVariableProxy(
4711 function_state_->generator_object_variable());
4712 args->Add(call_proxy, zone());
4713 Expression* call = factory()->NewCallRuntime(
4714 Runtime::kGeneratorClose, args, RelocInfo::kNoPosition);
4715 finally_block->statements()->Add(
4716 factory()->NewExpressionStatement(call, RelocInfo::kNoPosition),
4717 zone());
4718
4719 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
4720 RelocInfo::kNoPosition),
4721 zone());
4722 } else {
4723 ParseStatementList(body, Token::RBRACE, CHECK_OK);
4687 } 4724 }
4688 4725
4689 if (IsSubclassConstructor(kind)) { 4726 if (IsSubclassConstructor(kind)) {
4690 body->Add( 4727 body->Add(
4691 factory()->NewReturnStatement( 4728 factory()->NewReturnStatement(
4692 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), 4729 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4693 RelocInfo::kNoPosition), 4730 RelocInfo::kNoPosition),
4694 zone()); 4731 zone());
4695 } 4732 }
4696 } 4733 }
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after
5733 auto class_literal = value->AsClassLiteral(); 5770 auto class_literal = value->AsClassLiteral();
5734 if (class_literal->raw_name() == nullptr) { 5771 if (class_literal->raw_name() == nullptr) {
5735 class_literal->set_raw_name(name); 5772 class_literal->set_raw_name(name);
5736 } 5773 }
5737 } 5774 }
5738 } 5775 }
5739 5776
5740 5777
5741 } // namespace internal 5778 } // namespace internal
5742 } // namespace v8 5779 } // namespace v8
OLDNEW
« no previous file with comments | « src/js/generator.js ('k') | test/cctest/test-ast-expression-visitor.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698