| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 for (intptr_t i = 0; i < num_arguments; i++) { | 499 for (intptr_t i = 0; i < num_arguments; i++) { |
| 500 type_argument = arguments.TypeAt(i); | 500 type_argument = arguments.TypeAt(i); |
| 501 ResolveType(cls, type_argument, finalization); | 501 ResolveType(cls, type_argument, finalization); |
| 502 } | 502 } |
| 503 } | 503 } |
| 504 } | 504 } |
| 505 | 505 |
| 506 | 506 |
| 507 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { | 507 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { |
| 508 if (cls.IsMixinApplication()) { | 508 if (cls.IsMixinApplication()) { |
| 509 // Copy the type parameters to the mixin application. | 509 // Setup the type parameters of the mixin application and finalize the |
| 510 // mixin type. |
| 510 ApplyMixinType(cls); | 511 ApplyMixinType(cls); |
| 511 // Finalize the mixin type. | |
| 512 Type& mixin_type = Type::Handle(cls.mixin()); | |
| 513 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); | |
| 514 // TODO(regis): Check for a malbounded mixin_type. | |
| 515 cls.set_mixin(mixin_type); | |
| 516 } | 512 } |
| 517 // The type parameter bounds are not finalized here. | 513 // The type parameter bounds are not finalized here. |
| 518 const TypeArguments& type_parameters = | 514 const TypeArguments& type_parameters = |
| 519 TypeArguments::Handle(cls.type_parameters()); | 515 TypeArguments::Handle(cls.type_parameters()); |
| 520 if (!type_parameters.IsNull()) { | 516 if (!type_parameters.IsNull()) { |
| 521 TypeParameter& type_parameter = TypeParameter::Handle(); | 517 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 522 const intptr_t num_types = type_parameters.Length(); | 518 const intptr_t num_types = type_parameters.Length(); |
| 523 for (intptr_t i = 0; i < num_types; i++) { | 519 for (intptr_t i = 0; i < num_types; i++) { |
| 524 type_parameter ^= type_parameters.TypeAt(i); | 520 type_parameter ^= type_parameters.TypeAt(i); |
| 525 type_parameter ^= FinalizeType(cls, | 521 type_parameter ^= FinalizeType(cls, |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 const Class& parameterized_class = | 734 const Class& parameterized_class = |
| 739 Class::Handle(type_parameter.parameterized_class()); | 735 Class::Handle(type_parameter.parameterized_class()); |
| 740 ASSERT(!parameterized_class.IsNull()); | 736 ASSERT(!parameterized_class.IsNull()); |
| 741 // The index must reflect the position of this type parameter in the type | 737 // The index must reflect the position of this type parameter in the type |
| 742 // arguments vector of its parameterized class. The offset to add is the | 738 // arguments vector of its parameterized class. The offset to add is the |
| 743 // number of type arguments in the super type, which is equal to the | 739 // number of type arguments in the super type, which is equal to the |
| 744 // difference in number of type arguments and type parameters of the | 740 // difference in number of type arguments and type parameters of the |
| 745 // parameterized class. | 741 // parameterized class. |
| 746 const intptr_t offset = parameterized_class.NumTypeArguments() - | 742 const intptr_t offset = parameterized_class.NumTypeArguments() - |
| 747 parameterized_class.NumTypeParameters(); | 743 parameterized_class.NumTypeParameters(); |
| 748 type_parameter.set_index(type_parameter.index() + offset); | 744 // Calling NumTypeParameters() may finalize this type parameter if it |
| 749 type_parameter.set_is_finalized(); | 745 // belongs to a mixin application class. |
| 746 if (!type_parameter.IsFinalized()) { |
| 747 type_parameter.set_index(type_parameter.index() + offset); |
| 748 type_parameter.set_is_finalized(); |
| 749 } else { |
| 750 ASSERT(cls.IsMixinApplication()); |
| 751 } |
| 750 // We do not canonicalize type parameters. | 752 // We do not canonicalize type parameters. |
| 751 return type_parameter.raw(); | 753 return type_parameter.raw(); |
| 752 } | 754 } |
| 753 | 755 |
| 754 // At this point, we can only have a parameterized_type. | 756 // At this point, we can only have a parameterized_type. |
| 755 const Type& parameterized_type = Type::Cast(type); | 757 const Type& parameterized_type = Type::Cast(type); |
| 756 | 758 |
| 757 // Types illegally referring to themselves should have been detected earlier. | 759 // Types illegally referring to themselves should have been detected earlier. |
| 758 ASSERT(!parameterized_type.IsBeingFinalized()); | 760 ASSERT(!parameterized_type.IsBeingFinalized()); |
| 759 | 761 |
| (...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1677 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces); | 1679 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces); |
| 1678 | 1680 |
| 1679 if (FLAG_trace_class_finalization) { | 1681 if (FLAG_trace_class_finalization) { |
| 1680 OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n", | 1682 OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n", |
| 1681 String::Handle(mixin_type.Name()).ToCString(), | 1683 String::Handle(mixin_type.Name()).ToCString(), |
| 1682 String::Handle(mixin_app_class.Name()).ToCString(), | 1684 String::Handle(mixin_app_class.Name()).ToCString(), |
| 1683 TypeArguments::Handle( | 1685 TypeArguments::Handle( |
| 1684 mixin_app_class.type_parameters()).ToCString(), | 1686 mixin_app_class.type_parameters()).ToCString(), |
| 1685 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); | 1687 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); |
| 1686 } | 1688 } |
| 1689 // Mark the application class as having been applied its mixin type in order |
| 1690 // to avoid cycles while finalizing its mixin type. |
| 1687 mixin_app_class.set_is_mixin_type_applied(); | 1691 mixin_app_class.set_is_mixin_type_applied(); |
| 1692 // Finalize the mixin type, which may have been changed in case |
| 1693 // mixin_app_class is a typedef. |
| 1694 mixin_type = mixin_app_class.mixin(); |
| 1695 ASSERT(!mixin_type.IsBeingFinalized()); |
| 1696 mixin_type ^= |
| 1697 FinalizeType(mixin_app_class, mixin_type, kCanonicalizeWellFormed); |
| 1698 // TODO(regis): Check for a malbounded mixin_type. |
| 1699 mixin_app_class.set_mixin(mixin_type); |
| 1688 } | 1700 } |
| 1689 | 1701 |
| 1690 | 1702 |
| 1691 void ClassFinalizer::CreateForwardingConstructors( | 1703 void ClassFinalizer::CreateForwardingConstructors( |
| 1692 const Class& mixin_app, | 1704 const Class& mixin_app, |
| 1693 const GrowableObjectArray& cloned_funcs) { | 1705 const GrowableObjectArray& cloned_funcs) { |
| 1694 const String& mixin_name = String::Handle(mixin_app.Name()); | 1706 const String& mixin_name = String::Handle(mixin_app.Name()); |
| 1695 const Class& super_class = Class::Handle(mixin_app.SuperClass()); | 1707 const Class& super_class = Class::Handle(mixin_app.SuperClass()); |
| 1696 const String& super_name = String::Handle(super_class.Name()); | 1708 const String& super_name = String::Handle(super_class.Name()); |
| 1697 const Type& dynamic_type = Type::Handle(Type::DynamicType()); | 1709 const Type& dynamic_type = Type::Handle(Type::DynamicType()); |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2125 AbstractTypeArguments& type_args = | 2137 AbstractTypeArguments& type_args = |
| 2126 AbstractTypeArguments::Handle(type.arguments()); | 2138 AbstractTypeArguments::Handle(type.arguments()); |
| 2127 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 2139 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 2128 const intptr_t num_type_arguments = | 2140 const intptr_t num_type_arguments = |
| 2129 type_args.IsNull() ? 0 : type_args.Length(); | 2141 type_args.IsNull() ? 0 : type_args.Length(); |
| 2130 AbstractType& arg = AbstractType::Handle(); | 2142 AbstractType& arg = AbstractType::Handle(); |
| 2131 if (num_type_arguments > 0) { | 2143 if (num_type_arguments > 0) { |
| 2132 if (num_type_arguments == num_type_parameters) { | 2144 if (num_type_arguments == num_type_parameters) { |
| 2133 for (intptr_t i = 0; i < num_type_arguments; i++) { | 2145 for (intptr_t i = 0; i < num_type_arguments; i++) { |
| 2134 arg = type_args.TypeAt(i); | 2146 arg = type_args.TypeAt(i); |
| 2147 arg = arg.CloneUnfinalized(); |
| 2148 ASSERT(!arg.IsBeingFinalized()); |
| 2135 collected_args.Add(arg); | 2149 collected_args.Add(arg); |
| 2136 } | 2150 } |
| 2137 return; | 2151 return; |
| 2138 } | 2152 } |
| 2139 if (FLAG_error_on_bad_type) { | 2153 if (FLAG_error_on_bad_type) { |
| 2140 const Script& script = Script::Handle(cls.script()); | 2154 const Script& script = Script::Handle(cls.script()); |
| 2141 const String& type_class_name = String::Handle(type_class.Name()); | 2155 const String& type_class_name = String::Handle(type_class.Name()); |
| 2142 ReportError(Error::Handle(), // No previous error. | 2156 ReportError(Error::Handle(), // No previous error. |
| 2143 script, type.token_pos(), | 2157 script, type.token_pos(), |
| 2144 "wrong number of type arguments for class '%s'", | 2158 "wrong number of type arguments for class '%s'", |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2597 expected_name ^= String::New("_offset"); | 2611 expected_name ^= String::New("_offset"); |
| 2598 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2612 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2599 field ^= fields_array.At(2); | 2613 field ^= fields_array.At(2); |
| 2600 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2614 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2601 name ^= field.name(); | 2615 name ^= field.name(); |
| 2602 ASSERT(name.Equals("length")); | 2616 ASSERT(name.Equals("length")); |
| 2603 #endif | 2617 #endif |
| 2604 } | 2618 } |
| 2605 | 2619 |
| 2606 } // namespace dart | 2620 } // namespace dart |
| OLD | NEW |