| 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 |