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 2358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2369 const intptr_t result_cid = GetResultCidOfNativeFactory(node->function()); | 2369 const intptr_t result_cid = GetResultCidOfNativeFactory(node->function()); |
2370 if (result_cid != kDynamicCid) { | 2370 if (result_cid != kDynamicCid) { |
2371 call->set_result_cid(result_cid); | 2371 call->set_result_cid(result_cid); |
2372 call->set_is_native_list_factory(true); | 2372 call->set_is_native_list_factory(true); |
2373 } | 2373 } |
2374 } | 2374 } |
2375 ReturnDefinition(call); | 2375 ReturnDefinition(call); |
2376 } | 2376 } |
2377 | 2377 |
2378 | 2378 |
2379 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 2379 void EffectGraphVisitor::BuildClosureCall( |
2380 ClosureCallNode* node) { | 2380 ClosureCallNode* node, bool result_needed) { |
2381 ValueGraphVisitor for_closure(owner()); | 2381 ValueGraphVisitor for_closure(owner()); |
2382 node->closure()->Visit(&for_closure); | 2382 node->closure()->Visit(&for_closure); |
2383 Append(for_closure); | 2383 Append(for_closure); |
2384 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 2384 |
| 2385 LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value()); |
2385 | 2386 |
2386 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2387 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2387 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2388 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 2389 Value* closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2390 PushArgumentInstr* push_closure = PushArgument(closure_val); |
2388 arguments->Add(push_closure); | 2391 arguments->Add(push_closure); |
2389 BuildPushArguments(*node->arguments(), arguments); | 2392 BuildPushArguments(*node->arguments(), arguments); |
2390 | 2393 |
2391 // Save context around the call. | 2394 // Save context around the call. |
2392 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); | 2395 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); |
2393 BuildSaveContext(*owner()->parsed_function()->saved_current_context_var()); | 2396 BuildSaveContext(*owner()->parsed_function()->saved_current_context_var()); |
2394 return new ClosureCallInstr(node, arguments); | 2397 closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2398 Value* context_val = Bind(new LoadFieldInstr(closure_val, |
| 2399 Closure::context_offset(), |
| 2400 AbstractType::ZoneHandle(), |
| 2401 true)); // Immutable. |
| 2402 AddInstruction(new StoreContextInstr(context_val)); |
| 2403 closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2404 Value* function_val = Bind(new LoadFieldInstr(closure_val, |
| 2405 Closure::function_offset(), |
| 2406 AbstractType::ZoneHandle(), |
| 2407 true)); // Immutable. |
| 2408 Definition* closure_call = |
| 2409 new ClosureCallInstr(function_val, node, arguments); |
| 2410 if (result_needed) { |
| 2411 Value* result = Bind(closure_call); |
| 2412 Do(new StoreLocalInstr(*tmp_var, result)); |
| 2413 // Restore context from temp. |
| 2414 BuildRestoreContext( |
| 2415 *owner()->parsed_function()->saved_current_context_var()); |
| 2416 ReturnDefinition(ExitTempLocalScope(tmp_var)); |
| 2417 } else { |
| 2418 Do(closure_call); |
| 2419 // Restore context from saved location. |
| 2420 BuildRestoreContext( |
| 2421 *owner()->parsed_function()->saved_current_context_var()); |
| 2422 Do(ExitTempLocalScope(tmp_var)); |
| 2423 } |
2395 } | 2424 } |
2396 | 2425 |
2397 | 2426 |
2398 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2427 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
2399 Do(BuildClosureCall(node)); | 2428 BuildClosureCall(node, false); |
2400 // Restore context from saved location. | |
2401 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); | |
2402 BuildRestoreContext(*owner()->parsed_function()->saved_current_context_var()); | |
2403 } | 2429 } |
2404 | 2430 |
2405 | 2431 |
2406 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2432 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
2407 Value* result = Bind(BuildClosureCall(node)); | 2433 BuildClosureCall(node, true); |
2408 // Restore context from temp. | |
2409 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); | |
2410 BuildRestoreContext(*owner()->parsed_function()->saved_current_context_var()); | |
2411 ReturnValue(result); | |
2412 } | 2434 } |
2413 | 2435 |
2414 | 2436 |
2415 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 2437 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
2416 Value* context = Bind(new CurrentContextInstr()); | 2438 Value* context = Bind(new CurrentContextInstr()); |
2417 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 2439 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); |
2418 AddInstruction(new StoreContextInstr(clone)); | 2440 AddInstruction(new StoreContextInstr(clone)); |
2419 } | 2441 } |
2420 | 2442 |
2421 | 2443 |
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3858 function.token_pos(), | 3880 function.token_pos(), |
3859 LanguageError::kError, | 3881 LanguageError::kError, |
3860 Heap::kNew, | 3882 Heap::kNew, |
3861 "FlowGraphBuilder Bailout: %s %s", | 3883 "FlowGraphBuilder Bailout: %s %s", |
3862 String::Handle(function.name()).ToCString(), | 3884 String::Handle(function.name()).ToCString(), |
3863 reason)); | 3885 reason)); |
3864 Isolate::Current()->long_jump_base()->Jump(1, error); | 3886 Isolate::Current()->long_jump_base()->Jump(1, error); |
3865 } | 3887 } |
3866 | 3888 |
3867 } // namespace dart | 3889 } // namespace dart |
OLD | NEW |