Chromium Code Reviews| 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)) { |