| 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 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1702 // level. As a consequence, if this mixin application is used itself as a | 1702 // level. As a consequence, if this mixin application is used itself as a |
| 1703 // mixin in another mixin application, the bounds will be ignored, which | 1703 // mixin in another mixin application, the bounds will be ignored, which |
| 1704 // is correct, because the other mixin application does not inherit from | 1704 // is correct, because the other mixin application does not inherit from |
| 1705 // the super class of its mixin. Note also that the other mixin | 1705 // the super class of its mixin. Note also that the other mixin |
| 1706 // application will only mixin the last mixin type listed in the first | 1706 // application will only mixin the last mixin type listed in the first |
| 1707 // mixin application it is mixing in. | 1707 // mixin application it is mixing in. |
| 1708 param_bound = thread->isolate()->object_store()->object_type(); | 1708 param_bound = thread->isolate()->object_store()->object_type(); |
| 1709 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1709 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 1710 param ^= super_type_params.TypeAt(i); | 1710 param ^= super_type_params.TypeAt(i); |
| 1711 param_name = param.name(); | 1711 param_name = param.name(); |
| 1712 param_name = Symbols::FromConcat(param_name, Symbols::Backtick()); | 1712 param_name = Symbols::FromConcat(thread, |
| 1713 param_name, Symbols::Backtick()); |
| 1713 cloned_param = TypeParameter::New(mixin_app_class, | 1714 cloned_param = TypeParameter::New(mixin_app_class, |
| 1714 cloned_index, | 1715 cloned_index, |
| 1715 param_name, | 1716 param_name, |
| 1716 param_bound, | 1717 param_bound, |
| 1717 param.token_pos()); | 1718 param.token_pos()); |
| 1718 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1719 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1719 // Change the type arguments of the super type to refer to the | 1720 // Change the type arguments of the super type to refer to the |
| 1720 // cloned type parameters of the mixin application class. | 1721 // cloned type parameters of the mixin application class. |
| 1721 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1722 super_type_args.SetTypeAt(cloned_index, cloned_param); |
| 1722 cloned_index++; | 1723 cloned_index++; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1883 The instantiator vector consists of the cloned type parameters of M shifted by | 1884 The instantiator vector consists of the cloned type parameters of M shifted by |
| 1884 an offset corresponding to the finalized index of the first type parameter of M. | 1885 an offset corresponding to the finalized index of the first type parameter of M. |
| 1885 This is done in the recursive call to CloneMixinAppTypeParameters and does not | 1886 This is done in the recursive call to CloneMixinAppTypeParameters and does not |
| 1886 require specific code in ApplyMixinAppAlias. | 1887 require specific code in ApplyMixinAppAlias. |
| 1887 */ | 1888 */ |
| 1888 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class, | 1889 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class, |
| 1889 const TypeArguments& instantiator) { | 1890 const TypeArguments& instantiator) { |
| 1890 // If this mixin alias is aliasing another mixin alias, another class | 1891 // If this mixin alias is aliasing another mixin alias, another class |
| 1891 // will be inserted via recursion. No need to check here. | 1892 // will be inserted via recursion. No need to check here. |
| 1892 // The mixin type may or may not be finalized yet. | 1893 // The mixin type may or may not be finalized yet. |
| 1893 Zone* zone = Thread::Current()->zone(); | 1894 Thread* thread = Thread::Current(); |
| 1895 Zone* zone = thread->zone(); |
| 1894 AbstractType& super_type = AbstractType::Handle(zone, | 1896 AbstractType& super_type = AbstractType::Handle(zone, |
| 1895 mixin_app_class.super_type()); | 1897 mixin_app_class.super_type()); |
| 1896 const Type& mixin_type = Type::Handle(zone, mixin_app_class.mixin()); | 1898 const Type& mixin_type = Type::Handle(zone, mixin_app_class.mixin()); |
| 1897 const Class& mixin_class = Class::Handle(zone, mixin_type.type_class()); | 1899 const Class& mixin_class = Class::Handle(zone, mixin_type.type_class()); |
| 1898 ASSERT(mixin_class.is_mixin_app_alias()); | 1900 ASSERT(mixin_class.is_mixin_app_alias()); |
| 1899 const Class& aliased_mixin_app_class = Class::Handle(zone, | 1901 const Class& aliased_mixin_app_class = Class::Handle(zone, |
| 1900 mixin_class.SuperClass()); | 1902 mixin_class.SuperClass()); |
| 1901 // Note that the super class of aliased_mixin_app_class can itself be a | 1903 // Note that the super class of aliased_mixin_app_class can itself be a |
| 1902 // mixin application class (this happens if the alias is mixing more than one | 1904 // mixin application class (this happens if the alias is mixing more than one |
| 1903 // type). Instead of trying to recursively insert yet another class as the | 1905 // type). Instead of trying to recursively insert yet another class as the |
| 1904 // super class of this inserted class, we apply the composition rules of the | 1906 // super class of this inserted class, we apply the composition rules of the |
| 1905 // spec and only mixin the members of aliased_mixin_app_class, not those of | 1907 // spec and only mixin the members of aliased_mixin_app_class, not those of |
| 1906 // its super class. In other words, we only mixin the last mixin of the alias. | 1908 // its super class. In other words, we only mixin the last mixin of the alias. |
| 1907 const Type& aliased_mixin_type = Type::Handle(zone, | 1909 const Type& aliased_mixin_type = Type::Handle(zone, |
| 1908 aliased_mixin_app_class.mixin()); | 1910 aliased_mixin_app_class.mixin()); |
| 1909 // The name of the inserted mixin application class is the name of mixin | 1911 // The name of the inserted mixin application class is the name of mixin |
| 1910 // class name with a backtick added. | 1912 // class name with a backtick added. |
| 1911 String& inserted_class_name = String::Handle(zone, mixin_app_class.Name()); | 1913 String& inserted_class_name = String::Handle(zone, mixin_app_class.Name()); |
| 1912 inserted_class_name = String::Concat(inserted_class_name, | 1914 inserted_class_name = String::Concat(inserted_class_name, |
| 1913 Symbols::Backtick()); | 1915 Symbols::Backtick()); |
| 1914 const Library& library = Library::Handle(zone, mixin_app_class.library()); | 1916 const Library& library = Library::Handle(zone, mixin_app_class.library()); |
| 1915 Class& inserted_class = Class::Handle(zone, | 1917 Class& inserted_class = Class::Handle(zone, |
| 1916 library.LookupLocalClass(inserted_class_name)); | 1918 library.LookupLocalClass(inserted_class_name)); |
| 1917 if (inserted_class.IsNull()) { | 1919 if (inserted_class.IsNull()) { |
| 1918 inserted_class_name = Symbols::New(inserted_class_name); | 1920 inserted_class_name = Symbols::New(thread, inserted_class_name); |
| 1919 const Script& script = Script::Handle(zone, mixin_app_class.script()); | 1921 const Script& script = Script::Handle(zone, mixin_app_class.script()); |
| 1920 inserted_class = Class::New( | 1922 inserted_class = Class::New( |
| 1921 inserted_class_name, script, mixin_app_class.token_pos()); | 1923 inserted_class_name, script, mixin_app_class.token_pos()); |
| 1922 inserted_class.set_is_synthesized_class(); | 1924 inserted_class.set_is_synthesized_class(); |
| 1923 library.AddClass(inserted_class); | 1925 library.AddClass(inserted_class); |
| 1924 | 1926 |
| 1925 if (FLAG_trace_class_finalization) { | 1927 if (FLAG_trace_class_finalization) { |
| 1926 THR_Print("Creating mixin application alias %s\n", | 1928 THR_Print("Creating mixin application alias %s\n", |
| 1927 inserted_class.ToCString()); | 1929 inserted_class.ToCString()); |
| 1928 } | 1930 } |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2137 // class, but it does not instantiate them. | 2139 // class, but it does not instantiate them. |
| 2138 ASSERT(!mixin_type.IsMalbounded()); | 2140 ASSERT(!mixin_type.IsMalbounded()); |
| 2139 mixin_app_class.set_mixin(mixin_type); | 2141 mixin_app_class.set_mixin(mixin_type); |
| 2140 } | 2142 } |
| 2141 | 2143 |
| 2142 | 2144 |
| 2143 void ClassFinalizer::CreateForwardingConstructors( | 2145 void ClassFinalizer::CreateForwardingConstructors( |
| 2144 const Class& mixin_app, | 2146 const Class& mixin_app, |
| 2145 const Class& mixin_cls, | 2147 const Class& mixin_cls, |
| 2146 const GrowableObjectArray& cloned_funcs) { | 2148 const GrowableObjectArray& cloned_funcs) { |
| 2147 const String& mixin_name = String::Handle(mixin_app.Name()); | 2149 Thread* T = Thread::Current(); |
| 2148 const Class& super_class = Class::Handle(mixin_app.SuperClass()); | 2150 Zone* Z = T->zone(); |
| 2149 const String& super_name = String::Handle(super_class.Name()); | 2151 const String& mixin_name = String::Handle(Z, mixin_app.Name()); |
| 2150 const Array& functions = Array::Handle(super_class.functions()); | 2152 const Class& super_class = Class::Handle(Z, mixin_app.SuperClass()); |
| 2153 const String& super_name = String::Handle(Z, super_class.Name()); |
| 2154 const Array& functions = Array::Handle(Z, super_class.functions()); |
| 2151 const intptr_t num_functions = functions.Length(); | 2155 const intptr_t num_functions = functions.Length(); |
| 2152 Function& func = Function::Handle(); | 2156 Function& func = Function::Handle(Z); |
| 2153 for (intptr_t i = 0; i < num_functions; i++) { | 2157 for (intptr_t i = 0; i < num_functions; i++) { |
| 2154 func ^= functions.At(i); | 2158 func ^= functions.At(i); |
| 2155 if (func.IsGenerativeConstructor()) { | 2159 if (func.IsGenerativeConstructor()) { |
| 2156 // Build constructor name from mixin application class name | 2160 // Build constructor name from mixin application class name |
| 2157 // and name of cloned super class constructor. | 2161 // and name of cloned super class constructor. |
| 2158 const String& ctor_name = String::Handle(func.name()); | 2162 const String& ctor_name = String::Handle(Z, func.name()); |
| 2159 String& clone_name = String::Handle( | 2163 String& clone_name = String::Handle(Z, |
| 2160 String::SubString(ctor_name, super_name.Length())); | 2164 String::SubString(ctor_name, super_name.Length())); |
| 2161 clone_name = Symbols::FromConcat(mixin_name, clone_name); | 2165 clone_name = Symbols::FromConcat(T, mixin_name, clone_name); |
| 2162 | 2166 |
| 2163 if (FLAG_trace_class_finalization) { | 2167 if (FLAG_trace_class_finalization) { |
| 2164 THR_Print("Cloning constructor '%s' as '%s'\n", | 2168 THR_Print("Cloning constructor '%s' as '%s'\n", |
| 2165 ctor_name.ToCString(), | 2169 ctor_name.ToCString(), |
| 2166 clone_name.ToCString()); | 2170 clone_name.ToCString()); |
| 2167 } | 2171 } |
| 2168 | 2172 |
| 2169 // The owner of the forwarding constructor is the mixin application | 2173 // The owner of the forwarding constructor is the mixin application |
| 2170 // class. The source is the mixin class. The source may be needed | 2174 // class. The source is the mixin class. The source may be needed |
| 2171 // to parse field initializer expressions in the mixin class. | 2175 // to parse field initializer expressions in the mixin class. |
| 2172 const PatchClass& owner = | 2176 const PatchClass& owner = |
| 2173 PatchClass::Handle(PatchClass::New(mixin_app, mixin_cls)); | 2177 PatchClass::Handle(Z, PatchClass::New(mixin_app, mixin_cls)); |
| 2174 | 2178 |
| 2175 const Function& clone = Function::Handle( | 2179 const Function& clone = Function::Handle(Z, |
| 2176 Function::New(clone_name, | 2180 Function::New(clone_name, |
| 2177 func.kind(), | 2181 func.kind(), |
| 2178 func.is_static(), | 2182 func.is_static(), |
| 2179 false, // Not const. | 2183 false, // Not const. |
| 2180 false, // Not abstract. | 2184 false, // Not abstract. |
| 2181 false, // Not external. | 2185 false, // Not external. |
| 2182 false, // Not native. | 2186 false, // Not native. |
| 2183 owner, | 2187 owner, |
| 2184 mixin_cls.token_pos())); | 2188 mixin_cls.token_pos())); |
| 2185 clone.set_num_fixed_parameters(func.num_fixed_parameters()); | 2189 clone.set_num_fixed_parameters(func.num_fixed_parameters()); |
| 2186 clone.SetNumOptionalParameters(func.NumOptionalParameters(), | 2190 clone.SetNumOptionalParameters(func.NumOptionalParameters(), |
| 2187 func.HasOptionalPositionalParameters()); | 2191 func.HasOptionalPositionalParameters()); |
| 2188 clone.set_result_type(Object::dynamic_type()); | 2192 clone.set_result_type(Object::dynamic_type()); |
| 2189 clone.set_is_debuggable(false); | 2193 clone.set_is_debuggable(false); |
| 2190 | 2194 |
| 2191 const intptr_t num_parameters = func.NumParameters(); | 2195 const intptr_t num_parameters = func.NumParameters(); |
| 2192 // The cloned ctor shares the parameter names array with the | 2196 // The cloned ctor shares the parameter names array with the |
| 2193 // original. | 2197 // original. |
| 2194 const Array& parameter_names = Array::Handle(func.parameter_names()); | 2198 const Array& parameter_names = Array::Handle(Z, func.parameter_names()); |
| 2195 ASSERT(parameter_names.Length() == num_parameters); | 2199 ASSERT(parameter_names.Length() == num_parameters); |
| 2196 clone.set_parameter_names(parameter_names); | 2200 clone.set_parameter_names(parameter_names); |
| 2197 // The parameter types of the cloned constructor are 'dynamic'. | 2201 // The parameter types of the cloned constructor are 'dynamic'. |
| 2198 clone.set_parameter_types(Array::Handle(Array::New(num_parameters))); | 2202 clone.set_parameter_types(Array::Handle(Z, Array::New(num_parameters))); |
| 2199 for (intptr_t n = 0; n < num_parameters; n++) { | 2203 for (intptr_t n = 0; n < num_parameters; n++) { |
| 2200 clone.SetParameterTypeAt(n, Object::dynamic_type()); | 2204 clone.SetParameterTypeAt(n, Object::dynamic_type()); |
| 2201 } | 2205 } |
| 2202 cloned_funcs.Add(clone); | 2206 cloned_funcs.Add(clone); |
| 2203 } | 2207 } |
| 2204 } | 2208 } |
| 2205 } | 2209 } |
| 2206 | 2210 |
| 2207 | 2211 |
| 2208 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { | 2212 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2719 collected_args.Add(arg); | 2723 collected_args.Add(arg); |
| 2720 } | 2724 } |
| 2721 } | 2725 } |
| 2722 | 2726 |
| 2723 | 2727 |
| 2724 RawType* ClassFinalizer::ResolveMixinAppType( | 2728 RawType* ClassFinalizer::ResolveMixinAppType( |
| 2725 const Class& cls, | 2729 const Class& cls, |
| 2726 const MixinAppType& mixin_app_type) { | 2730 const MixinAppType& mixin_app_type) { |
| 2727 // Lookup or create mixin application classes in the library of cls | 2731 // Lookup or create mixin application classes in the library of cls |
| 2728 // and resolve super type and mixin types. | 2732 // and resolve super type and mixin types. |
| 2729 Zone* zone = Thread::Current()->zone(); | 2733 Thread* thread = Thread::Current(); |
| 2734 Zone* zone = thread->zone(); |
| 2730 const Library& library = Library::Handle(zone, cls.library()); | 2735 const Library& library = Library::Handle(zone, cls.library()); |
| 2731 ASSERT(!library.IsNull()); | 2736 ASSERT(!library.IsNull()); |
| 2732 const Script& script = Script::Handle(zone, cls.script()); | 2737 const Script& script = Script::Handle(zone, cls.script()); |
| 2733 ASSERT(!script.IsNull()); | 2738 ASSERT(!script.IsNull()); |
| 2734 const GrowableObjectArray& type_args = | 2739 const GrowableObjectArray& type_args = |
| 2735 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 2740 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
| 2736 AbstractType& mixin_super_type = | 2741 AbstractType& mixin_super_type = |
| 2737 AbstractType::Handle(zone, mixin_app_type.super_type()); | 2742 AbstractType::Handle(zone, mixin_app_type.super_type()); |
| 2738 ResolveType(cls, mixin_super_type); | 2743 ResolveType(cls, mixin_super_type); |
| 2739 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. | 2744 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2796 // and is not reused in a context where this optimization is not possible. | 2801 // and is not reused in a context where this optimization is not possible. |
| 2797 if (share_type_params) { | 2802 if (share_type_params) { |
| 2798 mixin_app_class_name = String::Concat(mixin_app_class_name, | 2803 mixin_app_class_name = String::Concat(mixin_app_class_name, |
| 2799 Symbols::Ampersand()); | 2804 Symbols::Ampersand()); |
| 2800 } | 2805 } |
| 2801 mixin_type_class_name = mixin_type.ClassName(); | 2806 mixin_type_class_name = mixin_type.ClassName(); |
| 2802 mixin_app_class_name = String::Concat(mixin_app_class_name, | 2807 mixin_app_class_name = String::Concat(mixin_app_class_name, |
| 2803 mixin_type_class_name); | 2808 mixin_type_class_name); |
| 2804 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); | 2809 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); |
| 2805 if (mixin_app_class.IsNull()) { | 2810 if (mixin_app_class.IsNull()) { |
| 2806 mixin_app_class_name = Symbols::New(mixin_app_class_name); | 2811 mixin_app_class_name = Symbols::New(thread, mixin_app_class_name); |
| 2807 mixin_app_class = Class::New(mixin_app_class_name, | 2812 mixin_app_class = Class::New(mixin_app_class_name, |
| 2808 script, | 2813 script, |
| 2809 mixin_type.token_pos()); | 2814 mixin_type.token_pos()); |
| 2810 mixin_app_class.set_super_type(mixin_super_type); | 2815 mixin_app_class.set_super_type(mixin_super_type); |
| 2811 mixin_type_class = mixin_type.type_class(); | 2816 mixin_type_class = mixin_type.type_class(); |
| 2812 const Type& generic_mixin_type = Type::Handle(zone, | 2817 const Type& generic_mixin_type = Type::Handle(zone, |
| 2813 Type::New(mixin_type_class, | 2818 Type::New(mixin_type_class, |
| 2814 Object::null_type_arguments(), | 2819 Object::null_type_arguments(), |
| 2815 mixin_type.token_pos())); | 2820 mixin_type.token_pos())); |
| 2816 mixin_app_class.set_mixin(generic_mixin_type); | 2821 mixin_app_class.set_mixin(generic_mixin_type); |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3310 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3315 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3311 field ^= fields_array.At(0); | 3316 field ^= fields_array.At(0); |
| 3312 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3317 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3313 name ^= field.name(); | 3318 name ^= field.name(); |
| 3314 expected_name ^= String::New("_data"); | 3319 expected_name ^= String::New("_data"); |
| 3315 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3320 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3316 #endif | 3321 #endif |
| 3317 } | 3322 } |
| 3318 | 3323 |
| 3319 } // namespace dart | 3324 } // namespace dart |
| OLD | NEW |