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 2151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2162 if (num_temps > 0) { | 2162 if (num_temps > 0) { |
2163 owner()->DeallocateTemps(num_temps); | 2163 owner()->DeallocateTemps(num_temps); |
2164 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); | 2164 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); |
2165 } else { | 2165 } else { |
2166 ReturnValue(result_value); | 2166 ReturnValue(result_value); |
2167 } | 2167 } |
2168 } | 2168 } |
2169 | 2169 |
2170 | 2170 |
2171 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 2171 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
2172 const AbstractTypeArguments& type_args = | 2172 const TypeArguments& type_args = |
2173 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 2173 TypeArguments::ZoneHandle(node->type().arguments()); |
2174 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 2174 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
2175 type_args); | 2175 type_args); |
2176 Value* num_elements = | 2176 Value* num_elements = |
2177 Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(node->length())))); | 2177 Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(node->length())))); |
2178 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 2178 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
2179 element_type, | 2179 element_type, |
2180 num_elements); | 2180 num_elements); |
2181 Value* array_val = Bind(create); | 2181 Value* array_val = Bind(create); |
2182 | 2182 |
2183 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); | 2183 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2482 } | 2482 } |
2483 | 2483 |
2484 | 2484 |
2485 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 2485 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
2486 Value* context = Bind(new CurrentContextInstr()); | 2486 Value* context = Bind(new CurrentContextInstr()); |
2487 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 2487 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); |
2488 AddInstruction(new StoreContextInstr(clone)); | 2488 AddInstruction(new StoreContextInstr(clone)); |
2489 } | 2489 } |
2490 | 2490 |
2491 | 2491 |
2492 Value* EffectGraphVisitor::BuildObjectAllocation( | 2492 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { |
2493 ConstructorCallNode* node) { | |
2494 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 2493 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
2495 const bool requires_type_arguments = cls.NumTypeArguments() > 0; | 2494 const bool requires_type_arguments = cls.NumTypeArguments() > 0; |
2496 | 2495 |
2497 // In checked mode, if the type arguments are uninstantiated, they may need to | 2496 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
2498 // be checked against declared bounds at run time. | 2497 new ZoneGrowableArray<PushArgumentInstr*>(); |
2499 Definition* allocation = NULL; | 2498 if (requires_type_arguments) { |
2500 if (FLAG_enable_type_checks && | |
2501 requires_type_arguments && | |
2502 !node->type_arguments().IsNull() && | |
2503 !node->type_arguments().IsInstantiated() && | |
2504 node->type_arguments().IsBounded()) { | |
2505 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | |
2506 new ZoneGrowableArray<PushArgumentInstr*>(4); | |
2507 // Argument 1: Empty argument slot for return value. | |
2508 Value* null_val = Bind(new ConstantInstr(Object::ZoneHandle())); | |
2509 allocate_arguments->Add(PushArgument(null_val)); | |
2510 // Argument 2: Class. | |
2511 Value* cls_val = | |
2512 Bind(new ConstantInstr(Class::ZoneHandle(node->constructor().Owner()))); | |
2513 allocate_arguments->Add(PushArgument(cls_val)); | |
2514 // Build arguments 3 and 4. | |
2515 BuildConstructorTypeArguments(node, allocate_arguments); | 2499 BuildConstructorTypeArguments(node, allocate_arguments); |
| 2500 } |
2516 | 2501 |
2517 // The uninstantiated type arguments cannot be verified to be within their | 2502 Definition* allocation = new AllocateObjectInstr( |
2518 // bounds at compile time, so verify them at runtime. | 2503 node->token_pos(), |
2519 allocation = new AllocateObjectWithBoundsCheckInstr(node); | 2504 Class::ZoneHandle(node->constructor().Owner()), |
2520 } else { | 2505 allocate_arguments); |
2521 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | |
2522 new ZoneGrowableArray<PushArgumentInstr*>(); | |
2523 if (requires_type_arguments) { | |
2524 BuildConstructorTypeArguments(node, allocate_arguments); | |
2525 } | |
2526 | 2506 |
2527 allocation = new AllocateObjectInstr( | |
2528 node->token_pos(), | |
2529 Class::ZoneHandle(node->constructor().Owner()), | |
2530 allocate_arguments); | |
2531 } | |
2532 return Bind(allocation); | 2507 return Bind(allocation); |
2533 } | 2508 } |
2534 | 2509 |
2535 | 2510 |
2536 void EffectGraphVisitor::BuildConstructorCall( | 2511 void EffectGraphVisitor::BuildConstructorCall( |
2537 ConstructorCallNode* node, | 2512 ConstructorCallNode* node, |
2538 PushArgumentInstr* push_alloc_value) { | 2513 PushArgumentInstr* push_alloc_value) { |
2539 Value* ctor_arg = Bind( | 2514 Value* ctor_arg = Bind( |
2540 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 2515 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
2541 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 2516 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2642 | 2617 |
2643 | 2618 |
2644 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 2619 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
2645 // is not NULL. | 2620 // is not NULL. |
2646 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2621 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
2647 intptr_t token_pos, | 2622 intptr_t token_pos, |
2648 const Class& instantiator_class, | 2623 const Class& instantiator_class, |
2649 Value* instantiator) { | 2624 Value* instantiator) { |
2650 if (instantiator_class.NumTypeParameters() == 0) { | 2625 if (instantiator_class.NumTypeParameters() == 0) { |
2651 // The type arguments are compile time constants. | 2626 // The type arguments are compile time constants. |
2652 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 2627 TypeArguments& type_arguments = TypeArguments::ZoneHandle(); |
2653 // Type is temporary. Only its type arguments are preserved. | 2628 // Type is temporary. Only its type arguments are preserved. |
2654 Type& type = Type::Handle( | 2629 Type& type = Type::Handle( |
2655 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 2630 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
2656 type ^= ClassFinalizer::FinalizeType( | 2631 type ^= ClassFinalizer::FinalizeType( |
2657 instantiator_class, type, ClassFinalizer::kFinalize); | 2632 instantiator_class, type, ClassFinalizer::kFinalize); |
2658 ASSERT(!type.IsMalformedOrMalbounded()); | 2633 ASSERT(!type.IsMalformedOrMalbounded()); |
2659 type_arguments = type.arguments(); | 2634 type_arguments = type.arguments(); |
2660 type_arguments = type_arguments.Canonicalize(); | 2635 type_arguments = type_arguments.Canonicalize(); |
2661 return Bind(new ConstantInstr(type_arguments)); | 2636 return Bind(new ConstantInstr(type_arguments)); |
2662 } | 2637 } |
2663 Function& outer_function = | 2638 Function& outer_function = |
2664 Function::Handle(owner()->parsed_function()->function().raw()); | 2639 Function::Handle(owner()->parsed_function()->function().raw()); |
2665 while (outer_function.IsLocalFunction()) { | 2640 while (outer_function.IsLocalFunction()) { |
2666 outer_function = outer_function.parent_function(); | 2641 outer_function = outer_function.parent_function(); |
2667 } | 2642 } |
2668 if (outer_function.IsFactory()) { | 2643 if (outer_function.IsFactory()) { |
2669 // No instantiator for factories. | 2644 // No instantiator for factories. |
2670 ASSERT(instantiator == NULL); | 2645 ASSERT(instantiator == NULL); |
2671 ASSERT(owner()->parsed_function()->instantiator() != NULL); | 2646 ASSERT(owner()->parsed_function()->instantiator() != NULL); |
2672 ValueGraphVisitor for_instantiator(owner()); | 2647 ValueGraphVisitor for_instantiator(owner()); |
2673 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); | 2648 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); |
2674 Append(for_instantiator); | 2649 Append(for_instantiator); |
2675 return for_instantiator.value(); | 2650 return for_instantiator.value(); |
2676 } | 2651 } |
2677 if (instantiator == NULL) { | 2652 if (instantiator == NULL) { |
2678 instantiator = BuildInstantiator(); | 2653 instantiator = BuildInstantiator(); |
2679 } | 2654 } |
2680 // The instantiator is the receiver of the caller, which is not a factory. | 2655 // The instantiator is the receiver of the caller, which is not a factory. |
2681 // The receiver cannot be null; extract its AbstractTypeArguments object. | 2656 // The receiver cannot be null; extract its TypeArguments object. |
2682 // Note that in the factory case, the instantiator is the first parameter | 2657 // Note that in the factory case, the instantiator is the first parameter |
2683 // of the factory, i.e. already an AbstractTypeArguments object. | 2658 // of the factory, i.e. already a TypeArguments object. |
2684 intptr_t type_arguments_field_offset = | 2659 intptr_t type_arguments_field_offset = |
2685 instantiator_class.type_arguments_field_offset(); | 2660 instantiator_class.type_arguments_field_offset(); |
2686 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); | 2661 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); |
2687 | 2662 |
2688 return Bind(new LoadFieldInstr( | 2663 return Bind(new LoadFieldInstr( |
2689 instantiator, | 2664 instantiator, |
2690 type_arguments_field_offset, | 2665 type_arguments_field_offset, |
2691 Type::ZoneHandle())); // Not an instance, no type. | 2666 Type::ZoneHandle())); // Not an instance, no type. |
2692 } | 2667 } |
2693 | 2668 |
2694 | 2669 |
2695 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 2670 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
2696 intptr_t token_pos, | 2671 intptr_t token_pos, |
2697 const AbstractTypeArguments& type_arguments) { | 2672 const TypeArguments& type_arguments) { |
2698 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 2673 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
2699 return Bind(new ConstantInstr(type_arguments)); | 2674 return Bind(new ConstantInstr(type_arguments)); |
2700 } | 2675 } |
2701 // The type arguments are uninstantiated. | 2676 // The type arguments are uninstantiated. |
2702 const Class& instantiator_class = Class::ZoneHandle( | 2677 const Class& instantiator_class = Class::ZoneHandle( |
2703 owner()->parsed_function()->function().Owner()); | 2678 owner()->parsed_function()->function().Owner()); |
2704 Value* instantiator_value = | 2679 Value* instantiator_value = |
2705 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 2680 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
2706 const bool use_instantiator_type_args = | 2681 const bool use_instantiator_type_args = |
2707 type_arguments.IsUninstantiatedIdentity() || | 2682 type_arguments.IsUninstantiatedIdentity() || |
(...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4030 LanguageError::kError, | 4005 LanguageError::kError, |
4031 Heap::kNew, | 4006 Heap::kNew, |
4032 "FlowGraphBuilder Bailout: %s %s", | 4007 "FlowGraphBuilder Bailout: %s %s", |
4033 String::Handle(function.name()).ToCString(), | 4008 String::Handle(function.name()).ToCString(), |
4034 reason)); | 4009 reason)); |
4035 Isolate::Current()->long_jump_base()->Jump(1, error); | 4010 Isolate::Current()->long_jump_base()->Jump(1, error); |
4036 } | 4011 } |
4037 | 4012 |
4038 | 4013 |
4039 } // namespace dart | 4014 } // namespace dart |
OLD | NEW |