| Index: runtime/vm/ast_transformer.cc
|
| ===================================================================
|
| --- runtime/vm/ast_transformer.cc (revision 44105)
|
| +++ runtime/vm/ast_transformer.cc (working copy)
|
| @@ -45,11 +45,9 @@
|
| #undef DEFINE_UNREACHABLE
|
|
|
| AwaitTransformer::AwaitTransformer(SequenceNode* preamble,
|
| - const ParsedFunction& parsed_function,
|
| LocalScope* function_top)
|
| : preamble_(preamble),
|
| temp_cnt_(0),
|
| - parsed_function_(parsed_function),
|
| function_top_(function_top),
|
| thread_(Thread::Current()) {
|
| ASSERT(function_top_ != NULL);
|
| @@ -109,6 +107,30 @@
|
| }
|
|
|
|
|
| +// Restore the currently relevant :saved_try_context_var on the stack
|
| +// from the captured :async_saved_try_ctx_var_<try_index>.
|
| +AstNode* AwaitTransformer::RestoreSavedTryContext(Zone* zone,
|
| + LocalScope* scope,
|
| + int16_t try_index) {
|
| + LocalVariable* saved_try_ctx =
|
| + scope->LookupVariable(Symbols::SavedTryContextVar(), false);
|
| + ASSERT((saved_try_ctx != NULL) && !saved_try_ctx->is_captured());
|
| + const String& async_saved_try_ctx_name = String::ZoneHandle(zone,
|
| + Symbols::New(String::Handle(zone,
|
| + String::NewFormatted("%s%d",
|
| + Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
|
| + try_index))));
|
| + LocalVariable* async_saved_try_ctx =
|
| + scope->LookupVariable(async_saved_try_ctx_name, false);
|
| + ASSERT(async_saved_try_ctx != NULL);
|
| + ASSERT(async_saved_try_ctx->is_captured());
|
| + return new (zone) StoreLocalNode(
|
| + Scanner::kNoSourcePos,
|
| + saved_try_ctx,
|
| + new (zone) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx));
|
| +}
|
| +
|
| +
|
| void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
|
| // Await transformation:
|
| //
|
| @@ -212,16 +234,19 @@
|
| preamble_->Add(continuation_return);
|
|
|
| // 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 =
|
| - GetVariableInScope(preamble_->scope(), async_saved_try_ctx_name);
|
| - preamble_->Add(new (Z) StoreLocalNode(
|
| - Scanner::kNoSourcePos,
|
| - parsed_function_.saved_try_ctx(),
|
| - new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx)));
|
| + // restoring the saved try context that lives on the stack and possibly the
|
| + // saved try context of the outer try block.
|
| + if (node->try_scope() != NULL) {
|
| + preamble_->Add(RestoreSavedTryContext(Z,
|
| + node->try_scope(),
|
| + node->try_index()));
|
| + if (node->outer_try_scope() != NULL) {
|
| + preamble_->Add(RestoreSavedTryContext(Z,
|
| + node->outer_try_scope(),
|
| + node->outer_try_index()));
|
| + }
|
| + } else {
|
| + ASSERT(node->outer_try_scope() == NULL);
|
| }
|
|
|
| LoadLocalNode* load_error_param = new (Z) LoadLocalNode(
|
|
|