| 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 2051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2062 // The mixin type cannot be malbounded, since it merely substitutes the | 2062 // The mixin type cannot be malbounded, since it merely substitutes the |
| 2063 // type parameters of the mixin class with those of the mixin application | 2063 // type parameters of the mixin class with those of the mixin application |
| 2064 // class, but it does not instantiate them. | 2064 // class, but it does not instantiate them. |
| 2065 ASSERT(!mixin_type.IsMalbounded()); | 2065 ASSERT(!mixin_type.IsMalbounded()); |
| 2066 mixin_app_class.set_mixin(mixin_type); | 2066 mixin_app_class.set_mixin(mixin_type); |
| 2067 } | 2067 } |
| 2068 | 2068 |
| 2069 | 2069 |
| 2070 void ClassFinalizer::CreateForwardingConstructors( | 2070 void ClassFinalizer::CreateForwardingConstructors( |
| 2071 const Class& mixin_app, | 2071 const Class& mixin_app, |
| 2072 const Class& mixin_cls, |
| 2072 const GrowableObjectArray& cloned_funcs) { | 2073 const GrowableObjectArray& cloned_funcs) { |
| 2073 const String& mixin_name = String::Handle(mixin_app.Name()); | 2074 const String& mixin_name = String::Handle(mixin_app.Name()); |
| 2074 const Class& super_class = Class::Handle(mixin_app.SuperClass()); | 2075 const Class& super_class = Class::Handle(mixin_app.SuperClass()); |
| 2075 const String& super_name = String::Handle(super_class.Name()); | 2076 const String& super_name = String::Handle(super_class.Name()); |
| 2076 const Array& functions = Array::Handle(super_class.functions()); | 2077 const Array& functions = Array::Handle(super_class.functions()); |
| 2077 const intptr_t num_functions = functions.Length(); | 2078 const intptr_t num_functions = functions.Length(); |
| 2078 Function& func = Function::Handle(); | 2079 Function& func = Function::Handle(); |
| 2079 for (intptr_t i = 0; i < num_functions; i++) { | 2080 for (intptr_t i = 0; i < num_functions; i++) { |
| 2080 func ^= functions.At(i); | 2081 func ^= functions.At(i); |
| 2081 if (func.IsGenerativeConstructor()) { | 2082 if (func.IsGenerativeConstructor()) { |
| 2082 // Build constructor name from mixin application class name | 2083 // Build constructor name from mixin application class name |
| 2083 // and name of cloned super class constructor. | 2084 // and name of cloned super class constructor. |
| 2084 const String& ctor_name = String::Handle(func.name()); | 2085 const String& ctor_name = String::Handle(func.name()); |
| 2085 String& clone_name = String::Handle( | 2086 String& clone_name = String::Handle( |
| 2086 String::SubString(ctor_name, super_name.Length())); | 2087 String::SubString(ctor_name, super_name.Length())); |
| 2087 clone_name = Symbols::FromConcat(mixin_name, clone_name); | 2088 clone_name = Symbols::FromConcat(mixin_name, clone_name); |
| 2088 | 2089 |
| 2089 if (FLAG_trace_class_finalization) { | 2090 if (FLAG_trace_class_finalization) { |
| 2090 THR_Print("Cloning constructor '%s' as '%s'\n", | 2091 THR_Print("Cloning constructor '%s' as '%s'\n", |
| 2091 ctor_name.ToCString(), | 2092 ctor_name.ToCString(), |
| 2092 clone_name.ToCString()); | 2093 clone_name.ToCString()); |
| 2093 } | 2094 } |
| 2095 |
| 2096 // The owner of the forwarding constructor is the mixin application |
| 2097 // class. The source is the mixin class. The source may be needed |
| 2098 // to parse field initializer expressions in the mixin class. |
| 2099 const PatchClass& owner = |
| 2100 PatchClass::Handle(PatchClass::New(mixin_app, mixin_cls)); |
| 2101 |
| 2094 const Function& clone = Function::Handle( | 2102 const Function& clone = Function::Handle( |
| 2095 Function::New(clone_name, | 2103 Function::New(clone_name, |
| 2096 func.kind(), | 2104 func.kind(), |
| 2097 func.is_static(), | 2105 func.is_static(), |
| 2098 false, // Not const. | 2106 false, // Not const. |
| 2099 false, // Not abstract. | 2107 false, // Not abstract. |
| 2100 false, // Not external. | 2108 false, // Not external. |
| 2101 false, // Not native. | 2109 false, // Not native. |
| 2102 mixin_app, | 2110 owner, |
| 2103 mixin_app.token_pos())); | 2111 mixin_cls.token_pos())); |
| 2104 | |
| 2105 clone.set_num_fixed_parameters(func.num_fixed_parameters()); | 2112 clone.set_num_fixed_parameters(func.num_fixed_parameters()); |
| 2106 clone.SetNumOptionalParameters(func.NumOptionalParameters(), | 2113 clone.SetNumOptionalParameters(func.NumOptionalParameters(), |
| 2107 func.HasOptionalPositionalParameters()); | 2114 func.HasOptionalPositionalParameters()); |
| 2108 clone.set_result_type(Object::dynamic_type()); | 2115 clone.set_result_type(Object::dynamic_type()); |
| 2109 clone.set_is_debuggable(false); | 2116 clone.set_is_debuggable(false); |
| 2110 | 2117 |
| 2111 const intptr_t num_parameters = func.NumParameters(); | 2118 const intptr_t num_parameters = func.NumParameters(); |
| 2112 // The cloned ctor shares the parameter names array with the | 2119 // The cloned ctor shares the parameter names array with the |
| 2113 // original. | 2120 // original. |
| 2114 const Array& parameter_names = Array::Handle(func.parameter_names()); | 2121 const Array& parameter_names = Array::Handle(func.parameter_names()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2144 if (FLAG_trace_class_finalization) { | 2151 if (FLAG_trace_class_finalization) { |
| 2145 THR_Print("Applying mixin members of %s to %s at pos %" Pd "\n", | 2152 THR_Print("Applying mixin members of %s to %s at pos %" Pd "\n", |
| 2146 mixin_cls.ToCString(), | 2153 mixin_cls.ToCString(), |
| 2147 cls.ToCString(), | 2154 cls.ToCString(), |
| 2148 cls.token_pos()); | 2155 cls.token_pos()); |
| 2149 } | 2156 } |
| 2150 | 2157 |
| 2151 const GrowableObjectArray& cloned_funcs = | 2158 const GrowableObjectArray& cloned_funcs = |
| 2152 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 2159 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
| 2153 | 2160 |
| 2154 CreateForwardingConstructors(cls, cloned_funcs); | 2161 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); |
| 2155 | 2162 |
| 2156 Array& functions = Array::Handle(zone); | 2163 Array& functions = Array::Handle(zone); |
| 2157 Function& func = Function::Handle(zone); | 2164 Function& func = Function::Handle(zone); |
| 2158 // The parser creates the mixin application class with no functions. | 2165 // The parser creates the mixin application class with no functions. |
| 2159 ASSERT((functions = cls.functions(), functions.Length() == 0)); | 2166 ASSERT((functions = cls.functions(), functions.Length() == 0)); |
| 2160 // Now clone the functions from the mixin class. | 2167 // Now clone the functions from the mixin class. |
| 2161 functions = mixin_cls.functions(); | 2168 functions = mixin_cls.functions(); |
| 2162 const intptr_t num_functions = functions.Length(); | 2169 const intptr_t num_functions = functions.Length(); |
| 2163 for (intptr_t i = 0; i < num_functions; i++) { | 2170 for (intptr_t i = 0; i < num_functions; i++) { |
| 2164 func ^= functions.At(i); | 2171 func ^= functions.At(i); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2374 if (!super.IsNull()) { | 2381 if (!super.IsNull()) { |
| 2375 FinalizeClass(super); | 2382 FinalizeClass(super); |
| 2376 } | 2383 } |
| 2377 // Mark as parsed and finalized. | 2384 // Mark as parsed and finalized. |
| 2378 cls.Finalize(); | 2385 cls.Finalize(); |
| 2379 // Mixin app alias classes may still lack their forwarding constructor. | 2386 // Mixin app alias classes may still lack their forwarding constructor. |
| 2380 if (cls.is_mixin_app_alias() && | 2387 if (cls.is_mixin_app_alias() && |
| 2381 (cls.functions() == Object::empty_array().raw())) { | 2388 (cls.functions() == Object::empty_array().raw())) { |
| 2382 const GrowableObjectArray& cloned_funcs = | 2389 const GrowableObjectArray& cloned_funcs = |
| 2383 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2390 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2384 CreateForwardingConstructors(cls, cloned_funcs); | 2391 |
| 2392 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); |
| 2393 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 2394 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); |
| 2395 |
| 2396 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); |
| 2385 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); | 2397 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); |
| 2386 cls.SetFunctions(functions); | 2398 cls.SetFunctions(functions); |
| 2387 } | 2399 } |
| 2388 // Every class should have at least a constructor, unless it is a top level | 2400 // Every class should have at least a constructor, unless it is a top level |
| 2389 // class or a signature class. | 2401 // class or a signature class. |
| 2390 ASSERT(cls.IsTopLevel() || | 2402 ASSERT(cls.IsTopLevel() || |
| 2391 cls.IsSignatureClass() || | 2403 cls.IsSignatureClass() || |
| 2392 (Array::Handle(cls.functions()).Length() > 0)); | 2404 (Array::Handle(cls.functions()).Length() > 0)); |
| 2393 // Resolve and finalize all member types. | 2405 // Resolve and finalize all member types. |
| 2394 ResolveAndFinalizeMemberTypes(cls); | 2406 ResolveAndFinalizeMemberTypes(cls); |
| (...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3208 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3220 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3209 field ^= fields_array.At(0); | 3221 field ^= fields_array.At(0); |
| 3210 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3222 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3211 name ^= field.name(); | 3223 name ^= field.name(); |
| 3212 expected_name ^= String::New("_data"); | 3224 expected_name ^= String::New("_data"); |
| 3213 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3225 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3214 #endif | 3226 #endif |
| 3215 } | 3227 } |
| 3216 | 3228 |
| 3217 } // namespace dart | 3229 } // namespace dart |
| OLD | NEW |