| 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 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2137 for (intptr_t n = 0; n < num_parameters; n++) { | 2137 for (intptr_t n = 0; n < num_parameters; n++) { |
| 2138 clone.SetParameterTypeAt(n, dynamic_type); | 2138 clone.SetParameterTypeAt(n, dynamic_type); |
| 2139 } | 2139 } |
| 2140 cloned_funcs.Add(clone); | 2140 cloned_funcs.Add(clone); |
| 2141 } | 2141 } |
| 2142 } | 2142 } |
| 2143 } | 2143 } |
| 2144 | 2144 |
| 2145 | 2145 |
| 2146 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { | 2146 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { |
| 2147 Isolate* isolate = Isolate::Current(); | 2147 Zone* zone = Thread::Current()->zone(); |
| 2148 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); | 2148 const Type& mixin_type = Type::Handle(zone, cls.mixin()); |
| 2149 ASSERT(!mixin_type.IsNull()); | 2149 ASSERT(!mixin_type.IsNull()); |
| 2150 ASSERT(mixin_type.HasResolvedTypeClass()); | 2150 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 2151 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); | 2151 const Class& mixin_cls = Class::Handle(zone, mixin_type.type_class()); |
| 2152 FinalizeClass(mixin_cls); | 2152 FinalizeClass(mixin_cls); |
| 2153 // If the mixin is a mixin application alias class, there are no members to | 2153 // If the mixin is a mixin application alias class, there are no members to |
| 2154 // apply here. A new synthesized class representing the aliased mixin | 2154 // apply here. A new synthesized class representing the aliased mixin |
| 2155 // application class was inserted in the super chain of this mixin application | 2155 // application class was inserted in the super chain of this mixin application |
| 2156 // class. Members of the actual mixin class will be applied when visiting | 2156 // class. Members of the actual mixin class will be applied when visiting |
| 2157 // the mixin application class referring to the actual mixin. | 2157 // the mixin application class referring to the actual mixin. |
| 2158 ASSERT(!mixin_cls.is_mixin_app_alias() || | 2158 ASSERT(!mixin_cls.is_mixin_app_alias() || |
| 2159 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication()); | 2159 Class::Handle(zone, cls.SuperClass()).IsMixinApplication()); |
| 2160 // A default constructor will be created for the mixin app alias class. | 2160 // A default constructor will be created for the mixin app alias class. |
| 2161 | 2161 |
| 2162 if (FLAG_trace_class_finalization) { | 2162 if (FLAG_trace_class_finalization) { |
| 2163 ISL_Print("Applying mixin members of %s to %s at pos %" Pd "\n", | 2163 ISL_Print("Applying mixin members of %s to %s at pos %" Pd "\n", |
| 2164 mixin_cls.ToCString(), | 2164 mixin_cls.ToCString(), |
| 2165 cls.ToCString(), | 2165 cls.ToCString(), |
| 2166 cls.token_pos()); | 2166 cls.token_pos()); |
| 2167 } | 2167 } |
| 2168 | 2168 |
| 2169 const GrowableObjectArray& cloned_funcs = | 2169 const GrowableObjectArray& cloned_funcs = |
| 2170 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | 2170 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
| 2171 | 2171 |
| 2172 CreateForwardingConstructors(cls, cloned_funcs); | 2172 CreateForwardingConstructors(cls, cloned_funcs); |
| 2173 | 2173 |
| 2174 Array& functions = Array::Handle(isolate); | 2174 Array& functions = Array::Handle(zone); |
| 2175 Function& func = Function::Handle(isolate); | 2175 Function& func = Function::Handle(zone); |
| 2176 // The parser creates the mixin application class with no functions. | 2176 // The parser creates the mixin application class with no functions. |
| 2177 ASSERT((functions = cls.functions(), functions.Length() == 0)); | 2177 ASSERT((functions = cls.functions(), functions.Length() == 0)); |
| 2178 // Now clone the functions from the mixin class. | 2178 // Now clone the functions from the mixin class. |
| 2179 functions = mixin_cls.functions(); | 2179 functions = mixin_cls.functions(); |
| 2180 const intptr_t num_functions = functions.Length(); | 2180 const intptr_t num_functions = functions.Length(); |
| 2181 for (intptr_t i = 0; i < num_functions; i++) { | 2181 for (intptr_t i = 0; i < num_functions; i++) { |
| 2182 func ^= functions.At(i); | 2182 func ^= functions.At(i); |
| 2183 if (func.IsGenerativeConstructor()) { | 2183 if (func.IsGenerativeConstructor()) { |
| 2184 // A mixin class must not have explicit constructors. | 2184 // A mixin class must not have explicit constructors. |
| 2185 if (!func.IsImplicitConstructor()) { | 2185 if (!func.IsImplicitConstructor()) { |
| 2186 ReportError(cls, cls.token_pos(), | 2186 ReportError(cls, cls.token_pos(), |
| 2187 "mixin class '%s' must not have constructors\n", | 2187 "mixin class '%s' must not have constructors\n", |
| 2188 String::Handle(isolate, mixin_cls.Name()).ToCString()); | 2188 String::Handle(zone, mixin_cls.Name()).ToCString()); |
| 2189 } | 2189 } |
| 2190 continue; // Skip the implicit constructor. | 2190 continue; // Skip the implicit constructor. |
| 2191 } | 2191 } |
| 2192 if (!func.is_static() && | 2192 if (!func.is_static() && |
| 2193 !func.IsMethodExtractor() && | 2193 !func.IsMethodExtractor() && |
| 2194 !func.IsNoSuchMethodDispatcher() && | 2194 !func.IsNoSuchMethodDispatcher() && |
| 2195 !func.IsInvokeFieldDispatcher()) { | 2195 !func.IsInvokeFieldDispatcher()) { |
| 2196 func = func.Clone(cls); | 2196 func = func.Clone(cls); |
| 2197 cloned_funcs.Add(func); | 2197 cloned_funcs.Add(func); |
| 2198 } | 2198 } |
| 2199 } | 2199 } |
| 2200 functions = Array::MakeArray(cloned_funcs); | 2200 functions = Array::MakeArray(cloned_funcs); |
| 2201 cls.SetFunctions(functions); | 2201 cls.SetFunctions(functions); |
| 2202 | 2202 |
| 2203 // Now clone the fields from the mixin class. There should be no | 2203 // Now clone the fields from the mixin class. There should be no |
| 2204 // existing fields in the mixin application class. | 2204 // existing fields in the mixin application class. |
| 2205 ASSERT(Array::Handle(cls.fields()).Length() == 0); | 2205 ASSERT(Array::Handle(cls.fields()).Length() == 0); |
| 2206 const Array& fields = Array::Handle(isolate, mixin_cls.fields()); | 2206 const Array& fields = Array::Handle(zone, mixin_cls.fields()); |
| 2207 Field& field = Field::Handle(isolate); | |
| 2208 const GrowableObjectArray& cloned_fields = | |
| 2209 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
| 2210 const intptr_t num_fields = fields.Length(); | 2207 const intptr_t num_fields = fields.Length(); |
| 2208 Field& field = Field::Handle(zone); |
| 2209 GrowableArray<const Field*> cloned_fields(num_fields); |
| 2211 for (intptr_t i = 0; i < num_fields; i++) { | 2210 for (intptr_t i = 0; i < num_fields; i++) { |
| 2212 field ^= fields.At(i); | 2211 field ^= fields.At(i); |
| 2213 // Static fields are shared between the mixin class and the mixin | 2212 // Static fields are shared between the mixin class and the mixin |
| 2214 // application class. | 2213 // application class. |
| 2215 if (!field.is_static()) { | 2214 if (!field.is_static()) { |
| 2216 field = field.Clone(cls); | 2215 const Field& cloned = Field::ZoneHandle(zone, field.Clone(cls)); |
| 2217 cloned_fields.Add(field); | 2216 cloned_fields.Add(&cloned); |
| 2218 } | 2217 } |
| 2219 } | 2218 } |
| 2220 cls.AddFields(cloned_fields); | 2219 cls.AddFields(cloned_fields); |
| 2221 | 2220 |
| 2222 if (FLAG_trace_class_finalization) { | 2221 if (FLAG_trace_class_finalization) { |
| 2223 ISL_Print("Done applying mixin members of %s to %s\n", | 2222 ISL_Print("Done applying mixin members of %s to %s\n", |
| 2224 mixin_cls.ToCString(), | 2223 mixin_cls.ToCString(), |
| 2225 cls.ToCString()); | 2224 cls.ToCString()); |
| 2226 } | 2225 } |
| 2227 } | 2226 } |
| (...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3217 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3216 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3218 field ^= fields_array.At(0); | 3217 field ^= fields_array.At(0); |
| 3219 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3218 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3220 name ^= field.name(); | 3219 name ^= field.name(); |
| 3221 expected_name ^= String::New("_data"); | 3220 expected_name ^= String::New("_data"); |
| 3222 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3221 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3223 #endif | 3222 #endif |
| 3224 } | 3223 } |
| 3225 | 3224 |
| 3226 } // namespace dart | 3225 } // namespace dart |
| OLD | NEW |