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