Index: runtime/vm/flow_graph_builder.cc |
=================================================================== |
--- runtime/vm/flow_graph_builder.cc (revision 35546) |
+++ runtime/vm/flow_graph_builder.cc (working copy) |
@@ -2376,39 +2376,61 @@ |
} |
-ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
- ClosureCallNode* node) { |
+void EffectGraphVisitor::BuildClosureCall( |
+ ClosureCallNode* node, bool result_needed) { |
ValueGraphVisitor for_closure(owner()); |
node->closure()->Visit(&for_closure); |
Append(for_closure); |
- PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
+ LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value()); |
+ |
ZoneGrowableArray<PushArgumentInstr*>* arguments = |
new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
+ Value* closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
+ PushArgumentInstr* push_closure = PushArgument(closure_val); |
arguments->Add(push_closure); |
BuildPushArguments(*node->arguments(), arguments); |
// Save context around the call. |
ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); |
BuildSaveContext(*owner()->parsed_function()->saved_current_context_var()); |
- return new ClosureCallInstr(node, arguments); |
+ closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
+ Value* context_val = Bind(new LoadFieldInstr(closure_val, |
+ Closure::context_offset(), |
+ AbstractType::ZoneHandle(), |
+ true)); // Immutable. |
+ AddInstruction(new StoreContextInstr(context_val)); |
+ closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
+ Value* function_val = Bind(new LoadFieldInstr(closure_val, |
+ Closure::function_offset(), |
+ AbstractType::ZoneHandle(), |
+ true)); // Immutable. |
+ Definition* closure_call = |
+ new ClosureCallInstr(function_val, node, arguments); |
+ if (result_needed) { |
+ Value* result = Bind(closure_call); |
+ Do(new StoreLocalInstr(*tmp_var, result)); |
+ // Restore context from temp. |
+ BuildRestoreContext( |
+ *owner()->parsed_function()->saved_current_context_var()); |
+ ReturnDefinition(ExitTempLocalScope(tmp_var)); |
+ } else { |
+ Do(closure_call); |
+ // Restore context from saved location. |
+ BuildRestoreContext( |
+ *owner()->parsed_function()->saved_current_context_var()); |
+ Do(ExitTempLocalScope(tmp_var)); |
+ } |
} |
void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
- Do(BuildClosureCall(node)); |
- // Restore context from saved location. |
- ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); |
- BuildRestoreContext(*owner()->parsed_function()->saved_current_context_var()); |
+ BuildClosureCall(node, false); |
} |
void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
- Value* result = Bind(BuildClosureCall(node)); |
- // Restore context from temp. |
- ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); |
- BuildRestoreContext(*owner()->parsed_function()->saved_current_context_var()); |
- ReturnValue(result); |
+ BuildClosureCall(node, true); |
} |