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

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

Issue 19023005: Implement forwarding constructors for mixins (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months 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 | Annotate | Revision Log
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/flags.h" 7 #include "vm/flags.h"
8 #include "vm/heap.h" 8 #include "vm/heap.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 1384
1385 if (FLAG_trace_class_finalization) { 1385 if (FLAG_trace_class_finalization) {
1386 OS::Print("done mixin type appl %s %s extending '%s'\n", 1386 OS::Print("done mixin type appl %s %s extending '%s'\n",
1387 String::Handle(cls.Name()).ToCString(), 1387 String::Handle(cls.Name()).ToCString(),
1388 TypeArguments::Handle(cls.type_parameters()).ToCString(), 1388 TypeArguments::Handle(cls.type_parameters()).ToCString(),
1389 AbstractType::Handle(cls.super_type()).ToCString()); 1389 AbstractType::Handle(cls.super_type()).ToCString());
1390 } 1390 }
1391 } 1391 }
1392 1392
1393 1393
1394 void ClassFinalizer::CreateForwardingConstructors(
1395 const Class& mixin_app,
1396 const GrowableObjectArray& cloned_funcs) {
srdjan 2013/07/12 21:53:57 ditto
hausner 2013/07/12 22:00:42 Done.
1397 const String& mixin_name = String::Handle(mixin_app.Name());
1398 const Class& super_class = Class::Handle(mixin_app.SuperClass());
1399 const String& super_name = String::Handle(super_class.Name());
1400 const Type& dynamic_type = Type::Handle(Type::DynamicType());
1401 const Array& functions = Array::Handle(super_class.functions());
1402 intptr_t num_functions = functions.Length();
1403 Function& func = Function::Handle();
1404 for (intptr_t i = 0; i < num_functions; i++) {
1405 func ^= functions.At(i);
1406 if (func.IsConstructor()) {
1407 // Build constructor name from mixin application class name
1408 // and name of cloned super class constructor.
1409 String& ctor_name = String::Handle(func.name());
1410 ctor_name = String::SubString(ctor_name, super_name.Length());
1411 String& clone_name =
1412 String::Handle(String::Concat(mixin_name, ctor_name));
1413 clone_name = Symbols::New(clone_name);
1414
1415 const Function& clone = Function::Handle(
1416 Function::New(clone_name,
1417 func.kind(),
1418 func.is_static(),
1419 func.is_const(),
1420 func.is_abstract(),
1421 func.is_external(),
1422 mixin_app,
1423 mixin_app.token_pos()));
1424
1425 clone.set_num_fixed_parameters(func.num_fixed_parameters());
1426 clone.SetNumOptionalParameters(func.NumOptionalParameters(),
1427 func.HasOptionalPositionalParameters());
1428 clone.set_result_type(dynamic_type);
1429
1430 const int num_parameters = func.NumParameters();
1431 // The cloned ctor shares the parameter names array with the
1432 // original.
1433 const Array& parameter_names = Array::Handle(func.parameter_names());
1434 ASSERT(parameter_names.Length() == num_parameters);
1435 clone.set_parameter_names(parameter_names);
1436 // The parameter types of the cloned constructor are 'dynamic'.
1437 clone.set_parameter_types(Array::Handle(Array::New(num_parameters)));
1438 for (intptr_t n = 0; n < num_parameters; n++) {
1439 clone.SetParameterTypeAt(n, dynamic_type);
1440 }
1441 cloned_funcs.Add(clone);
1442 }
1443 }
1444 }
1445
1446
1394 void ClassFinalizer::ApplyMixin(const Class& cls) { 1447 void ClassFinalizer::ApplyMixin(const Class& cls) {
1395 Isolate* isolate = Isolate::Current(); 1448 Isolate* isolate = Isolate::Current();
1396 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); 1449 const Type& mixin_type = Type::Handle(isolate, cls.mixin());
1397 ASSERT(!mixin_type.IsNull()); 1450 ASSERT(!mixin_type.IsNull());
1398 ASSERT(mixin_type.HasResolvedTypeClass()); 1451 ASSERT(mixin_type.HasResolvedTypeClass());
1399 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); 1452 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class());
1400 mixin_cls.EnsureIsFinalized(isolate); 1453 mixin_cls.EnsureIsFinalized(isolate);
1401 1454
1402 if (FLAG_trace_class_finalization) { 1455 if (FLAG_trace_class_finalization) {
1403 OS::Print("Applying mixin '%s' to '%s' at pos %"Pd"\n", 1456 OS::Print("Applying mixin '%s' to '%s' at pos %"Pd"\n",
1404 String::Handle(mixin_cls.Name()).ToCString(), 1457 String::Handle(mixin_cls.Name()).ToCString(),
1405 cls.ToCString(), 1458 cls.ToCString(),
1406 cls.token_pos()); 1459 cls.token_pos());
1407 } 1460 }
1408 1461
1409 const GrowableObjectArray& cloned_funcs = 1462 const GrowableObjectArray& cloned_funcs =
1410 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); 1463 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
1464
1465 CreateForwardingConstructors(cls, cloned_funcs);
1466
1411 Array& functions = Array::Handle(isolate); 1467 Array& functions = Array::Handle(isolate);
1412 Function& func = Function::Handle(isolate); 1468 Function& func = Function::Handle(isolate);
1413 // The parser creates the mixin application class and adds just 1469 // The parser creates the mixin application class with no functions.
1414 // one function, the implicit constructor. 1470 ASSERT((functions = cls.functions(), functions.Length() == 0));
1415 functions = cls.functions();
1416 ASSERT(functions.Length() == 1);
1417 func ^= functions.At(0);
1418 ASSERT(func.IsImplicitConstructor());
1419 cloned_funcs.Add(func);
1420 // Now clone the functions from the mixin class. 1471 // Now clone the functions from the mixin class.
1421 functions = mixin_cls.functions(); 1472 functions = mixin_cls.functions();
1422 const intptr_t num_functions = functions.Length(); 1473 const intptr_t num_functions = functions.Length();
1423 for (int i = 0; i < num_functions; i++) { 1474 for (int i = 0; i < num_functions; i++) {
1424 func ^= functions.At(i); 1475 func ^= functions.At(i);
1425 if (func.IsConstructor()) { 1476 if (func.IsConstructor()) {
1426 // A mixin class must not have explicit constructors. 1477 // A mixin class must not have explicit constructors.
1427 if (!func.IsImplicitConstructor()) { 1478 if (!func.IsImplicitConstructor()) {
1428 const Script& script = Script::Handle(isolate, cls.script()); 1479 const Script& script = Script::Handle(isolate, cls.script());
1429 ReportError(script, cls.token_pos(), 1480 ReportError(script, cls.token_pos(),
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 expected_name ^= String::New("_offset"); 2188 expected_name ^= String::New("_offset");
2138 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2189 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2139 field ^= fields_array.At(2); 2190 field ^= fields_array.At(2);
2140 ASSERT(field.Offset() == TypedDataView::length_offset()); 2191 ASSERT(field.Offset() == TypedDataView::length_offset());
2141 name ^= field.name(); 2192 name ^= field.name();
2142 ASSERT(name.Equals("length")); 2193 ASSERT(name.Equals("length"));
2143 #endif 2194 #endif
2144 } 2195 }
2145 2196
2146 } // namespace dart 2197 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698