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

Side by Side 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: add scope via sequencenode add method 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 1039
1040 intptr_t current_context_level = owner()->context_level(); 1040 intptr_t current_context_level = owner()->context_level();
1041 ASSERT(current_context_level >= 0); 1041 ASSERT(current_context_level >= 0);
1042 if (owner()->parsed_function()->saved_entry_context_var() != NULL) { 1042 if (owner()->parsed_function()->saved_entry_context_var() != NULL) {
1043 // CTX on entry was saved, but not linked as context parent. 1043 // CTX on entry was saved, but not linked as context parent.
1044 BuildRestoreContext(*owner()->parsed_function()->saved_entry_context_var()); 1044 BuildRestoreContext(*owner()->parsed_function()->saved_entry_context_var());
1045 } else { 1045 } else {
1046 UnchainContexts(current_context_level); 1046 UnchainContexts(current_context_level);
1047 } 1047 }
1048 1048
1049 // Async functions contain two types of return statements:
1050 // 1) Returns that should complete the completer once all finally blocks have
1051 // been inlined (call: :async_completer.complete(return_value)). These
1052 // returns end up returning null in the end.
1053 // 2) "Continuation" returns that should not complete the completer.
1054 //
1055 // We distinguish those types by whether a scope() has been set or not.
hausner 2014/08/12 20:51:26 Is it possible to have a return without a sequence
Michael Lippautz (Google) 2014/08/12 21:13:57 True. I added a flag for this that is always true
1056 //
1057 if (function.is_async_closure() && node->scope() != NULL) {
1058 // Temporary store the computed return value.
1059 Do(BuildStoreExprTemp(return_value));
1060
1061 LocalVariable* rcv_var = node->scope()->LookupVariable(
1062 Symbols::AsyncCompleter(), false);
1063 ASSERT(rcv_var != NULL && rcv_var->is_captured());
1064 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var));
1065 Value* returned_value = Bind(BuildLoadExprTemp());
1066 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1067 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
1068 arguments->Add(PushArgument(rcv_value));
1069 arguments->Add(PushArgument(returned_value));
1070 InstanceCallInstr* call = new(I) InstanceCallInstr(
1071 Scanner::kNoSourcePos,
1072 Symbols::CompleterComplete(),
1073 Token::kILLEGAL,
1074 arguments,
1075 Object::null_array(),
1076 1,
1077 owner()->ic_data_array());
1078 Do(call);
1079
1080 // Rebind the return value for the actual return call to be null.
1081 return_value = BuildNullValue();
1082 }
1083
1049 AddReturnExit(node->token_pos(), return_value); 1084 AddReturnExit(node->token_pos(), return_value);
1050 } 1085 }
1051 1086
1052 1087
1053 // <Expression> ::= Literal { literal: Instance } 1088 // <Expression> ::= Literal { literal: Instance }
1054 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 1089 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
1055 ReturnDefinition(new(I) ConstantInstr(node->literal())); 1090 ReturnDefinition(new(I) ConstantInstr(node->literal()));
1056 } 1091 }
1057 1092
1058 1093
(...skipping 2897 matching lines...) Expand 10 before | Expand all | Expand 10 after
3956 Report::MessageF(Report::kBailout, 3991 Report::MessageF(Report::kBailout,
3957 Script::Handle(function.script()), 3992 Script::Handle(function.script()),
3958 function.token_pos(), 3993 function.token_pos(),
3959 "FlowGraphBuilder Bailout: %s %s", 3994 "FlowGraphBuilder Bailout: %s %s",
3960 String::Handle(function.name()).ToCString(), 3995 String::Handle(function.name()).ToCString(),
3961 reason); 3996 reason);
3962 UNREACHABLE(); 3997 UNREACHABLE();
3963 } 3998 }
3964 3999
3965 } // namespace dart 4000 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698