| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1507 | 1507 |
| 1508 | 1508 |
| 1509 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1509 void EffectGraphVisitor::BuildTypecheckPushArguments( |
| 1510 intptr_t token_pos, | 1510 intptr_t token_pos, |
| 1511 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1511 PushArgumentInstr** push_instantiator_type_arguments_result) { |
| 1512 const Class& instantiator_class = Class::Handle( | 1512 const Class& instantiator_class = Class::Handle( |
| 1513 Z, owner()->function().Owner()); | 1513 Z, owner()->function().Owner()); |
| 1514 // Since called only when type tested against is not instantiated. | 1514 // Since called only when type tested against is not instantiated. |
| 1515 ASSERT(instantiator_class.IsGeneric()); | 1515 ASSERT(instantiator_class.IsGeneric()); |
| 1516 Value* instantiator_type_arguments = NULL; | 1516 Value* instantiator_type_arguments = NULL; |
| 1517 Value* instantiator = BuildInstantiator(token_pos, instantiator_class); | 1517 Value* instantiator = BuildInstantiator(token_pos); |
| 1518 if (instantiator == NULL) { | 1518 if (instantiator == NULL) { |
| 1519 // No instantiator when inside factory. | 1519 // No instantiator when inside factory. |
| 1520 instantiator_type_arguments = | 1520 instantiator_type_arguments = |
| 1521 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1521 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1522 } else { | 1522 } else { |
| 1523 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1523 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 1524 token_pos, instantiator_class, instantiator); | 1524 token_pos, instantiator_class, instantiator); |
| 1525 } | 1525 } |
| 1526 *push_instantiator_type_arguments_result = | 1526 *push_instantiator_type_arguments_result = |
| 1527 PushArgument(instantiator_type_arguments); | 1527 PushArgument(instantiator_type_arguments); |
| 1528 } | 1528 } |
| 1529 | 1529 |
| 1530 | 1530 |
| 1531 | 1531 |
| 1532 void EffectGraphVisitor::BuildTypecheckArguments( | 1532 void EffectGraphVisitor::BuildTypecheckArguments( |
| 1533 intptr_t token_pos, | 1533 intptr_t token_pos, |
| 1534 Value** instantiator_type_arguments_result) { | 1534 Value** instantiator_type_arguments_result) { |
| 1535 Value* instantiator = NULL; | 1535 Value* instantiator = NULL; |
| 1536 Value* instantiator_type_arguments = NULL; | 1536 Value* instantiator_type_arguments = NULL; |
| 1537 const Class& instantiator_class = Class::Handle( | 1537 const Class& instantiator_class = Class::Handle( |
| 1538 Z, owner()->function().Owner()); | 1538 Z, owner()->function().Owner()); |
| 1539 // Since called only when type tested against is not instantiated. | 1539 // Since called only when type tested against is not instantiated. |
| 1540 ASSERT(instantiator_class.IsGeneric()); | 1540 ASSERT(instantiator_class.IsGeneric()); |
| 1541 instantiator = BuildInstantiator(token_pos, instantiator_class); | 1541 instantiator = BuildInstantiator(token_pos); |
| 1542 if (instantiator == NULL) { | 1542 if (instantiator == NULL) { |
| 1543 // No instantiator when inside factory. | 1543 // No instantiator when inside factory. |
| 1544 instantiator_type_arguments = | 1544 instantiator_type_arguments = |
| 1545 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1545 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1546 } else { | 1546 } else { |
| 1547 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1547 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 1548 token_pos, instantiator_class, instantiator); | 1548 token_pos, instantiator_class, instantiator); |
| 1549 } | 1549 } |
| 1550 *instantiator_type_arguments_result = instantiator_type_arguments; | 1550 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 1551 } | 1551 } |
| (...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2535 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val, | 2535 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val, |
| 2536 node->token_pos()); | 2536 node->token_pos()); |
| 2537 // Store type arguments if scope class is generic. | 2537 // Store type arguments if scope class is generic. |
| 2538 const FunctionType& function_type = | 2538 const FunctionType& function_type = |
| 2539 FunctionType::ZoneHandle(Z, function.SignatureType()); | 2539 FunctionType::ZoneHandle(Z, function.SignatureType()); |
| 2540 const Class& scope_cls = Class::ZoneHandle(Z, function_type.scope_class()); | 2540 const Class& scope_cls = Class::ZoneHandle(Z, function_type.scope_class()); |
| 2541 if (scope_cls.IsGeneric()) { | 2541 if (scope_cls.IsGeneric()) { |
| 2542 ASSERT(function.Owner() == scope_cls.raw()); | 2542 ASSERT(function.Owner() == scope_cls.raw()); |
| 2543 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var, | 2543 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var, |
| 2544 node->token_pos())); | 2544 node->token_pos())); |
| 2545 const Class& instantiator_class = Class::Handle( |
| 2546 Z, owner()->function().Owner()); |
| 2545 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), | 2547 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| 2546 scope_cls, | 2548 instantiator_class, |
| 2547 NULL); | 2549 NULL); |
| 2548 Do(new(Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(), | 2550 Do(new(Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(), |
| 2549 closure_tmp_val, | 2551 closure_tmp_val, |
| 2550 type_arguments, | 2552 type_arguments, |
| 2551 kEmitStoreBarrier, | 2553 kEmitStoreBarrier, |
| 2552 node->token_pos())); | 2554 node->token_pos())); |
| 2553 } | 2555 } |
| 2554 | 2556 |
| 2555 // Store function. | 2557 // Store function. |
| 2556 Value* closure_tmp_val = | 2558 Value* closure_tmp_val = |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2909 // t_n+1 <- ctor-arg | 2911 // t_n+1 <- ctor-arg |
| 2910 // t_n+2... <- constructor arguments start here | 2912 // t_n+2... <- constructor arguments start here |
| 2911 // StaticCall(constructor, t_n+1, t_n+2, ...) | 2913 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 2912 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 2914 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 2913 Value* allocated_value = BuildObjectAllocation(node); | 2915 Value* allocated_value = BuildObjectAllocation(node); |
| 2914 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2916 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 2915 BuildConstructorCall(node, push_allocated_value); | 2917 BuildConstructorCall(node, push_allocated_value); |
| 2916 } | 2918 } |
| 2917 | 2919 |
| 2918 | 2920 |
| 2919 Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos, | 2921 Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos) { |
| 2920 const Class& instantiator_class) { | |
| 2921 ASSERT(instantiator_class.IsGeneric()); | |
| 2922 Function& outer_function = Function::Handle(Z, owner()->function().raw()); | 2922 Function& outer_function = Function::Handle(Z, owner()->function().raw()); |
| 2923 while (outer_function.IsLocalFunction()) { | 2923 while (outer_function.IsLocalFunction()) { |
| 2924 outer_function = outer_function.parent_function(); | 2924 outer_function = outer_function.parent_function(); |
| 2925 } | 2925 } |
| 2926 if (outer_function.IsFactory()) { | 2926 if (outer_function.IsFactory()) { |
| 2927 return NULL; | 2927 return NULL; |
| 2928 } | 2928 } |
| 2929 | 2929 |
| 2930 LocalVariable* instantiator = owner()->parsed_function().instantiator(); | 2930 LocalVariable* instantiator = owner()->parsed_function().instantiator(); |
| 2931 ASSERT(instantiator != NULL); | 2931 ASSERT(instantiator != NULL); |
| 2932 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); | 2932 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); |
| 2933 return result; | 2933 return result; |
| 2934 } | 2934 } |
| 2935 | 2935 |
| 2936 | 2936 |
| 2937 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 2937 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 2938 // is not NULL. | 2938 // is not NULL. |
| 2939 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2939 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 2940 intptr_t token_pos, | 2940 intptr_t token_pos, |
| 2941 const Class& instantiator_class, | 2941 const Class& instantiator_class, |
| 2942 Value* instantiator) { | 2942 Value* instantiator) { |
| 2943 if (instantiator_class.NumTypeParameters() == 0) { | 2943 if (!instantiator_class.IsGeneric()) { |
| 2944 // The type arguments are compile time constants. | 2944 // The type arguments are compile time constants. |
| 2945 TypeArguments& type_arguments = | 2945 TypeArguments& type_arguments = |
| 2946 TypeArguments::ZoneHandle(Z, TypeArguments::null()); | 2946 TypeArguments::ZoneHandle(Z, TypeArguments::null()); |
| 2947 // Type is temporary. Only its type arguments are preserved. | 2947 // Type is temporary. Only its type arguments are preserved. |
| 2948 Type& type = Type::Handle( | 2948 Type& type = Type::Handle( |
| 2949 Z, | 2949 Z, |
| 2950 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 2950 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 2951 type ^= ClassFinalizer::FinalizeType( | 2951 type ^= ClassFinalizer::FinalizeType( |
| 2952 instantiator_class, type, ClassFinalizer::kFinalize); | 2952 instantiator_class, type, ClassFinalizer::kFinalize); |
| 2953 ASSERT(!type.IsMalformedOrMalbounded()); | 2953 ASSERT(!type.IsMalformedOrMalbounded()); |
| 2954 type_arguments = type.arguments(); | 2954 type_arguments = type.arguments(); |
| 2955 type_arguments = type_arguments.Canonicalize(); | 2955 type_arguments = type_arguments.Canonicalize(); |
| 2956 return Bind(new(Z) ConstantInstr(type_arguments)); | 2956 return Bind(new(Z) ConstantInstr(type_arguments)); |
| 2957 } | 2957 } |
| 2958 Function& outer_function = Function::Handle(Z, owner()->function().raw()); | 2958 Function& outer_function = Function::Handle(Z, owner()->function().raw()); |
| 2959 while (outer_function.IsLocalFunction()) { | 2959 while (outer_function.IsLocalFunction()) { |
| 2960 outer_function = outer_function.parent_function(); | 2960 outer_function = outer_function.parent_function(); |
| 2961 } | 2961 } |
| 2962 if (outer_function.IsFactory()) { | 2962 if (outer_function.IsFactory()) { |
| 2963 // No instantiator for factories. | 2963 // No instantiator for factories. |
| 2964 ASSERT(instantiator == NULL); | 2964 ASSERT(instantiator == NULL); |
| 2965 LocalVariable* instantiator_var = | 2965 LocalVariable* instantiator_var = |
| 2966 owner()->parsed_function().instantiator(); | 2966 owner()->parsed_function().instantiator(); |
| 2967 ASSERT(instantiator_var != NULL); | 2967 ASSERT(instantiator_var != NULL); |
| 2968 return Bind(BuildLoadLocal(*instantiator_var, token_pos)); | 2968 return Bind(BuildLoadLocal(*instantiator_var, token_pos)); |
| 2969 } | 2969 } |
| 2970 if (instantiator == NULL) { | 2970 if (instantiator == NULL) { |
| 2971 instantiator = BuildInstantiator(token_pos, instantiator_class); | 2971 instantiator = BuildInstantiator(token_pos); |
| 2972 } | 2972 } |
| 2973 // The instantiator is the receiver of the caller, which is not a factory. | 2973 // The instantiator is the receiver of the caller, which is not a factory. |
| 2974 // The receiver cannot be null; extract its TypeArguments object. | 2974 // The receiver cannot be null; extract its TypeArguments object. |
| 2975 // Note that in the factory case, the instantiator is the first parameter | 2975 // Note that in the factory case, the instantiator is the first parameter |
| 2976 // of the factory, i.e. already a TypeArguments object. | 2976 // of the factory, i.e. already a TypeArguments object. |
| 2977 intptr_t type_arguments_field_offset = | 2977 intptr_t type_arguments_field_offset = |
| 2978 instantiator_class.type_arguments_field_offset(); | 2978 instantiator_class.type_arguments_field_offset(); |
| 2979 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); | 2979 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); |
| 2980 | 2980 |
| 2981 return Bind(new(Z) LoadFieldInstr( | 2981 return Bind(new(Z) LoadFieldInstr( |
| (...skipping 1684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4666 Script::Handle(function.script()), | 4666 Script::Handle(function.script()), |
| 4667 function.token_pos(), | 4667 function.token_pos(), |
| 4668 Report::AtLocation, | 4668 Report::AtLocation, |
| 4669 "FlowGraphBuilder Bailout: %s %s", | 4669 "FlowGraphBuilder Bailout: %s %s", |
| 4670 String::Handle(function.name()).ToCString(), | 4670 String::Handle(function.name()).ToCString(), |
| 4671 reason); | 4671 reason); |
| 4672 UNREACHABLE(); | 4672 UNREACHABLE(); |
| 4673 } | 4673 } |
| 4674 | 4674 |
| 4675 } // namespace dart | 4675 } // namespace dart |
| OLD | NEW |