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

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

Issue 23453024: Keep track of type parameter processing in mixin application classes. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 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 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 AbstractType& type_argument = AbstractType::Handle(); 504 AbstractType& type_argument = AbstractType::Handle();
505 for (intptr_t i = 0; i < num_arguments; i++) { 505 for (intptr_t i = 0; i < num_arguments; i++) {
506 type_argument = arguments.TypeAt(i); 506 type_argument = arguments.TypeAt(i);
507 ResolveType(cls, type_argument, finalization); 507 ResolveType(cls, type_argument, finalization);
508 } 508 }
509 } 509 }
510 } 510 }
511 511
512 512
513 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { 513 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
514 if (cls.mixin() != Type::null()) {
siva 2013/09/04 21:07:00 Might be more readable to have a isMixin() method
regis 2013/09/04 22:14:27 Added IsMixinApplication() to class Class.
515 // Copy the type parameters to the mixin application.
516 ApplyMixinType(cls);
517 }
514 // The type parameter bounds are not finalized here. 518 // The type parameter bounds are not finalized here.
515 const TypeArguments& type_parameters = 519 const TypeArguments& type_parameters =
516 TypeArguments::Handle(cls.type_parameters()); 520 TypeArguments::Handle(cls.type_parameters());
517 if (!type_parameters.IsNull()) { 521 if (!type_parameters.IsNull()) {
518 TypeParameter& type_parameter = TypeParameter::Handle(); 522 TypeParameter& type_parameter = TypeParameter::Handle();
519 const intptr_t num_types = type_parameters.Length(); 523 const intptr_t num_types = type_parameters.Length();
520 for (intptr_t i = 0; i < num_types; i++) { 524 for (intptr_t i = 0; i < num_types; i++) {
521 type_parameter ^= type_parameters.TypeAt(i); 525 type_parameter ^= type_parameters.TypeAt(i);
522 type_parameter ^= FinalizeType(cls, 526 type_parameter ^= FinalizeType(cls,
523 type_parameter, 527 type_parameter,
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 } 1307 }
1304 } 1308 }
1305 } 1309 }
1306 } 1310 }
1307 1311
1308 1312
1309 // Copy the type parameters of the super and mixin classes to the 1313 // Copy the type parameters of the super and mixin classes to the
1310 // mixin application class. Change type arguments of super type and of 1314 // mixin application class. Change type arguments of super type and of
1311 // interfaces to refer to the respective type parameters of the mixin 1315 // interfaces to refer to the respective type parameters of the mixin
1312 // application class. 1316 // application class.
1313 void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) { 1317 void ClassFinalizer::CloneTypeParameters(const Class& mixin_app_class) {
1314 ASSERT(mixapp_class.NumTypeParameters() == 0); 1318 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null());
1315 1319
1316 const AbstractType& super_type = 1320 const AbstractType& super_type =
1317 AbstractType::Handle(mixapp_class.super_type()); 1321 AbstractType::Handle(mixin_app_class.super_type());
1318 ASSERT(super_type.IsResolved()); 1322 ASSERT(super_type.IsResolved());
1319 const Class& super_class = Class::Handle(super_type.type_class()); 1323 const Class& super_class = Class::Handle(super_type.type_class());
1320 const Type& mixin_type = Type::Handle(mixapp_class.mixin()); 1324 const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
1321 const Class& mixin_class = Class::Handle(mixin_type.type_class()); 1325 const Class& mixin_class = Class::Handle(mixin_type.type_class());
1322 const int num_super_parameters = super_class.NumTypeParameters(); 1326 const int num_super_parameters = super_class.NumTypeParameters();
1323 const int num_mixin_parameters = mixin_class.NumTypeParameters(); 1327 const int num_mixin_parameters = mixin_class.NumTypeParameters();
1324 if ((num_super_parameters + num_mixin_parameters) == 0) { 1328 if ((num_super_parameters + num_mixin_parameters) == 0) {
1325 return; 1329 return;
1326 } 1330 }
1327 1331
1328 // First, clone the super class type parameters. Rename them so that 1332 // First, clone the super class type parameters. Rename them so that
1329 // there can be no name conflict between the parameters of the super 1333 // there can be no name conflict between the parameters of the super
1330 // class and the mixin class. 1334 // class and the mixin class.
1331 const TypeArguments& cloned_type_params = TypeArguments::Handle( 1335 const TypeArguments& cloned_type_params = TypeArguments::Handle(
1332 TypeArguments::New(num_super_parameters + num_mixin_parameters)); 1336 TypeArguments::New(num_super_parameters + num_mixin_parameters));
1333 TypeParameter& param = TypeParameter::Handle(); 1337 TypeParameter& param = TypeParameter::Handle();
1334 TypeParameter& cloned_param = TypeParameter::Handle(); 1338 TypeParameter& cloned_param = TypeParameter::Handle();
1335 String& param_name = String::Handle(); 1339 String& param_name = String::Handle();
1336 AbstractType& param_bound = AbstractType::Handle(); 1340 AbstractType& param_bound = AbstractType::Handle();
1337 int cloned_index = 0; 1341 int cloned_index = 0;
1338 if (num_super_parameters > 0) { 1342 if (num_super_parameters > 0) {
1339 const TypeArguments& super_params = 1343 const TypeArguments& super_params =
1340 TypeArguments::Handle(super_class.type_parameters()); 1344 TypeArguments::Handle(super_class.type_parameters());
1341 const TypeArguments& super_type_args = 1345 const TypeArguments& super_type_args =
1342 TypeArguments::Handle(TypeArguments::New(num_super_parameters)); 1346 TypeArguments::Handle(TypeArguments::New(num_super_parameters));
1343 for (int i = 0; i < num_super_parameters; i++) { 1347 for (int i = 0; i < num_super_parameters; i++) {
1344 param ^= super_params.TypeAt(i); 1348 param ^= super_params.TypeAt(i);
1345 param_name = param.name(); 1349 param_name = param.name();
1346 param_bound = param.bound(); 1350 param_bound = param.bound();
1347 // TODO(hausner): handle type bounds. 1351 // TODO(hausner): handle type bounds.
1348 if (!param_bound.IsObjectType()) { 1352 if (!param_bound.IsObjectType()) {
1349 const Script& script = Script::Handle(mixapp_class.script()); 1353 const Script& script = Script::Handle(mixin_app_class.script());
1350 ReportError(Error::Handle(), // No previous error. 1354 ReportError(Error::Handle(), // No previous error.
1351 script, param.token_pos(), 1355 script, param.token_pos(),
1352 "type parameter '%s': type bounds not yet" 1356 "type parameter '%s': type bounds not yet"
1353 " implemented for mixins\n", 1357 " implemented for mixins\n",
1354 param_name.ToCString()); 1358 param_name.ToCString());
1355 } 1359 }
1356 param_name = String::Concat(param_name, Symbols::Backtick()); 1360 param_name = String::Concat(param_name, Symbols::Backtick());
1357 param_name = Symbols::New(param_name); 1361 param_name = Symbols::New(param_name);
1358 cloned_param = TypeParameter::New(mixapp_class, 1362 cloned_param = TypeParameter::New(mixin_app_class,
1359 cloned_index, 1363 cloned_index,
1360 param_name, 1364 param_name,
1361 param_bound, 1365 param_bound,
1362 param.token_pos()); 1366 param.token_pos());
1363 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1367 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1364 // Change the type arguments of the super type to refer to the 1368 // Change the type arguments of the super type to refer to the
1365 // cloned type parameters of the mixin application class. 1369 // cloned type parameters of the mixin application class.
1366 super_type_args.SetTypeAt(cloned_index, cloned_param); 1370 super_type_args.SetTypeAt(cloned_index, cloned_param);
1367 cloned_index++; 1371 cloned_index++;
1368 } 1372 }
(...skipping 13 matching lines...) Expand all
1382 TypeArguments::Handle(mixin_class.type_parameters()); 1386 TypeArguments::Handle(mixin_class.type_parameters());
1383 const TypeArguments& interface_type_args = TypeArguments::Handle( 1387 const TypeArguments& interface_type_args = TypeArguments::Handle(
1384 TypeArguments::New(num_mixin_parameters)); 1388 TypeArguments::New(num_mixin_parameters));
1385 for (int i = 0; i < num_mixin_parameters; i++) { 1389 for (int i = 0; i < num_mixin_parameters; i++) {
1386 param ^= mixin_params.TypeAt(i); 1390 param ^= mixin_params.TypeAt(i);
1387 param_name = param.name(); 1391 param_name = param.name();
1388 param_bound = param.bound(); 1392 param_bound = param.bound();
1389 1393
1390 // TODO(hausner): handle type bounds. 1394 // TODO(hausner): handle type bounds.
1391 if (!param_bound.IsObjectType()) { 1395 if (!param_bound.IsObjectType()) {
1392 const Script& script = Script::Handle(mixapp_class.script()); 1396 const Script& script = Script::Handle(mixin_app_class.script());
1393 ReportError(Error::Handle(), // No previous error. 1397 ReportError(Error::Handle(), // No previous error.
1394 script, param.token_pos(), 1398 script, param.token_pos(),
1395 "type parameter '%s': type bounds not yet" 1399 "type parameter '%s': type bounds not yet"
1396 " implemented for mixins\n", 1400 " implemented for mixins\n",
1397 param_name.ToCString()); 1401 param_name.ToCString());
1398 } 1402 }
1399 cloned_param = TypeParameter::New(mixapp_class, 1403 cloned_param = TypeParameter::New(mixin_app_class,
1400 cloned_index, 1404 cloned_index,
1401 param_name, 1405 param_name,
1402 param_bound, 1406 param_bound,
1403 param.token_pos()); 1407 param.token_pos());
1404 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1408 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1405 interface_type_args.SetTypeAt(i, cloned_param); 1409 interface_type_args.SetTypeAt(i, cloned_param);
1406 cloned_index++; 1410 cloned_index++;
1407 } 1411 }
1408 1412
1409 // Lastly, change the type arguments of the single interface type to 1413 // Lastly, change the type arguments of the single interface type to
1410 // refer to the cloned type parameters of the mixin application class. 1414 // refer to the cloned type parameters of the mixin application class.
1411 Array& interface_types = Array::Handle(mixapp_class.interfaces()); 1415 Array& interface_types = Array::Handle(mixin_app_class.interfaces());
1412 ASSERT(interface_types.Length() == 1); 1416 ASSERT(interface_types.Length() == 1);
1413 AbstractType& interface_type = AbstractType::Handle(); 1417 AbstractType& interface_type = AbstractType::Handle();
1414 interface_type ^= interface_types.At(0); 1418 interface_type ^= interface_types.At(0);
1415 ASSERT(interface_type.IsResolved()); 1419 ASSERT(interface_type.IsResolved());
1416 // TODO(hausner): May need to handle BoundedType here. 1420 // TODO(hausner): May need to handle BoundedType here.
1417 ASSERT(interface_type.IsType()); 1421 ASSERT(interface_type.IsType());
1418 Type::Cast(interface_type).set_arguments(interface_type_args); 1422 Type::Cast(interface_type).set_arguments(interface_type_args);
1419 ASSERT(!interface_type.IsFinalized()); 1423 ASSERT(!interface_type.IsFinalized());
1420 } 1424 }
1421 mixapp_class.set_type_parameters(cloned_type_params); 1425 mixin_app_class.set_type_parameters(cloned_type_params);
1422 } 1426 }
1423 1427
1424 1428
1425 void ClassFinalizer::ApplyMixinTypes(const Class& cls) { 1429 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) {
1426 const Type& mixin_type = Type::Handle(cls.mixin()); 1430 if (mixin_app_class.is_mixin_type_applied()) {
1431 return;
1432 }
1433 const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
1427 ASSERT(!mixin_type.IsNull()); 1434 ASSERT(!mixin_type.IsNull());
1428 ASSERT(mixin_type.HasResolvedTypeClass()); 1435 ASSERT(mixin_type.HasResolvedTypeClass());
1429 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); 1436 const Class& mixin_cls = Class::Handle(mixin_type.type_class());
1430 1437
1431 if (FLAG_trace_class_finalization) { 1438 if (FLAG_trace_class_finalization) {
1432 OS::Print("Applying mixin type '%s' to '%s' at pos %" Pd "\n", 1439 OS::Print("Applying mixin type '%s' to '%s' at pos %" Pd "\n",
1433 String::Handle(mixin_type.Name()).ToCString(), 1440 String::Handle(mixin_type.Name()).ToCString(),
1434 cls.ToCString(), 1441 mixin_app_class.ToCString(),
1435 cls.token_pos()); 1442 mixin_app_class.token_pos());
1436 } 1443 }
1437 1444
1438 // Check that the super class of the mixin class is extending 1445 // Check that the super class of the mixin class is extending
1439 // class Object. 1446 // class Object.
1440 const AbstractType& mixin_super_type = 1447 const AbstractType& mixin_super_type =
1441 AbstractType::Handle(mixin_cls.super_type()); 1448 AbstractType::Handle(mixin_cls.super_type());
1442 if (!mixin_super_type.IsObjectType()) { 1449 if (!mixin_super_type.IsObjectType()) {
1443 const Script& script = Script::Handle(cls.script()); 1450 const Script& script = Script::Handle(mixin_app_class.script());
1444 const String& class_name = String::Handle(mixin_cls.Name()); 1451 const String& class_name = String::Handle(mixin_cls.Name());
1445 ReportError(Error::Handle(), // No previous error. 1452 ReportError(Error::Handle(), // No previous error.
1446 script, cls.token_pos(), 1453 script, mixin_app_class.token_pos(),
1447 "mixin class %s must extend class Object", 1454 "mixin class %s must extend class Object",
1448 class_name.ToCString()); 1455 class_name.ToCString());
1449 } 1456 }
1450 1457
1451 // Copy type parameters to mixin application class. 1458 // Copy type parameters to mixin application class.
1452 CloneTypeParameters(cls); 1459 CloneTypeParameters(mixin_app_class);
1453 1460
1454 if (FLAG_trace_class_finalization) { 1461 if (FLAG_trace_class_finalization) {
1455 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n", 1462 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n",
1456 String::Handle(mixin_type.Name()).ToCString(), 1463 String::Handle(mixin_type.Name()).ToCString(),
1457 String::Handle(cls.Name()).ToCString(), 1464 String::Handle(mixin_app_class.Name()).ToCString(),
1458 TypeArguments::Handle(cls.type_parameters()).ToCString(), 1465 TypeArguments::Handle(
1459 AbstractType::Handle(cls.super_type()).ToCString()); 1466 mixin_app_class.type_parameters()).ToCString(),
1467 AbstractType::Handle(mixin_app_class.super_type()).ToCString());
1460 } 1468 }
1469 mixin_app_class.set_is_mixin_type_applied();
1461 } 1470 }
1462 1471
1463 1472
1464 void ClassFinalizer::CreateForwardingConstructors( 1473 void ClassFinalizer::CreateForwardingConstructors(
1465 const Class& mixin_app, 1474 const Class& mixin_app,
1466 const GrowableObjectArray& cloned_funcs) { 1475 const GrowableObjectArray& cloned_funcs) {
1467 const String& mixin_name = String::Handle(mixin_app.Name()); 1476 const String& mixin_name = String::Handle(mixin_app.Name());
1468 const Class& super_class = Class::Handle(mixin_app.SuperClass()); 1477 const Class& super_class = Class::Handle(mixin_app.SuperClass());
1469 const String& super_name = String::Handle(super_class.Name()); 1478 const String& super_name = String::Handle(super_class.Name());
1470 const Type& dynamic_type = Type::Handle(Type::DynamicType()); 1479 const Type& dynamic_type = Type::Handle(Type::DynamicType());
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 ReportError(Error::Handle(), // No previous error. 1612 ReportError(Error::Handle(), // No previous error.
1604 script, cls.token_pos(), 1613 script, cls.token_pos(),
1605 "class '%s' has a cycle in its superclass relationship", 1614 "class '%s' has a cycle in its superclass relationship",
1606 name.ToCString()); 1615 name.ToCString());
1607 } 1616 }
1608 // Finalize super class. 1617 // Finalize super class.
1609 const Class& super_class = Class::Handle(cls.SuperClass()); 1618 const Class& super_class = Class::Handle(cls.SuperClass());
1610 if (!super_class.IsNull()) { 1619 if (!super_class.IsNull()) {
1611 FinalizeTypesInClass(super_class); 1620 FinalizeTypesInClass(super_class);
1612 } 1621 }
1613 if (cls.mixin() != Type::null()) {
1614 // Copy the type parameters to the mixin application.
1615 ApplyMixinTypes(cls);
1616 }
1617 // Finalize type parameters before finalizing the super type. 1622 // Finalize type parameters before finalizing the super type.
1618 FinalizeTypeParameters(cls); 1623 FinalizeTypeParameters(cls);
1619 ResolveUpperBounds(cls); 1624 ResolveUpperBounds(cls);
1620 // Finalize super type. 1625 // Finalize super type.
1621 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 1626 AbstractType& super_type = AbstractType::Handle(cls.super_type());
1622 if (!super_type.IsNull()) { 1627 if (!super_type.IsNull()) {
1623 // In case of a bound error in the super type in production mode, the 1628 // In case of a bound error in the super type in production mode, the
1624 // finalized super type will be a BoundedType with a malformed bound. 1629 // finalized super type will be a BoundedType with a malformed bound.
1625 // It should not be a problem if the class is written to a snapshot and 1630 // It should not be a problem if the class is written to a snapshot and
1626 // later executed in checked mode. Note that the finalized type argument 1631 // later executed in checked mode. Note that the finalized type argument
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1853 AbstractTypeArguments& type_args = 1858 AbstractTypeArguments& type_args =
1854 AbstractTypeArguments::Handle(type.arguments()); 1859 AbstractTypeArguments::Handle(type.arguments());
1855 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 1860 const intptr_t num_type_parameters = type_class.NumTypeParameters();
1856 const intptr_t num_type_arguments = 1861 const intptr_t num_type_arguments =
1857 type_args.IsNull() ? 0 : type_args.Length(); 1862 type_args.IsNull() ? 0 : type_args.Length();
1858 AbstractType& arg = AbstractType::Handle(); 1863 AbstractType& arg = AbstractType::Handle();
1859 if (num_type_arguments > 0) { 1864 if (num_type_arguments > 0) {
1860 if (num_type_arguments != num_type_parameters) { 1865 if (num_type_arguments != num_type_parameters) {
1861 const Script& script = Script::Handle(cls.script()); 1866 const Script& script = Script::Handle(cls.script());
1862 const String& type_class_name = String::Handle(type_class.Name()); 1867 const String& type_class_name = String::Handle(type_class.Name());
1868 // TODO(regis): This should not be a compile time error anymore.
1863 ReportError(Error::Handle(), // No previous error. 1869 ReportError(Error::Handle(), // No previous error.
1864 script, type.token_pos(), 1870 script, type.token_pos(),
1865 "wrong number of type arguments for class '%s'", 1871 "wrong number of type arguments for class '%s'",
1866 type_class_name.ToCString()); 1872 type_class_name.ToCString());
1867 } 1873 }
1868 for (int i = 0; i < num_type_arguments; i++) { 1874 for (int i = 0; i < num_type_arguments; i++) {
1869 arg = type_args.TypeAt(i); 1875 arg = type_args.TypeAt(i);
1870 collected_args.Add(arg); 1876 collected_args.Add(arg);
1871 } 1877 }
1872 } else { 1878 } else {
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 expected_name ^= String::New("_offset"); 2328 expected_name ^= String::New("_offset");
2323 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2329 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2324 field ^= fields_array.At(2); 2330 field ^= fields_array.At(2);
2325 ASSERT(field.Offset() == TypedDataView::length_offset()); 2331 ASSERT(field.Offset() == TypedDataView::length_offset());
2326 name ^= field.name(); 2332 name ^= field.name();
2327 ASSERT(name.Equals("length")); 2333 ASSERT(name.Equals("length"));
2328 #endif 2334 #endif
2329 } 2335 }
2330 2336
2331 } // namespace dart 2337 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | runtime/vm/object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698