Chromium Code Reviews| Index: runtime/vm/flow_graph_builder.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_builder.cc (revision 43883) |
| +++ runtime/vm/flow_graph_builder.cc (working copy) |
| @@ -1111,7 +1111,9 @@ |
| AddReturnExit(node->token_pos(), return_value); |
| - if ((function.IsAsyncClosure() || function.IsSyncGenClosure()) && |
| + if ((function.IsAsyncClosure() || |
| + function.IsSyncGenClosure() || |
| + function.IsAsyncGenClosure()) && |
| (node->return_type() == ReturnNode::kContinuationTarget)) { |
| JoinEntryInstr* const join = new(I) JoinEntryInstr( |
| owner()->AllocateBlockId(), owner()->try_index()); |
| @@ -1483,11 +1485,28 @@ |
| } |
| -void EffectGraphVisitor::BuildYieldJump(LocalVariable* old_context, |
| - LocalVariable* iterator_param, |
| - const intptr_t old_ctx_level, |
| - JoinEntryInstr* target) { |
| +void EffectGraphVisitor::BuildAsyncYieldJump(LocalVariable* old_context, |
| + const intptr_t old_ctx_level, |
|
Ivan Posva
2015/02/23 08:23:36
old_ctx_level is not used in this function. Why is
hausner
2015/02/23 17:12:01
Copy-paste error. I think I will need it though si
|
| + JoinEntryInstr* target) { |
| // Building a jump consists of the following actions: |
| + // * Restore the old context from :await_cxt_var. |
| + // * Append a Goto to the target's join. |
| + ASSERT((old_context != NULL) && old_context->is_captured()); |
| + |
| + // Restore the saved continuation context, i.e. the context that was |
| + // saved into :await_ctx_var before the closure suspended. |
| + BuildRestoreContext(*old_context); |
| + |
| + // Goto saved join. |
| + Goto(target); |
| +} |
| + |
| + |
| +void EffectGraphVisitor::BuildSyncYieldJump(LocalVariable* old_context, |
| + LocalVariable* iterator_param, |
| + const intptr_t old_ctx_level, |
| + JoinEntryInstr* target) { |
| + // Building a jump consists of the following actions: |
| // * Load the generator body's iterator parameter (:iterator) |
| // from the current context into a temporary. |
| // * Restore the old context from :await_cxt_var. |
| @@ -3882,7 +3901,9 @@ |
| // The preamble is generated after visiting the body. |
| GotoInstr* preamble_start = NULL; |
| if (is_top_level_sequence && |
| - (function.IsAsyncClosure() || function.IsSyncGenClosure())) { |
| + (function.IsAsyncClosure() || |
| + function.IsSyncGenClosure() || |
| + function.IsAsyncGenClosure())) { |
| JoinEntryInstr* preamble_end = new(I) JoinEntryInstr( |
| owner()->AllocateBlockId(), owner()->try_index()); |
| ASSERT(exit() != NULL); |
| @@ -3908,7 +3929,9 @@ |
| // After generating the CFG for the body we can create the preamble |
| // because we know exactly how many continuation states we need. |
| if (is_top_level_sequence && |
| - (function.IsAsyncClosure() || function.IsSyncGenClosure())) { |
| + (function.IsAsyncClosure() || |
| + function.IsSyncGenClosure() || |
| + function.IsAsyncGenClosure())) { |
| ASSERT(preamble_start != NULL); |
| // We are at the top level. Fetch the corresponding scope. |
| LocalScope* top_scope = node->scope(); |
| @@ -3954,14 +3977,19 @@ |
| stack_trace_param, |
| (*owner()->await_levels())[i], |
| (*owner()->await_joins())[i]); |
| + } else if (function.IsAsyncGenClosure()) { |
| + for_true.BuildAsyncYieldJump(old_context, |
| + (*owner()->await_levels())[i], |
| + (*owner()->await_joins())[i]); |
| + |
| } else { |
| ASSERT(function.IsSyncGenClosure()); |
| LocalVariable* iterator_param = |
| top_scope->LookupVariable(Symbols::IteratorParameter(), false); |
| - for_true.BuildYieldJump(old_context, |
| - iterator_param, |
| - (*owner()->await_levels())[i], |
| - (*owner()->await_joins())[i]); |
| + for_true.BuildSyncYieldJump(old_context, |
| + iterator_param, |
| + (*owner()->await_levels())[i], |
| + (*owner()->await_joins())[i]); |
| } |
| Join(for_test, for_true, for_false); |