Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |