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 |