OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 3577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3588 } | 3588 } |
3589 | 3589 |
3590 | 3590 |
3591 bool AbstractTypeArguments::IsResolved() const { | 3591 bool AbstractTypeArguments::IsResolved() const { |
3592 // AbstractTypeArguments is an abstract class. | 3592 // AbstractTypeArguments is an abstract class. |
3593 UNREACHABLE(); | 3593 UNREACHABLE(); |
3594 return false; | 3594 return false; |
3595 } | 3595 } |
3596 | 3596 |
3597 | 3597 |
3598 bool AbstractTypeArguments::IsInstantiated() const { | 3598 bool AbstractTypeArguments::IsInstantiated(GrowableObjectArray* trail) const { |
3599 // AbstractTypeArguments is an abstract class. | 3599 // AbstractTypeArguments is an abstract class. |
3600 UNREACHABLE(); | 3600 UNREACHABLE(); |
3601 return false; | 3601 return false; |
3602 } | 3602 } |
3603 | 3603 |
3604 | 3604 |
3605 bool AbstractTypeArguments::IsUninstantiatedIdentity() const { | 3605 bool AbstractTypeArguments::IsUninstantiatedIdentity() const { |
3606 // AbstractTypeArguments is an abstract class. | 3606 // AbstractTypeArguments is an abstract class. |
3607 UNREACHABLE(); | 3607 UNREACHABLE(); |
3608 return false; | 3608 return false; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3666 strings.SetAt(s++, Symbols::CommaSpace()); | 3666 strings.SetAt(s++, Symbols::CommaSpace()); |
3667 } | 3667 } |
3668 } | 3668 } |
3669 strings.SetAt(s++, Symbols::RAngleBracket()); | 3669 strings.SetAt(s++, Symbols::RAngleBracket()); |
3670 ASSERT(s == num_strings); | 3670 ASSERT(s == num_strings); |
3671 name = String::ConcatAll(strings); | 3671 name = String::ConcatAll(strings); |
3672 return Symbols::New(name); | 3672 return Symbols::New(name); |
3673 } | 3673 } |
3674 | 3674 |
3675 | 3675 |
3676 bool AbstractTypeArguments::Equals(const AbstractTypeArguments& other) const { | 3676 bool AbstractTypeArguments::IsEquivalent(const AbstractTypeArguments& other, |
| 3677 GrowableObjectArray* trail) const { |
3677 if (this->raw() == other.raw()) { | 3678 if (this->raw() == other.raw()) { |
3678 return true; | 3679 return true; |
3679 } | 3680 } |
3680 if (IsNull() || other.IsNull()) { | 3681 if (IsNull() || other.IsNull()) { |
3681 return false; | 3682 return false; |
3682 } | 3683 } |
3683 const intptr_t num_types = Length(); | 3684 const intptr_t num_types = Length(); |
3684 if (num_types != other.Length()) { | 3685 if (num_types != other.Length()) { |
3685 return false; | 3686 return false; |
3686 } | 3687 } |
3687 AbstractType& type = AbstractType::Handle(); | 3688 AbstractType& type = AbstractType::Handle(); |
3688 AbstractType& other_type = AbstractType::Handle(); | 3689 AbstractType& other_type = AbstractType::Handle(); |
3689 for (intptr_t i = 0; i < num_types; i++) { | 3690 for (intptr_t i = 0; i < num_types; i++) { |
3690 type = TypeAt(i); | 3691 type = TypeAt(i); |
3691 other_type = other.TypeAt(i); | 3692 other_type = other.TypeAt(i); |
3692 if (!type.Equals(other_type)) { | 3693 if (!type.IsEquivalent(other_type, trail)) { |
3693 return false; | 3694 return false; |
3694 } | 3695 } |
3695 } | 3696 } |
3696 return true; | 3697 return true; |
3697 } | 3698 } |
3698 | 3699 |
3699 | 3700 |
3700 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( | 3701 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( |
3701 const AbstractTypeArguments& instantiator_type_arguments, | 3702 const AbstractTypeArguments& instantiator_type_arguments, |
3702 Error* bound_error) const { | 3703 Error* bound_error, |
| 3704 GrowableObjectArray* trail) const { |
3703 // AbstractTypeArguments is an abstract class. | 3705 // AbstractTypeArguments is an abstract class. |
3704 UNREACHABLE(); | 3706 UNREACHABLE(); |
3705 return NULL; | 3707 return NULL; |
3706 } | 3708 } |
3707 | 3709 |
3708 | 3710 |
3709 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, | 3711 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, |
3710 intptr_t from_index, | 3712 intptr_t from_index, |
3711 intptr_t len) const { | 3713 intptr_t len) const { |
3712 ASSERT(Length() >= (from_index + len)); | 3714 ASSERT(Length() >= (from_index + len)); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3801 for (intptr_t i = 0; i < num_types; i++) { | 3803 for (intptr_t i = 0; i < num_types; i++) { |
3802 type = TypeAt(i); | 3804 type = TypeAt(i); |
3803 if (!type.IsResolved()) { | 3805 if (!type.IsResolved()) { |
3804 return false; | 3806 return false; |
3805 } | 3807 } |
3806 } | 3808 } |
3807 return true; | 3809 return true; |
3808 } | 3810 } |
3809 | 3811 |
3810 | 3812 |
3811 bool TypeArguments::IsInstantiated() const { | 3813 bool TypeArguments::IsInstantiated(GrowableObjectArray* trail) const { |
3812 AbstractType& type = AbstractType::Handle(); | 3814 AbstractType& type = AbstractType::Handle(); |
3813 const intptr_t num_types = Length(); | 3815 const intptr_t num_types = Length(); |
3814 for (intptr_t i = 0; i < num_types; i++) { | 3816 for (intptr_t i = 0; i < num_types; i++) { |
3815 type = TypeAt(i); | 3817 type = TypeAt(i); |
3816 ASSERT(!type.IsNull()); | 3818 ASSERT(!type.IsNull()); |
3817 if (!type.IsInstantiated()) { | 3819 if (!type.IsInstantiated(trail)) { |
3818 return false; | 3820 return false; |
3819 } | 3821 } |
3820 } | 3822 } |
3821 return true; | 3823 return true; |
3822 } | 3824 } |
3823 | 3825 |
3824 | 3826 |
3825 bool TypeArguments::IsUninstantiatedIdentity() const { | 3827 bool TypeArguments::IsUninstantiatedIdentity() const { |
3826 ASSERT(!IsInstantiated()); | 3828 ASSERT(!IsInstantiated()); |
3827 AbstractType& type = AbstractType::Handle(); | 3829 AbstractType& type = AbstractType::Handle(); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3957 if (!type_args.IsNull() && type_args.IsBounded()) { | 3959 if (!type_args.IsNull() && type_args.IsBounded()) { |
3958 return true; | 3960 return true; |
3959 } | 3961 } |
3960 } | 3962 } |
3961 return false; | 3963 return false; |
3962 } | 3964 } |
3963 | 3965 |
3964 | 3966 |
3965 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( | 3967 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( |
3966 const AbstractTypeArguments& instantiator_type_arguments, | 3968 const AbstractTypeArguments& instantiator_type_arguments, |
3967 Error* bound_error) const { | 3969 Error* bound_error, |
| 3970 GrowableObjectArray* trail) const { |
3968 ASSERT(!IsInstantiated()); | 3971 ASSERT(!IsInstantiated()); |
3969 if (!instantiator_type_arguments.IsNull() && | 3972 if (!instantiator_type_arguments.IsNull() && |
3970 IsUninstantiatedIdentity() && | 3973 IsUninstantiatedIdentity() && |
3971 (instantiator_type_arguments.Length() == Length())) { | 3974 (instantiator_type_arguments.Length() == Length())) { |
3972 return instantiator_type_arguments.raw(); | 3975 return instantiator_type_arguments.raw(); |
3973 } | 3976 } |
3974 const intptr_t num_types = Length(); | 3977 const intptr_t num_types = Length(); |
3975 TypeArguments& instantiated_array = | 3978 TypeArguments& instantiated_array = |
3976 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); | 3979 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); |
3977 AbstractType& type = AbstractType::Handle(); | 3980 AbstractType& type = AbstractType::Handle(); |
3978 for (intptr_t i = 0; i < num_types; i++) { | 3981 for (intptr_t i = 0; i < num_types; i++) { |
3979 type = TypeAt(i); | 3982 type = TypeAt(i); |
3980 if (!type.IsInstantiated()) { | 3983 if (!type.IsInstantiated()) { |
3981 type = type.InstantiateFrom(instantiator_type_arguments, bound_error); | 3984 type = type.InstantiateFrom(instantiator_type_arguments, |
| 3985 bound_error, |
| 3986 trail); |
3982 } | 3987 } |
3983 instantiated_array.SetTypeAt(i, type); | 3988 instantiated_array.SetTypeAt(i, type); |
3984 } | 3989 } |
3985 return instantiated_array.raw(); | 3990 return instantiated_array.raw(); |
3986 } | 3991 } |
3987 | 3992 |
3988 | 3993 |
3989 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { | 3994 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { |
3990 if (len < 0 || len > kMaxElements) { | 3995 if (len < 0 || len > kMaxElements) { |
3991 // This should be caught before we reach here. | 3996 // This should be caught before we reach here. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4102 TypeArguments::New(num_types)); | 4107 TypeArguments::New(num_types)); |
4103 for (intptr_t i = 0; i < num_types; i++) { | 4108 for (intptr_t i = 0; i < num_types; i++) { |
4104 type = TypeAt(i); | 4109 type = TypeAt(i); |
4105 type = type.CloneUnfinalized(); | 4110 type = type.CloneUnfinalized(); |
4106 clone.SetTypeAt(i, type); | 4111 clone.SetTypeAt(i, type); |
4107 } | 4112 } |
4108 return clone.raw(); | 4113 return clone.raw(); |
4109 } | 4114 } |
4110 | 4115 |
4111 | 4116 |
4112 RawAbstractTypeArguments* TypeArguments::Canonicalize() const { | 4117 RawAbstractTypeArguments* TypeArguments::Canonicalize( |
| 4118 GrowableObjectArray* trail) const { |
4113 if (IsNull() || IsCanonical()) { | 4119 if (IsNull() || IsCanonical()) { |
4114 ASSERT(IsOld()); | 4120 ASSERT(IsOld()); |
4115 return this->raw(); | 4121 return this->raw(); |
4116 } | 4122 } |
4117 Isolate* isolate = Isolate::Current(); | 4123 Isolate* isolate = Isolate::Current(); |
4118 ObjectStore* object_store = isolate->object_store(); | 4124 ObjectStore* object_store = isolate->object_store(); |
4119 const Array& table = Array::Handle(isolate, | 4125 const Array& table = Array::Handle(isolate, |
4120 object_store->canonical_type_arguments()); | 4126 object_store->canonical_type_arguments()); |
4121 ASSERT(table.Length() > 0); | 4127 ASSERT(table.Length() > 0); |
4122 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, | 4128 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, |
4123 table, | 4129 table, |
4124 *this, | 4130 *this, |
4125 Hash()); | 4131 Hash()); |
4126 TypeArguments& result = TypeArguments::Handle(isolate); | 4132 TypeArguments& result = TypeArguments::Handle(isolate); |
4127 result ^= table.At(index); | 4133 result ^= table.At(index); |
4128 if (result.IsNull()) { | 4134 if (result.IsNull()) { |
4129 // Canonicalize each type argument. | 4135 // Canonicalize each type argument. |
4130 const intptr_t num_types = Length(); | 4136 const intptr_t num_types = Length(); |
4131 AbstractType& type = AbstractType::Handle(isolate); | 4137 AbstractType& type = AbstractType::Handle(isolate); |
4132 for (intptr_t i = 0; i < num_types; i++) { | 4138 for (intptr_t i = 0; i < num_types; i++) { |
4133 type = TypeAt(i); | 4139 type = TypeAt(i); |
4134 type = type.Canonicalize(); | 4140 type = type.Canonicalize(trail); |
4135 SetTypeAt(i, type); | 4141 SetTypeAt(i, type); |
4136 } | 4142 } |
4137 // Make sure we have an old space object and add it to the table. | 4143 // Make sure we have an old space object and add it to the table. |
4138 if (this->IsNew()) { | 4144 if (this->IsNew()) { |
4139 result ^= Object::Clone(*this, Heap::kOld); | 4145 result ^= Object::Clone(*this, Heap::kOld); |
4140 } else { | 4146 } else { |
4141 result ^= this->raw(); | 4147 result ^= this->raw(); |
4142 } | 4148 } |
4143 ASSERT(result.IsOld()); | 4149 ASSERT(result.IsOld()); |
4144 InsertIntoCanonicalTypeArguments(isolate, table, result, index); | 4150 InsertIntoCanonicalTypeArguments(isolate, table, result, index); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4198 | 4204 |
4199 | 4205 |
4200 void InstantiatedTypeArguments::SetTypeAt(intptr_t index, | 4206 void InstantiatedTypeArguments::SetTypeAt(intptr_t index, |
4201 const AbstractType& value) const { | 4207 const AbstractType& value) const { |
4202 // We only replace individual argument types during resolution at compile | 4208 // We only replace individual argument types during resolution at compile |
4203 // time, when no type parameters are instantiated yet. | 4209 // time, when no type parameters are instantiated yet. |
4204 UNREACHABLE(); | 4210 UNREACHABLE(); |
4205 } | 4211 } |
4206 | 4212 |
4207 | 4213 |
4208 RawAbstractTypeArguments* InstantiatedTypeArguments::Canonicalize() const { | 4214 RawAbstractTypeArguments* InstantiatedTypeArguments::Canonicalize( |
| 4215 GrowableObjectArray* trail) const { |
4209 const intptr_t num_types = Length(); | 4216 const intptr_t num_types = Length(); |
4210 const TypeArguments& type_args = TypeArguments::Handle( | 4217 const TypeArguments& type_args = TypeArguments::Handle( |
4211 TypeArguments::New(num_types, Heap::kOld)); | 4218 TypeArguments::New(num_types, Heap::kOld)); |
4212 AbstractType& type = AbstractType::Handle(); | 4219 AbstractType& type = AbstractType::Handle(); |
4213 for (intptr_t i = 0; i < num_types; i++) { | 4220 for (intptr_t i = 0; i < num_types; i++) { |
4214 type = TypeAt(i); | 4221 type = TypeAt(i); |
4215 type_args.SetTypeAt(i, type); | 4222 type_args.SetTypeAt(i, type); |
4216 } | 4223 } |
4217 return type_args.Canonicalize(); | 4224 return type_args.Canonicalize(trail); |
4218 } | 4225 } |
4219 | 4226 |
4220 | 4227 |
4221 void InstantiatedTypeArguments::set_uninstantiated_type_arguments( | 4228 void InstantiatedTypeArguments::set_uninstantiated_type_arguments( |
4222 const AbstractTypeArguments& value) const { | 4229 const AbstractTypeArguments& value) const { |
4223 StorePointer(&raw_ptr()->uninstantiated_type_arguments_, value.raw()); | 4230 StorePointer(&raw_ptr()->uninstantiated_type_arguments_, value.raw()); |
4224 } | 4231 } |
4225 | 4232 |
4226 | 4233 |
4227 void InstantiatedTypeArguments::set_instantiator_type_arguments( | 4234 void InstantiatedTypeArguments::set_instantiator_type_arguments( |
(...skipping 7585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11813 } | 11820 } |
11814 | 11821 |
11815 | 11822 |
11816 intptr_t AbstractType::token_pos() const { | 11823 intptr_t AbstractType::token_pos() const { |
11817 // AbstractType is an abstract class. | 11824 // AbstractType is an abstract class. |
11818 UNREACHABLE(); | 11825 UNREACHABLE(); |
11819 return -1; | 11826 return -1; |
11820 } | 11827 } |
11821 | 11828 |
11822 | 11829 |
11823 bool AbstractType::IsInstantiated() const { | 11830 bool AbstractType::IsInstantiated(GrowableObjectArray* trail) const { |
11824 // AbstractType is an abstract class. | 11831 // AbstractType is an abstract class. |
11825 UNREACHABLE(); | 11832 UNREACHABLE(); |
11826 return false; | 11833 return false; |
11827 } | 11834 } |
11828 | 11835 |
11829 | 11836 |
11830 bool AbstractType::IsFinalized() const { | 11837 bool AbstractType::IsFinalized() const { |
11831 // AbstractType is an abstract class. | 11838 // AbstractType is an abstract class. |
11832 UNREACHABLE(); | 11839 UNREACHABLE(); |
11833 return false; | 11840 return false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11868 return LanguageError::null(); | 11875 return LanguageError::null(); |
11869 } | 11876 } |
11870 | 11877 |
11871 | 11878 |
11872 void AbstractType::set_error(const LanguageError& value) const { | 11879 void AbstractType::set_error(const LanguageError& value) const { |
11873 // AbstractType is an abstract class. | 11880 // AbstractType is an abstract class. |
11874 UNREACHABLE(); | 11881 UNREACHABLE(); |
11875 } | 11882 } |
11876 | 11883 |
11877 | 11884 |
11878 bool AbstractType::Equals(const Instance& other) const { | 11885 bool AbstractType::IsEquivalent(const Instance& other, |
| 11886 GrowableObjectArray* trail) const { |
11879 // AbstractType is an abstract class. | 11887 // AbstractType is an abstract class. |
11880 UNREACHABLE(); | 11888 UNREACHABLE(); |
11881 return false; | 11889 return false; |
11882 } | 11890 } |
11883 | 11891 |
11884 | 11892 |
11885 RawAbstractType* AbstractType::InstantiateFrom( | 11893 RawAbstractType* AbstractType::InstantiateFrom( |
11886 const AbstractTypeArguments& instantiator_type_arguments, | 11894 const AbstractTypeArguments& instantiator_type_arguments, |
11887 Error* bound_error) const { | 11895 Error* bound_error, |
| 11896 GrowableObjectArray* trail) const { |
11888 // AbstractType is an abstract class. | 11897 // AbstractType is an abstract class. |
11889 UNREACHABLE(); | 11898 UNREACHABLE(); |
11890 return NULL; | 11899 return NULL; |
11891 } | 11900 } |
11892 | 11901 |
11893 | 11902 |
11894 RawAbstractType* AbstractType::CloneUnfinalized() const { | 11903 RawAbstractType* AbstractType::CloneUnfinalized() const { |
11895 // AbstractType is an abstract class. | 11904 // AbstractType is an abstract class. |
11896 UNREACHABLE(); | 11905 UNREACHABLE(); |
11897 return NULL; | 11906 return NULL; |
11898 } | 11907 } |
11899 | 11908 |
11900 | 11909 |
11901 RawAbstractType* AbstractType::Canonicalize() const { | 11910 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const { |
11902 // AbstractType is an abstract class. | 11911 // AbstractType is an abstract class. |
11903 UNREACHABLE(); | 11912 UNREACHABLE(); |
11904 return NULL; | 11913 return NULL; |
11905 } | 11914 } |
11906 | 11915 |
11907 | 11916 |
11908 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 11917 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
11909 if (IsBoundedType()) { | 11918 if (IsBoundedType()) { |
11910 const AbstractType& type = AbstractType::Handle( | 11919 const AbstractType& type = AbstractType::Handle( |
11911 BoundedType::Cast(*this).type()); | 11920 BoundedType::Cast(*this).type()); |
11912 if (name_visibility == kUserVisibleName) { | 11921 if (name_visibility == kUserVisibleName) { |
11913 return type.BuildName(kUserVisibleName); | 11922 return type.BuildName(kUserVisibleName); |
11914 } | 11923 } |
11915 String& type_name = String::Handle(type.BuildName(kInternalName)); | 11924 String& type_name = String::Handle(type.BuildName(kInternalName)); |
11916 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); | 11925 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); |
11917 // Building the bound name may lead into cycles. | 11926 // Build the bound name without causing divergence. |
11918 const AbstractType& bound = AbstractType::Handle( | 11927 const AbstractType& bound = AbstractType::Handle( |
11919 BoundedType::Cast(*this).bound()); | 11928 BoundedType::Cast(*this).bound()); |
11920 String& bound_name = String::Handle(); | 11929 String& bound_name = String::Handle(); |
11921 if (bound.IsTypeParameter()) { | 11930 if (bound.IsTypeParameter()) { |
11922 bound_name = TypeParameter::Cast(bound).name(); | 11931 bound_name = TypeParameter::Cast(bound).name(); |
11923 } else if (bound.IsType()) { | 11932 } else if (bound.IsType()) { |
11924 const Class& cls = Class::Handle(Type::Cast(bound).type_class()); | 11933 const Class& cls = Class::Handle(Type::Cast(bound).type_class()); |
11925 bound_name = cls.Name(); | 11934 bound_name = cls.Name(); |
11926 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) { | 11935 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) { |
11927 bound_name = String::Concat(bound_name, Symbols::OptimizedOut()); | 11936 bound_name = String::Concat(bound_name, Symbols::OptimizedOut()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11968 // The actual type argument vector can be longer than necessary, because | 11977 // The actual type argument vector can be longer than necessary, because |
11969 // of type optimizations. | 11978 // of type optimizations. |
11970 if (IsFinalized() && cls.is_type_finalized()) { | 11979 if (IsFinalized() && cls.is_type_finalized()) { |
11971 first_type_param_index = cls.NumTypeArguments() - num_type_params; | 11980 first_type_param_index = cls.NumTypeArguments() - num_type_params; |
11972 } else { | 11981 } else { |
11973 first_type_param_index = num_args - num_type_params; | 11982 first_type_param_index = num_args - num_type_params; |
11974 } | 11983 } |
11975 } | 11984 } |
11976 if (cls.IsSignatureClass()) { | 11985 if (cls.IsSignatureClass()) { |
11977 // We may be reporting an error about a malformed function type. In that | 11986 // We may be reporting an error about a malformed function type. In that |
11978 // case, avoid instantiating the signature, since it may lead to cycles. | 11987 // case, avoid instantiating the signature, since it may cause divergence. |
11979 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { | 11988 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { |
11980 return class_name.raw(); | 11989 return class_name.raw(); |
11981 } | 11990 } |
11982 // In order to avoid cycles, print the name of a typedef (non-canonical | 11991 // To avoid divergence, print the name of a typedef (non-canonical |
11983 // signature class) as a regular, possibly parameterized, class. | 11992 // signature class) as a regular, possibly parameterized, class. |
11984 if (cls.IsCanonicalSignatureClass()) { | 11993 if (cls.IsCanonicalSignatureClass()) { |
11985 const Function& signature_function = Function::Handle( | 11994 const Function& signature_function = Function::Handle( |
11986 cls.signature_function()); | 11995 cls.signature_function()); |
11987 // Signature classes have no super type, however, they take as many | 11996 // Signature classes have no super type, however, they take as many |
11988 // type arguments as the owner class of their signature function (if it | 11997 // type arguments as the owner class of their signature function (if it |
11989 // is non static and generic, see Class::NumTypeArguments()). Therefore, | 11998 // is non static and generic, see Class::NumTypeArguments()). Therefore, |
11990 // first_type_param_index may be greater than 0 here. | 11999 // first_type_param_index may be greater than 0 here. |
11991 return signature_function.InstantiatedSignatureFrom(args, | 12000 return signature_function.InstantiatedSignatureFrom(args, |
11992 name_visibility); | 12001 name_visibility); |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12377 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); | 12386 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); |
12378 #endif | 12387 #endif |
12379 } | 12388 } |
12380 | 12389 |
12381 | 12390 |
12382 RawAbstractTypeArguments* Type::arguments() const { | 12391 RawAbstractTypeArguments* Type::arguments() const { |
12383 return raw_ptr()->arguments_; | 12392 return raw_ptr()->arguments_; |
12384 } | 12393 } |
12385 | 12394 |
12386 | 12395 |
12387 bool Type::IsInstantiated() const { | 12396 bool Type::IsInstantiated(GrowableObjectArray* trail) const { |
12388 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { | 12397 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { |
12389 return true; | 12398 return true; |
12390 } | 12399 } |
12391 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { | 12400 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { |
12392 return false; | 12401 return false; |
12393 } | 12402 } |
12394 const AbstractTypeArguments& args = | 12403 const AbstractTypeArguments& args = |
12395 AbstractTypeArguments::Handle(arguments()); | 12404 AbstractTypeArguments::Handle(arguments()); |
12396 return args.IsNull() || args.IsInstantiated(); | 12405 return args.IsNull() || args.IsInstantiated(trail); |
12397 } | 12406 } |
12398 | 12407 |
12399 | 12408 |
12400 RawAbstractType* Type::InstantiateFrom( | 12409 RawAbstractType* Type::InstantiateFrom( |
12401 const AbstractTypeArguments& instantiator_type_arguments, | 12410 const AbstractTypeArguments& instantiator_type_arguments, |
12402 Error* bound_error) const { | 12411 Error* bound_error, |
| 12412 GrowableObjectArray* trail) const { |
12403 ASSERT(IsFinalized() || IsBeingFinalized()); | 12413 ASSERT(IsFinalized() || IsBeingFinalized()); |
12404 ASSERT(!IsInstantiated()); | 12414 ASSERT(!IsInstantiated()); |
12405 // Return the uninstantiated type unchanged if malformed. No copy needed. | 12415 // Return the uninstantiated type unchanged if malformed. No copy needed. |
12406 if (IsMalformed()) { | 12416 if (IsMalformed()) { |
12407 return raw(); | 12417 return raw(); |
12408 } | 12418 } |
12409 AbstractTypeArguments& type_arguments = | 12419 AbstractTypeArguments& type_arguments = |
12410 AbstractTypeArguments::Handle(arguments()); | 12420 AbstractTypeArguments::Handle(arguments()); |
12411 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | 12421 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
12412 bound_error); | 12422 bound_error, |
| 12423 trail); |
12413 // Note that the type class has to be resolved at this time, but not | 12424 // Note that the type class has to be resolved at this time, but not |
12414 // necessarily finalized yet. We may be checking bounds at compile time. | 12425 // necessarily finalized yet. We may be checking bounds at compile time. |
12415 const Class& cls = Class::Handle(type_class()); | 12426 const Class& cls = Class::Handle(type_class()); |
12416 // This uninstantiated type is not modified, as it can be instantiated | 12427 // This uninstantiated type is not modified, as it can be instantiated |
12417 // with different instantiators. | 12428 // with different instantiators. |
12418 Type& instantiated_type = Type::Handle( | 12429 Type& instantiated_type = Type::Handle( |
12419 Type::New(cls, type_arguments, token_pos())); | 12430 Type::New(cls, type_arguments, token_pos())); |
12420 ASSERT(type_arguments.IsNull() || | 12431 ASSERT(type_arguments.IsNull() || |
12421 (type_arguments.Length() == cls.NumTypeArguments())); | 12432 (type_arguments.Length() == cls.NumTypeArguments())); |
12422 instantiated_type.SetIsFinalized(); | 12433 instantiated_type.SetIsFinalized(); |
12423 return instantiated_type.raw(); | 12434 return instantiated_type.raw(); |
12424 } | 12435 } |
12425 | 12436 |
12426 | 12437 |
12427 bool Type::Equals(const Instance& other) const { | 12438 bool Type::IsEquivalent(const Instance& other, |
| 12439 GrowableObjectArray* trail) const { |
12428 ASSERT(!IsNull()); | 12440 ASSERT(!IsNull()); |
12429 if (raw() == other.raw()) { | 12441 if (raw() == other.raw()) { |
12430 return true; | 12442 return true; |
12431 } | 12443 } |
12432 if (other.IsTypeRef()) { | 12444 if (other.IsTypeRef()) { |
12433 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | 12445 // Unfold right hand type. Divergence is controlled by left hand type. |
12434 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | 12446 const AbstractType& other_ref_type = AbstractType::Handle( |
| 12447 TypeRef::Cast(other).type()); |
| 12448 ASSERT(!other_ref_type.IsTypeRef()); |
| 12449 return IsEquivalent(other_ref_type, trail); |
12435 } | 12450 } |
12436 if (!other.IsType()) { | 12451 if (!other.IsType()) { |
12437 return false; | 12452 return false; |
12438 } | 12453 } |
12439 const Type& other_type = Type::Cast(other); | 12454 const Type& other_type = Type::Cast(other); |
12440 ASSERT(IsResolved() && other_type.IsResolved()); | 12455 ASSERT(IsResolved() && other_type.IsResolved()); |
12441 if (IsMalformed() || other_type.IsMalformed()) { | 12456 if (IsMalformed() || other_type.IsMalformed()) { |
12442 return false; | 12457 return false; |
12443 } | 12458 } |
12444 if (type_class() != other_type.type_class()) { | 12459 if (type_class() != other_type.type_class()) { |
(...skipping 23 matching lines...) Expand all Loading... |
12468 if (other_type_args.IsNull()) { | 12483 if (other_type_args.IsNull()) { |
12469 return type_args.IsRaw(from_index, num_type_params); | 12484 return type_args.IsRaw(from_index, num_type_params); |
12470 } | 12485 } |
12471 ASSERT(type_args.Length() >= (from_index + num_type_params)); | 12486 ASSERT(type_args.Length() >= (from_index + num_type_params)); |
12472 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); | 12487 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); |
12473 AbstractType& type_arg = AbstractType::Handle(); | 12488 AbstractType& type_arg = AbstractType::Handle(); |
12474 AbstractType& other_type_arg = AbstractType::Handle(); | 12489 AbstractType& other_type_arg = AbstractType::Handle(); |
12475 for (intptr_t i = 0; i < num_type_params; i++) { | 12490 for (intptr_t i = 0; i < num_type_params; i++) { |
12476 type_arg = type_args.TypeAt(from_index + i); | 12491 type_arg = type_args.TypeAt(from_index + i); |
12477 other_type_arg = other_type_args.TypeAt(from_index + i); | 12492 other_type_arg = other_type_args.TypeAt(from_index + i); |
12478 if (!type_arg.Equals(other_type_arg)) { | 12493 if (!type_arg.IsEquivalent(other_type_arg, trail)) { |
12479 return false; | 12494 return false; |
12480 } | 12495 } |
12481 } | 12496 } |
12482 return true; | 12497 return true; |
12483 } | 12498 } |
12484 | 12499 |
12485 | 12500 |
12486 RawAbstractType* Type::CloneUnfinalized() const { | 12501 RawAbstractType* Type::CloneUnfinalized() const { |
12487 ASSERT(IsResolved()); | 12502 ASSERT(IsResolved()); |
12488 if (IsFinalized()) { | 12503 if (IsFinalized()) { |
12489 return raw(); | 12504 return raw(); |
12490 } | 12505 } |
12491 ASSERT(!IsMalformed()); // Malformed types are finalized. | 12506 ASSERT(!IsMalformed()); // Malformed types are finalized. |
12492 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. | 12507 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. |
12493 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); | 12508 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); |
12494 type_args = type_args.CloneUnfinalized(); | 12509 type_args = type_args.CloneUnfinalized(); |
12495 const Class& type_cls = Class::Handle(type_class()); | 12510 const Class& type_cls = Class::Handle(type_class()); |
12496 return Type::New(type_cls, type_args, token_pos()); | 12511 return Type::New(type_cls, type_args, token_pos()); |
12497 } | 12512 } |
12498 | 12513 |
12499 | 12514 |
12500 RawAbstractType* Type::Canonicalize() const { | 12515 RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const { |
12501 ASSERT(IsFinalized()); | 12516 ASSERT(IsFinalized()); |
12502 if (IsCanonical() || IsMalformed()) { | 12517 if (IsCanonical() || IsMalformed()) { |
12503 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); | 12518 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); |
12504 return this->raw(); | 12519 return this->raw(); |
12505 } | 12520 } |
12506 Isolate* isolate = Isolate::Current(); | 12521 Isolate* isolate = Isolate::Current(); |
12507 Type& type = Type::Handle(isolate); | 12522 Type& type = Type::Handle(isolate); |
12508 const Class& cls = Class::Handle(isolate, type_class()); | 12523 const Class& cls = Class::Handle(isolate, type_class()); |
12509 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) { | 12524 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) { |
12510 return Object::dynamic_type(); | 12525 return Object::dynamic_type(); |
(...skipping 30 matching lines...) Expand all Loading... |
12541 ASSERT(type.IsFinalized()); | 12556 ASSERT(type.IsFinalized()); |
12542 if (this->Equals(type)) { | 12557 if (this->Equals(type)) { |
12543 return type.raw(); | 12558 return type.raw(); |
12544 } | 12559 } |
12545 index++; | 12560 index++; |
12546 } | 12561 } |
12547 // Canonicalize the type arguments. | 12562 // Canonicalize the type arguments. |
12548 AbstractTypeArguments& type_args = | 12563 AbstractTypeArguments& type_args = |
12549 AbstractTypeArguments::Handle(isolate, arguments()); | 12564 AbstractTypeArguments::Handle(isolate, arguments()); |
12550 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments())); | 12565 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments())); |
12551 type_args = type_args.Canonicalize(); | 12566 type_args = type_args.Canonicalize(trail); |
12552 set_arguments(type_args); | 12567 set_arguments(type_args); |
12553 // The type needs to be added to the list. Grow the list if it is full. | 12568 // The type needs to be added to the list. Grow the list if it is full. |
12554 if (index == canonical_types_len) { | 12569 if (index == canonical_types_len) { |
12555 const intptr_t kLengthIncrement = 2; // Raw and parameterized. | 12570 const intptr_t kLengthIncrement = 2; // Raw and parameterized. |
12556 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; | 12571 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; |
12557 const Array& new_canonical_types = Array::Handle( | 12572 const Array& new_canonical_types = Array::Handle( |
12558 isolate, Array::Grow(canonical_types, new_length, Heap::kOld)); | 12573 isolate, Array::Grow(canonical_types, new_length, Heap::kOld)); |
12559 cls.set_canonical_types(new_canonical_types); | 12574 cls.set_canonical_types(new_canonical_types); |
12560 new_canonical_types.SetAt(index, *this); | 12575 new_canonical_types.SetAt(index, *this); |
12561 } else { | 12576 } else { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12680 return "Unresolved Type"; | 12695 return "Unresolved Type"; |
12681 } | 12696 } |
12682 } | 12697 } |
12683 | 12698 |
12684 | 12699 |
12685 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { | 12700 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { |
12686 JSONObject jsobj(stream); | 12701 JSONObject jsobj(stream); |
12687 } | 12702 } |
12688 | 12703 |
12689 | 12704 |
12690 bool TypeRef::IsInstantiated() const { | 12705 bool TypeRef::IsInstantiated(GrowableObjectArray* trail) const { |
12691 if (is_being_checked()) { | 12706 if (TestAndAddToTrail(&trail)) { |
12692 return true; | 12707 return true; |
12693 } | 12708 } |
12694 set_is_being_checked(true); | 12709 return AbstractType::Handle(type()).IsInstantiated(trail); |
12695 const bool result = AbstractType::Handle(type()).IsInstantiated(); | |
12696 set_is_being_checked(false); | |
12697 return result; | |
12698 } | 12710 } |
12699 | 12711 |
12700 | 12712 |
12701 bool TypeRef::Equals(const Instance& other) const { | 12713 bool TypeRef::IsEquivalent(const Instance& other, |
12702 // TODO(regis): Use trail instead of mark bit. | 12714 GrowableObjectArray* trail) const { |
12703 if (raw() == other.raw()) { | 12715 if (raw() == other.raw()) { |
12704 return true; | 12716 return true; |
12705 } | 12717 } |
12706 if (is_being_checked()) { | 12718 if (TestAndAddBuddyToTrail(&trail, other)) { |
12707 return true; | 12719 return true; |
12708 } | 12720 } |
12709 set_is_being_checked(true); | 12721 return AbstractType::Handle(type()).IsEquivalent(other, trail); |
12710 const bool result = AbstractType::Handle(type()).Equals(other); | |
12711 set_is_being_checked(false); | |
12712 return result; | |
12713 } | 12722 } |
12714 | 12723 |
12715 | 12724 |
12716 RawAbstractType* TypeRef::InstantiateFrom( | 12725 RawAbstractType* TypeRef::InstantiateFrom( |
12717 const AbstractTypeArguments& instantiator_type_arguments, | 12726 const AbstractTypeArguments& instantiator_type_arguments, |
12718 Error* bound_error) const { | 12727 Error* bound_error, |
| 12728 GrowableObjectArray* trail) const { |
| 12729 TypeRef& instantiated_type_ref = TypeRef::Handle(); |
| 12730 instantiated_type_ref ^= OnlyBuddyInTrail(trail); |
| 12731 if (!instantiated_type_ref.IsNull()) { |
| 12732 return instantiated_type_ref.raw(); |
| 12733 } |
| 12734 instantiated_type_ref = TypeRef::New(Type::Handle(Type::DynamicType())); |
| 12735 AddOnlyBuddyToTrail(&trail, instantiated_type_ref); |
12719 const AbstractType& ref_type = AbstractType::Handle(type()); | 12736 const AbstractType& ref_type = AbstractType::Handle(type()); |
12720 // TODO(regis): Use trail instead of mark bit plus temporary redirection, | |
12721 // because it could be marked for another reason. | |
12722 if (is_being_checked()) { | |
12723 ASSERT(ref_type.IsTypeRef()); | |
12724 return ref_type.raw(); | |
12725 } | |
12726 set_is_being_checked(true); | |
12727 ASSERT(!ref_type.IsTypeRef()); | 12737 ASSERT(!ref_type.IsTypeRef()); |
12728 const TypeRef& instantiated_type_ref = TypeRef::Handle( | |
12729 TypeRef::New(ref_type)); | |
12730 // TODO(regis): instantiated_type_ref should be stored in the trail instead. | |
12731 set_type(instantiated_type_ref); | |
12732 const AbstractType& instantiated_ref_type = AbstractType::Handle( | 12738 const AbstractType& instantiated_ref_type = AbstractType::Handle( |
12733 ref_type.InstantiateFrom(instantiator_type_arguments, bound_error)); | 12739 ref_type.InstantiateFrom(instantiator_type_arguments, |
| 12740 bound_error, |
| 12741 trail)); |
12734 instantiated_type_ref.set_type(instantiated_ref_type); | 12742 instantiated_type_ref.set_type(instantiated_ref_type); |
12735 set_type(ref_type); | |
12736 set_is_being_checked(false); | |
12737 return instantiated_type_ref.raw(); | 12743 return instantiated_type_ref.raw(); |
12738 } | 12744 } |
12739 | 12745 |
12740 | 12746 |
12741 void TypeRef::set_type(const AbstractType& value) const { | 12747 void TypeRef::set_type(const AbstractType& value) const { |
12742 ASSERT(value.HasResolvedTypeClass()); | 12748 ASSERT(value.HasResolvedTypeClass()); |
12743 StorePointer(&raw_ptr()->type_, value.raw()); | 12749 StorePointer(&raw_ptr()->type_, value.raw()); |
12744 } | 12750 } |
12745 | 12751 |
12746 | 12752 |
12747 void TypeRef::set_is_being_checked(bool value) const { | 12753 // A TypeRef cannot be canonical by definition. Only its referenced type can be. |
12748 raw_ptr()->is_being_checked_ = value; | |
12749 } | |
12750 | |
12751 | |
12752 // This function only canonicalizes the referenced type, but not the TypeRef | |
12753 // itself, since it cannot be canonical by definition. | |
12754 // Consider the type Derived, where class Derived extends Base<Derived>. | 12754 // Consider the type Derived, where class Derived extends Base<Derived>. |
12755 // The first type argument of its flattened type argument vector is Derived, | 12755 // The first type argument of its flattened type argument vector is Derived, |
12756 // i.e. itself, but pointer equality is not possible. | 12756 // i.e. itself, but pointer equality is not possible. |
12757 RawAbstractType* TypeRef::Canonicalize() const { | 12757 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const { |
12758 // TODO(regis): Use trail, not mark bit. | 12758 if (TestAndAddToTrail(&trail)) { |
12759 if (is_being_checked()) { | |
12760 return raw(); | 12759 return raw(); |
12761 } | 12760 } |
12762 set_is_being_checked(true); | |
12763 AbstractType& ref_type = AbstractType::Handle(type()); | 12761 AbstractType& ref_type = AbstractType::Handle(type()); |
12764 ASSERT(!ref_type.IsTypeRef()); | 12762 ref_type = ref_type.Canonicalize(trail); |
12765 ref_type = ref_type.Canonicalize(); | |
12766 set_type(ref_type); | 12763 set_type(ref_type); |
12767 // No need to call SetCanonical(), since a TypeRef cannot be canonical by | 12764 return raw(); |
12768 // definition. | |
12769 set_is_being_checked(false); | |
12770 // We return the referenced type instead of the TypeRef in order to provide | |
12771 // pointer equality in simple cases, e.g. in language/f_bounded_equality_test. | |
12772 return ref_type.raw(); | |
12773 } | 12765 } |
12774 | 12766 |
12775 | 12767 |
12776 intptr_t TypeRef::Hash() const { | 12768 intptr_t TypeRef::Hash() const { |
12777 // TODO(regis): Use trail and hash of referenced type. | 12769 // Do not calculate the hash of the referenced type to avoid divergence. |
12778 // Do not calculate the hash of the referenced type to avoid cycles. | |
12779 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); | 12770 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); |
12780 return FinalizeHash(result); | 12771 return FinalizeHash(result); |
12781 } | 12772 } |
12782 | 12773 |
12783 | 12774 |
| 12775 bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const { |
| 12776 if (*trail == NULL) { |
| 12777 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); |
| 12778 } else { |
| 12779 const intptr_t len = (*trail)->Length(); |
| 12780 for (intptr_t i = 0; i < len; i++) { |
| 12781 if ((*trail)->At(i) == this->raw()) { |
| 12782 return true; |
| 12783 } |
| 12784 } |
| 12785 } |
| 12786 (*trail)->Add(*this); |
| 12787 return false; |
| 12788 } |
| 12789 |
| 12790 |
| 12791 bool TypeRef::TestAndAddBuddyToTrail(GrowableObjectArray** trail, |
| 12792 const Object& buddy) const { |
| 12793 if (*trail == NULL) { |
| 12794 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); |
| 12795 } else { |
| 12796 const intptr_t len = (*trail)->Length(); |
| 12797 ASSERT((len % 2) == 0); |
| 12798 for (intptr_t i = 0; i < len; i += 2) { |
| 12799 if (((*trail)->At(i) == this->raw()) && |
| 12800 ((*trail)->At(i + 1) == buddy.raw())) { |
| 12801 return true; |
| 12802 } |
| 12803 } |
| 12804 } |
| 12805 (*trail)->Add(*this); |
| 12806 (*trail)->Add(buddy); |
| 12807 return false; |
| 12808 } |
| 12809 |
| 12810 |
| 12811 RawObject* TypeRef::OnlyBuddyInTrail(GrowableObjectArray* trail) const { |
| 12812 if (trail == NULL) { |
| 12813 return Object::null(); |
| 12814 } |
| 12815 const intptr_t len = trail->Length(); |
| 12816 ASSERT((len % 2) == 0); |
| 12817 for (intptr_t i = 0; i < len; i += 2) { |
| 12818 if (trail->At(i) == this->raw()) { |
| 12819 ASSERT(trail->At(i + 1) != Object::null()); |
| 12820 return trail->At(i + 1); |
| 12821 } |
| 12822 } |
| 12823 return Object::null(); |
| 12824 } |
| 12825 |
| 12826 |
| 12827 void TypeRef::AddOnlyBuddyToTrail(GrowableObjectArray** trail, |
| 12828 const Object& buddy) const { |
| 12829 if (*trail == NULL) { |
| 12830 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); |
| 12831 } else { |
| 12832 ASSERT(OnlyBuddyInTrail(*trail) == Object::null()); |
| 12833 } |
| 12834 (*trail)->Add(*this); |
| 12835 (*trail)->Add(buddy); |
| 12836 } |
| 12837 |
| 12838 |
12784 RawTypeRef* TypeRef::New() { | 12839 RawTypeRef* TypeRef::New() { |
12785 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); | 12840 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); |
12786 RawObject* raw = Object::Allocate(TypeRef::kClassId, | 12841 RawObject* raw = Object::Allocate(TypeRef::kClassId, |
12787 TypeRef::InstanceSize(), | 12842 TypeRef::InstanceSize(), |
12788 Heap::kOld); | 12843 Heap::kOld); |
12789 return reinterpret_cast<RawTypeRef*>(raw); | 12844 return reinterpret_cast<RawTypeRef*>(raw); |
12790 } | 12845 } |
12791 | 12846 |
12792 | 12847 |
12793 RawTypeRef* TypeRef::New(const AbstractType& type) { | 12848 RawTypeRef* TypeRef::New(const AbstractType& type) { |
12794 const TypeRef& result = TypeRef::Handle(TypeRef::New()); | 12849 const TypeRef& result = TypeRef::Handle(TypeRef::New()); |
12795 result.set_type(type); | 12850 result.set_type(type); |
12796 result.set_is_being_checked(false); | |
12797 return result.raw(); | 12851 return result.raw(); |
12798 } | 12852 } |
12799 | 12853 |
12800 | 12854 |
12801 const char* TypeRef::ToCString() const { | 12855 const char* TypeRef::ToCString() const { |
12802 const char* format = "TypeRef: %s%s"; | 12856 const char* format = "TypeRef: %s%s"; |
12803 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( | 12857 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( |
12804 type()).type_class()).Name()).ToCString(); | 12858 type()).type_class()).Name()).ToCString(); |
12805 const char* args_cstr = (AbstractType::Handle( | 12859 const char* args_cstr = (AbstractType::Handle( |
12806 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>"; | 12860 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>"; |
12807 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; | 12861 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; |
12808 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 12862 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
12809 OS::SNPrint(chars, len, format, type_cstr, args_cstr); | 12863 OS::SNPrint(chars, len, format, type_cstr, args_cstr); |
12810 return chars; | 12864 return chars; |
12811 } | 12865 } |
12812 | 12866 |
12813 | 12867 |
12814 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { | 12868 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { |
12815 JSONObject jsobj(stream); | 12869 JSONObject jsobj(stream); |
12816 } | 12870 } |
12817 | 12871 |
12818 | 12872 |
12819 void TypeParameter::set_is_finalized() const { | 12873 void TypeParameter::set_is_finalized() const { |
12820 ASSERT(!IsFinalized()); | 12874 ASSERT(!IsFinalized()); |
12821 set_type_state(RawTypeParameter::kFinalizedUninstantiated); | 12875 set_type_state(RawTypeParameter::kFinalizedUninstantiated); |
12822 } | 12876 } |
12823 | 12877 |
12824 | 12878 |
12825 bool TypeParameter::Equals(const Instance& other) const { | 12879 bool TypeParameter::IsEquivalent(const Instance& other, |
| 12880 GrowableObjectArray* trail) const { |
12826 if (raw() == other.raw()) { | 12881 if (raw() == other.raw()) { |
12827 return true; | 12882 return true; |
12828 } | 12883 } |
12829 if (other.IsTypeRef()) { | 12884 if (other.IsTypeRef()) { |
12830 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | 12885 // Unfold right hand type. Divergence is controlled by left hand type. |
12831 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | 12886 const AbstractType& other_ref_type = AbstractType::Handle( |
| 12887 TypeRef::Cast(other).type()); |
| 12888 ASSERT(!other_ref_type.IsTypeRef()); |
| 12889 return IsEquivalent(other_ref_type, trail); |
12832 } | 12890 } |
12833 if (!other.IsTypeParameter()) { | 12891 if (!other.IsTypeParameter()) { |
12834 return false; | 12892 return false; |
12835 } | 12893 } |
12836 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 12894 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
12837 if (parameterized_class() != other_type_param.parameterized_class()) { | 12895 if (parameterized_class() != other_type_param.parameterized_class()) { |
12838 return false; | 12896 return false; |
12839 } | 12897 } |
12840 if (IsFinalized() == other_type_param.IsFinalized()) { | 12898 if (IsFinalized() == other_type_param.IsFinalized()) { |
12841 return index() == other_type_param.index(); | 12899 return index() == other_type_param.index(); |
(...skipping 20 matching lines...) Expand all Loading... |
12862 } | 12920 } |
12863 | 12921 |
12864 | 12922 |
12865 void TypeParameter::set_bound(const AbstractType& value) const { | 12923 void TypeParameter::set_bound(const AbstractType& value) const { |
12866 StorePointer(&raw_ptr()->bound_, value.raw()); | 12924 StorePointer(&raw_ptr()->bound_, value.raw()); |
12867 } | 12925 } |
12868 | 12926 |
12869 | 12927 |
12870 RawAbstractType* TypeParameter::InstantiateFrom( | 12928 RawAbstractType* TypeParameter::InstantiateFrom( |
12871 const AbstractTypeArguments& instantiator_type_arguments, | 12929 const AbstractTypeArguments& instantiator_type_arguments, |
12872 Error* bound_error) const { | 12930 Error* bound_error, |
| 12931 GrowableObjectArray* trail) const { |
12873 ASSERT(IsFinalized()); | 12932 ASSERT(IsFinalized()); |
12874 if (instantiator_type_arguments.IsNull()) { | 12933 if (instantiator_type_arguments.IsNull()) { |
12875 return Type::DynamicType(); | 12934 return Type::DynamicType(); |
12876 } | 12935 } |
12877 const AbstractType& type_arg = AbstractType::Handle( | 12936 const AbstractType& type_arg = AbstractType::Handle( |
12878 instantiator_type_arguments.TypeAt(index())); | 12937 instantiator_type_arguments.TypeAt(index())); |
12879 // There is no need to canonicalize the instantiated type parameter, since all | 12938 // There is no need to canonicalize the instantiated type parameter, since all |
12880 // type arguments are canonicalized at type finalization time. It would be too | 12939 // type arguments are canonicalized at type finalization time. It would be too |
12881 // early to canonicalize the returned type argument here, since instantiation | 12940 // early to canonicalize the returned type argument here, since instantiation |
12882 // not only happens at run time, but also during type finalization. | 12941 // not only happens at run time, but also during type finalization. |
12883 // However, if the type argument is a reference to a canonical type, we | |
12884 // return the referenced canonical type instead of the type reference to | |
12885 // provide pointer equality in some simple cases, e.g. in | |
12886 // language/f_bounded_equality_test. | |
12887 if (type_arg.IsTypeRef()) { | |
12888 const AbstractType& ref_type = AbstractType::Handle( | |
12889 TypeRef::Cast(type_arg).type()); | |
12890 if (ref_type.IsCanonical()) { | |
12891 return ref_type.raw(); | |
12892 } | |
12893 } | |
12894 return type_arg.raw(); | 12942 return type_arg.raw(); |
12895 } | 12943 } |
12896 | 12944 |
12897 | 12945 |
12898 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 12946 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
12899 const AbstractType& upper_bound, | 12947 const AbstractType& upper_bound, |
12900 Error* bound_error) const { | 12948 Error* bound_error) const { |
12901 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 12949 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
12902 ASSERT(bounded_type.IsFinalized()); | 12950 ASSERT(bounded_type.IsFinalized()); |
12903 ASSERT(upper_bound.IsFinalized()); | 12951 ASSERT(upper_bound.IsFinalized()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12950 index(), | 12998 index(), |
12951 String::Handle(name()), | 12999 String::Handle(name()), |
12952 AbstractType::Handle(bound()), | 13000 AbstractType::Handle(bound()), |
12953 token_pos()); | 13001 token_pos()); |
12954 } | 13002 } |
12955 | 13003 |
12956 | 13004 |
12957 intptr_t TypeParameter::Hash() const { | 13005 intptr_t TypeParameter::Hash() const { |
12958 ASSERT(IsFinalized()); | 13006 ASSERT(IsFinalized()); |
12959 uword result = Class::Handle(parameterized_class()).id(); | 13007 uword result = Class::Handle(parameterized_class()).id(); |
12960 // Do not include the hash of the bound, which could lead to cycles. | 13008 // No need to include the hash of the bound, since the type parameter is fully |
| 13009 // identified by its class and index. |
12961 result <<= index(); | 13010 result <<= index(); |
12962 return FinalizeHash(result); | 13011 return FinalizeHash(result); |
12963 } | 13012 } |
12964 | 13013 |
12965 | 13014 |
12966 RawTypeParameter* TypeParameter::New() { | 13015 RawTypeParameter* TypeParameter::New() { |
12967 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != | 13016 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != |
12968 Class::null()); | 13017 Class::null()); |
12969 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 13018 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
12970 TypeParameter::InstanceSize(), | 13019 TypeParameter::InstanceSize(), |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13034 bool BoundedType::IsMalformedOrMalbounded() const { | 13083 bool BoundedType::IsMalformedOrMalbounded() const { |
13035 return AbstractType::Handle(type()).IsMalformedOrMalbounded(); | 13084 return AbstractType::Handle(type()).IsMalformedOrMalbounded(); |
13036 } | 13085 } |
13037 | 13086 |
13038 | 13087 |
13039 RawLanguageError* BoundedType::error() const { | 13088 RawLanguageError* BoundedType::error() const { |
13040 return AbstractType::Handle(type()).error(); | 13089 return AbstractType::Handle(type()).error(); |
13041 } | 13090 } |
13042 | 13091 |
13043 | 13092 |
13044 bool BoundedType::Equals(const Instance& other) const { | 13093 bool BoundedType::IsEquivalent(const Instance& other, |
| 13094 GrowableObjectArray* trail) const { |
13045 // BoundedType are not canonicalized, because their bound may get finalized | 13095 // BoundedType are not canonicalized, because their bound may get finalized |
13046 // after the BoundedType is created and initialized. | 13096 // after the BoundedType is created and initialized. |
13047 if (raw() == other.raw()) { | 13097 if (raw() == other.raw()) { |
13048 return true; | 13098 return true; |
13049 } | 13099 } |
13050 if (other.IsTypeRef()) { | 13100 if (other.IsTypeRef()) { |
13051 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | 13101 // Unfold right hand type. Divergence is controlled by left hand type. |
13052 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | 13102 const AbstractType& other_ref_type = AbstractType::Handle( |
| 13103 TypeRef::Cast(other).type()); |
| 13104 ASSERT(!other_ref_type.IsTypeRef()); |
| 13105 return IsEquivalent(other_ref_type, trail); |
13053 } | 13106 } |
13054 if (!other.IsBoundedType()) { | 13107 if (!other.IsBoundedType()) { |
13055 return false; | 13108 return false; |
13056 } | 13109 } |
13057 const BoundedType& other_bounded = BoundedType::Cast(other); | 13110 const BoundedType& other_bounded = BoundedType::Cast(other); |
13058 if (type_parameter() != other_bounded.type_parameter()) { | 13111 if (type_parameter() != other_bounded.type_parameter()) { |
13059 // Not a structural compare. | |
13060 // Note that a deep comparison of bounds could lead to cycles. | |
13061 return false; | 13112 return false; |
13062 } | 13113 } |
13063 const AbstractType& this_type = AbstractType::Handle(type()); | 13114 const AbstractType& this_type = AbstractType::Handle(type()); |
13064 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); | 13115 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); |
13065 if (!this_type.Equals(other_type)) { | 13116 if (!this_type.IsEquivalent(other_type, trail)) { |
13066 return false; | 13117 return false; |
13067 } | 13118 } |
13068 const AbstractType& this_bound = AbstractType::Handle(bound()); | 13119 const AbstractType& this_bound = AbstractType::Handle(bound()); |
13069 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); | 13120 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); |
13070 return this_bound.IsFinalized() && | 13121 return this_bound.IsFinalized() && |
13071 other_bound.IsFinalized() && | 13122 other_bound.IsFinalized() && |
13072 this_bound.Equals(other_bound); | 13123 this_bound.Equals(other_bound); // Different graph, do not pass trail. |
13073 } | 13124 } |
13074 | 13125 |
13075 | 13126 |
13076 void BoundedType::set_type(const AbstractType& value) const { | 13127 void BoundedType::set_type(const AbstractType& value) const { |
13077 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); | 13128 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); |
13078 ASSERT(!value.IsMalformed()); | 13129 ASSERT(!value.IsMalformed()); |
13079 StorePointer(&raw_ptr()->type_, value.raw()); | 13130 StorePointer(&raw_ptr()->type_, value.raw()); |
13080 } | 13131 } |
13081 | 13132 |
13082 | 13133 |
13083 void BoundedType::set_bound(const AbstractType& value) const { | 13134 void BoundedType::set_bound(const AbstractType& value) const { |
13084 // The bound may still be unfinalized because of legal cycles. | 13135 // The bound may still be unfinalized because of legal cycles. |
13085 // It must be finalized before it is checked at run time, though. | 13136 // It must be finalized before it is checked at run time, though. |
13086 StorePointer(&raw_ptr()->bound_, value.raw()); | 13137 StorePointer(&raw_ptr()->bound_, value.raw()); |
13087 } | 13138 } |
13088 | 13139 |
13089 | 13140 |
13090 void BoundedType::set_type_parameter(const TypeParameter& value) const { | 13141 void BoundedType::set_type_parameter(const TypeParameter& value) const { |
13091 // A null type parameter is set when marking a type malformed because of a | 13142 // A null type parameter is set when marking a type malformed because of a |
13092 // bound error at compile time. | 13143 // bound error at compile time. |
13093 ASSERT(value.IsNull() || value.IsFinalized()); | 13144 ASSERT(value.IsNull() || value.IsFinalized()); |
13094 StorePointer(&raw_ptr()->type_parameter_, value.raw()); | 13145 StorePointer(&raw_ptr()->type_parameter_, value.raw()); |
13095 } | 13146 } |
13096 | 13147 |
13097 | 13148 |
13098 void BoundedType::set_is_being_checked(bool value) const { | |
13099 raw_ptr()->is_being_checked_ = value; | |
13100 } | |
13101 | |
13102 | |
13103 RawAbstractType* BoundedType::InstantiateFrom( | 13149 RawAbstractType* BoundedType::InstantiateFrom( |
13104 const AbstractTypeArguments& instantiator_type_arguments, | 13150 const AbstractTypeArguments& instantiator_type_arguments, |
13105 Error* bound_error) const { | 13151 Error* bound_error, |
| 13152 GrowableObjectArray* trail) const { |
13106 ASSERT(IsFinalized()); | 13153 ASSERT(IsFinalized()); |
13107 AbstractType& bounded_type = AbstractType::Handle(type()); | 13154 AbstractType& bounded_type = AbstractType::Handle(type()); |
13108 if (!bounded_type.IsInstantiated()) { | 13155 if (!bounded_type.IsInstantiated()) { |
13109 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, | 13156 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, |
13110 bound_error); | 13157 bound_error, |
| 13158 trail); |
13111 } | 13159 } |
13112 if (FLAG_enable_type_checks && | 13160 if (FLAG_enable_type_checks && bound_error->IsNull()) { |
13113 bound_error->IsNull() && | |
13114 !is_being_checked()) { | |
13115 // Avoid endless recursion while checking and instantiating bound. | |
13116 set_is_being_checked(true); | |
13117 AbstractType& upper_bound = AbstractType::Handle(bound()); | 13161 AbstractType& upper_bound = AbstractType::Handle(bound()); |
13118 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); | 13162 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); |
13119 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 13163 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
13120 if (!upper_bound.IsInstantiated()) { | 13164 if (!upper_bound.IsInstantiated()) { |
13121 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, | 13165 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, |
13122 bound_error); | 13166 bound_error, |
| 13167 trail); |
13123 } | 13168 } |
13124 if (bound_error->IsNull()) { | 13169 if (bound_error->IsNull()) { |
13125 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && | 13170 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && |
13126 bound_error->IsNull()) { | 13171 bound_error->IsNull()) { |
13127 // We cannot determine yet whether the bounded_type is below the | 13172 // We cannot determine yet whether the bounded_type is below the |
13128 // upper_bound, because one or both of them is still uninstantiated. | 13173 // upper_bound, because one or both of them is still uninstantiated. |
13129 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); | 13174 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); |
13130 // Postpone bound check by returning a new BoundedType with partially | 13175 // Postpone bound check by returning a new BoundedType with partially |
13131 // instantiated bounded_type and upper_bound, but keeping type_param. | 13176 // instantiated bounded_type and upper_bound, but keeping type_param. |
13132 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); | 13177 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); |
13133 } | 13178 } |
13134 } | 13179 } |
13135 set_is_being_checked(false); | |
13136 } | 13180 } |
13137 return bounded_type.raw(); | 13181 return bounded_type.raw(); |
13138 } | 13182 } |
13139 | 13183 |
13140 | 13184 |
13141 RawAbstractType* BoundedType::CloneUnfinalized() const { | 13185 RawAbstractType* BoundedType::CloneUnfinalized() const { |
13142 if (IsFinalized()) { | 13186 if (IsFinalized()) { |
13143 return raw(); | 13187 return raw(); |
13144 } | 13188 } |
13145 AbstractType& bounded_type = AbstractType::Handle(type()); | 13189 AbstractType& bounded_type = AbstractType::Handle(type()); |
13146 | 13190 |
13147 bounded_type = bounded_type.CloneUnfinalized(); | 13191 bounded_type = bounded_type.CloneUnfinalized(); |
13148 // No need to clone bound or type parameter, as they are not part of the | 13192 // No need to clone bound or type parameter, as they are not part of the |
13149 // finalization state of this bounded type. | 13193 // finalization state of this bounded type. |
13150 return BoundedType::New(bounded_type, | 13194 return BoundedType::New(bounded_type, |
13151 AbstractType::Handle(bound()), | 13195 AbstractType::Handle(bound()), |
13152 TypeParameter::Handle(type_parameter())); | 13196 TypeParameter::Handle(type_parameter())); |
13153 } | 13197 } |
13154 | 13198 |
13155 | 13199 |
13156 intptr_t BoundedType::Hash() const { | 13200 intptr_t BoundedType::Hash() const { |
13157 uword result = AbstractType::Handle(type()).Hash(); | 13201 uword result = AbstractType::Handle(type()).Hash(); |
13158 // Do not include the hash of the bound, which could lead to cycles. | 13202 // No need to include the hash of the bound, since the bound is defined by the |
| 13203 // type parameter (modulo instantiation state). |
13159 result += TypeParameter::Handle(type_parameter()).Hash(); | 13204 result += TypeParameter::Handle(type_parameter()).Hash(); |
13160 return FinalizeHash(result); | 13205 return FinalizeHash(result); |
13161 } | 13206 } |
13162 | 13207 |
13163 | 13208 |
13164 RawBoundedType* BoundedType::New() { | 13209 RawBoundedType* BoundedType::New() { |
13165 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != | 13210 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != |
13166 Class::null()); | 13211 Class::null()); |
13167 RawObject* raw = Object::Allocate(BoundedType::kClassId, | 13212 RawObject* raw = Object::Allocate(BoundedType::kClassId, |
13168 BoundedType::InstanceSize(), | 13213 BoundedType::InstanceSize(), |
13169 Heap::kOld); | 13214 Heap::kOld); |
13170 return reinterpret_cast<RawBoundedType*>(raw); | 13215 return reinterpret_cast<RawBoundedType*>(raw); |
13171 } | 13216 } |
13172 | 13217 |
13173 | 13218 |
13174 RawBoundedType* BoundedType::New(const AbstractType& type, | 13219 RawBoundedType* BoundedType::New(const AbstractType& type, |
13175 const AbstractType& bound, | 13220 const AbstractType& bound, |
13176 const TypeParameter& type_parameter) { | 13221 const TypeParameter& type_parameter) { |
13177 const BoundedType& result = BoundedType::Handle(BoundedType::New()); | 13222 const BoundedType& result = BoundedType::Handle(BoundedType::New()); |
13178 result.set_type(type); | 13223 result.set_type(type); |
13179 result.set_bound(bound); | 13224 result.set_bound(bound); |
13180 result.set_type_parameter(type_parameter); | 13225 result.set_type_parameter(type_parameter); |
13181 result.set_is_being_checked(false); | |
13182 return result.raw(); | 13226 return result.raw(); |
13183 } | 13227 } |
13184 | 13228 |
13185 | 13229 |
13186 const char* BoundedType::ToCString() const { | 13230 const char* BoundedType::ToCString() const { |
13187 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; | 13231 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; |
13188 const char* type_cstr = String::Handle(AbstractType::Handle( | 13232 const char* type_cstr = String::Handle(AbstractType::Handle( |
13189 type()).Name()).ToCString(); | 13233 type()).Name()).ToCString(); |
13190 const char* bound_cstr = String::Handle(AbstractType::Handle( | 13234 const char* bound_cstr = String::Handle(AbstractType::Handle( |
13191 bound()).Name()).ToCString(); | 13235 bound()).Name()).ToCString(); |
(...skipping 3735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16927 return "_MirrorReference"; | 16971 return "_MirrorReference"; |
16928 } | 16972 } |
16929 | 16973 |
16930 | 16974 |
16931 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 16975 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
16932 Instance::PrintToJSONStream(stream, ref); | 16976 Instance::PrintToJSONStream(stream, ref); |
16933 } | 16977 } |
16934 | 16978 |
16935 | 16979 |
16936 } // namespace dart | 16980 } // namespace dart |
OLD | NEW |