Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2305)

Unified Diff: runtime/vm/flow_graph_builder.cc

Issue 460763002: Fix returning from async functions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_builder.cc
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index cacb2fbcd6e4f3219a4957661a06779bae7b6256..b87633016fce9a1d36cfb9075ac2fd070fd3a136 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1046,6 +1046,41 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
UnchainContexts(current_context_level);
}
+ // Async functions contain two types of return statements:
+ // 1) Returns that should complete the completer once all finally blocks have
+ // been inlined (call: :async_completer.complete(return_value)). These
+ // returns end up returning null in the end.
+ // 2) "Continuation" returns that should not complete the completer.
+ //
+ // We distinguish those types by whether a return_scope() has been set or not.
+ //
+ if (function.is_async_closure() && node->return_scope() != NULL) {
+ // Temporary store the computed return value.
+ Do(BuildStoreExprTemp(return_value));
+
+ LocalVariable* rcv_var = node->return_scope()->LookupVariable(
+ Symbols::AsyncCompleter(), false);
+ ASSERT(rcv_var != NULL && rcv_var->is_captured());
+ Value* rcv_value = Bind(BuildLoadLocal(*rcv_var));
+ Value* returned_value = Bind(BuildLoadExprTemp());
+ ZoneGrowableArray<PushArgumentInstr*>* arguments =
+ new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+ arguments->Add(PushArgument(rcv_value));
+ arguments->Add(PushArgument(returned_value));
+ InstanceCallInstr* call = new(I) InstanceCallInstr(
+ Scanner::kNoSourcePos,
+ Symbols::CompleterComplete(),
+ Token::kILLEGAL,
+ arguments,
+ Object::null_array(),
+ 1,
+ owner()->ic_data_array());
+ Do(call);
+
+ // Rebind the return value for the actual return call to be null.
+ return_value = BuildNullValue();
+ }
+
AddReturnExit(node->token_pos(), return_value);
}
« runtime/vm/ast.h ('K') | « runtime/vm/code_generator_test.cc ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698