 Chromium Code Reviews
 Chromium Code Reviews Issue 1634553002:
  Fix bug where generators got closed prematurely.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1634553002:
  Fix bug where generators got closed prematurely.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| Index: src/parsing/parser.cc | 
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc | 
| index dd9744e7f6314d72f1b3b91ad4b28218da7d1225..4a64cf5a22defb40f4c3463124060930c2effa0d 100644 | 
| --- a/src/parsing/parser.cc | 
| +++ b/src/parsing/parser.cc | 
| @@ -4655,35 +4655,61 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 
| { | 
| BlockState block_state(&scope_, inner_scope); | 
| - // For generators, allocate and yield an iterator on function entry. | 
| + // try { InitialYield; ...body...; FinalYield } | 
| 
Michael Starzinger
2016/01/25 12:56:05
nit: On top of the pseudo-code, can we add a descr
 | 
| + // finally { %GeneratorClose(generator) } | 
| + | 
| if (IsGeneratorFunction(kind)) { | 
| - ZoneList<Expression*>* arguments = | 
| - new(zone()) ZoneList<Expression*>(0, zone()); | 
| - CallRuntime* allocation = factory()->NewCallRuntime( | 
| - Runtime::kCreateJSGeneratorObject, arguments, pos); | 
| - VariableProxy* init_proxy = factory()->NewVariableProxy( | 
| - function_state_->generator_object_variable()); | 
| - Assignment* assignment = factory()->NewAssignment( | 
| - Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition); | 
| - VariableProxy* get_proxy = factory()->NewVariableProxy( | 
| - function_state_->generator_object_variable()); | 
| - Yield* yield = factory()->NewYield( | 
| - get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); | 
| - body->Add(factory()->NewExpressionStatement( | 
| - yield, RelocInfo::kNoPosition), zone()); | 
| - } | 
| + Block* try_block = | 
| + factory()->NewBlock(nullptr, 3, false, RelocInfo::kNoPosition); | 
| - ParseStatementList(body, Token::RBRACE, CHECK_OK); | 
| + { | 
| + ZoneList<Expression*>* arguments = | 
| + new (zone()) ZoneList<Expression*>(0, zone()); | 
| + CallRuntime* allocation = factory()->NewCallRuntime( | 
| + Runtime::kCreateJSGeneratorObject, arguments, pos); | 
| + VariableProxy* init_proxy = factory()->NewVariableProxy( | 
| + function_state_->generator_object_variable()); | 
| + Assignment* assignment = factory()->NewAssignment( | 
| + Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition); | 
| + VariableProxy* get_proxy = factory()->NewVariableProxy( | 
| + function_state_->generator_object_variable()); | 
| + Yield* yield = factory()->NewYield( | 
| + get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); | 
| + try_block->statements()->Add( | 
| + factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition), | 
| + zone()); | 
| + } | 
| + | 
| + ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK); | 
| - if (IsGeneratorFunction(kind)) { | 
| VariableProxy* get_proxy = factory()->NewVariableProxy( | 
| function_state_->generator_object_variable()); | 
| Expression* undefined = | 
| factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | 
| Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, | 
| RelocInfo::kNoPosition); | 
| - body->Add(factory()->NewExpressionStatement( | 
| - yield, RelocInfo::kNoPosition), zone()); | 
| + try_block->statements()->Add( | 
| + factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition), | 
| + zone()); | 
| + | 
| + Block* finally_block = | 
| + factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); | 
| + ZoneList<Expression*>* args = | 
| + new (zone()) ZoneList<Expression*>(1, zone()); | 
| + VariableProxy* call_proxy = factory()->NewVariableProxy( | 
| + function_state_->generator_object_variable()); | 
| + args->Add(call_proxy, zone()); | 
| + Expression* call = factory()->NewCallRuntime( | 
| + Runtime::kGeneratorClose, args, RelocInfo::kNoPosition); | 
| + finally_block->statements()->Add( | 
| + factory()->NewExpressionStatement(call, RelocInfo::kNoPosition), | 
| + zone()); | 
| + | 
| + body->Add(factory()->NewTryFinallyStatement(try_block, finally_block, | 
| + RelocInfo::kNoPosition), | 
| + zone()); | 
| + } else { | 
| + ParseStatementList(body, Token::RBRACE, CHECK_OK); | 
| } | 
| if (IsSubclassConstructor(kind)) { |