Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(604)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 1533823004: Fix owner of mixin forwarding constructors (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698