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

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

Issue 137543004: Support bounded mixins in the VM (fix issue 14453). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 11 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
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('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 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 // class S<T> { } 1386 // class S<T> { }
1387 // class M<T> { } 1387 // class M<T> { }
1388 // class C<E> extends S<E> with M<List<E>> { } 1388 // class C<E> extends S<E> with M<List<E>> { }
1389 // results in 1389 // results in
1390 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T> 1390 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T>
1391 // class C<E> extends S&M<E, List<E>> { } 1391 // class C<E> extends S&M<E, List<E>> { }
1392 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and 1392 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and
1393 // T, and use them as type arguments in S<T`> and M<T>. 1393 // T, and use them as type arguments in S<T`> and M<T>.
1394 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { 1394 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) {
1395 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); 1395 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null());
1396 const AbstractType& super_type = AbstractType::Handle( 1396 Isolate* isolate = Isolate::Current();
1397 const AbstractType& super_type = AbstractType::Handle(isolate,
1397 mixin_app_class.super_type()); 1398 mixin_app_class.super_type());
1398 ASSERT(super_type.IsResolved()); 1399 ASSERT(super_type.IsResolved());
1399 const Class& super_class = Class::Handle(super_type.type_class()); 1400 const Class& super_class = Class::Handle(isolate, super_type.type_class());
1400 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 1401 const intptr_t num_super_type_params = super_class.NumTypeParameters();
1401 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); 1402 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin());
1402 const Class& mixin_class = Class::Handle(mixin_type.type_class()); 1403 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class());
1403 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); 1404 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
1404 // The mixin class cannot be Object and this was checked earlier. 1405 // The mixin class cannot be Object and this was checked earlier.
1405 ASSERT(!mixin_class.IsObjectClass()); 1406 ASSERT(!mixin_class.IsObjectClass());
1406 1407
1407 // Add the mixin type to the interfaces that the mixin application 1408 // Add the mixin type to the interfaces that the mixin application
1408 // class implements. This is necessary so that type tests work. 1409 // class implements. This is necessary so that type tests work.
1409 const Array& interfaces = Array::Handle(Array::New(1)); 1410 const Array& interfaces = Array::Handle(isolate, Array::New(1));
1410 const Type& interface = Type::Handle(Type::New( 1411 const Type& interface = Type::Handle(isolate, Type::New(
1411 mixin_class, 1412 mixin_class,
1412 Object::null_abstract_type_arguments(), // Set again below if generic. 1413 Object::null_abstract_type_arguments(), // Set again below if generic.
1413 mixin_app_class.token_pos())); 1414 mixin_app_class.token_pos()));
1414 ASSERT(!interface.IsFinalized()); 1415 ASSERT(!interface.IsFinalized());
1415 interfaces.SetAt(0, interface); 1416 interfaces.SetAt(0, interface);
1416 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); 1417 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw());
1417 mixin_app_class.set_interfaces(interfaces); 1418 mixin_app_class.set_interfaces(interfaces);
1418 1419
1419 // If both the super type and the mixin type are non generic, the mixin 1420 // If both the super type and the mixin type are non generic, the mixin
1420 // application class is non generic as well and we can skip type parameter 1421 // application class is non generic as well and we can skip type parameter
1421 // cloning. 1422 // cloning.
1423 bool has_uninstantiated_bounds = false;
1422 if ((num_super_type_params + num_mixin_type_params) > 0) { 1424 if ((num_super_type_params + num_mixin_type_params) > 0) {
1423 // First, clone the super class type parameters. Rename them so that 1425 // First, clone the super class type parameters. Rename them so that
1424 // there can be no name conflict between the parameters of the super 1426 // there can be no name conflict between the parameters of the super
1425 // class and the mixin class. 1427 // class and the mixin class.
1426 const TypeArguments& cloned_type_params = TypeArguments::Handle( 1428 const TypeArguments& cloned_type_params = TypeArguments::Handle(isolate,
1427 TypeArguments::New(num_super_type_params + num_mixin_type_params)); 1429 TypeArguments::New(num_super_type_params + num_mixin_type_params));
1428 TypeParameter& param = TypeParameter::Handle(); 1430 TypeParameter& param = TypeParameter::Handle(isolate);
1429 TypeParameter& cloned_param = TypeParameter::Handle(); 1431 TypeParameter& cloned_param = TypeParameter::Handle(isolate);
1430 String& param_name = String::Handle(); 1432 String& param_name = String::Handle(isolate);
1431 AbstractType& param_bound = AbstractType::Handle(); 1433 AbstractType& param_bound = AbstractType::Handle(isolate);
1432 intptr_t cloned_index = 0; 1434 intptr_t cloned_index = 0;
1433 if (num_super_type_params > 0) { 1435 if (num_super_type_params > 0) {
1434 const TypeArguments& super_type_params = 1436 const TypeArguments& super_type_params =
1435 TypeArguments::Handle(super_class.type_parameters()); 1437 TypeArguments::Handle(isolate, super_class.type_parameters());
1436 const TypeArguments& super_type_args = 1438 const TypeArguments& super_type_args = TypeArguments::Handle(isolate,
1437 TypeArguments::Handle(TypeArguments::New(num_super_type_params)); 1439 TypeArguments::New(num_super_type_params));
1440 // The cloned super class type parameters do not need to repeat their
1441 // bounds, since the bound checks will be performed at the super class
1442 // level.
1443 param_bound = isolate->object_store()->object_type();
1438 for (intptr_t i = 0; i < num_super_type_params; i++) { 1444 for (intptr_t i = 0; i < num_super_type_params; i++) {
1439 param ^= super_type_params.TypeAt(i); 1445 param ^= super_type_params.TypeAt(i);
1440 param_name = param.name(); 1446 param_name = param.name();
1441 param_bound = param.bound();
1442 // TODO(14453): handle type bounds.
1443 if (!param_bound.IsObjectType()) {
1444 const Script& script = Script::Handle(mixin_app_class.script());
1445 ReportError(Error::Handle(), // No previous error.
1446 script, param.token_pos(),
1447 "type parameter '%s': type bounds not yet"
1448 " implemented for mixins\n",
1449 param_name.ToCString());
1450 }
1451 param_name = String::Concat(param_name, Symbols::Backtick()); 1447 param_name = String::Concat(param_name, Symbols::Backtick());
1452 param_name = Symbols::New(param_name); 1448 param_name = Symbols::New(param_name);
1453 cloned_param = TypeParameter::New(mixin_app_class, 1449 cloned_param = TypeParameter::New(mixin_app_class,
1454 cloned_index, 1450 cloned_index,
1455 param_name, 1451 param_name,
1456 param_bound, 1452 param_bound,
1457 param.token_pos()); 1453 param.token_pos());
1458 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1454 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1459 // Change the type arguments of the super type to refer to the 1455 // Change the type arguments of the super type to refer to the
1460 // cloned type parameters of the mixin application class. 1456 // cloned type parameters of the mixin application class.
1461 super_type_args.SetTypeAt(cloned_index, cloned_param); 1457 super_type_args.SetTypeAt(cloned_index, cloned_param);
1462 cloned_index++; 1458 cloned_index++;
1463 } 1459 }
1464 // TODO(14453): May need to handle BoundedType here. 1460 // The super type may have a BoundedType as type argument, but cannot be
1465 ASSERT(super_type.IsType()); 1461 // a BoundedType itself.
1466 Type::Cast(super_type).set_arguments(super_type_args); 1462 Type::Cast(super_type).set_arguments(super_type_args);
1467 ASSERT(!super_type.IsFinalized()); 1463 ASSERT(!super_type.IsFinalized());
1468 } 1464 }
1469 1465
1470 // Second, clone the type parameters of the mixin class. 1466 // Second, clone the type parameters of the mixin class.
1471 // We need to retain the parameter names of the mixin class 1467 // We need to retain the parameter names of the mixin class
1472 // since the code that will be compiled in the context of the 1468 // since the code that will be compiled in the context of the
1473 // mixin application class may refer to the type parameters 1469 // mixin application class may refer to the type parameters
1474 // with that name. 1470 // with that name.
1475 if (num_mixin_type_params > 0) { 1471 if (num_mixin_type_params > 0) {
1476 const TypeArguments& mixin_params = 1472 const TypeArguments& mixin_params =
1477 TypeArguments::Handle(mixin_class.type_parameters()); 1473 TypeArguments::Handle(isolate, mixin_class.type_parameters());
1478 const TypeArguments& mixin_type_args = TypeArguments::Handle( 1474 const TypeArguments& mixin_type_args = TypeArguments::Handle(isolate,
1479 TypeArguments::New(num_mixin_type_params)); 1475 TypeArguments::New(num_mixin_type_params));
1480 // TODO(regis): Can we share interface type and mixin_type? 1476 // TODO(regis): Can we share interface type and mixin_type?
1481 const TypeArguments& interface_type_args = TypeArguments::Handle( 1477 const TypeArguments& interface_type_args = TypeArguments::Handle(isolate,
1482 TypeArguments::New(num_mixin_type_params)); 1478 TypeArguments::New(num_mixin_type_params));
1483 for (intptr_t i = 0; i < num_mixin_type_params; i++) { 1479 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1484 param ^= mixin_params.TypeAt(i); 1480 param ^= mixin_params.TypeAt(i);
1485 param_name = param.name(); 1481 param_name = param.name();
1486 param_bound = param.bound(); 1482 param_bound = param.bound(); // The bound will be adjusted below.
1487 1483 if (!param_bound.IsInstantiated()) {
1488 // TODO(14453): handle type bounds. 1484 has_uninstantiated_bounds = true;
1489 if (!param_bound.IsObjectType()) {
1490 const Script& script = Script::Handle(mixin_app_class.script());
1491 ReportError(Error::Handle(), // No previous error.
1492 script, param.token_pos(),
1493 "type parameter '%s': type bounds not yet"
1494 " implemented for mixins\n",
1495 param_name.ToCString());
1496 } 1485 }
1497 cloned_param = TypeParameter::New(mixin_app_class, 1486 cloned_param = TypeParameter::New(mixin_app_class,
1498 cloned_index, 1487 cloned_index,
1499 param_name, 1488 param_name,
1500 param_bound, 1489 param_bound,
1501 param.token_pos()); 1490 param.token_pos());
1502 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1491 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1503 interface_type_args.SetTypeAt(i, cloned_param); 1492 interface_type_args.SetTypeAt(i, cloned_param);
1504 mixin_type_args.SetTypeAt(i, cloned_param); 1493 mixin_type_args.SetTypeAt(i, cloned_param);
1505 cloned_index++; 1494 cloned_index++;
1506 } 1495 }
1507 1496
1497 // Third, replace the type parameters appearing in the bounds of the mixin
1498 // type parameters, if any, by the cloned type parameters. This can be
1499 // done by instantiating each bound using the mixin_type_args as
1500 // instantiator. Since the mixin class must extend Object, its first type
1501 // parameter has index 0, therefore, the instantiator does not require
1502 // shifting. There is however an exception where the mixin class is an
1503 // alias, in which case shifting is required and performed later in
1504 // ApplyMixinAppAlias.
1505 // Unfinalized type parameters replace finalized type parameters, which
1506 // is not a problem since they will get finalized shortly as the mixin
1507 // application class gets finalized.
1508 if (has_uninstantiated_bounds && !mixin_class.is_mixin_app_alias()) {
1509 Error& bound_error = Error::Handle(isolate);
1510 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1511 param ^= mixin_type_args.TypeAt(i);
1512 param_bound = param.bound();
1513 if (!param_bound.IsInstantiated()) {
1514 param_bound = param_bound.InstantiateFrom(mixin_type_args,
1515 &bound_error);
1516 // The instantiator contains only TypeParameter objects and no
1517 // BoundedType objects, so no bound error may occur.
1518 ASSERT(bound_error.IsNull());
1519 ASSERT(!param_bound.IsInstantiated());
1520 param.set_bound(param_bound);
1521 }
1522 }
1523 }
1524
1508 // Lastly, set the type arguments of the mixin type and of the single 1525 // Lastly, set the type arguments of the mixin type and of the single
1509 // interface type. 1526 // interface type.
1510 ASSERT(!mixin_type.IsFinalized()); 1527 ASSERT(!mixin_type.IsFinalized());
1511 mixin_type.set_arguments(mixin_type_args); 1528 mixin_type.set_arguments(mixin_type_args);
1512 ASSERT(!interface.IsFinalized()); 1529 ASSERT(!interface.IsFinalized());
1513 interface.set_arguments(interface_type_args); 1530 interface.set_arguments(interface_type_args);
1514 } 1531 }
1515 mixin_app_class.set_type_parameters(cloned_type_params); 1532 mixin_app_class.set_type_parameters(cloned_type_params);
1516 } 1533 }
1517 // If the mixin class is a mixin application alias class, we insert a new 1534 // If the mixin class is a mixin application alias class, we insert a new
1518 // synthesized mixin application class in the super chain of this mixin 1535 // synthesized mixin application class in the super chain of this mixin
1519 // application class. The new class will have the aliased mixin as actual 1536 // application class. The new class will have the aliased mixin as actual
1520 // mixin. 1537 // mixin.
1521 if (mixin_class.is_mixin_app_alias()) { 1538 if (mixin_class.is_mixin_app_alias()) {
1522 ApplyMixinAppAlias(mixin_app_class); 1539 ApplyMixinAppAlias(mixin_app_class, has_uninstantiated_bounds);
1523 } 1540 }
1524 } 1541 }
1525 1542
1526 1543
1527 /* Support for mixin alias. 1544 /* Support for mixin alias.
1528 Consider the following example: 1545 Consider the following example:
1529 1546
1530 class I<T> { } 1547 class I<T> { }
1531 class J<T> { } 1548 class J<T> { }
1532 class S<T> { } 1549 class S<T> { }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 We now have: 1585 We now have:
1569 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... } 1586 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... }
1570 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { } 1587 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { }
1571 1588
1572 The main implementation difficulty resides in the fact that the type parameters 1589 The main implementation difficulty resides in the fact that the type parameters
1573 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type 1590 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type
1574 parameters U and V of S&A. However, Map<U, V> is copied from the super type 1591 parameters U and V of S&A. However, Map<U, V> is copied from the super type
1575 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation 1592 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation
1576 step with a properly crafted instantiator vector takes care of the required type 1593 step with a properly crafted instantiator vector takes care of the required type
1577 parameter substitution. 1594 parameter substitution.
1578
1579 The instantiator vector must end with the type parameters U and V of S&A. 1595 The instantiator vector must end with the type parameters U and V of S&A.
1580 The offset of the first type parameter U of S&A must be at the finalized index 1596 The offset of the first type parameter U of S&A must be at the finalized index
1581 of type parameter U of A. 1597 of type parameter U of A.
1598
1599 The same instantiator vector is used to adjust the type parameter bounds on U
1600 and V, if any. This step was postponed from CloneMixinAppTypeParameters above.
1601
1602 Also, a possible bound on type parameter T of M (not shown in the example above)
1603 must be applied to type parameter T of S&A`. If the bound is uninstantiated,
1604 i.e. if it refers to T or other type parameters of M, an instantiation step is
1605 required to substitute these type parameters of M with type parameters of S&A`.
1606 The instantiator vector consists of the cloned type parameters of M without
1607 offset, since class M must extend Object. This is done in the recursive call to
1608 CloneMixinAppTypeParameters and does not require specific code in
1609 ApplyMixinAppAlias.
1582 */ 1610 */
1583 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class) { 1611 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class,
1612 bool has_uninstantiated_bounds) {
1584 // If this mixin alias is aliasing another mixin alias, another class 1613 // If this mixin alias is aliasing another mixin alias, another class
1585 // will be inserted via recursion. No need to check here. 1614 // will be inserted via recursion. No need to check here.
1586 // The mixin type may or may not be finalized yet. 1615 // The mixin type may or may not be finalized yet.
1587 AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type()); 1616 Isolate* isolate = Isolate::Current();
1588 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); 1617 AbstractType& super_type = AbstractType::Handle(isolate,
1589 const Class& mixin_class = Class::Handle(mixin_type.type_class()); 1618 mixin_app_class.super_type());
1619 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin());
1620 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class());
1590 ASSERT(mixin_class.is_mixin_app_alias()); 1621 ASSERT(mixin_class.is_mixin_app_alias());
1591 const Class& aliased_mixin_app_class = Class::Handle( 1622 const Class& aliased_mixin_app_class = Class::Handle(isolate,
1592 mixin_class.SuperClass()); 1623 mixin_class.SuperClass());
1593 const Type& aliased_mixin_type = Type::Handle( 1624 const Type& aliased_mixin_type = Type::Handle(isolate,
1594 aliased_mixin_app_class.mixin()); 1625 aliased_mixin_app_class.mixin());
1595 // The name of the inserted mixin application class is the name of mixin 1626 // The name of the inserted mixin application class is the name of mixin
1596 // class name with a backtick added. 1627 // class name with a backtick added.
1597 String& inserted_class_name = String::Handle(mixin_app_class.Name()); 1628 String& inserted_class_name = String::Handle(isolate, mixin_app_class.Name());
1598 inserted_class_name = String::Concat(inserted_class_name, 1629 inserted_class_name = String::Concat(inserted_class_name,
1599 Symbols::Backtick()); 1630 Symbols::Backtick());
1600 const Library& library = Library::Handle(mixin_app_class.library()); 1631 const Library& library = Library::Handle(isolate, mixin_app_class.library());
1601 Class& inserted_class = Class::Handle( 1632 Class& inserted_class = Class::Handle(isolate,
1602 library.LookupLocalClass(inserted_class_name)); 1633 library.LookupLocalClass(inserted_class_name));
1603 if (inserted_class.IsNull()) { 1634 if (inserted_class.IsNull()) {
1604 inserted_class_name = Symbols::New(inserted_class_name); 1635 inserted_class_name = Symbols::New(inserted_class_name);
1605 const Script& script = Script::Handle(mixin_app_class.script()); 1636 const Script& script = Script::Handle(isolate, mixin_app_class.script());
1606 inserted_class = Class::New( 1637 inserted_class = Class::New(
1607 inserted_class_name, script, mixin_app_class.token_pos()); 1638 inserted_class_name, script, mixin_app_class.token_pos());
1608 inserted_class.set_is_synthesized_class(); 1639 inserted_class.set_is_synthesized_class();
1609 library.AddClass(inserted_class); 1640 library.AddClass(inserted_class);
1610 1641
1611 if (FLAG_trace_class_finalization) { 1642 if (FLAG_trace_class_finalization) {
1612 OS::Print("Creating mixin application alias %s\n", 1643 OS::Print("Creating mixin application alias %s\n",
1613 inserted_class.ToCString()); 1644 inserted_class.ToCString());
1614 } 1645 }
1615 1646
1616 // The super type of the inserted class is identical to the super type of 1647 // The super type of the inserted class is identical to the super type of
1617 // this mixin application class, except that it must refer to the type 1648 // this mixin application class, except that it must refer to the type
1618 // parameters of the inserted class rather than to those of the mixin 1649 // parameters of the inserted class rather than to those of the mixin
1619 // application class. 1650 // application class.
1620 // The type arguments of the super type will be set properly when calling 1651 // The type arguments of the super type will be set properly when calling
1621 // CloneMixinAppTypeParameters on the inserted class, as long as the super 1652 // CloneMixinAppTypeParameters on the inserted class, as long as the super
1622 // type class is set properly. 1653 // type class is set properly.
1623 inserted_class.set_super_type(super_type); // Super class only is used. 1654 inserted_class.set_super_type(super_type); // Super class only is used.
1624 1655
1625 // The mixin type and interface type must also be set before calling 1656 // The mixin type and interface type must also be set before calling
1626 // CloneMixinAppTypeParameters. 1657 // CloneMixinAppTypeParameters.
1627 // After FinalizeTypesInClass, they will refer to the type parameters of 1658 // After FinalizeTypesInClass, they will refer to the type parameters of
1628 // the mixin class typedef. 1659 // the mixin class typedef.
1629 const Type& generic_mixin_type = Type::Handle( 1660 const Type& generic_mixin_type = Type::Handle(isolate,
1630 Type::New(Class::Handle(aliased_mixin_type.type_class()), 1661 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()),
1631 Object::null_abstract_type_arguments(), 1662 Object::null_abstract_type_arguments(),
1632 aliased_mixin_type.token_pos())); 1663 aliased_mixin_type.token_pos()));
1633 inserted_class.set_mixin(generic_mixin_type); 1664 inserted_class.set_mixin(generic_mixin_type);
1634 // The interface will be set in CloneMixinAppTypeParameters. 1665 // The interface will be set in CloneMixinAppTypeParameters.
1635 } 1666 }
1636 1667
1637 // Finalize the types and call CloneMixinAppTypeParameters. 1668 // Finalize the types and call CloneMixinAppTypeParameters.
1638 FinalizeTypesInClass(inserted_class); 1669 FinalizeTypesInClass(inserted_class);
1639 1670
1640 // The super type of this mixin application class must point to the 1671 // The super type of this mixin application class must point to the
1641 // inserted class. The super type arguments are the concatenation of the 1672 // inserted class. The super type arguments are the concatenation of the
1642 // old super type arguments (propagating type arguments to the super class) 1673 // old super type arguments (propagating type arguments to the super class)
1643 // with new type arguments providing type arguments to the mixin. 1674 // with new type arguments providing type arguments to the mixin.
1644 // The appended type arguments are those of the super type of the mixin 1675 // The appended type arguments are those of the super type of the mixin
1645 // application alias that are forwarding to the aliased mixin type, except 1676 // application alias that are forwarding to the aliased mixin type, except
1646 // that they must refer to the type parameters of the mixin application 1677 // that they must refer to the type parameters of the mixin application
1647 // class rather than to those of the mixin application alias class. 1678 // class rather than to those of the mixin application alias class.
1648 // This type parameter substitution is performed by an instantiation step. 1679 // This type parameter substitution is performed by an instantiation step.
1649 // It is important that the type parameters of the mixin application class 1680 // It is important that the type parameters of the mixin application class
1650 // are not finalized yet, because new type parameters may have been added 1681 // are not finalized yet, because new type parameters may have been added
1651 // to the super class. 1682 // to the super class.
1652 Class& super_class = Class::Handle(super_type.type_class()); 1683 Class& super_class = Class::Handle(isolate, super_type.type_class());
1653 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); 1684 ASSERT(mixin_app_class.SuperClass() == super_class.raw());
1654 while (super_class.IsMixinApplication()) { 1685 while (super_class.IsMixinApplication()) {
1655 super_class = super_class.SuperClass(); 1686 super_class = super_class.SuperClass();
1656 } 1687 }
1657 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 1688 const intptr_t num_super_type_params = super_class.NumTypeParameters();
1658 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); 1689 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
1659 intptr_t offset = 1690 intptr_t offset =
1660 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters(); 1691 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters();
1661 const TypeArguments& type_params = 1692 const TypeArguments& type_params =
1662 TypeArguments::Handle(mixin_app_class.type_parameters()); 1693 TypeArguments::Handle(isolate, mixin_app_class.type_parameters());
1663 TypeArguments& instantiator = TypeArguments::Handle( 1694 TypeArguments& instantiator = TypeArguments::Handle(isolate,
1664 TypeArguments::New(offset + num_mixin_type_params)); 1695 TypeArguments::New(offset + num_mixin_type_params));
1665 AbstractType& type = AbstractType::Handle(); 1696 AbstractType& type = AbstractType::Handle(isolate);
1666 for (intptr_t i = 0; i < num_mixin_type_params; i++) { 1697 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1667 type = type_params.TypeAt(num_super_type_params + i); 1698 type = type_params.TypeAt(num_super_type_params + i);
1668 instantiator.SetTypeAt(offset + i, type); 1699 instantiator.SetTypeAt(offset + i, type);
1669 } 1700 }
1670 ASSERT(aliased_mixin_type.IsFinalized()); 1701 ASSERT(aliased_mixin_type.IsFinalized());
1671 const Class& aliased_mixin_type_class = Class::Handle( 1702 const Class& aliased_mixin_type_class = Class::Handle(isolate,
1672 aliased_mixin_type.type_class()); 1703 aliased_mixin_type.type_class());
1673 const intptr_t num_aliased_mixin_type_params = 1704 const intptr_t num_aliased_mixin_type_params =
1674 aliased_mixin_type_class.NumTypeParameters(); 1705 aliased_mixin_type_class.NumTypeParameters();
1675 const intptr_t num_aliased_mixin_type_args = 1706 const intptr_t num_aliased_mixin_type_args =
1676 aliased_mixin_type_class.NumTypeArguments(); 1707 aliased_mixin_type_class.NumTypeArguments();
1677 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; 1708 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params;
1678 ASSERT(inserted_class.NumTypeParameters() == 1709 ASSERT(inserted_class.NumTypeParameters() ==
1679 (num_super_type_params + num_aliased_mixin_type_params)); 1710 (num_super_type_params + num_aliased_mixin_type_params));
1680 // The aliased_mixin_type may be raw. 1711 // The aliased_mixin_type may be raw.
1681 const AbstractTypeArguments& mixin_class_super_type_args = 1712 const AbstractTypeArguments& mixin_class_super_type_args =
1682 AbstractTypeArguments::Handle( 1713 AbstractTypeArguments::Handle(isolate,
1683 AbstractType::Handle(mixin_class.super_type()).arguments()); 1714 AbstractType::Handle(isolate, mixin_class.super_type()).arguments());
1684 TypeArguments& new_mixin_type_args = TypeArguments::Handle(); 1715 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate);
1685 if ((num_aliased_mixin_type_params > 0) && 1716 if ((num_aliased_mixin_type_params > 0) &&
1686 !mixin_class_super_type_args.IsNull()) { 1717 !mixin_class_super_type_args.IsNull()) {
1687 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); 1718 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params);
1688 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { 1719 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
1689 type = mixin_class_super_type_args.TypeAt(offset + i); 1720 type = mixin_class_super_type_args.TypeAt(offset + i);
1690 new_mixin_type_args.SetTypeAt(i, type); 1721 new_mixin_type_args.SetTypeAt(i, type);
1691 } 1722 }
1692 } 1723 }
1693 if (!new_mixin_type_args.IsNull() && 1724 if (!new_mixin_type_args.IsNull() &&
1694 !new_mixin_type_args.IsInstantiated()) { 1725 !new_mixin_type_args.IsInstantiated()) {
1695 Error& bound_error = Error::Handle(); 1726 Error& bound_error = Error::Handle(isolate);
1696 new_mixin_type_args ^= 1727 new_mixin_type_args ^=
1697 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error); 1728 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error);
1698 // TODO(14453): Handle bound error. 1729 // The instantiator contains only TypeParameter objects and no BoundedType
1730 // objects, so no bound error may occur.
1699 ASSERT(bound_error.IsNull()); 1731 ASSERT(bound_error.IsNull());
1700 } 1732 }
1701 TypeArguments& new_super_type_args = TypeArguments::Handle(); 1733 TypeArguments& new_super_type_args = TypeArguments::Handle(isolate);
1702 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { 1734 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) {
1703 new_super_type_args = TypeArguments::New(num_super_type_params + 1735 new_super_type_args = TypeArguments::New(num_super_type_params +
1704 num_aliased_mixin_type_params); 1736 num_aliased_mixin_type_params);
1705 for (intptr_t i = 0; i < num_super_type_params; i++) { 1737 for (intptr_t i = 0; i < num_super_type_params; i++) {
1706 type = type_params.TypeAt(i); 1738 type = type_params.TypeAt(i);
1707 new_super_type_args.SetTypeAt(i, type); 1739 new_super_type_args.SetTypeAt(i, type);
1708 } 1740 }
1709 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { 1741 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
1710 if (new_mixin_type_args.IsNull()) { 1742 if (new_mixin_type_args.IsNull()) {
1711 type = Type::DynamicType(); 1743 type = Type::DynamicType();
1712 } else { 1744 } else {
1713 type = new_mixin_type_args.TypeAt(i); 1745 type = new_mixin_type_args.TypeAt(i);
1714 } 1746 }
1715 new_super_type_args.SetTypeAt(num_super_type_params + i, type); 1747 new_super_type_args.SetTypeAt(num_super_type_params + i, type);
1716 } 1748 }
1717 } 1749 }
1718 super_type = Type::New(inserted_class, 1750 super_type = Type::New(inserted_class,
1719 new_super_type_args, 1751 new_super_type_args,
1720 mixin_app_class.token_pos()); 1752 mixin_app_class.token_pos());
1721 mixin_app_class.set_super_type(super_type); 1753 mixin_app_class.set_super_type(super_type);
1754
1755 // Perform the bound adjustment posponed from CloneMixinAppTypeParameters.
1756 if (has_uninstantiated_bounds) {
1757 TypeParameter& param = TypeParameter::Handle(isolate);
1758 AbstractType& param_bound = AbstractType::Handle(isolate);
1759 Error& bound_error = Error::Handle(isolate);
1760 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1761 param ^= type_params.TypeAt(num_super_type_params + i);
1762 param_bound = param.bound();
1763 if (!param_bound.IsInstantiated()) {
1764 param_bound = param_bound.InstantiateFrom(instantiator, &bound_error);
1765 // The instantiator contains only TypeParameter objects and no
1766 // BoundedType objects, so no bound error may occur.
1767 ASSERT(bound_error.IsNull());
1768 ASSERT(!param_bound.IsInstantiated());
1769 param.set_bound(param_bound);
1770 }
1771 }
1772 }
1773
1722 // Mark this mixin application class as being an alias. 1774 // Mark this mixin application class as being an alias.
1723 mixin_app_class.set_is_mixin_app_alias(); 1775 mixin_app_class.set_is_mixin_app_alias();
1724 ASSERT(!mixin_app_class.is_type_finalized()); 1776 ASSERT(!mixin_app_class.is_type_finalized());
1725 ASSERT(!mixin_app_class.is_mixin_type_applied()); 1777 ASSERT(!mixin_app_class.is_mixin_type_applied());
1726 if (FLAG_trace_class_finalization) { 1778 if (FLAG_trace_class_finalization) {
1727 OS::Print("Inserting class %s to mixin application alias %s " 1779 OS::Print("Inserting class %s to mixin application alias %s "
1728 "with super type '%s'\n", 1780 "with super type '%s'\n",
1729 inserted_class.ToCString(), 1781 inserted_class.ToCString(),
1730 mixin_app_class.ToCString(), 1782 mixin_app_class.ToCString(),
1731 String::Handle(super_type.Name()).ToCString()); 1783 String::Handle(isolate, super_type.Name()).ToCString());
1732 } 1784 }
1733 } 1785 }
1734 1786
1735 1787
1736 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, 1788 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class,
1737 GrowableObjectArray* pending_types) { 1789 GrowableObjectArray* pending_types) {
1738 if (mixin_app_class.is_mixin_type_applied()) { 1790 if (mixin_app_class.is_mixin_type_applied()) {
1739 return; 1791 return;
1740 } 1792 }
1741 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); 1793 Type& mixin_type = Type::Handle(mixin_app_class.mixin());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 } 1851 }
1800 // Mark the application class as having been applied its mixin type in order 1852 // Mark the application class as having been applied its mixin type in order
1801 // to avoid cycles while finalizing its mixin type. 1853 // to avoid cycles while finalizing its mixin type.
1802 mixin_app_class.set_is_mixin_type_applied(); 1854 mixin_app_class.set_is_mixin_type_applied();
1803 // Finalize the mixin type, which may have been changed in case 1855 // Finalize the mixin type, which may have been changed in case
1804 // mixin_app_class is an alias. 1856 // mixin_app_class is an alias.
1805 mixin_type = mixin_app_class.mixin(); 1857 mixin_type = mixin_app_class.mixin();
1806 ASSERT(!mixin_type.IsBeingFinalized()); 1858 ASSERT(!mixin_type.IsBeingFinalized());
1807 mixin_type ^= 1859 mixin_type ^=
1808 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types); 1860 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types);
1809 // TODO(14453): Check for a malbounded mixin_type. 1861 // The mixin type cannot be malbounded, since it merely substitutes the
1862 // type parameters of the mixin class with those of the mixin application
1863 // class, but it does not instantiate them.
1864 ASSERT(!mixin_type.IsMalbounded());
1810 mixin_app_class.set_mixin(mixin_type); 1865 mixin_app_class.set_mixin(mixin_type);
1811 } 1866 }
1812 1867
1813 1868
1814 void ClassFinalizer::CreateForwardingConstructors( 1869 void ClassFinalizer::CreateForwardingConstructors(
1815 const Class& mixin_app, 1870 const Class& mixin_app,
1816 const GrowableObjectArray& cloned_funcs) { 1871 const GrowableObjectArray& cloned_funcs) {
1817 const String& mixin_name = String::Handle(mixin_app.Name()); 1872 const String& mixin_name = String::Handle(mixin_app.Name());
1818 const Class& super_class = Class::Handle(mixin_app.SuperClass()); 1873 const Class& super_class = Class::Handle(mixin_app.SuperClass());
1819 const String& super_name = String::Handle(super_class.Name()); 1874 const String& super_name = String::Handle(super_class.Name());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1869 } 1924 }
1870 } 1925 }
1871 1926
1872 1927
1873 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { 1928 void ClassFinalizer::ApplyMixinMembers(const Class& cls) {
1874 Isolate* isolate = Isolate::Current(); 1929 Isolate* isolate = Isolate::Current();
1875 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); 1930 const Type& mixin_type = Type::Handle(isolate, cls.mixin());
1876 ASSERT(!mixin_type.IsNull()); 1931 ASSERT(!mixin_type.IsNull());
1877 ASSERT(mixin_type.HasResolvedTypeClass()); 1932 ASSERT(mixin_type.HasResolvedTypeClass());
1878 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); 1933 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class());
1879 mixin_cls.EnsureIsFinalized(isolate); 1934 const Error& error = Error::Handle(mixin_cls.EnsureIsFinalized(isolate));
1935 ASSERT(error.IsNull());
1880 // If the mixin is a mixin application alias class, there are no members to 1936 // If the mixin is a mixin application alias class, there are no members to
1881 // apply here. A new synthesized class representing the aliased mixin 1937 // apply here. A new synthesized class representing the aliased mixin
1882 // application class was inserted in the super chain of this mixin application 1938 // application class was inserted in the super chain of this mixin application
1883 // class. Members of the actual mixin class will be applied when visiting 1939 // class. Members of the actual mixin class will be applied when visiting
1884 // the mixin application class referring to the actual mixin. 1940 // the mixin application class referring to the actual mixin.
1885 ASSERT(!mixin_cls.is_mixin_app_alias() || 1941 ASSERT(!mixin_cls.is_mixin_app_alias() ||
1886 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication()); 1942 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication());
1887 // A default constructor will be created for the mixin app alias class. 1943 // A default constructor will be created for the mixin app alias class.
1888 1944
1889 if (FLAG_trace_class_finalization) { 1945 if (FLAG_trace_class_finalization) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 } 2031 }
1976 // Finalize type parameters before finalizing the super type. 2032 // Finalize type parameters before finalizing the super type.
1977 FinalizeTypeParameters(cls); // May change super type. 2033 FinalizeTypeParameters(cls); // May change super type.
1978 super_class = cls.SuperClass(); 2034 super_class = cls.SuperClass();
1979 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); 2035 ASSERT(super_class.IsNull() || super_class.is_type_finalized());
1980 ResolveUpperBounds(cls); 2036 ResolveUpperBounds(cls);
1981 // Finalize super type. 2037 // Finalize super type.
1982 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 2038 AbstractType& super_type = AbstractType::Handle(cls.super_type());
1983 if (!super_type.IsNull()) { 2039 if (!super_type.IsNull()) {
1984 // In case of a bound error in the super type in production mode, the 2040 // In case of a bound error in the super type in production mode, the
1985 // finalized super type will be a BoundedType with a malformed bound. 2041 // finalized super type will have a BoundedType as type argument for the
2042 // out of bound type argument.
1986 // It should not be a problem if the class is written to a snapshot and 2043 // It should not be a problem if the class is written to a snapshot and
1987 // later executed in checked mode. Note that the finalized type argument 2044 // later executed in checked mode. Note that the finalized type argument
1988 // vector of any type of the base class will contain a BoundedType for the 2045 // vector of any type of the base class will contain a BoundedType for the
1989 // out of bound type argument. 2046 // out of bound type argument.
1990 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); 2047 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed);
1991 cls.set_super_type(super_type); 2048 cls.set_super_type(super_type);
1992 } 2049 }
1993 if (cls.IsSignatureClass()) { 2050 if (cls.IsSignatureClass()) {
1994 // Check for illegal self references. 2051 // Check for illegal self references.
1995 GrowableArray<intptr_t> visited_aliases; 2052 GrowableArray<intptr_t> visited_aliases;
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 // and resolve super type and mixin types. 2365 // and resolve super type and mixin types.
2309 const Library& library = Library::Handle(cls.library()); 2366 const Library& library = Library::Handle(cls.library());
2310 ASSERT(!library.IsNull()); 2367 ASSERT(!library.IsNull());
2311 const Script& script = Script::Handle(cls.script()); 2368 const Script& script = Script::Handle(cls.script());
2312 ASSERT(!script.IsNull()); 2369 ASSERT(!script.IsNull());
2313 const GrowableObjectArray& type_args = 2370 const GrowableObjectArray& type_args =
2314 GrowableObjectArray::Handle(GrowableObjectArray::New()); 2371 GrowableObjectArray::Handle(GrowableObjectArray::New());
2315 AbstractType& mixin_super_type = 2372 AbstractType& mixin_super_type =
2316 AbstractType::Handle(mixin_app_type.super_type()); 2373 AbstractType::Handle(mixin_app_type.super_type());
2317 ResolveType(cls, mixin_super_type); 2374 ResolveType(cls, mixin_super_type);
2318 ASSERT(mixin_super_type.HasResolvedTypeClass()); 2375 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed.
2319 // TODO(14453): May need to handle BoundedType here. 2376 // The super type may have a BoundedType as type argument, but cannot be
2320 ASSERT(mixin_super_type.IsType()); 2377 // a BoundedType itself.
2321 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); 2378 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args);
2322 AbstractType& mixin_type = AbstractType::Handle(); 2379 AbstractType& mixin_type = AbstractType::Handle();
2323 Type& generic_mixin_type = Type::Handle(); 2380 Type& generic_mixin_type = Type::Handle();
2324 Class& mixin_type_class = Class::Handle(); 2381 Class& mixin_type_class = Class::Handle();
2325 Class& mixin_app_class = Class::Handle(); 2382 Class& mixin_app_class = Class::Handle();
2326 String& mixin_app_class_name = String::Handle(); 2383 String& mixin_app_class_name = String::Handle();
2327 String& mixin_type_class_name = String::Handle(); 2384 String& mixin_type_class_name = String::Handle();
2328 const intptr_t depth = mixin_app_type.Depth(); 2385 const intptr_t depth = mixin_app_type.Depth();
2329 for (intptr_t i = 0; i < depth; i++) { 2386 for (intptr_t i = 0; i < depth; i++) {
2330 mixin_type = mixin_app_type.MixinTypeAt(i); 2387 mixin_type = mixin_app_type.MixinTypeAt(i);
2331 ASSERT(!mixin_type.IsNull()); 2388 ASSERT(!mixin_type.IsNull());
2332 ResolveType(cls, mixin_type); 2389 ResolveType(cls, mixin_type);
2333 ASSERT(mixin_type.HasResolvedTypeClass()); 2390 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed.
2334 ASSERT(mixin_type.IsType()); 2391 ASSERT(mixin_type.IsType());
2335 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); 2392 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args);
2336 2393
2337 // The name of the mixin application class is a combination of 2394 // The name of the mixin application class is a combination of
2338 // the super class name and mixin class name. 2395 // the super class name and mixin class name.
2339 mixin_app_class_name = mixin_super_type.ClassName(); 2396 mixin_app_class_name = mixin_super_type.ClassName();
2340 mixin_app_class_name = String::Concat(mixin_app_class_name, 2397 mixin_app_class_name = String::Concat(mixin_app_class_name,
2341 Symbols::Ampersand()); 2398 Symbols::Ampersand());
2342 mixin_type_class_name = mixin_type.ClassName(); 2399 mixin_type_class_name = mixin_type.ClassName();
2343 mixin_app_class_name = String::Concat(mixin_app_class_name, 2400 mixin_app_class_name = String::Concat(mixin_app_class_name,
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 expected_name ^= String::New("_offset"); 2860 expected_name ^= String::New("_offset");
2804 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2861 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2805 field ^= fields_array.At(2); 2862 field ^= fields_array.At(2);
2806 ASSERT(field.Offset() == TypedDataView::length_offset()); 2863 ASSERT(field.Offset() == TypedDataView::length_offset());
2807 name ^= field.name(); 2864 name ^= field.name();
2808 ASSERT(name.Equals("length")); 2865 ASSERT(name.Equals("length"));
2809 #endif 2866 #endif
2810 } 2867 }
2811 2868
2812 } // namespace dart 2869 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698