Chromium Code Reviews| Index: runtime/vm/parser.cc |
| =================================================================== |
| --- runtime/vm/parser.cc (revision 43705) |
| +++ runtime/vm/parser.cc (working copy) |
| @@ -3171,7 +3171,7 @@ |
| } else if (func.IsSyncGenClosure()) { |
| // The closure containing the body of a sync generator is debuggable. |
| ASSERT(func.is_debuggable()); |
| - // Nothing special to do. |
| + async_temp_scope_ = current_block_->scope; |
| } |
| BoolScope allow_await(&this->await_is_keyword_, |
| @@ -5975,8 +5975,11 @@ |
| } |
| ASSERT(try_blocks_list_ != NULL); |
| + ASSERT(innermost_function().IsAsyncClosure() || |
| + innermost_function().IsAsyncFunction()); |
| if (innermost_function().IsAsyncClosure() || |
| innermost_function().IsAsyncFunction()) { |
| + // This should always be true here. |
|
regis
2015/02/11 23:53:44
Add a TODO if you want to revisit this code. Other
hausner
2015/02/12 00:18:50
Removed the if. The assertion never fired in our t
|
| if ((try_blocks_list_->outer_try_block() != NULL) && |
| (try_blocks_list_->outer_try_block()->try_block() |
| ->scope->function_level() == |
| @@ -6081,7 +6084,9 @@ |
| PushTryBlock(current_block_); |
| if (innermost_function().IsAsyncClosure() || |
| - innermost_function().IsAsyncFunction()) { |
| + innermost_function().IsAsyncFunction() || |
| + innermost_function().IsSyncGenClosure() || |
| + innermost_function().IsSyncGenerator()) { |
| SetupSavedTryContext(context_var); |
| } |
| } |
| @@ -6164,10 +6169,7 @@ |
| OpenFunctionBlock(body); |
| AddFormalParamsToScope(&closure_params, current_block_->scope); |
| OpenBlock(); |
| - |
| - /* |
| - async_temp_scope_ = current_block_->scope; // Is this needed? |
| - */ |
| + async_temp_scope_ = current_block_->scope; |
| return body.raw(); |
| } |
| @@ -8196,7 +8198,9 @@ |
| // outer try block (if it exists). The current try block has already been |
| // removed from the stack of try blocks. |
| if ((innermost_function().IsAsyncClosure() || |
| - innermost_function().IsAsyncFunction()) && |
| + innermost_function().IsAsyncFunction() || |
| + innermost_function().IsSyncGenClosure() || |
| + innermost_function().IsSyncGenerator()) && |
| (try_blocks_list_ != NULL)) { |
| // We need two unchain two scopes: finally clause, and the try block level. |
| RestoreSavedTryContext(current_block_->scope->parent()->parent(), |
| @@ -8356,7 +8360,9 @@ |
| // outer try block (if it exists). |
| ASSERT(try_blocks_list_ != NULL); |
| if (innermost_function().IsAsyncClosure() || |
| - innermost_function().IsAsyncFunction()) { |
| + innermost_function().IsAsyncFunction() || |
| + innermost_function().IsSyncGenClosure() || |
| + innermost_function().IsSyncGenerator()) { |
| if ((try_blocks_list_->outer_try_block() != NULL) && |
| (try_blocks_list_->outer_try_block()->try_block() |
| ->scope->function_level() == |
| @@ -8464,7 +8470,9 @@ |
| // outer try block (if it exists). |
| ASSERT(try_blocks_list_ != NULL); |
| if (innermost_function().IsAsyncClosure() || |
| - innermost_function().IsAsyncFunction()) { |
| + innermost_function().IsAsyncFunction() || |
| + innermost_function().IsSyncGenClosure() || |
| + innermost_function().IsSyncGenerator()) { |
| if ((try_blocks_list_->outer_try_block() != NULL) && |
| (try_blocks_list_->outer_try_block()->try_block() |
| ->scope->function_level() == |
| @@ -8495,6 +8503,7 @@ |
| Scanner::kNoSourcePos, |
| async_saved_try_ctx_name, |
| Type::ZoneHandle(Z, Type::DynamicType())); |
| + ASSERT(async_temp_scope_ != NULL); |
| async_temp_scope_->AddVariable(async_saved_try_ctx); |
| async_saved_try_ctx->set_is_captured(); |
| async_saved_try_ctx = current_block_->scope->LookupVariable( |
| @@ -8600,7 +8609,9 @@ |
| ExpectToken(Token::kLBRACE); |
| if (innermost_function().IsAsyncClosure() || |
| - innermost_function().IsAsyncFunction()) { |
| + innermost_function().IsAsyncFunction() || |
| + innermost_function().IsSyncGenClosure() || |
| + innermost_function().IsSyncGenerator()) { |
| SetupSavedTryContext(context_var); |
| } |
| @@ -8842,6 +8853,22 @@ |
| new(Z) LiteralNode(TokenPos(), Bool::True())); |
| return_true->set_return_type(ReturnNode::kContinuationTarget); |
| yield->AddNode(return_true); |
| + |
| + // If this expression is part of a try block, also append the code for |
| + // restoring the saved try context that lives on the stack. |
| + const String& async_saved_try_ctx_name = |
| + String::Handle(Z, parsed_function()->async_saved_try_ctx_name()); |
| + if (!async_saved_try_ctx_name.IsNull()) { |
| + LocalVariable* async_saved_try_ctx = |
| + current_block_->scope->LookupVariable(async_saved_try_ctx_name, |
| + false); |
| + ASSERT(async_saved_try_ctx != NULL); |
| + yield->AddNode(new (Z) StoreLocalNode( |
| + Scanner::kNoSourcePos, |
| + parsed_function()->saved_try_ctx(), |
| + new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx))); |
| + } |
| + |
| statement = yield; |
| ExpectSemicolon(); |
| } else if (token == Token::kIF) { |