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 |