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

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

Issue 1393373003: Remove isolate argument from handle allocation: Part I (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Cleanups Created 5 years, 2 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
« no previous file with comments | « runtime/vm/benchmark_test.cc ('k') | runtime/vm/class_finalizer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/class_finalizer.h" 5 #include "vm/class_finalizer.h"
6 6
7 #include "vm/code_generator.h" 7 #include "vm/code_generator.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/benchmark_test.cc ('k') | runtime/vm/class_finalizer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698