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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 | 113 |
114 // Processing ObjectStore::pending_classes_ occurs: | 114 // Processing ObjectStore::pending_classes_ occurs: |
115 // a) when bootstrap process completes (VerifyBootstrapClasses). | 115 // a) when bootstrap process completes (VerifyBootstrapClasses). |
116 // b) after the user classes are loaded (dart_api). | 116 // b) after the user classes are loaded (dart_api). |
117 bool ClassFinalizer::ProcessPendingClasses() { | 117 bool ClassFinalizer::ProcessPendingClasses() { |
118 Thread* thread = Thread::Current(); | 118 Thread* thread = Thread::Current(); |
119 Isolate* isolate = thread->isolate(); | 119 Isolate* isolate = thread->isolate(); |
120 ASSERT(isolate != NULL); | 120 ASSERT(isolate != NULL); |
121 HANDLESCOPE(thread); | 121 HANDLESCOPE(thread); |
122 ObjectStore* object_store = isolate->object_store(); | 122 ObjectStore* object_store = isolate->object_store(); |
123 const Error& error = Error::Handle(isolate, object_store->sticky_error()); | 123 const Error& error = |
| 124 Error::Handle(thread->zone(), object_store->sticky_error()); |
124 if (!error.IsNull()) { | 125 if (!error.IsNull()) { |
125 return false; | 126 return false; |
126 } | 127 } |
127 if (AllClassesFinalized()) { | 128 if (AllClassesFinalized()) { |
128 return true; | 129 return true; |
129 } | 130 } |
130 | 131 |
131 LongJumpScope jump; | 132 LongJumpScope jump; |
132 if (setjmp(*jump.Set()) == 0) { | 133 if (setjmp(*jump.Set()) == 0) { |
133 GrowableObjectArray& class_array = GrowableObjectArray::Handle(); | 134 GrowableObjectArray& class_array = GrowableObjectArray::Handle(); |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 // The induced type set S consists of the super types of any type in S as well | 556 // The induced type set S consists of the super types of any type in S as well |
556 // as the type arguments of any parameterized type in S. | 557 // as the type arguments of any parameterized type in S. |
557 // The Dart Language Specification does not disallow the declaration and use of | 558 // The Dart Language Specification does not disallow the declaration and use of |
558 // non-contractive types (this may change). They are nevertheless disallowed | 559 // non-contractive types (this may change). They are nevertheless disallowed |
559 // as an implementation restriction in the VM since they cause divergence. | 560 // as an implementation restriction in the VM since they cause divergence. |
560 // A non-contractive type can be detected by looking at the queue of types | 561 // A non-contractive type can be detected by looking at the queue of types |
561 // pending finalization that are mutually recursive with the checked type. | 562 // pending finalization that are mutually recursive with the checked type. |
562 void ClassFinalizer::CheckRecursiveType(const Class& cls, | 563 void ClassFinalizer::CheckRecursiveType(const Class& cls, |
563 const Type& type, | 564 const Type& type, |
564 PendingTypes* pending_types) { | 565 PendingTypes* pending_types) { |
565 Isolate* isolate = Isolate::Current(); | 566 Zone* zone = Thread::Current()->zone(); |
566 if (FLAG_trace_type_finalization) { | 567 if (FLAG_trace_type_finalization) { |
567 THR_Print("Checking recursive type '%s': %s\n", | 568 THR_Print("Checking recursive type '%s': %s\n", |
568 String::Handle(type.Name()).ToCString(), | 569 String::Handle(type.Name()).ToCString(), |
569 type.ToCString()); | 570 type.ToCString()); |
570 } | 571 } |
571 const Class& type_cls = Class::Handle(isolate, type.type_class()); | 572 const Class& type_cls = Class::Handle(zone, type.type_class()); |
572 const TypeArguments& arguments = | 573 const TypeArguments& arguments = |
573 TypeArguments::Handle(isolate, type.arguments()); | 574 TypeArguments::Handle(zone, type.arguments()); |
574 // A type can only be recursive via its type arguments. | 575 // A type can only be recursive via its type arguments. |
575 ASSERT(!arguments.IsNull()); | 576 ASSERT(!arguments.IsNull()); |
576 const intptr_t num_type_args = arguments.Length(); | 577 const intptr_t num_type_args = arguments.Length(); |
577 ASSERT(num_type_args > 0); | 578 ASSERT(num_type_args > 0); |
578 ASSERT(num_type_args == type_cls.NumTypeArguments()); | 579 ASSERT(num_type_args == type_cls.NumTypeArguments()); |
579 const intptr_t num_type_params = type_cls.NumTypeParameters(); | 580 const intptr_t num_type_params = type_cls.NumTypeParameters(); |
580 const intptr_t first_type_param = num_type_args - num_type_params; | 581 const intptr_t first_type_param = num_type_args - num_type_params; |
581 // If the type is not generic (num_type_params == 0) or if its type parameters | 582 // If the type is not generic (num_type_params == 0) or if its type parameters |
582 // are instantiated, no divergence can occur. Note that if the type parameters | 583 // are instantiated, no divergence can occur. Note that if the type parameters |
583 // are null, i.e. if the generic type is raw, they are considered | 584 // are null, i.e. if the generic type is raw, they are considered |
584 // instantiated and no divergence can occur. | 585 // instantiated and no divergence can occur. |
585 if ((num_type_params == 0) || | 586 if ((num_type_params == 0) || |
586 arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) { | 587 arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) { |
587 return; | 588 return; |
588 } | 589 } |
589 // The type parameters are not instantiated. Verify that there is no other | 590 // The type parameters are not instantiated. Verify that there is no other |
590 // type pending finalization with the same type class, but different | 591 // type pending finalization with the same type class, but different |
591 // uninstantiated type parameters. | 592 // uninstantiated type parameters. |
592 TypeArguments& pending_arguments = TypeArguments::Handle(isolate); | 593 TypeArguments& pending_arguments = TypeArguments::Handle(zone); |
593 const intptr_t num_pending_types = pending_types->length(); | 594 const intptr_t num_pending_types = pending_types->length(); |
594 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { | 595 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { |
595 const Type& pending_type = Type::Cast(pending_types->At(i)); | 596 const Type& pending_type = Type::Cast(pending_types->At(i)); |
596 if (FLAG_trace_type_finalization) { | 597 if (FLAG_trace_type_finalization) { |
597 THR_Print(" Comparing with pending type '%s': %s\n", | 598 THR_Print(" Comparing with pending type '%s': %s\n", |
598 String::Handle(pending_type.Name()).ToCString(), | 599 String::Handle(pending_type.Name()).ToCString(), |
599 pending_type.ToCString()); | 600 pending_type.ToCString()); |
600 } | 601 } |
601 if ((pending_type.raw() != type.raw()) && | 602 if ((pending_type.raw() != type.raw()) && |
602 (pending_type.type_class() == type_cls.raw())) { | 603 (pending_type.type_class() == type_cls.raw())) { |
603 pending_arguments = pending_type.arguments(); | 604 pending_arguments = pending_type.arguments(); |
604 if (!pending_arguments.IsSubvectorEquivalent(arguments, | 605 if (!pending_arguments.IsSubvectorEquivalent(arguments, |
605 first_type_param, | 606 first_type_param, |
606 num_type_params) && | 607 num_type_params) && |
607 !pending_arguments.IsSubvectorInstantiated(first_type_param, | 608 !pending_arguments.IsSubvectorInstantiated(first_type_param, |
608 num_type_params)) { | 609 num_type_params)) { |
609 // Reject the non-contractive recursive type. | 610 // Reject the non-contractive recursive type. |
610 const String& type_name = String::Handle(isolate, type.Name()); | 611 const String& type_name = String::Handle(zone, type.Name()); |
611 ReportError(cls, type.token_pos(), | 612 ReportError(cls, type.token_pos(), |
612 "illegal recursive type '%s'", type_name.ToCString()); | 613 "illegal recursive type '%s'", type_name.ToCString()); |
613 } | 614 } |
614 } | 615 } |
615 } | 616 } |
616 } | 617 } |
617 | 618 |
618 | 619 |
619 // Finalize the type argument vector 'arguments' of the type defined by the | 620 // Finalize the type argument vector 'arguments' of the type defined by the |
620 // class 'cls' parameterized with the type arguments 'cls_args'. | 621 // class 'cls' parameterized with the type arguments 'cls_args'. |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 // class C<E extends BE> extends S<E> with M<List<E>> { } | 1567 // class C<E extends BE> extends S<E> with M<List<E>> { } |
1567 // results in | 1568 // results in |
1568 // class S&M<T`, T extends BT> extends S<T`> implements M<T> { } | 1569 // class S&M<T`, T extends BT> extends S<T`> implements M<T> { } |
1569 // class C<E extends BE> extends S&M<E, List<E>> { } | 1570 // class C<E extends BE> extends S&M<E, List<E>> { } |
1570 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and | 1571 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and |
1571 // T, and use them as type arguments in S<T`> and M<T>. | 1572 // T, and use them as type arguments in S<T`> and M<T>. |
1572 // Note that the bound BT on T of S is not applied to T` of S&M. However, the | 1573 // Note that the bound BT on T of S is not applied to T` of S&M. However, the |
1573 // bound BT on T of M is applied to T of S&M. See comments below. | 1574 // bound BT on T of M is applied to T of S&M. See comments below. |
1574 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { | 1575 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { |
1575 ASSERT(mixin_app_class.type_parameters() == TypeArguments::null()); | 1576 ASSERT(mixin_app_class.type_parameters() == TypeArguments::null()); |
1576 Isolate* isolate = Isolate::Current(); | 1577 Thread* thread = Thread::Current(); |
1577 const AbstractType& super_type = AbstractType::Handle(isolate, | 1578 Zone* zone = thread->zone(); |
| 1579 const AbstractType& super_type = AbstractType::Handle(zone, |
1578 mixin_app_class.super_type()); | 1580 mixin_app_class.super_type()); |
1579 ASSERT(super_type.IsResolved()); | 1581 ASSERT(super_type.IsResolved()); |
1580 const Class& super_class = Class::Handle(isolate, super_type.type_class()); | 1582 const Class& super_class = Class::Handle(zone, super_type.type_class()); |
1581 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1583 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
1582 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); | 1584 const Type& mixin_type = Type::Handle(zone, mixin_app_class.mixin()); |
1583 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); | 1585 const Class& mixin_class = Class::Handle(zone, mixin_type.type_class()); |
1584 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1586 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
1585 | 1587 |
1586 // The mixin type (in raw form) should have been added to the interfaces | 1588 // The mixin type (in raw form) should have been added to the interfaces |
1587 // implemented by the mixin application class. This is necessary so that cycle | 1589 // implemented by the mixin application class. This is necessary so that cycle |
1588 // check works at compile time (type arguments are ignored) and so that | 1590 // check works at compile time (type arguments are ignored) and so that |
1589 // type tests work at runtime (by then, type arguments will have been set, see | 1591 // type tests work at runtime (by then, type arguments will have been set, see |
1590 // below). | 1592 // below). |
1591 ASSERT(mixin_app_class.interfaces() != Object::empty_array().raw()); | 1593 ASSERT(mixin_app_class.interfaces() != Object::empty_array().raw()); |
1592 | 1594 |
1593 // If both the super type and the mixin type are non generic, the mixin | 1595 // If both the super type and the mixin type are non generic, the mixin |
1594 // application class is non generic as well and we can skip type parameter | 1596 // application class is non generic as well and we can skip type parameter |
1595 // cloning. | 1597 // cloning. |
1596 TypeArguments& instantiator = TypeArguments::Handle(isolate); | 1598 TypeArguments& instantiator = TypeArguments::Handle(zone); |
1597 if ((num_super_type_params + num_mixin_type_params) > 0) { | 1599 if ((num_super_type_params + num_mixin_type_params) > 0) { |
1598 // If the last ampersand in the name of the mixin application class is | 1600 // If the last ampersand in the name of the mixin application class is |
1599 // doubled, the same type parameters can propagate the type arguments to | 1601 // doubled, the same type parameters can propagate the type arguments to |
1600 // the super type and to the mixin type. | 1602 // the super type and to the mixin type. |
1601 bool share_type_params = false; | 1603 bool share_type_params = false; |
1602 if (num_super_type_params == num_mixin_type_params) { | 1604 if (num_super_type_params == num_mixin_type_params) { |
1603 const String& name = String::Handle(isolate, mixin_app_class.Name()); | 1605 const String& name = String::Handle(zone, mixin_app_class.Name()); |
1604 for (intptr_t i = name.Length() - 1; i > 0; --i) { | 1606 for (intptr_t i = name.Length() - 1; i > 0; --i) { |
1605 if (name.CharAt(i) == '&') { | 1607 if (name.CharAt(i) == '&') { |
1606 if (name.CharAt(i - 1) == '&') { | 1608 if (name.CharAt(i - 1) == '&') { |
1607 share_type_params = true; | 1609 share_type_params = true; |
1608 } | 1610 } |
1609 break; | 1611 break; |
1610 } | 1612 } |
1611 } | 1613 } |
1612 } | 1614 } |
1613 | 1615 |
1614 const TypeArguments& cloned_type_params = TypeArguments::Handle(isolate, | 1616 const TypeArguments& cloned_type_params = TypeArguments::Handle(zone, |
1615 TypeArguments::New((share_type_params ? 0 : num_super_type_params) + | 1617 TypeArguments::New((share_type_params ? 0 : num_super_type_params) + |
1616 num_mixin_type_params)); | 1618 num_mixin_type_params)); |
1617 TypeParameter& param = TypeParameter::Handle(isolate); | 1619 TypeParameter& param = TypeParameter::Handle(zone); |
1618 TypeParameter& cloned_param = TypeParameter::Handle(isolate); | 1620 TypeParameter& cloned_param = TypeParameter::Handle(zone); |
1619 String& param_name = String::Handle(isolate); | 1621 String& param_name = String::Handle(zone); |
1620 AbstractType& param_bound = AbstractType::Handle(isolate); | 1622 AbstractType& param_bound = AbstractType::Handle(zone); |
1621 intptr_t cloned_index = 0; | 1623 intptr_t cloned_index = 0; |
1622 | 1624 |
1623 // First, clone the super class type parameters. Rename them so that | 1625 // First, clone the super class type parameters. Rename them so that |
1624 // there can be no name conflict between the parameters of the super | 1626 // there can be no name conflict between the parameters of the super |
1625 // class and the mixin class. | 1627 // class and the mixin class. |
1626 if (!share_type_params && (num_super_type_params > 0)) { | 1628 if (!share_type_params && (num_super_type_params > 0)) { |
1627 const TypeArguments& super_type_params = | 1629 const TypeArguments& super_type_params = |
1628 TypeArguments::Handle(isolate, super_class.type_parameters()); | 1630 TypeArguments::Handle(zone, super_class.type_parameters()); |
1629 const TypeArguments& super_type_args = TypeArguments::Handle(isolate, | 1631 const TypeArguments& super_type_args = TypeArguments::Handle(zone, |
1630 TypeArguments::New(num_super_type_params)); | 1632 TypeArguments::New(num_super_type_params)); |
1631 // The cloned super class type parameters do not need to repeat their | 1633 // The cloned super class type parameters do not need to repeat their |
1632 // bounds, since the bound checks will be performed at the super class | 1634 // bounds, since the bound checks will be performed at the super class |
1633 // level. As a consequence, if this mixin application is used itself as a | 1635 // level. As a consequence, if this mixin application is used itself as a |
1634 // mixin in another mixin application, the bounds will be ignored, which | 1636 // mixin in another mixin application, the bounds will be ignored, which |
1635 // is correct, because the other mixin application does not inherit from | 1637 // is correct, because the other mixin application does not inherit from |
1636 // the super class of its mixin. Note also that the other mixin | 1638 // the super class of its mixin. Note also that the other mixin |
1637 // application will only mixin the last mixin type listed in the first | 1639 // application will only mixin the last mixin type listed in the first |
1638 // mixin application it is mixing in. | 1640 // mixin application it is mixing in. |
1639 param_bound = isolate->object_store()->object_type(); | 1641 param_bound = thread->isolate()->object_store()->object_type(); |
1640 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1642 for (intptr_t i = 0; i < num_super_type_params; i++) { |
1641 param ^= super_type_params.TypeAt(i); | 1643 param ^= super_type_params.TypeAt(i); |
1642 param_name = param.name(); | 1644 param_name = param.name(); |
1643 param_name = Symbols::FromConcat(param_name, Symbols::Backtick()); | 1645 param_name = Symbols::FromConcat(param_name, Symbols::Backtick()); |
1644 cloned_param = TypeParameter::New(mixin_app_class, | 1646 cloned_param = TypeParameter::New(mixin_app_class, |
1645 cloned_index, | 1647 cloned_index, |
1646 param_name, | 1648 param_name, |
1647 param_bound, | 1649 param_bound, |
1648 param.token_pos()); | 1650 param.token_pos()); |
1649 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1651 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
1650 // Change the type arguments of the super type to refer to the | 1652 // Change the type arguments of the super type to refer to the |
1651 // cloned type parameters of the mixin application class. | 1653 // cloned type parameters of the mixin application class. |
1652 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1654 super_type_args.SetTypeAt(cloned_index, cloned_param); |
1653 cloned_index++; | 1655 cloned_index++; |
1654 } | 1656 } |
1655 // The super type may have a BoundedType as type argument, but cannot be | 1657 // The super type may have a BoundedType as type argument, but cannot be |
1656 // a BoundedType itself. | 1658 // a BoundedType itself. |
1657 Type::Cast(super_type).set_arguments(super_type_args); | 1659 Type::Cast(super_type).set_arguments(super_type_args); |
1658 ASSERT(!super_type.IsFinalized()); | 1660 ASSERT(!super_type.IsFinalized()); |
1659 } | 1661 } |
1660 | 1662 |
1661 // Second, clone the type parameters of the mixin class. | 1663 // Second, clone the type parameters of the mixin class. |
1662 // We need to retain the parameter names of the mixin class | 1664 // We need to retain the parameter names of the mixin class |
1663 // since the code that will be compiled in the context of the | 1665 // since the code that will be compiled in the context of the |
1664 // mixin application class may refer to the type parameters | 1666 // mixin application class may refer to the type parameters |
1665 // with that name. We also retain the type parameter bounds. | 1667 // with that name. We also retain the type parameter bounds. |
1666 if (num_mixin_type_params > 0) { | 1668 if (num_mixin_type_params > 0) { |
1667 const TypeArguments& mixin_params = | 1669 const TypeArguments& mixin_params = |
1668 TypeArguments::Handle(isolate, mixin_class.type_parameters()); | 1670 TypeArguments::Handle(zone, mixin_class.type_parameters()); |
1669 const intptr_t offset = | 1671 const intptr_t offset = |
1670 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters(); | 1672 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters(); |
1671 const TypeArguments& mixin_type_args = TypeArguments::Handle(isolate, | 1673 const TypeArguments& mixin_type_args = TypeArguments::Handle(zone, |
1672 TypeArguments::New(num_mixin_type_params)); | 1674 TypeArguments::New(num_mixin_type_params)); |
1673 instantiator ^= TypeArguments::New(offset + num_mixin_type_params); | 1675 instantiator ^= TypeArguments::New(offset + num_mixin_type_params); |
1674 bool has_uninstantiated_bounds = false; | 1676 bool has_uninstantiated_bounds = false; |
1675 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1677 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
1676 param ^= mixin_params.TypeAt(i); | 1678 param ^= mixin_params.TypeAt(i); |
1677 param_name = param.name(); | 1679 param_name = param.name(); |
1678 param_bound = param.bound(); // The bound will be adjusted below. | 1680 param_bound = param.bound(); // The bound will be adjusted below. |
1679 if (!param_bound.IsInstantiated()) { | 1681 if (!param_bound.IsInstantiated()) { |
1680 has_uninstantiated_bounds = true; | 1682 has_uninstantiated_bounds = true; |
1681 } | 1683 } |
(...skipping 11 matching lines...) Expand all Loading... |
1693 // Third, replace the type parameters appearing in the bounds of the mixin | 1695 // Third, replace the type parameters appearing in the bounds of the mixin |
1694 // type parameters, if any, by the cloned type parameters. This can be | 1696 // type parameters, if any, by the cloned type parameters. This can be |
1695 // done by instantiating each bound using the instantiator built above. | 1697 // done by instantiating each bound using the instantiator built above. |
1696 // If the mixin class extends a generic super class, its first finalized | 1698 // If the mixin class extends a generic super class, its first finalized |
1697 // type parameter has a non-zero index, therefore, the instantiator | 1699 // type parameter has a non-zero index, therefore, the instantiator |
1698 // requires shifting by the offset calculated above. | 1700 // requires shifting by the offset calculated above. |
1699 // Unfinalized type parameters replace finalized type parameters, which | 1701 // Unfinalized type parameters replace finalized type parameters, which |
1700 // is not a problem since they will get finalized shortly as the mixin | 1702 // is not a problem since they will get finalized shortly as the mixin |
1701 // application class gets finalized. | 1703 // application class gets finalized. |
1702 if (has_uninstantiated_bounds) { | 1704 if (has_uninstantiated_bounds) { |
1703 Error& bound_error = Error::Handle(isolate); | 1705 Error& bound_error = Error::Handle(zone); |
1704 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1706 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
1705 param ^= mixin_type_args.TypeAt(i); | 1707 param ^= mixin_type_args.TypeAt(i); |
1706 param_bound = param.bound(); | 1708 param_bound = param.bound(); |
1707 if (!param_bound.IsInstantiated()) { | 1709 if (!param_bound.IsInstantiated()) { |
1708 // Make sure the bound is finalized before instantiating it. | 1710 // Make sure the bound is finalized before instantiating it. |
1709 if (!param_bound.IsFinalized() && | 1711 if (!param_bound.IsFinalized() && |
1710 !param_bound.IsBeingFinalized()) { | 1712 !param_bound.IsBeingFinalized()) { |
1711 param_bound = | 1713 param_bound = |
1712 FinalizeType(mixin_app_class, param_bound, kCanonicalize); | 1714 FinalizeType(mixin_app_class, param_bound, kCanonicalize); |
1713 param.set_bound(param_bound); // In case part of recursive type. | 1715 param.set_bound(param_bound); // In case part of recursive type. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1814 The instantiator vector consists of the cloned type parameters of M shifted by | 1816 The instantiator vector consists of the cloned type parameters of M shifted by |
1815 an offset corresponding to the finalized index of the first type parameter of M. | 1817 an offset corresponding to the finalized index of the first type parameter of M. |
1816 This is done in the recursive call to CloneMixinAppTypeParameters and does not | 1818 This is done in the recursive call to CloneMixinAppTypeParameters and does not |
1817 require specific code in ApplyMixinAppAlias. | 1819 require specific code in ApplyMixinAppAlias. |
1818 */ | 1820 */ |
1819 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class, | 1821 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class, |
1820 const TypeArguments& instantiator) { | 1822 const TypeArguments& instantiator) { |
1821 // If this mixin alias is aliasing another mixin alias, another class | 1823 // If this mixin alias is aliasing another mixin alias, another class |
1822 // will be inserted via recursion. No need to check here. | 1824 // will be inserted via recursion. No need to check here. |
1823 // The mixin type may or may not be finalized yet. | 1825 // The mixin type may or may not be finalized yet. |
1824 Isolate* isolate = Isolate::Current(); | 1826 Zone* zone = Thread::Current()->zone(); |
1825 AbstractType& super_type = AbstractType::Handle(isolate, | 1827 AbstractType& super_type = AbstractType::Handle(zone, |
1826 mixin_app_class.super_type()); | 1828 mixin_app_class.super_type()); |
1827 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); | 1829 const Type& mixin_type = Type::Handle(zone, mixin_app_class.mixin()); |
1828 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); | 1830 const Class& mixin_class = Class::Handle(zone, mixin_type.type_class()); |
1829 ASSERT(mixin_class.is_mixin_app_alias()); | 1831 ASSERT(mixin_class.is_mixin_app_alias()); |
1830 const Class& aliased_mixin_app_class = Class::Handle(isolate, | 1832 const Class& aliased_mixin_app_class = Class::Handle(zone, |
1831 mixin_class.SuperClass()); | 1833 mixin_class.SuperClass()); |
1832 // Note that the super class of aliased_mixin_app_class can itself be a | 1834 // Note that the super class of aliased_mixin_app_class can itself be a |
1833 // mixin application class (this happens if the alias is mixing more than one | 1835 // mixin application class (this happens if the alias is mixing more than one |
1834 // type). Instead of trying to recursively insert yet another class as the | 1836 // type). Instead of trying to recursively insert yet another class as the |
1835 // super class of this inserted class, we apply the composition rules of the | 1837 // super class of this inserted class, we apply the composition rules of the |
1836 // spec and only mixin the members of aliased_mixin_app_class, not those of | 1838 // spec and only mixin the members of aliased_mixin_app_class, not those of |
1837 // its super class. In other words, we only mixin the last mixin of the alias. | 1839 // its super class. In other words, we only mixin the last mixin of the alias. |
1838 const Type& aliased_mixin_type = Type::Handle(isolate, | 1840 const Type& aliased_mixin_type = Type::Handle(zone, |
1839 aliased_mixin_app_class.mixin()); | 1841 aliased_mixin_app_class.mixin()); |
1840 // The name of the inserted mixin application class is the name of mixin | 1842 // The name of the inserted mixin application class is the name of mixin |
1841 // class name with a backtick added. | 1843 // class name with a backtick added. |
1842 String& inserted_class_name = String::Handle(isolate, mixin_app_class.Name()); | 1844 String& inserted_class_name = String::Handle(zone, mixin_app_class.Name()); |
1843 inserted_class_name = String::Concat(inserted_class_name, | 1845 inserted_class_name = String::Concat(inserted_class_name, |
1844 Symbols::Backtick()); | 1846 Symbols::Backtick()); |
1845 const Library& library = Library::Handle(isolate, mixin_app_class.library()); | 1847 const Library& library = Library::Handle(zone, mixin_app_class.library()); |
1846 Class& inserted_class = Class::Handle(isolate, | 1848 Class& inserted_class = Class::Handle(zone, |
1847 library.LookupLocalClass(inserted_class_name)); | 1849 library.LookupLocalClass(inserted_class_name)); |
1848 if (inserted_class.IsNull()) { | 1850 if (inserted_class.IsNull()) { |
1849 inserted_class_name = Symbols::New(inserted_class_name); | 1851 inserted_class_name = Symbols::New(inserted_class_name); |
1850 const Script& script = Script::Handle(isolate, mixin_app_class.script()); | 1852 const Script& script = Script::Handle(zone, mixin_app_class.script()); |
1851 inserted_class = Class::New( | 1853 inserted_class = Class::New( |
1852 inserted_class_name, script, mixin_app_class.token_pos()); | 1854 inserted_class_name, script, mixin_app_class.token_pos()); |
1853 inserted_class.set_is_synthesized_class(); | 1855 inserted_class.set_is_synthesized_class(); |
1854 library.AddClass(inserted_class); | 1856 library.AddClass(inserted_class); |
1855 | 1857 |
1856 if (FLAG_trace_class_finalization) { | 1858 if (FLAG_trace_class_finalization) { |
1857 THR_Print("Creating mixin application alias %s\n", | 1859 THR_Print("Creating mixin application alias %s\n", |
1858 inserted_class.ToCString()); | 1860 inserted_class.ToCString()); |
1859 } | 1861 } |
1860 | 1862 |
1861 // The super type of the inserted class is identical to the super type of | 1863 // The super type of the inserted class is identical to the super type of |
1862 // this mixin application class, except that it must refer to the type | 1864 // this mixin application class, except that it must refer to the type |
1863 // parameters of the inserted class rather than to those of the mixin | 1865 // parameters of the inserted class rather than to those of the mixin |
1864 // application class. | 1866 // application class. |
1865 // The type arguments of the super type will be set properly when calling | 1867 // The type arguments of the super type will be set properly when calling |
1866 // CloneMixinAppTypeParameters on the inserted class, as long as the super | 1868 // CloneMixinAppTypeParameters on the inserted class, as long as the super |
1867 // type class is set properly. | 1869 // type class is set properly. |
1868 inserted_class.set_super_type(super_type); // Super class only is used. | 1870 inserted_class.set_super_type(super_type); // Super class only is used. |
1869 | 1871 |
1870 // The mixin type and interface type must also be set before calling | 1872 // The mixin type and interface type must also be set before calling |
1871 // CloneMixinAppTypeParameters. | 1873 // CloneMixinAppTypeParameters. |
1872 // After FinalizeTypesInClass, if the mixin type and interface type are | 1874 // After FinalizeTypesInClass, if the mixin type and interface type are |
1873 // generic, their type arguments will refer to the type parameters of | 1875 // generic, their type arguments will refer to the type parameters of |
1874 // inserted_class. | 1876 // inserted_class. |
1875 const Type& inserted_class_mixin_type = Type::Handle(isolate, | 1877 const Type& inserted_class_mixin_type = Type::Handle(zone, |
1876 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()), | 1878 Type::New(Class::Handle(zone, aliased_mixin_type.type_class()), |
1877 Object::null_type_arguments(), | 1879 Object::null_type_arguments(), |
1878 aliased_mixin_type.token_pos())); | 1880 aliased_mixin_type.token_pos())); |
1879 inserted_class.set_mixin(inserted_class_mixin_type); | 1881 inserted_class.set_mixin(inserted_class_mixin_type); |
1880 // Add the mixin type to the list of interfaces that the mixin application | 1882 // Add the mixin type to the list of interfaces that the mixin application |
1881 // class implements. This is necessary so that cycle check work at | 1883 // class implements. This is necessary so that cycle check work at |
1882 // compile time (type arguments are ignored by that check). | 1884 // compile time (type arguments are ignored by that check). |
1883 const Array& interfaces = Array::Handle(Array::New(1)); | 1885 const Array& interfaces = Array::Handle(Array::New(1)); |
1884 interfaces.SetAt(0, inserted_class_mixin_type); | 1886 interfaces.SetAt(0, inserted_class_mixin_type); |
1885 ASSERT(inserted_class.interfaces() == Object::empty_array().raw()); | 1887 ASSERT(inserted_class.interfaces() == Object::empty_array().raw()); |
1886 inserted_class.set_interfaces(interfaces); | 1888 inserted_class.set_interfaces(interfaces); |
(...skipping 10 matching lines...) Expand all Loading... |
1897 // old super type arguments (propagating type arguments to the super class) | 1899 // old super type arguments (propagating type arguments to the super class) |
1898 // with new type arguments providing type arguments to the mixin. | 1900 // with new type arguments providing type arguments to the mixin. |
1899 // The appended type arguments are those of the super type of the mixin | 1901 // The appended type arguments are those of the super type of the mixin |
1900 // application alias that are forwarding to the aliased mixin type, except | 1902 // application alias that are forwarding to the aliased mixin type, except |
1901 // that they must refer to the type parameters of the mixin application | 1903 // that they must refer to the type parameters of the mixin application |
1902 // class rather than to those of the mixin application alias class. | 1904 // class rather than to those of the mixin application alias class. |
1903 // This type parameter substitution is performed by an instantiation step. | 1905 // This type parameter substitution is performed by an instantiation step. |
1904 // It is important that the type parameters of the mixin application class | 1906 // It is important that the type parameters of the mixin application class |
1905 // are not finalized yet, because new type parameters may have been added | 1907 // are not finalized yet, because new type parameters may have been added |
1906 // to the super class. | 1908 // to the super class. |
1907 const Class& super_class = Class::Handle(isolate, super_type.type_class()); | 1909 const Class& super_class = Class::Handle(zone, super_type.type_class()); |
1908 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); // Will change. | 1910 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); // Will change. |
1909 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1911 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
1910 AbstractType& type = AbstractType::Handle(isolate); | 1912 AbstractType& type = AbstractType::Handle(zone); |
1911 // The instantiator is mapping finalized type parameters of mixin_class to | 1913 // The instantiator is mapping finalized type parameters of mixin_class to |
1912 // unfinalized type parameters of mixin_app_class. | 1914 // unfinalized type parameters of mixin_app_class. |
1913 ASSERT(aliased_mixin_type.IsFinalized()); | 1915 ASSERT(aliased_mixin_type.IsFinalized()); |
1914 const Class& aliased_mixin_type_class = Class::Handle(isolate, | 1916 const Class& aliased_mixin_type_class = Class::Handle(zone, |
1915 aliased_mixin_type.type_class()); | 1917 aliased_mixin_type.type_class()); |
1916 const intptr_t num_aliased_mixin_type_params = | 1918 const intptr_t num_aliased_mixin_type_params = |
1917 aliased_mixin_type_class.NumTypeParameters(); | 1919 aliased_mixin_type_class.NumTypeParameters(); |
1918 ASSERT(inserted_class.NumTypeParameters() == | 1920 ASSERT(inserted_class.NumTypeParameters() == |
1919 (num_super_type_params + num_aliased_mixin_type_params)); | 1921 (num_super_type_params + num_aliased_mixin_type_params)); |
1920 const AbstractType& mixin_class_super_type = | 1922 const AbstractType& mixin_class_super_type = |
1921 AbstractType::Handle(isolate, mixin_class.super_type()); | 1923 AbstractType::Handle(zone, mixin_class.super_type()); |
1922 ASSERT(mixin_class_super_type.IsFinalized()); | 1924 ASSERT(mixin_class_super_type.IsFinalized()); |
1923 // The aliased_mixin_type may be raw. | 1925 // The aliased_mixin_type may be raw. |
1924 const TypeArguments& mixin_class_super_type_args = | 1926 const TypeArguments& mixin_class_super_type_args = |
1925 TypeArguments::Handle(isolate, mixin_class_super_type.arguments()); | 1927 TypeArguments::Handle(zone, mixin_class_super_type.arguments()); |
1926 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate); | 1928 TypeArguments& new_mixin_type_args = TypeArguments::Handle(zone); |
1927 if ((num_aliased_mixin_type_params > 0) && | 1929 if ((num_aliased_mixin_type_params > 0) && |
1928 !mixin_class_super_type_args.IsNull()) { | 1930 !mixin_class_super_type_args.IsNull()) { |
1929 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); | 1931 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); |
1930 AbstractType& bounded_type = AbstractType::Handle(isolate); | 1932 AbstractType& bounded_type = AbstractType::Handle(zone); |
1931 AbstractType& upper_bound = AbstractType::Handle(isolate); | 1933 AbstractType& upper_bound = AbstractType::Handle(zone); |
1932 TypeParameter& type_parameter = TypeParameter::Handle(isolate); | 1934 TypeParameter& type_parameter = TypeParameter::Handle(zone); |
1933 Error& bound_error = Error::Handle(isolate); | 1935 Error& bound_error = Error::Handle(zone); |
1934 const intptr_t offset = | 1936 const intptr_t offset = |
1935 mixin_class_super_type_args.Length() - num_aliased_mixin_type_params; | 1937 mixin_class_super_type_args.Length() - num_aliased_mixin_type_params; |
1936 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 1938 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
1937 type = mixin_class_super_type_args.TypeAt(offset + i); | 1939 type = mixin_class_super_type_args.TypeAt(offset + i); |
1938 if (!type.IsInstantiated()) { | 1940 if (!type.IsInstantiated()) { |
1939 // In the presence of bounds, the bounded type and the upper bound must | 1941 // In the presence of bounds, the bounded type and the upper bound must |
1940 // be instantiated separately. Instantiating a BoundedType would wrap | 1942 // be instantiated separately. Instantiating a BoundedType would wrap |
1941 // the BoundedType in another BoundedType. | 1943 // the BoundedType in another BoundedType. |
1942 if (type.IsBoundedType()) { | 1944 if (type.IsBoundedType()) { |
1943 bounded_type = BoundedType::Cast(type).type(); | 1945 bounded_type = BoundedType::Cast(type).type(); |
1944 bounded_type = bounded_type.InstantiateFrom(instantiator, | 1946 bounded_type = bounded_type.InstantiateFrom(instantiator, |
1945 &bound_error); | 1947 &bound_error); |
1946 // The instantiator contains only TypeParameter objects and no | 1948 // The instantiator contains only TypeParameter objects and no |
1947 // BoundedType objects, so no bound error may occur. | 1949 // BoundedType objects, so no bound error may occur. |
1948 ASSERT(bound_error.IsNull()); | 1950 ASSERT(bound_error.IsNull()); |
1949 upper_bound = BoundedType::Cast(type).bound(); | 1951 upper_bound = BoundedType::Cast(type).bound(); |
1950 upper_bound = upper_bound.InstantiateFrom(instantiator, &bound_error); | 1952 upper_bound = upper_bound.InstantiateFrom(instantiator, &bound_error); |
1951 ASSERT(bound_error.IsNull()); | 1953 ASSERT(bound_error.IsNull()); |
1952 type_parameter = BoundedType::Cast(type).type_parameter(); | 1954 type_parameter = BoundedType::Cast(type).type_parameter(); |
1953 // The type parameter that declared the bound does not change. | 1955 // The type parameter that declared the bound does not change. |
1954 type = BoundedType::New(bounded_type, upper_bound, type_parameter); | 1956 type = BoundedType::New(bounded_type, upper_bound, type_parameter); |
1955 } else { | 1957 } else { |
1956 type = type.InstantiateFrom(instantiator, &bound_error); | 1958 type = type.InstantiateFrom(instantiator, &bound_error); |
1957 ASSERT(bound_error.IsNull()); | 1959 ASSERT(bound_error.IsNull()); |
1958 } | 1960 } |
1959 } | 1961 } |
1960 new_mixin_type_args.SetTypeAt(i, type); | 1962 new_mixin_type_args.SetTypeAt(i, type); |
1961 } | 1963 } |
1962 } | 1964 } |
1963 TypeArguments& new_super_type_args = TypeArguments::Handle(isolate); | 1965 TypeArguments& new_super_type_args = TypeArguments::Handle(zone); |
1964 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { | 1966 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { |
1965 new_super_type_args = TypeArguments::New(num_super_type_params + | 1967 new_super_type_args = TypeArguments::New(num_super_type_params + |
1966 num_aliased_mixin_type_params); | 1968 num_aliased_mixin_type_params); |
1967 const TypeArguments& type_params = | 1969 const TypeArguments& type_params = |
1968 TypeArguments::Handle(isolate, mixin_app_class.type_parameters()); | 1970 TypeArguments::Handle(zone, mixin_app_class.type_parameters()); |
1969 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1971 for (intptr_t i = 0; i < num_super_type_params; i++) { |
1970 type = type_params.TypeAt(i); | 1972 type = type_params.TypeAt(i); |
1971 new_super_type_args.SetTypeAt(i, type); | 1973 new_super_type_args.SetTypeAt(i, type); |
1972 } | 1974 } |
1973 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 1975 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
1974 if (new_mixin_type_args.IsNull()) { | 1976 if (new_mixin_type_args.IsNull()) { |
1975 type = Type::DynamicType(); | 1977 type = Type::DynamicType(); |
1976 } else { | 1978 } else { |
1977 type = new_mixin_type_args.TypeAt(i); | 1979 type = new_mixin_type_args.TypeAt(i); |
1978 } | 1980 } |
1979 new_super_type_args.SetTypeAt(num_super_type_params + i, type); | 1981 new_super_type_args.SetTypeAt(num_super_type_params + i, type); |
1980 } | 1982 } |
1981 } | 1983 } |
1982 super_type = Type::New(inserted_class, | 1984 super_type = Type::New(inserted_class, |
1983 new_super_type_args, | 1985 new_super_type_args, |
1984 mixin_app_class.token_pos()); | 1986 mixin_app_class.token_pos()); |
1985 mixin_app_class.set_super_type(super_type); | 1987 mixin_app_class.set_super_type(super_type); |
1986 | 1988 |
1987 // Mark this mixin application class as being an alias. | 1989 // Mark this mixin application class as being an alias. |
1988 mixin_app_class.set_is_mixin_app_alias(); | 1990 mixin_app_class.set_is_mixin_app_alias(); |
1989 ASSERT(!mixin_app_class.is_type_finalized()); | 1991 ASSERT(!mixin_app_class.is_type_finalized()); |
1990 ASSERT(!mixin_app_class.is_mixin_type_applied()); | 1992 ASSERT(!mixin_app_class.is_mixin_type_applied()); |
1991 if (FLAG_trace_class_finalization) { | 1993 if (FLAG_trace_class_finalization) { |
1992 THR_Print("Inserting class '%s' %s\n" | 1994 THR_Print("Inserting class '%s' %s\n" |
1993 " as super type '%s' with %" Pd " type args: %s\n" | 1995 " as super type '%s' with %" Pd " type args: %s\n" |
1994 " of mixin application alias '%s' %s\n", | 1996 " of mixin application alias '%s' %s\n", |
1995 String::Handle(inserted_class.Name()).ToCString(), | 1997 String::Handle(inserted_class.Name()).ToCString(), |
1996 TypeArguments::Handle( | 1998 TypeArguments::Handle( |
1997 inserted_class.type_parameters()).ToCString(), | 1999 inserted_class.type_parameters()).ToCString(), |
1998 String::Handle(isolate, super_type.Name()).ToCString(), | 2000 String::Handle(zone, super_type.Name()).ToCString(), |
1999 num_super_type_params + num_aliased_mixin_type_params, | 2001 num_super_type_params + num_aliased_mixin_type_params, |
2000 super_type.ToCString(), | 2002 super_type.ToCString(), |
2001 String::Handle(mixin_app_class.Name()).ToCString(), | 2003 String::Handle(mixin_app_class.Name()).ToCString(), |
2002 TypeArguments::Handle( | 2004 TypeArguments::Handle( |
2003 mixin_app_class.type_parameters()).ToCString()); | 2005 mixin_app_class.type_parameters()).ToCString()); |
2004 } | 2006 } |
2005 } | 2007 } |
2006 | 2008 |
2007 | 2009 |
2008 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, | 2010 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2620 collected_args.Add(arg); | 2622 collected_args.Add(arg); |
2621 } | 2623 } |
2622 } | 2624 } |
2623 | 2625 |
2624 | 2626 |
2625 RawType* ClassFinalizer::ResolveMixinAppType( | 2627 RawType* ClassFinalizer::ResolveMixinAppType( |
2626 const Class& cls, | 2628 const Class& cls, |
2627 const MixinAppType& mixin_app_type) { | 2629 const MixinAppType& mixin_app_type) { |
2628 // Lookup or create mixin application classes in the library of cls | 2630 // Lookup or create mixin application classes in the library of cls |
2629 // and resolve super type and mixin types. | 2631 // and resolve super type and mixin types. |
2630 Isolate* isolate = Isolate::Current(); | 2632 Zone* zone = Thread::Current()->zone(); |
2631 const Library& library = Library::Handle(isolate, cls.library()); | 2633 const Library& library = Library::Handle(zone, cls.library()); |
2632 ASSERT(!library.IsNull()); | 2634 ASSERT(!library.IsNull()); |
2633 const Script& script = Script::Handle(isolate, cls.script()); | 2635 const Script& script = Script::Handle(zone, cls.script()); |
2634 ASSERT(!script.IsNull()); | 2636 ASSERT(!script.IsNull()); |
2635 const GrowableObjectArray& type_args = | 2637 const GrowableObjectArray& type_args = |
2636 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | 2638 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
2637 AbstractType& mixin_super_type = | 2639 AbstractType& mixin_super_type = |
2638 AbstractType::Handle(isolate, mixin_app_type.super_type()); | 2640 AbstractType::Handle(zone, mixin_app_type.super_type()); |
2639 ResolveType(cls, mixin_super_type); | 2641 ResolveType(cls, mixin_super_type); |
2640 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. | 2642 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. |
2641 // The super type may have a BoundedType as type argument, but cannot be | 2643 // The super type may have a BoundedType as type argument, but cannot be |
2642 // a BoundedType itself. | 2644 // a BoundedType itself. |
2643 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | 2645 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
2644 AbstractType& mixin_type = AbstractType::Handle(isolate); | 2646 AbstractType& mixin_type = AbstractType::Handle(zone); |
2645 Class& mixin_type_class = Class::Handle(isolate); | 2647 Class& mixin_type_class = Class::Handle(zone); |
2646 Class& mixin_app_class = Class::Handle(isolate); | 2648 Class& mixin_app_class = Class::Handle(zone); |
2647 String& mixin_app_class_name = String::Handle(isolate); | 2649 String& mixin_app_class_name = String::Handle(zone); |
2648 String& mixin_type_class_name = String::Handle(isolate); | 2650 String& mixin_type_class_name = String::Handle(zone); |
2649 AbstractType& super_type_arg = AbstractType::Handle(isolate); | 2651 AbstractType& super_type_arg = AbstractType::Handle(zone); |
2650 AbstractType& mixin_type_arg = AbstractType::Handle(isolate); | 2652 AbstractType& mixin_type_arg = AbstractType::Handle(zone); |
2651 const intptr_t depth = mixin_app_type.Depth(); | 2653 const intptr_t depth = mixin_app_type.Depth(); |
2652 for (intptr_t i = 0; i < depth; i++) { | 2654 for (intptr_t i = 0; i < depth; i++) { |
2653 mixin_type = mixin_app_type.MixinTypeAt(i); | 2655 mixin_type = mixin_app_type.MixinTypeAt(i); |
2654 ASSERT(!mixin_type.IsNull()); | 2656 ASSERT(!mixin_type.IsNull()); |
2655 ResolveType(cls, mixin_type); | 2657 ResolveType(cls, mixin_type); |
2656 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. | 2658 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
2657 ASSERT(mixin_type.IsType()); | 2659 ASSERT(mixin_type.IsType()); |
2658 const intptr_t num_super_type_args = type_args.Length(); | 2660 const intptr_t num_super_type_args = type_args.Length(); |
2659 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); | 2661 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
2660 | 2662 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2695 mixin_app_class_name = String::Concat(mixin_app_class_name, | 2697 mixin_app_class_name = String::Concat(mixin_app_class_name, |
2696 mixin_type_class_name); | 2698 mixin_type_class_name); |
2697 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); | 2699 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); |
2698 if (mixin_app_class.IsNull()) { | 2700 if (mixin_app_class.IsNull()) { |
2699 mixin_app_class_name = Symbols::New(mixin_app_class_name); | 2701 mixin_app_class_name = Symbols::New(mixin_app_class_name); |
2700 mixin_app_class = Class::New(mixin_app_class_name, | 2702 mixin_app_class = Class::New(mixin_app_class_name, |
2701 script, | 2703 script, |
2702 mixin_type.token_pos()); | 2704 mixin_type.token_pos()); |
2703 mixin_app_class.set_super_type(mixin_super_type); | 2705 mixin_app_class.set_super_type(mixin_super_type); |
2704 mixin_type_class = mixin_type.type_class(); | 2706 mixin_type_class = mixin_type.type_class(); |
2705 const Type& generic_mixin_type = Type::Handle(isolate, | 2707 const Type& generic_mixin_type = Type::Handle(zone, |
2706 Type::New(mixin_type_class, | 2708 Type::New(mixin_type_class, |
2707 Object::null_type_arguments(), | 2709 Object::null_type_arguments(), |
2708 mixin_type.token_pos())); | 2710 mixin_type.token_pos())); |
2709 mixin_app_class.set_mixin(generic_mixin_type); | 2711 mixin_app_class.set_mixin(generic_mixin_type); |
2710 // Add the mixin type to the list of interfaces that the mixin application | 2712 // Add the mixin type to the list of interfaces that the mixin application |
2711 // class implements. This is necessary so that cycle check work at | 2713 // class implements. This is necessary so that cycle check work at |
2712 // compile time (type arguments are ignored by that check). | 2714 // compile time (type arguments are ignored by that check). |
2713 const Array& interfaces = Array::Handle(isolate, Array::New(1)); | 2715 const Array& interfaces = Array::Handle(zone, Array::New(1)); |
2714 interfaces.SetAt(0, generic_mixin_type); | 2716 interfaces.SetAt(0, generic_mixin_type); |
2715 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); | 2717 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
2716 mixin_app_class.set_interfaces(interfaces); | 2718 mixin_app_class.set_interfaces(interfaces); |
2717 mixin_app_class.set_is_synthesized_class(); | 2719 mixin_app_class.set_is_synthesized_class(); |
2718 library.AddClass(mixin_app_class); | 2720 library.AddClass(mixin_app_class); |
2719 | 2721 |
2720 // No need to add the new class to pending_classes, since it will be | 2722 // No need to add the new class to pending_classes, since it will be |
2721 // processed via the super_type chain of a pending class. | 2723 // processed via the super_type chain of a pending class. |
2722 | 2724 |
2723 if (FLAG_trace_class_finalization) { | 2725 if (FLAG_trace_class_finalization) { |
2724 THR_Print("Creating mixin application %s\n", | 2726 THR_Print("Creating mixin application %s\n", |
2725 mixin_app_class.ToCString()); | 2727 mixin_app_class.ToCString()); |
2726 } | 2728 } |
2727 } | 2729 } |
2728 // This mixin application class becomes the type class of the super type of | 2730 // This mixin application class becomes the type class of the super type of |
2729 // the next mixin application class. It is however too early to provide the | 2731 // the next mixin application class. It is however too early to provide the |
2730 // correct super type arguments. We use the raw type for now. | 2732 // correct super type arguments. We use the raw type for now. |
2731 mixin_super_type = Type::New(mixin_app_class, | 2733 mixin_super_type = Type::New(mixin_app_class, |
2732 Object::null_type_arguments(), | 2734 Object::null_type_arguments(), |
2733 mixin_type.token_pos()); | 2735 mixin_type.token_pos()); |
2734 } | 2736 } |
2735 TypeArguments& mixin_app_args = TypeArguments::Handle(isolate); | 2737 TypeArguments& mixin_app_args = TypeArguments::Handle(zone); |
2736 if (type_args.Length() > 0) { | 2738 if (type_args.Length() > 0) { |
2737 mixin_app_args = TypeArguments::New(type_args.Length()); | 2739 mixin_app_args = TypeArguments::New(type_args.Length()); |
2738 AbstractType& type_arg = AbstractType::Handle(isolate); | 2740 AbstractType& type_arg = AbstractType::Handle(zone); |
2739 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2741 for (intptr_t i = 0; i < type_args.Length(); i++) { |
2740 type_arg ^= type_args.At(i); | 2742 type_arg ^= type_args.At(i); |
2741 mixin_app_args.SetTypeAt(i, type_arg); | 2743 mixin_app_args.SetTypeAt(i, type_arg); |
2742 } | 2744 } |
2743 } | 2745 } |
2744 if (FLAG_trace_class_finalization) { | 2746 if (FLAG_trace_class_finalization) { |
2745 THR_Print("ResolveMixinAppType: mixin appl type args: %s\n", | 2747 THR_Print("ResolveMixinAppType: mixin appl type args: %s\n", |
2746 mixin_app_args.ToCString()); | 2748 mixin_app_args.ToCString()); |
2747 } | 2749 } |
2748 // The mixin application class at depth k is a subclass of mixin application | 2750 // The mixin application class at depth k is a subclass of mixin application |
(...skipping 15 matching lines...) Expand all Loading... |
2764 // we found a loop. | 2766 // we found a loop. |
2765 void ClassFinalizer::ResolveSuperTypeAndInterfaces( | 2767 void ClassFinalizer::ResolveSuperTypeAndInterfaces( |
2766 const Class& cls, GrowableArray<intptr_t>* visited) { | 2768 const Class& cls, GrowableArray<intptr_t>* visited) { |
2767 if (cls.is_cycle_free()) { | 2769 if (cls.is_cycle_free()) { |
2768 return; | 2770 return; |
2769 } | 2771 } |
2770 ASSERT(visited != NULL); | 2772 ASSERT(visited != NULL); |
2771 if (FLAG_trace_class_finalization) { | 2773 if (FLAG_trace_class_finalization) { |
2772 THR_Print("Resolving super and interfaces: %s\n", cls.ToCString()); | 2774 THR_Print("Resolving super and interfaces: %s\n", cls.ToCString()); |
2773 } | 2775 } |
2774 Isolate* isolate = Isolate::Current(); | 2776 Zone* zone = Thread::Current()->zone(); |
2775 const intptr_t cls_index = cls.id(); | 2777 const intptr_t cls_index = cls.id(); |
2776 for (intptr_t i = 0; i < visited->length(); i++) { | 2778 for (intptr_t i = 0; i < visited->length(); i++) { |
2777 if ((*visited)[i] == cls_index) { | 2779 if ((*visited)[i] == cls_index) { |
2778 // We have already visited class 'cls'. We found a cycle. | 2780 // We have already visited class 'cls'. We found a cycle. |
2779 const String& class_name = String::Handle(isolate, cls.Name()); | 2781 const String& class_name = String::Handle(zone, cls.Name()); |
2780 ReportError(cls, cls.token_pos(), | 2782 ReportError(cls, cls.token_pos(), |
2781 "cyclic reference found for class '%s'", | 2783 "cyclic reference found for class '%s'", |
2782 class_name.ToCString()); | 2784 class_name.ToCString()); |
2783 } | 2785 } |
2784 } | 2786 } |
2785 | 2787 |
2786 // If the class/interface has no explicit super class/interfaces | 2788 // If the class/interface has no explicit super class/interfaces |
2787 // and is not a mixin application, we are done. | 2789 // and is not a mixin application, we are done. |
2788 AbstractType& super_type = AbstractType::Handle(isolate, cls.super_type()); | 2790 AbstractType& super_type = AbstractType::Handle(zone, cls.super_type()); |
2789 Array& super_interfaces = Array::Handle(isolate, cls.interfaces()); | 2791 Array& super_interfaces = Array::Handle(zone, cls.interfaces()); |
2790 if ((super_type.IsNull() || super_type.IsObjectType()) && | 2792 if ((super_type.IsNull() || super_type.IsObjectType()) && |
2791 (super_interfaces.Length() == 0)) { | 2793 (super_interfaces.Length() == 0)) { |
2792 cls.set_is_cycle_free(); | 2794 cls.set_is_cycle_free(); |
2793 return; | 2795 return; |
2794 } | 2796 } |
2795 | 2797 |
2796 if (super_type.IsMixinAppType()) { | 2798 if (super_type.IsMixinAppType()) { |
2797 // For the cycle check below to work, ResolveMixinAppType needs to set | 2799 // For the cycle check below to work, ResolveMixinAppType needs to set |
2798 // the mixin interfaces in the super classes, even if only in raw form. | 2800 // the mixin interfaces in the super classes, even if only in raw form. |
2799 // It is indeed too early to set the correct type arguments, which is not | 2801 // It is indeed too early to set the correct type arguments, which is not |
2800 // a problem since they are ignored in the cycle check. | 2802 // a problem since they are ignored in the cycle check. |
2801 const MixinAppType& mixin_app_type = MixinAppType::Cast(super_type); | 2803 const MixinAppType& mixin_app_type = MixinAppType::Cast(super_type); |
2802 super_type = ResolveMixinAppType(cls, mixin_app_type); | 2804 super_type = ResolveMixinAppType(cls, mixin_app_type); |
2803 cls.set_super_type(super_type); | 2805 cls.set_super_type(super_type); |
2804 } | 2806 } |
2805 | 2807 |
2806 // If cls belongs to core lib, restrictions about allowed interfaces | 2808 // If cls belongs to core lib, restrictions about allowed interfaces |
2807 // are lifted. | 2809 // are lifted. |
2808 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); | 2810 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); |
2809 | 2811 |
2810 // Resolve and check the super type and interfaces of cls. | 2812 // Resolve and check the super type and interfaces of cls. |
2811 visited->Add(cls_index); | 2813 visited->Add(cls_index); |
2812 AbstractType& interface = AbstractType::Handle(isolate); | 2814 AbstractType& interface = AbstractType::Handle(zone); |
2813 Class& interface_class = Class::Handle(isolate); | 2815 Class& interface_class = Class::Handle(zone); |
2814 | 2816 |
2815 // Resolve super type. Failures lead to a longjmp. | 2817 // Resolve super type. Failures lead to a longjmp. |
2816 ResolveType(cls, super_type); | 2818 ResolveType(cls, super_type); |
2817 if (super_type.IsMalformedOrMalbounded()) { | 2819 if (super_type.IsMalformedOrMalbounded()) { |
2818 ReportError(Error::Handle(isolate, super_type.error())); | 2820 ReportError(Error::Handle(zone, super_type.error())); |
2819 } | 2821 } |
2820 if (super_type.IsDynamicType()) { | 2822 if (super_type.IsDynamicType()) { |
2821 ReportError(cls, cls.token_pos(), | 2823 ReportError(cls, cls.token_pos(), |
2822 "class '%s' may not extend 'dynamic'", | 2824 "class '%s' may not extend 'dynamic'", |
2823 String::Handle(isolate, cls.Name()).ToCString()); | 2825 String::Handle(zone, cls.Name()).ToCString()); |
2824 } | 2826 } |
2825 interface_class = super_type.type_class(); | 2827 interface_class = super_type.type_class(); |
2826 if (interface_class.IsSignatureClass()) { | 2828 if (interface_class.IsSignatureClass()) { |
2827 ReportError(cls, cls.token_pos(), | 2829 ReportError(cls, cls.token_pos(), |
2828 "class '%s' may not extend function type alias '%s'", | 2830 "class '%s' may not extend function type alias '%s'", |
2829 String::Handle(isolate, cls.Name()).ToCString(), | 2831 String::Handle(zone, cls.Name()).ToCString(), |
2830 String::Handle(isolate, | 2832 String::Handle(zone, |
2831 super_type.UserVisibleName()).ToCString()); | 2833 super_type.UserVisibleName()).ToCString()); |
2832 } | 2834 } |
2833 if (interface_class.is_enum_class()) { | 2835 if (interface_class.is_enum_class()) { |
2834 ReportError(cls, cls.token_pos(), | 2836 ReportError(cls, cls.token_pos(), |
2835 "class '%s' may not extend enum '%s'", | 2837 "class '%s' may not extend enum '%s'", |
2836 String::Handle(isolate, cls.Name()).ToCString(), | 2838 String::Handle(zone, cls.Name()).ToCString(), |
2837 String::Handle(isolate, interface_class.Name()).ToCString()); | 2839 String::Handle(zone, interface_class.Name()).ToCString()); |
2838 } | 2840 } |
2839 | 2841 |
2840 // If cls belongs to core lib or to core lib's implementation, restrictions | 2842 // If cls belongs to core lib or to core lib's implementation, restrictions |
2841 // about allowed interfaces are lifted. | 2843 // about allowed interfaces are lifted. |
2842 if (!cls_belongs_to_core_lib) { | 2844 if (!cls_belongs_to_core_lib) { |
2843 // Prevent extending core implementation classes. | 2845 // Prevent extending core implementation classes. |
2844 bool is_error = false; | 2846 bool is_error = false; |
2845 switch (interface_class.id()) { | 2847 switch (interface_class.id()) { |
2846 case kNumberCid: | 2848 case kNumberCid: |
2847 case kIntegerCid: // Class Integer, not int. | 2849 case kIntegerCid: // Class Integer, not int. |
(...skipping 24 matching lines...) Expand all Loading... |
2872 // Special case: classes for which we don't have a known class id. | 2874 // Special case: classes for which we don't have a known class id. |
2873 if (super_type.IsDoubleType() || | 2875 if (super_type.IsDoubleType() || |
2874 super_type.IsIntType() || | 2876 super_type.IsIntType() || |
2875 super_type.IsStringType()) { | 2877 super_type.IsStringType()) { |
2876 is_error = true; | 2878 is_error = true; |
2877 } | 2879 } |
2878 break; | 2880 break; |
2879 } | 2881 } |
2880 } | 2882 } |
2881 if (is_error) { | 2883 if (is_error) { |
2882 const String& interface_name = String::Handle(isolate, | 2884 const String& interface_name = String::Handle(zone, |
2883 interface_class.Name()); | 2885 interface_class.Name()); |
2884 ReportError(cls, cls.token_pos(), | 2886 ReportError(cls, cls.token_pos(), |
2885 "'%s' is not allowed to extend '%s'", | 2887 "'%s' is not allowed to extend '%s'", |
2886 String::Handle(isolate, cls.Name()).ToCString(), | 2888 String::Handle(zone, cls.Name()).ToCString(), |
2887 interface_name.ToCString()); | 2889 interface_name.ToCString()); |
2888 } | 2890 } |
2889 } | 2891 } |
2890 // Now resolve the super interfaces of the super type. | 2892 // Now resolve the super interfaces of the super type. |
2891 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2893 ResolveSuperTypeAndInterfaces(interface_class, visited); |
2892 | 2894 |
2893 // Resolve interfaces. Failures lead to a longjmp. | 2895 // Resolve interfaces. Failures lead to a longjmp. |
2894 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 2896 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
2895 interface ^= super_interfaces.At(i); | 2897 interface ^= super_interfaces.At(i); |
2896 ResolveType(cls, interface); | 2898 ResolveType(cls, interface); |
2897 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. | 2899 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
2898 // A malbounded interface is only reported when involved in a type test. | 2900 // A malbounded interface is only reported when involved in a type test. |
2899 if (interface.IsMalformed()) { | 2901 if (interface.IsMalformed()) { |
2900 ReportError(Error::Handle(isolate, interface.error())); | 2902 ReportError(Error::Handle(zone, interface.error())); |
2901 } | 2903 } |
2902 if (interface.IsDynamicType()) { | 2904 if (interface.IsDynamicType()) { |
2903 ReportError(cls, cls.token_pos(), | 2905 ReportError(cls, cls.token_pos(), |
2904 "'dynamic' may not be used as interface"); | 2906 "'dynamic' may not be used as interface"); |
2905 } | 2907 } |
2906 interface_class = interface.type_class(); | 2908 interface_class = interface.type_class(); |
2907 if (interface_class.IsSignatureClass()) { | 2909 if (interface_class.IsSignatureClass()) { |
2908 const String& interface_name = String::Handle(isolate, | 2910 const String& interface_name = String::Handle(zone, |
2909 interface_class.Name()); | 2911 interface_class.Name()); |
2910 ReportError(cls, cls.token_pos(), | 2912 ReportError(cls, cls.token_pos(), |
2911 "function type alias '%s' may not be used as interface", | 2913 "function type alias '%s' may not be used as interface", |
2912 interface_name.ToCString()); | 2914 interface_name.ToCString()); |
2913 } | 2915 } |
2914 if (interface_class.is_enum_class()) { | 2916 if (interface_class.is_enum_class()) { |
2915 const String& interface_name = String::Handle(isolate, | 2917 const String& interface_name = String::Handle(zone, |
2916 interface_class.Name()); | 2918 interface_class.Name()); |
2917 ReportError(cls, cls.token_pos(), | 2919 ReportError(cls, cls.token_pos(), |
2918 "enum '%s' may not be used as interface", | 2920 "enum '%s' may not be used as interface", |
2919 interface_name.ToCString()); | 2921 interface_name.ToCString()); |
2920 } | 2922 } |
2921 // Verify that unless cls belongs to core lib, it cannot extend, implement, | 2923 // Verify that unless cls belongs to core lib, it cannot extend, implement, |
2922 // or mixin any of Null, bool, num, int, double, String, dynamic. | 2924 // or mixin any of Null, bool, num, int, double, String, dynamic. |
2923 if (!cls_belongs_to_core_lib) { | 2925 if (!cls_belongs_to_core_lib) { |
2924 if (interface.IsBoolType() || | 2926 if (interface.IsBoolType() || |
2925 interface.IsNullType() || | 2927 interface.IsNullType() || |
2926 interface.IsNumberType() || | 2928 interface.IsNumberType() || |
2927 interface.IsIntType() || | 2929 interface.IsIntType() || |
2928 interface.IsDoubleType() || | 2930 interface.IsDoubleType() || |
2929 interface.IsStringType() || | 2931 interface.IsStringType() || |
2930 interface.IsDynamicType()) { | 2932 interface.IsDynamicType()) { |
2931 const String& interface_name = String::Handle(isolate, | 2933 const String& interface_name = String::Handle(zone, |
2932 interface_class.Name()); | 2934 interface_class.Name()); |
2933 if (cls.IsMixinApplication()) { | 2935 if (cls.IsMixinApplication()) { |
2934 ReportError(cls, cls.token_pos(), | 2936 ReportError(cls, cls.token_pos(), |
2935 "illegal mixin of '%s'", | 2937 "illegal mixin of '%s'", |
2936 interface_name.ToCString()); | 2938 interface_name.ToCString()); |
2937 } else { | 2939 } else { |
2938 ReportError(cls, cls.token_pos(), | 2940 ReportError(cls, cls.token_pos(), |
2939 "'%s' is not allowed to extend or implement '%s'", | 2941 "'%s' is not allowed to extend or implement '%s'", |
2940 String::Handle(isolate, cls.Name()).ToCString(), | 2942 String::Handle(zone, cls.Name()).ToCString(), |
2941 interface_name.ToCString()); | 2943 interface_name.ToCString()); |
2942 } | 2944 } |
2943 } | 2945 } |
2944 } | 2946 } |
2945 interface_class.set_is_implemented(); | 2947 interface_class.set_is_implemented(); |
2946 // Now resolve the super interfaces. | 2948 // Now resolve the super interfaces. |
2947 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2949 ResolveSuperTypeAndInterfaces(interface_class, visited); |
2948 } | 2950 } |
2949 visited->RemoveLast(); | 2951 visited->RemoveLast(); |
2950 cls.set_is_cycle_free(); | 2952 cls.set_is_cycle_free(); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3202 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3204 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3203 field ^= fields_array.At(0); | 3205 field ^= fields_array.At(0); |
3204 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3206 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3205 name ^= field.name(); | 3207 name ^= field.name(); |
3206 expected_name ^= String::New("_data"); | 3208 expected_name ^= String::New("_data"); |
3207 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3209 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3208 #endif | 3210 #endif |
3209 } | 3211 } |
3210 | 3212 |
3211 } // namespace dart | 3213 } // namespace dart |
OLD | NEW |