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

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: update language test status 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
« no previous file with comments | « runtime/vm/ast.cc ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..2927213577986f886e77c47c4381546a75af7f65 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1046,6 +1046,42 @@ 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 but return
+ // the value.
+ //
+ // We distinguish those kinds of nodes via is_regular_return().
+ //
+ if (function.is_async_closure() && node->is_regular_return()) {
+ // Temporary store the computed return value.
+ Do(BuildStoreExprTemp(return_value));
+
+ LocalVariable* rcv_var = node->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));
Florian Schneider 2014/08/13 11:10:29 I'm not sure this works. Is this code path exercis
+ 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);
}
« no previous file with comments | « runtime/vm/ast.cc ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698