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/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 2756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2767 ReportError(Error::Handle(zone, mixin_super_type.error())); | 2767 ReportError(Error::Handle(zone, mixin_super_type.error())); |
2768 } | 2768 } |
2769 if (mixin_super_type.IsDynamicType()) { | 2769 if (mixin_super_type.IsDynamicType()) { |
2770 ReportError(cls, cls.token_pos(), "class '%s' may not extend 'dynamic'", | 2770 ReportError(cls, cls.token_pos(), "class '%s' may not extend 'dynamic'", |
2771 String::Handle(zone, cls.Name()).ToCString()); | 2771 String::Handle(zone, cls.Name()).ToCString()); |
2772 } | 2772 } |
2773 // The super type may have a BoundedType as type argument, but cannot be | 2773 // The super type may have a BoundedType as type argument, but cannot be |
2774 // a BoundedType itself. | 2774 // a BoundedType itself. |
2775 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | 2775 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
2776 AbstractType& mixin_type = AbstractType::Handle(zone); | 2776 AbstractType& mixin_type = AbstractType::Handle(zone); |
| 2777 Class& mixin_app_class = Class::Handle(zone); |
| 2778 Class& mixin_super_type_class = Class::Handle(zone); |
2777 Class& mixin_type_class = Class::Handle(zone); | 2779 Class& mixin_type_class = Class::Handle(zone); |
2778 Class& mixin_app_class = Class::Handle(zone); | 2780 Library& mixin_super_type_library = Library::Handle(zone); |
| 2781 Library& mixin_type_library = Library::Handle(zone); |
2779 String& mixin_app_class_name = String::Handle(zone); | 2782 String& mixin_app_class_name = String::Handle(zone); |
2780 String& mixin_type_class_name = String::Handle(zone); | 2783 String& mixin_type_class_name = String::Handle(zone); |
2781 AbstractType& super_type_arg = AbstractType::Handle(zone); | 2784 AbstractType& super_type_arg = AbstractType::Handle(zone); |
2782 AbstractType& mixin_type_arg = AbstractType::Handle(zone); | 2785 AbstractType& mixin_type_arg = AbstractType::Handle(zone); |
| 2786 Type& generic_mixin_type = Type::Handle(zone); |
| 2787 Array& interfaces = Array::Handle(zone); |
2783 const intptr_t depth = mixin_app_type.Depth(); | 2788 const intptr_t depth = mixin_app_type.Depth(); |
2784 for (intptr_t i = 0; i < depth; i++) { | 2789 for (intptr_t i = 0; i < depth; i++) { |
2785 mixin_type = mixin_app_type.MixinTypeAt(i); | 2790 mixin_type = mixin_app_type.MixinTypeAt(i); |
2786 ASSERT(!mixin_type.IsNull()); | 2791 ASSERT(!mixin_type.IsNull()); |
2787 ResolveType(cls, mixin_type); | 2792 ResolveType(cls, mixin_type); |
2788 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. | 2793 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
2789 ASSERT(mixin_type.IsType()); | 2794 ASSERT(mixin_type.IsType()); |
| 2795 if (mixin_type.IsMalformedOrMalbounded()) { |
| 2796 ReportError(Error::Handle(zone, mixin_type.error())); |
| 2797 } |
| 2798 if (mixin_type.IsDynamicType()) { |
| 2799 ReportError(cls, cls.token_pos(), "class '%s' may not mixin 'dynamic'", |
| 2800 String::Handle(zone, cls.Name()).ToCString()); |
| 2801 } |
2790 const intptr_t num_super_type_args = type_args.Length(); | 2802 const intptr_t num_super_type_args = type_args.Length(); |
2791 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); | 2803 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
2792 | 2804 |
2793 // If the mixin type has identical type arguments as the super type, they | 2805 // If the mixin type has identical type arguments as the super type, they |
2794 // can share the same type parameters of the mixin application class, | 2806 // can share the same type parameters of the mixin application class, |
2795 // thereby allowing for further optimizations, such as instantiator vector | 2807 // thereby allowing for further optimizations, such as instantiator vector |
2796 // reuse or sharing of type arguments with the super class. | 2808 // reuse or sharing of type arguments with the super class. |
2797 bool share_type_params = (num_super_type_args > 0) && | 2809 bool share_type_params = (num_super_type_args > 0) && |
2798 (type_args.Length() == 2 * num_super_type_args); | 2810 (type_args.Length() == 2 * num_super_type_args); |
2799 if (share_type_params) { | 2811 if (share_type_params) { |
2800 for (intptr_t i = 0; i < num_super_type_args; i++) { | 2812 for (intptr_t i = 0; i < num_super_type_args; i++) { |
2801 super_type_arg ^= type_args.At(i); | 2813 super_type_arg ^= type_args.At(i); |
2802 mixin_type_arg ^= type_args.At(num_super_type_args + i); | 2814 mixin_type_arg ^= type_args.At(num_super_type_args + i); |
2803 if (!super_type_arg.Equals(mixin_type_arg)) { | 2815 if (!super_type_arg.Equals(mixin_type_arg)) { |
2804 share_type_params = false; | 2816 share_type_params = false; |
2805 break; | 2817 break; |
2806 } | 2818 } |
2807 } | 2819 } |
2808 if (share_type_params) { | 2820 if (share_type_params) { |
2809 // Cut the type argument vector in half. | 2821 // Cut the type argument vector in half. |
2810 type_args.SetLength(num_super_type_args); | 2822 type_args.SetLength(num_super_type_args); |
2811 } | 2823 } |
2812 } | 2824 } |
2813 | 2825 |
2814 // The name of the mixin application class is a combination of | 2826 // The name of the mixin application class is a combination of |
2815 // the super class name and mixin class name. | 2827 // the super class name and mixin class name, as well as their respective |
| 2828 // library private keys if their library is different than the library of |
| 2829 // the mixin application class. |
| 2830 // Note that appending the library url would break naming conventions (e.g. |
| 2831 // no period in the class name). |
2816 mixin_app_class_name = mixin_super_type.ClassName(); | 2832 mixin_app_class_name = mixin_super_type.ClassName(); |
| 2833 mixin_super_type_class = mixin_super_type.type_class(); |
| 2834 mixin_super_type_library = mixin_super_type_class.library(); |
| 2835 if (mixin_super_type_library.raw() != library.raw()) { |
| 2836 mixin_app_class_name = String::Concat( |
| 2837 mixin_app_class_name, |
| 2838 String::Handle(zone, mixin_super_type_library.private_key())); |
| 2839 } |
2817 mixin_app_class_name = | 2840 mixin_app_class_name = |
2818 String::Concat(mixin_app_class_name, Symbols::Ampersand()); | 2841 String::Concat(mixin_app_class_name, Symbols::Ampersand()); |
2819 // If the type parameters are shared between the super type and the mixin | 2842 // If the type parameters are shared between the super type and the mixin |
2820 // type, use two ampersand symbols, so that the class has a different name | 2843 // type, use two ampersand symbols, so that the class has a different name |
2821 // and is not reused in a context where this optimization is not possible. | 2844 // and is not reused in a context where this optimization is not possible. |
2822 if (share_type_params) { | 2845 if (share_type_params) { |
2823 mixin_app_class_name = | 2846 mixin_app_class_name = |
2824 String::Concat(mixin_app_class_name, Symbols::Ampersand()); | 2847 String::Concat(mixin_app_class_name, Symbols::Ampersand()); |
2825 } | 2848 } |
2826 mixin_type_class_name = mixin_type.ClassName(); | 2849 mixin_type_class_name = mixin_type.ClassName(); |
| 2850 mixin_type_class = mixin_type.type_class(); |
| 2851 mixin_type_library = mixin_type_class.library(); |
| 2852 if (mixin_type_library.raw() != library.raw()) { |
| 2853 mixin_type_class_name = String::Concat( |
| 2854 mixin_type_class_name, |
| 2855 String::Handle(zone, mixin_type_library.private_key())); |
| 2856 } |
2827 mixin_app_class_name = | 2857 mixin_app_class_name = |
2828 String::Concat(mixin_app_class_name, mixin_type_class_name); | 2858 String::Concat(mixin_app_class_name, mixin_type_class_name); |
2829 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); | 2859 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); |
2830 if (mixin_app_class.IsNull()) { | 2860 if (mixin_app_class.IsNull()) { |
2831 mixin_app_class_name = Symbols::New(thread, mixin_app_class_name); | 2861 mixin_app_class_name = Symbols::New(thread, mixin_app_class_name); |
2832 mixin_app_class = Class::New(library, mixin_app_class_name, script, | 2862 mixin_app_class = Class::New(library, mixin_app_class_name, script, |
2833 mixin_type.token_pos()); | 2863 mixin_type.token_pos()); |
2834 mixin_app_class.set_super_type(mixin_super_type); | 2864 mixin_app_class.set_super_type(mixin_super_type); |
2835 mixin_type_class = mixin_type.type_class(); | 2865 generic_mixin_type = |
2836 const Type& generic_mixin_type = Type::Handle( | 2866 Type::New(mixin_type_class, Object::null_type_arguments(), |
2837 zone, Type::New(mixin_type_class, Object::null_type_arguments(), | 2867 mixin_type.token_pos()); |
2838 mixin_type.token_pos())); | |
2839 mixin_app_class.set_mixin(generic_mixin_type); | 2868 mixin_app_class.set_mixin(generic_mixin_type); |
2840 // Add the mixin type to the list of interfaces that the mixin application | 2869 // Add the mixin type to the list of interfaces that the mixin application |
2841 // class implements. This is necessary so that cycle check work at | 2870 // class implements. This is necessary so that cycle check work at |
2842 // compile time (type arguments are ignored by that check). | 2871 // compile time (type arguments are ignored by that check). |
2843 const Array& interfaces = Array::Handle(zone, Array::New(1)); | 2872 interfaces = Array::New(1); |
2844 interfaces.SetAt(0, generic_mixin_type); | 2873 interfaces.SetAt(0, generic_mixin_type); |
2845 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); | 2874 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
2846 mixin_app_class.set_interfaces(interfaces); | 2875 mixin_app_class.set_interfaces(interfaces); |
2847 mixin_app_class.set_is_synthesized_class(); | 2876 mixin_app_class.set_is_synthesized_class(); |
2848 library.AddClass(mixin_app_class); | 2877 library.AddClass(mixin_app_class); |
2849 | 2878 |
2850 // No need to add the new class to pending_classes, since it will be | 2879 // No need to add the new class to pending_classes, since it will be |
2851 // processed via the super_type chain of a pending class. | 2880 // processed via the super_type chain of a pending class. |
2852 | 2881 |
2853 if (FLAG_trace_class_finalization) { | 2882 if (FLAG_trace_class_finalization) { |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3321 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3350 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3322 field ^= fields_array.At(0); | 3351 field ^= fields_array.At(0); |
3323 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3352 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3324 name ^= field.name(); | 3353 name ^= field.name(); |
3325 expected_name ^= String::New("_data"); | 3354 expected_name ^= String::New("_data"); |
3326 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3355 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3327 #endif | 3356 #endif |
3328 } | 3357 } |
3329 | 3358 |
3330 } // namespace dart | 3359 } // namespace dart |
OLD | NEW |