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 |