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 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 // Last element contains the count of used slots. | 895 // Last element contains the count of used slots. |
896 const intptr_t kInitialCanonicalTypeArgumentsSize = 4; | 896 const intptr_t kInitialCanonicalTypeArgumentsSize = 4; |
897 array = Array::New(kInitialCanonicalTypeArgumentsSize + 1); | 897 array = Array::New(kInitialCanonicalTypeArgumentsSize + 1); |
898 array.SetAt(kInitialCanonicalTypeArgumentsSize, Smi::Handle(Smi::New(0))); | 898 array.SetAt(kInitialCanonicalTypeArgumentsSize, Smi::Handle(Smi::New(0))); |
899 object_store->set_canonical_type_arguments(array); | 899 object_store->set_canonical_type_arguments(array); |
900 | 900 |
901 // Setup type class early in the process. | 901 // Setup type class early in the process. |
902 cls = Class::New<Type>(); | 902 cls = Class::New<Type>(); |
903 object_store->set_type_class(cls); | 903 object_store->set_type_class(cls); |
904 | 904 |
| 905 cls = Class::New<TypeRef>(); |
| 906 object_store->set_type_ref_class(cls); |
| 907 |
905 cls = Class::New<TypeParameter>(); | 908 cls = Class::New<TypeParameter>(); |
906 object_store->set_type_parameter_class(cls); | 909 object_store->set_type_parameter_class(cls); |
907 | 910 |
908 cls = Class::New<BoundedType>(); | 911 cls = Class::New<BoundedType>(); |
909 object_store->set_bounded_type_class(cls); | 912 object_store->set_bounded_type_class(cls); |
910 | 913 |
911 cls = Class::New<MixinAppType>(); | 914 cls = Class::New<MixinAppType>(); |
912 object_store->set_mixin_app_type_class(cls); | 915 object_store->set_mixin_app_type_class(cls); |
913 | 916 |
914 // Pre-allocate the OneByteString class needed by the symbol table. | 917 // Pre-allocate the OneByteString class needed by the symbol table. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 cls.set_num_type_arguments(0); | 1029 cls.set_num_type_arguments(0); |
1027 cls.set_num_own_type_arguments(0); | 1030 cls.set_num_own_type_arguments(0); |
1028 cls.set_is_prefinalized(); | 1031 cls.set_is_prefinalized(); |
1029 RegisterClass(cls, Symbols::Null(), core_lib); | 1032 RegisterClass(cls, Symbols::Null(), core_lib); |
1030 pending_classes.Add(cls); | 1033 pending_classes.Add(cls); |
1031 | 1034 |
1032 cls = object_store->type_class(); | 1035 cls = object_store->type_class(); |
1033 RegisterPrivateClass(cls, Symbols::Type(), core_lib); | 1036 RegisterPrivateClass(cls, Symbols::Type(), core_lib); |
1034 pending_classes.Add(cls); | 1037 pending_classes.Add(cls); |
1035 | 1038 |
| 1039 cls = object_store->type_ref_class(); |
| 1040 RegisterPrivateClass(cls, Symbols::TypeRef(), core_lib); |
| 1041 pending_classes.Add(cls); |
| 1042 |
1036 cls = object_store->type_parameter_class(); | 1043 cls = object_store->type_parameter_class(); |
1037 RegisterPrivateClass(cls, Symbols::TypeParameter(), core_lib); | 1044 RegisterPrivateClass(cls, Symbols::TypeParameter(), core_lib); |
1038 pending_classes.Add(cls); | 1045 pending_classes.Add(cls); |
1039 | 1046 |
1040 cls = object_store->bounded_type_class(); | 1047 cls = object_store->bounded_type_class(); |
1041 RegisterPrivateClass(cls, Symbols::BoundedType(), core_lib); | 1048 RegisterPrivateClass(cls, Symbols::BoundedType(), core_lib); |
1042 pending_classes.Add(cls); | 1049 pending_classes.Add(cls); |
1043 | 1050 |
1044 cls = object_store->mixin_app_type_class(); | 1051 cls = object_store->mixin_app_type_class(); |
1045 RegisterPrivateClass(cls, Symbols::MixinAppType(), core_lib); | 1052 RegisterPrivateClass(cls, Symbols::MixinAppType(), core_lib); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 | 1290 |
1284 // Set up empty classes in the object store, these will get | 1291 // Set up empty classes in the object store, these will get |
1285 // initialized correctly when we read from the snapshot. | 1292 // initialized correctly when we read from the snapshot. |
1286 // This is done to allow bootstrapping of reading classes from the snapshot. | 1293 // This is done to allow bootstrapping of reading classes from the snapshot. |
1287 cls = Class::New<Instance>(kInstanceCid); | 1294 cls = Class::New<Instance>(kInstanceCid); |
1288 object_store->set_object_class(cls); | 1295 object_store->set_object_class(cls); |
1289 | 1296 |
1290 cls = Class::New<Type>(); | 1297 cls = Class::New<Type>(); |
1291 object_store->set_type_class(cls); | 1298 object_store->set_type_class(cls); |
1292 | 1299 |
| 1300 cls = Class::New<TypeRef>(); |
| 1301 object_store->set_type_ref_class(cls); |
| 1302 |
1293 cls = Class::New<TypeParameter>(); | 1303 cls = Class::New<TypeParameter>(); |
1294 object_store->set_type_parameter_class(cls); | 1304 object_store->set_type_parameter_class(cls); |
1295 | 1305 |
1296 cls = Class::New<BoundedType>(); | 1306 cls = Class::New<BoundedType>(); |
1297 object_store->set_bounded_type_class(cls); | 1307 object_store->set_bounded_type_class(cls); |
1298 | 1308 |
1299 cls = Class::New<MixinAppType>(); | 1309 cls = Class::New<MixinAppType>(); |
1300 object_store->set_mixin_app_type_class(cls); | 1310 object_store->set_mixin_app_type_class(cls); |
1301 | 1311 |
1302 cls = Class::New<Array>(); | 1312 cls = Class::New<Array>(); |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 return Class::null(); | 1994 return Class::null(); |
1985 } | 1995 } |
1986 const AbstractType& sup_type = AbstractType::Handle(super_type()); | 1996 const AbstractType& sup_type = AbstractType::Handle(super_type()); |
1987 return sup_type.type_class(); | 1997 return sup_type.type_class(); |
1988 } | 1998 } |
1989 | 1999 |
1990 | 2000 |
1991 void Class::set_super_type(const AbstractType& value) const { | 2001 void Class::set_super_type(const AbstractType& value) const { |
1992 ASSERT(value.IsNull() || | 2002 ASSERT(value.IsNull() || |
1993 (value.IsType() && !value.IsDynamicType()) || | 2003 (value.IsType() && !value.IsDynamicType()) || |
| 2004 value.IsTypeRef() || |
1994 value.IsBoundedType() || | 2005 value.IsBoundedType() || |
1995 value.IsMixinAppType()); | 2006 value.IsMixinAppType()); |
1996 StorePointer(&raw_ptr()->super_type_, value.raw()); | 2007 StorePointer(&raw_ptr()->super_type_, value.raw()); |
1997 } | 2008 } |
1998 | 2009 |
1999 | 2010 |
2000 // Return a TypeParameter if the type_name is a type parameter of this class. | 2011 // Return a TypeParameter if the type_name is a type parameter of this class. |
2001 // Return null otherwise. | 2012 // Return null otherwise. |
2002 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { | 2013 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { |
2003 ASSERT(!type_name.IsNull()); | 2014 ASSERT(!type_name.IsNull()); |
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3506 Class& type_class = Class::Handle(); | 3517 Class& type_class = Class::Handle(); |
3507 for (intptr_t i = 0; i < len; i++) { | 3518 for (intptr_t i = 0; i < len; i++) { |
3508 type = TypeAt(from_index + i); | 3519 type = TypeAt(from_index + i); |
3509 ASSERT(!type.IsNull()); | 3520 ASSERT(!type.IsNull()); |
3510 if (!type.HasResolvedTypeClass()) { | 3521 if (!type.HasResolvedTypeClass()) { |
3511 if (raw_instantiated && type.IsTypeParameter()) { | 3522 if (raw_instantiated && type.IsTypeParameter()) { |
3512 // An uninstantiated type parameter is equivalent to dynamic (even in | 3523 // An uninstantiated type parameter is equivalent to dynamic (even in |
3513 // the presence of a malformed bound in checked mode). | 3524 // the presence of a malformed bound in checked mode). |
3514 continue; | 3525 continue; |
3515 } | 3526 } |
3516 ASSERT((!raw_instantiated && type.IsTypeParameter()) || | |
3517 type.IsBoundedType() || | |
3518 type.IsMalformed()); | |
3519 return false; | 3527 return false; |
3520 } | 3528 } |
3521 type_class = type.type_class(); | 3529 type_class = type.type_class(); |
3522 if (!type_class.IsDynamicClass()) { | 3530 if (!type_class.IsDynamicClass()) { |
3523 return false; | 3531 return false; |
3524 } | 3532 } |
3525 } | 3533 } |
3526 return true; | 3534 return true; |
3527 } | 3535 } |
3528 | 3536 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3572 return Smi::Value(raw_ptr()->length_); | 3580 return Smi::Value(raw_ptr()->length_); |
3573 } | 3581 } |
3574 | 3582 |
3575 | 3583 |
3576 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { | 3584 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { |
3577 return *TypeAddr(index); | 3585 return *TypeAddr(index); |
3578 } | 3586 } |
3579 | 3587 |
3580 | 3588 |
3581 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { | 3589 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { |
3582 ASSERT(!IsCanonical()); | 3590 const AbstractType& type_arg = AbstractType::Handle(TypeAt(index)); |
3583 StorePointer(TypeAddr(index), value.raw()); | 3591 if (type_arg.IsTypeRef()) { |
| 3592 if (value.raw() != type_arg.raw()) { |
| 3593 TypeRef::Cast(type_arg).set_type(value); |
| 3594 } |
| 3595 } else { |
| 3596 StorePointer(TypeAddr(index), value.raw()); |
| 3597 } |
3584 } | 3598 } |
3585 | 3599 |
3586 | 3600 |
3587 bool TypeArguments::IsResolved() const { | 3601 bool TypeArguments::IsResolved() const { |
3588 AbstractType& type = AbstractType::Handle(); | 3602 AbstractType& type = AbstractType::Handle(); |
3589 const intptr_t num_types = Length(); | 3603 const intptr_t num_types = Length(); |
3590 for (intptr_t i = 0; i < num_types; i++) { | 3604 for (intptr_t i = 0; i < num_types; i++) { |
3591 type = TypeAt(i); | 3605 type = TypeAt(i); |
3592 if (!type.IsResolved()) { | 3606 if (!type.IsResolved()) { |
3593 return false; | 3607 return false; |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3908 const Array& table = Array::Handle(isolate, | 3922 const Array& table = Array::Handle(isolate, |
3909 object_store->canonical_type_arguments()); | 3923 object_store->canonical_type_arguments()); |
3910 ASSERT(table.Length() > 0); | 3924 ASSERT(table.Length() > 0); |
3911 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, | 3925 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, |
3912 table, | 3926 table, |
3913 *this, | 3927 *this, |
3914 Hash()); | 3928 Hash()); |
3915 TypeArguments& result = TypeArguments::Handle(isolate); | 3929 TypeArguments& result = TypeArguments::Handle(isolate); |
3916 result ^= table.At(index); | 3930 result ^= table.At(index); |
3917 if (result.IsNull()) { | 3931 if (result.IsNull()) { |
| 3932 // Canonicalize each type argument. |
| 3933 const intptr_t num_types = Length(); |
| 3934 AbstractType& type = AbstractType::Handle(isolate); |
| 3935 for (intptr_t i = 0; i < num_types; i++) { |
| 3936 type = TypeAt(i); |
| 3937 type = type.Canonicalize(); |
| 3938 SetTypeAt(i, type); |
| 3939 } |
3918 // Make sure we have an old space object and add it to the table. | 3940 // Make sure we have an old space object and add it to the table. |
3919 if (this->IsNew()) { | 3941 if (this->IsNew()) { |
3920 result ^= Object::Clone(*this, Heap::kOld); | 3942 result ^= Object::Clone(*this, Heap::kOld); |
3921 } else { | 3943 } else { |
3922 result ^= this->raw(); | 3944 result ^= this->raw(); |
3923 } | 3945 } |
3924 ASSERT(result.IsOld()); | 3946 ASSERT(result.IsOld()); |
3925 InsertIntoCanonicalTypeArguments(isolate, table, result, index); | 3947 InsertIntoCanonicalTypeArguments(isolate, table, result, index); |
3926 } | 3948 } |
3927 ASSERT(result.Equals(*this)); | 3949 ASSERT(result.Equals(*this)); |
(...skipping 7628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11556 | 11578 |
11557 | 11579 |
11558 void AbstractType::set_error(const LanguageError& value) const { | 11580 void AbstractType::set_error(const LanguageError& value) const { |
11559 // AbstractType is an abstract class. | 11581 // AbstractType is an abstract class. |
11560 UNREACHABLE(); | 11582 UNREACHABLE(); |
11561 } | 11583 } |
11562 | 11584 |
11563 | 11585 |
11564 bool AbstractType::Equals(const Instance& other) const { | 11586 bool AbstractType::Equals(const Instance& other) const { |
11565 // AbstractType is an abstract class. | 11587 // AbstractType is an abstract class. |
11566 ASSERT(raw() == AbstractType::null()); | 11588 UNREACHABLE(); |
11567 return other.IsNull(); | 11589 return false; |
11568 } | 11590 } |
11569 | 11591 |
11570 | 11592 |
11571 RawAbstractType* AbstractType::InstantiateFrom( | 11593 RawAbstractType* AbstractType::InstantiateFrom( |
11572 const AbstractTypeArguments& instantiator_type_arguments, | 11594 const AbstractTypeArguments& instantiator_type_arguments, |
11573 Error* bound_error) const { | 11595 Error* bound_error) const { |
11574 // AbstractType is an abstract class. | 11596 // AbstractType is an abstract class. |
11575 UNREACHABLE(); | 11597 UNREACHABLE(); |
11576 return NULL; | 11598 return NULL; |
11577 } | 11599 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11678 name_visibility); | 11700 name_visibility); |
11679 } | 11701 } |
11680 } | 11702 } |
11681 } else { | 11703 } else { |
11682 const UnresolvedClass& cls = UnresolvedClass::Handle(unresolved_class()); | 11704 const UnresolvedClass& cls = UnresolvedClass::Handle(unresolved_class()); |
11683 class_name = cls.Name(); | 11705 class_name = cls.Name(); |
11684 num_type_params = num_args; | 11706 num_type_params = num_args; |
11685 first_type_param_index = 0; | 11707 first_type_param_index = 0; |
11686 } | 11708 } |
11687 String& type_name = String::Handle(); | 11709 String& type_name = String::Handle(); |
11688 if (num_type_params == 0) { | 11710 if ((num_type_params == 0) || |
| 11711 args.IsRaw(first_type_param_index, num_type_params)) { |
11689 type_name = class_name.raw(); | 11712 type_name = class_name.raw(); |
11690 } else { | 11713 } else { |
11691 const String& args_name = String::Handle( | 11714 const String& args_name = String::Handle( |
11692 args.SubvectorName(first_type_param_index, | 11715 args.SubvectorName(first_type_param_index, |
11693 num_type_params, | 11716 num_type_params, |
11694 name_visibility)); | 11717 name_visibility)); |
11695 type_name = String::Concat(class_name, args_name); | 11718 type_name = String::Concat(class_name, args_name); |
11696 } | 11719 } |
11697 // The name is only used for type checking and debugging purposes. | 11720 // The name is only used for type checking and debugging purposes. |
11698 // Unless profiling data shows otherwise, it is not worth caching the name in | 11721 // Unless profiling data shows otherwise, it is not worth caching the name in |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12047 ASSERT(!unresolved_class.IsNull()); | 12070 ASSERT(!unresolved_class.IsNull()); |
12048 return unresolved_class.raw(); | 12071 return unresolved_class.raw(); |
12049 #else | 12072 #else |
12050 ASSERT(!Object::Handle(raw_ptr()->type_class_).IsNull()); | 12073 ASSERT(!Object::Handle(raw_ptr()->type_class_).IsNull()); |
12051 ASSERT(Object::Handle(raw_ptr()->type_class_).IsUnresolvedClass()); | 12074 ASSERT(Object::Handle(raw_ptr()->type_class_).IsUnresolvedClass()); |
12052 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); | 12075 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); |
12053 #endif | 12076 #endif |
12054 } | 12077 } |
12055 | 12078 |
12056 | 12079 |
12057 RawString* Type::TypeClassName() const { | |
12058 if (HasResolvedTypeClass()) { | |
12059 const Class& cls = Class::Handle(type_class()); | |
12060 return cls.Name(); | |
12061 } else { | |
12062 const UnresolvedClass& cls = UnresolvedClass::Handle(unresolved_class()); | |
12063 return cls.Name(); | |
12064 } | |
12065 } | |
12066 | |
12067 | |
12068 RawAbstractTypeArguments* Type::arguments() const { | 12080 RawAbstractTypeArguments* Type::arguments() const { |
12069 return raw_ptr()->arguments_; | 12081 return raw_ptr()->arguments_; |
12070 } | 12082 } |
12071 | 12083 |
12072 | 12084 |
12073 bool Type::IsInstantiated() const { | 12085 bool Type::IsInstantiated() const { |
12074 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { | 12086 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { |
12075 return true; | 12087 return true; |
12076 } | 12088 } |
12077 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { | 12089 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { |
12078 return false; | 12090 return false; |
12079 } | 12091 } |
12080 const AbstractTypeArguments& args = | 12092 const AbstractTypeArguments& args = |
12081 AbstractTypeArguments::Handle(arguments()); | 12093 AbstractTypeArguments::Handle(arguments()); |
12082 return args.IsNull() || args.IsInstantiated(); | 12094 return args.IsNull() || args.IsInstantiated(); |
12083 } | 12095 } |
12084 | 12096 |
12085 | 12097 |
12086 RawAbstractType* Type::InstantiateFrom( | 12098 RawAbstractType* Type::InstantiateFrom( |
12087 const AbstractTypeArguments& instantiator_type_arguments, | 12099 const AbstractTypeArguments& instantiator_type_arguments, |
12088 Error* bound_error) const { | 12100 Error* bound_error) const { |
12089 ASSERT(IsResolved()); | 12101 ASSERT(IsFinalized() || IsBeingFinalized()); |
12090 ASSERT(!IsInstantiated()); | 12102 ASSERT(!IsInstantiated()); |
12091 // Return the uninstantiated type unchanged if malformed. No copy needed. | 12103 // Return the uninstantiated type unchanged if malformed. No copy needed. |
12092 if (IsMalformed()) { | 12104 if (IsMalformed()) { |
12093 return raw(); | 12105 return raw(); |
12094 } | 12106 } |
12095 AbstractTypeArguments& type_arguments = | 12107 AbstractTypeArguments& type_arguments = |
12096 AbstractTypeArguments::Handle(arguments()); | 12108 AbstractTypeArguments::Handle(arguments()); |
12097 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | 12109 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
12098 bound_error); | 12110 bound_error); |
12099 // Note that the type class has to be resolved at this time, but not | 12111 // Note that the type class has to be resolved at this time, but not |
12100 // necessarily finalized yet. We may be checking bounds at compile time. | 12112 // necessarily finalized yet. We may be checking bounds at compile time. |
12101 const Class& cls = Class::Handle(type_class()); | 12113 const Class& cls = Class::Handle(type_class()); |
12102 // This uninstantiated type is not modified, as it can be instantiated | 12114 // This uninstantiated type is not modified, as it can be instantiated |
12103 // with different instantiators. | 12115 // with different instantiators. |
12104 Type& instantiated_type = Type::Handle( | 12116 Type& instantiated_type = Type::Handle( |
12105 Type::New(cls, type_arguments, token_pos())); | 12117 Type::New(cls, type_arguments, token_pos())); |
12106 ASSERT(type_arguments.IsNull() || | 12118 ASSERT(type_arguments.IsNull() || |
12107 (type_arguments.Length() == cls.NumTypeArguments())); | 12119 (type_arguments.Length() == cls.NumTypeArguments())); |
12108 instantiated_type.SetIsFinalized(); | 12120 instantiated_type.SetIsFinalized(); |
12109 return instantiated_type.raw(); | 12121 return instantiated_type.raw(); |
12110 } | 12122 } |
12111 | 12123 |
12112 | 12124 |
12113 bool Type::Equals(const Instance& other) const { | 12125 bool Type::Equals(const Instance& other) const { |
12114 ASSERT(!IsNull()); | 12126 ASSERT(!IsNull()); |
12115 if (raw() == other.raw()) { | 12127 if (raw() == other.raw()) { |
12116 return true; | 12128 return true; |
12117 } | 12129 } |
| 12130 if (other.IsTypeRef()) { |
| 12131 // TODO(regis): Use trail. For now, we "unfold" the right hand type. |
| 12132 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); |
| 12133 } |
12118 if (!other.IsType()) { | 12134 if (!other.IsType()) { |
12119 return false; | 12135 return false; |
12120 } | 12136 } |
12121 const Type& other_type = Type::Cast(other); | 12137 const Type& other_type = Type::Cast(other); |
12122 ASSERT(IsResolved() && other_type.IsResolved()); | 12138 ASSERT(IsResolved() && other_type.IsResolved()); |
12123 if (IsMalformed() || other_type.IsMalformed()) { | 12139 if (IsMalformed() || other_type.IsMalformed()) { |
12124 return false; | 12140 return false; |
12125 } | 12141 } |
12126 if (type_class() != other_type.type_class()) { | 12142 if (type_class() != other_type.type_class()) { |
12127 return false; | 12143 return false; |
12128 } | 12144 } |
12129 if (!IsFinalized() || !other_type.IsFinalized()) { | 12145 if (!IsFinalized() || !other_type.IsFinalized()) { |
12130 return false; | 12146 return false; |
12131 } | 12147 } |
12132 if (arguments() == other_type.arguments()) { | 12148 if (arguments() == other_type.arguments()) { |
12133 return true; | 12149 return true; |
12134 } | 12150 } |
12135 const Class& cls = Class::Handle(type_class()); | 12151 const Class& cls = Class::Handle(type_class()); |
| 12152 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 12153 if (num_type_params == 0) { |
| 12154 // Shortcut unnecessary handle allocation below. |
| 12155 return true; |
| 12156 } |
| 12157 const intptr_t num_type_args = cls.NumTypeArguments(); |
| 12158 const intptr_t from_index = num_type_args - num_type_params; |
12136 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( | 12159 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( |
12137 arguments()); | 12160 arguments()); |
12138 const AbstractTypeArguments& other_type_args = AbstractTypeArguments::Handle( | 12161 const AbstractTypeArguments& other_type_args = AbstractTypeArguments::Handle( |
12139 other_type.arguments()); | 12162 other_type.arguments()); |
12140 const intptr_t num_type_args = cls.NumTypeArguments(); | |
12141 const intptr_t num_type_params = cls.NumTypeParameters(); | |
12142 const intptr_t from_index = num_type_args - num_type_params; | |
12143 if (type_args.IsNull()) { | 12163 if (type_args.IsNull()) { |
12144 return other_type_args.IsRaw(from_index, num_type_params); | 12164 return other_type_args.IsRaw(from_index, num_type_params); |
12145 } | 12165 } |
12146 if (other_type_args.IsNull()) { | 12166 if (other_type_args.IsNull()) { |
12147 return type_args.IsRaw(from_index, num_type_params); | 12167 return type_args.IsRaw(from_index, num_type_params); |
12148 } | 12168 } |
12149 ASSERT(type_args.Length() >= (from_index + num_type_params)); | 12169 ASSERT(type_args.Length() >= (from_index + num_type_params)); |
12150 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); | 12170 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); |
12151 AbstractType& type_arg = AbstractType::Handle(); | 12171 AbstractType& type_arg = AbstractType::Handle(); |
12152 AbstractType& other_type_arg = AbstractType::Handle(); | 12172 AbstractType& other_type_arg = AbstractType::Handle(); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12339 return "Unresolved Type"; | 12359 return "Unresolved Type"; |
12340 } | 12360 } |
12341 } | 12361 } |
12342 | 12362 |
12343 | 12363 |
12344 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { | 12364 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { |
12345 JSONObject jsobj(stream); | 12365 JSONObject jsobj(stream); |
12346 } | 12366 } |
12347 | 12367 |
12348 | 12368 |
| 12369 bool TypeRef::IsInstantiated() const { |
| 12370 if (is_being_checked()) { |
| 12371 return true; |
| 12372 } |
| 12373 set_is_being_checked(true); |
| 12374 const bool result = AbstractType::Handle(type()).IsInstantiated(); |
| 12375 set_is_being_checked(false); |
| 12376 return result; |
| 12377 } |
| 12378 |
| 12379 |
| 12380 bool TypeRef::Equals(const Instance& other) const { |
| 12381 // TODO(regis): Use trail instead of mark bit. |
| 12382 if (raw() == other.raw()) { |
| 12383 return true; |
| 12384 } |
| 12385 if (is_being_checked()) { |
| 12386 return true; |
| 12387 } |
| 12388 set_is_being_checked(true); |
| 12389 const bool result = AbstractType::Handle(type()).Equals(other); |
| 12390 set_is_being_checked(false); |
| 12391 return result; |
| 12392 } |
| 12393 |
| 12394 |
| 12395 RawAbstractType* TypeRef::InstantiateFrom( |
| 12396 const AbstractTypeArguments& instantiator_type_arguments, |
| 12397 Error* bound_error) const { |
| 12398 const AbstractType& ref_type = AbstractType::Handle(type()); |
| 12399 // TODO(regis): Use trail instead of mark bit plus temporary redirection, |
| 12400 // because it could be marked for another reason. |
| 12401 if (is_being_checked()) { |
| 12402 ASSERT(ref_type.IsTypeRef()); |
| 12403 return ref_type.raw(); |
| 12404 } |
| 12405 set_is_being_checked(true); |
| 12406 ASSERT(!ref_type.IsTypeRef()); |
| 12407 const TypeRef& instantiated_type_ref = TypeRef::Handle( |
| 12408 TypeRef::New(ref_type)); |
| 12409 // TODO(regis): instantiated_type_ref should be stored in the trail instead. |
| 12410 set_type(instantiated_type_ref); |
| 12411 const AbstractType& instantiated_ref_type = AbstractType::Handle( |
| 12412 ref_type.InstantiateFrom(instantiator_type_arguments, bound_error)); |
| 12413 instantiated_type_ref.set_type(instantiated_ref_type); |
| 12414 set_type(ref_type); |
| 12415 set_is_being_checked(false); |
| 12416 return instantiated_type_ref.raw(); |
| 12417 } |
| 12418 |
| 12419 |
| 12420 void TypeRef::set_type(const AbstractType& value) const { |
| 12421 ASSERT(value.HasResolvedTypeClass()); |
| 12422 StorePointer(&raw_ptr()->type_, value.raw()); |
| 12423 } |
| 12424 |
| 12425 |
| 12426 void TypeRef::set_is_being_checked(bool value) const { |
| 12427 raw_ptr()->is_being_checked_ = value; |
| 12428 } |
| 12429 |
| 12430 |
| 12431 // This function only canonicalizes the referenced type, but not the TypeRef |
| 12432 // itself, since it cannot be canonical by definition. |
| 12433 // Consider the type Derived, where class Derived extends Base<Derived>. |
| 12434 // The first type argument of its flattened type argument vector is Derived, |
| 12435 // i.e. itself, but pointer equality is not possible. |
| 12436 RawAbstractType* TypeRef::Canonicalize() const { |
| 12437 // TODO(regis): Use trail, not mark bit. |
| 12438 if (is_being_checked()) { |
| 12439 return raw(); |
| 12440 } |
| 12441 set_is_being_checked(true); |
| 12442 AbstractType& ref_type = AbstractType::Handle(type()); |
| 12443 ASSERT(!ref_type.IsTypeRef()); |
| 12444 ref_type = ref_type.Canonicalize(); |
| 12445 set_type(ref_type); |
| 12446 // No need to call SetCanonical(), since a TypeRef cannot be canonical by |
| 12447 // definition. |
| 12448 set_is_being_checked(false); |
| 12449 // We return the referenced type instead of the TypeRef in order to provide |
| 12450 // pointer equality in simple cases, e.g. in language/f_bounded_equality_test. |
| 12451 return ref_type.raw(); |
| 12452 } |
| 12453 |
| 12454 |
| 12455 intptr_t TypeRef::Hash() const { |
| 12456 // TODO(regis): Use trail and hash of referenced type. |
| 12457 // Do not calculate the hash of the referenced type to avoid cycles. |
| 12458 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); |
| 12459 return FinalizeHash(result); |
| 12460 } |
| 12461 |
| 12462 |
| 12463 RawTypeRef* TypeRef::New() { |
| 12464 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); |
| 12465 RawObject* raw = Object::Allocate(TypeRef::kClassId, |
| 12466 TypeRef::InstanceSize(), |
| 12467 Heap::kOld); |
| 12468 return reinterpret_cast<RawTypeRef*>(raw); |
| 12469 } |
| 12470 |
| 12471 |
| 12472 RawTypeRef* TypeRef::New(const AbstractType& type) { |
| 12473 const TypeRef& result = TypeRef::Handle(TypeRef::New()); |
| 12474 result.set_type(type); |
| 12475 result.set_is_being_checked(false); |
| 12476 return result.raw(); |
| 12477 } |
| 12478 |
| 12479 |
| 12480 const char* TypeRef::ToCString() const { |
| 12481 const char* format = "TypeRef: %s%s"; |
| 12482 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( |
| 12483 type()).type_class()).Name()).ToCString(); |
| 12484 const char* args_cstr = (AbstractType::Handle( |
| 12485 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>"; |
| 12486 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; |
| 12487 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 12488 OS::SNPrint(chars, len, format, type_cstr, args_cstr); |
| 12489 return chars; |
| 12490 } |
| 12491 |
| 12492 |
| 12493 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 12494 JSONObject jsobj(stream); |
| 12495 } |
| 12496 |
| 12497 |
12349 void TypeParameter::set_is_finalized() const { | 12498 void TypeParameter::set_is_finalized() const { |
12350 ASSERT(!IsFinalized()); | 12499 ASSERT(!IsFinalized()); |
12351 set_type_state(RawTypeParameter::kFinalizedUninstantiated); | 12500 set_type_state(RawTypeParameter::kFinalizedUninstantiated); |
12352 } | 12501 } |
12353 | 12502 |
12354 | 12503 |
12355 bool TypeParameter::Equals(const Instance& other) const { | 12504 bool TypeParameter::Equals(const Instance& other) const { |
12356 if (raw() == other.raw()) { | 12505 if (raw() == other.raw()) { |
12357 return true; | 12506 return true; |
12358 } | 12507 } |
| 12508 if (other.IsTypeRef()) { |
| 12509 // TODO(regis): Use trail. For now, we "unfold" the right hand type. |
| 12510 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); |
| 12511 } |
12359 if (!other.IsTypeParameter()) { | 12512 if (!other.IsTypeParameter()) { |
12360 return false; | 12513 return false; |
12361 } | 12514 } |
12362 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 12515 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
12363 if (parameterized_class() != other_type_param.parameterized_class()) { | 12516 if (parameterized_class() != other_type_param.parameterized_class()) { |
12364 return false; | 12517 return false; |
12365 } | 12518 } |
12366 if (IsFinalized() == other_type_param.IsFinalized()) { | 12519 if (IsFinalized() == other_type_param.IsFinalized()) { |
12367 return index() == other_type_param.index(); | 12520 return index() == other_type_param.index(); |
12368 } | 12521 } |
(...skipping 24 matching lines...) Expand all Loading... |
12393 } | 12546 } |
12394 | 12547 |
12395 | 12548 |
12396 RawAbstractType* TypeParameter::InstantiateFrom( | 12549 RawAbstractType* TypeParameter::InstantiateFrom( |
12397 const AbstractTypeArguments& instantiator_type_arguments, | 12550 const AbstractTypeArguments& instantiator_type_arguments, |
12398 Error* bound_error) const { | 12551 Error* bound_error) const { |
12399 ASSERT(IsFinalized()); | 12552 ASSERT(IsFinalized()); |
12400 if (instantiator_type_arguments.IsNull()) { | 12553 if (instantiator_type_arguments.IsNull()) { |
12401 return Type::DynamicType(); | 12554 return Type::DynamicType(); |
12402 } | 12555 } |
12403 return instantiator_type_arguments.TypeAt(index()); | 12556 const AbstractType& type_arg = AbstractType::Handle( |
| 12557 instantiator_type_arguments.TypeAt(index())); |
| 12558 // There is no need to canonicalize the instantiated type parameter, since all |
| 12559 // type arguments are canonicalized at type finalization time. It would be too |
| 12560 // early to canonicalize the returned type argument here, since instantiation |
| 12561 // not only happens at run time, but also during type finalization. |
| 12562 // However, if the type argument is a reference to a canonical type, we |
| 12563 // return the referenced canonical type instead of the type reference to |
| 12564 // provide pointer equality in some simple cases, e.g. in |
| 12565 // language/f_bounded_equality_test. |
| 12566 if (type_arg.IsTypeRef()) { |
| 12567 const AbstractType& ref_type = AbstractType::Handle( |
| 12568 TypeRef::Cast(type_arg).type()); |
| 12569 if (ref_type.IsCanonical()) { |
| 12570 return ref_type.raw(); |
| 12571 } |
| 12572 } |
| 12573 return type_arg.raw(); |
12404 } | 12574 } |
12405 | 12575 |
12406 | 12576 |
12407 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 12577 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
12408 const AbstractType& upper_bound, | 12578 const AbstractType& upper_bound, |
12409 Error* bound_error) const { | 12579 Error* bound_error) const { |
12410 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 12580 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
12411 ASSERT(bounded_type.IsFinalized()); | 12581 ASSERT(bounded_type.IsFinalized()); |
12412 ASSERT(upper_bound.IsFinalized()); | 12582 ASSERT(upper_bound.IsFinalized()); |
12413 ASSERT(!bounded_type.IsMalformed()); | 12583 ASSERT(!bounded_type.IsMalformed()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12458 return TypeParameter::New(Class::Handle(parameterized_class()), | 12628 return TypeParameter::New(Class::Handle(parameterized_class()), |
12459 index(), | 12629 index(), |
12460 String::Handle(name()), | 12630 String::Handle(name()), |
12461 AbstractType::Handle(bound()), | 12631 AbstractType::Handle(bound()), |
12462 token_pos()); | 12632 token_pos()); |
12463 } | 12633 } |
12464 | 12634 |
12465 | 12635 |
12466 intptr_t TypeParameter::Hash() const { | 12636 intptr_t TypeParameter::Hash() const { |
12467 ASSERT(IsFinalized()); | 12637 ASSERT(IsFinalized()); |
12468 uword result = 0; | 12638 uword result = Class::Handle(parameterized_class()).id(); |
12469 result += Class::Handle(parameterized_class()).id(); | |
12470 // Do not include the hash of the bound, which could lead to cycles. | 12639 // Do not include the hash of the bound, which could lead to cycles. |
12471 result <<= index(); | 12640 result <<= index(); |
12472 return FinalizeHash(result); | 12641 return FinalizeHash(result); |
12473 } | 12642 } |
12474 | 12643 |
12475 | 12644 |
12476 RawTypeParameter* TypeParameter::New() { | 12645 RawTypeParameter* TypeParameter::New() { |
12477 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != | 12646 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != |
12478 Class::null()); | 12647 Class::null()); |
12479 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 12648 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12550 return AbstractType::Handle(type()).error(); | 12719 return AbstractType::Handle(type()).error(); |
12551 } | 12720 } |
12552 | 12721 |
12553 | 12722 |
12554 bool BoundedType::Equals(const Instance& other) const { | 12723 bool BoundedType::Equals(const Instance& other) const { |
12555 // BoundedType are not canonicalized, because their bound may get finalized | 12724 // BoundedType are not canonicalized, because their bound may get finalized |
12556 // after the BoundedType is created and initialized. | 12725 // after the BoundedType is created and initialized. |
12557 if (raw() == other.raw()) { | 12726 if (raw() == other.raw()) { |
12558 return true; | 12727 return true; |
12559 } | 12728 } |
| 12729 if (other.IsTypeRef()) { |
| 12730 // TODO(regis): Use trail. For now, we "unfold" the right hand type. |
| 12731 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); |
| 12732 } |
12560 if (!other.IsBoundedType()) { | 12733 if (!other.IsBoundedType()) { |
12561 return false; | 12734 return false; |
12562 } | 12735 } |
12563 const BoundedType& other_bounded = BoundedType::Cast(other); | 12736 const BoundedType& other_bounded = BoundedType::Cast(other); |
12564 if (type_parameter() != other_bounded.type_parameter()) { | 12737 if (type_parameter() != other_bounded.type_parameter()) { |
12565 // Not a structural compare. | 12738 // Not a structural compare. |
12566 // Note that a deep comparison of bounds could lead to cycles. | 12739 // Note that a deep comparison of bounds could lead to cycles. |
12567 return false; | 12740 return false; |
12568 } | 12741 } |
12569 const AbstractType& this_type = AbstractType::Handle(type()); | 12742 const AbstractType& this_type = AbstractType::Handle(type()); |
12570 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); | 12743 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); |
12571 if (!this_type.Equals(other_type)) { | 12744 if (!this_type.Equals(other_type)) { |
12572 return false; | 12745 return false; |
12573 } | 12746 } |
12574 const AbstractType& this_bound = AbstractType::Handle(bound()); | 12747 const AbstractType& this_bound = AbstractType::Handle(bound()); |
12575 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); | 12748 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); |
12576 return this_bound.IsFinalized() && | 12749 return this_bound.IsFinalized() && |
12577 other_bound.IsFinalized() && | 12750 other_bound.IsFinalized() && |
12578 this_bound.Equals(other_bound); | 12751 this_bound.Equals(other_bound); |
12579 } | 12752 } |
12580 | 12753 |
12581 | 12754 |
12582 void BoundedType::set_type(const AbstractType& value) const { | 12755 void BoundedType::set_type(const AbstractType& value) const { |
12583 ASSERT(value.IsFinalized()); | 12756 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); |
12584 ASSERT(!value.IsMalformed()); | 12757 ASSERT(!value.IsMalformed()); |
12585 StorePointer(&raw_ptr()->type_, value.raw()); | 12758 StorePointer(&raw_ptr()->type_, value.raw()); |
12586 } | 12759 } |
12587 | 12760 |
12588 | 12761 |
12589 void BoundedType::set_bound(const AbstractType& value) const { | 12762 void BoundedType::set_bound(const AbstractType& value) const { |
12590 // The bound may still be unfinalized because of legal cycles. | 12763 // The bound may still be unfinalized because of legal cycles. |
12591 // It must be finalized before it is checked at run time, though. | 12764 // It must be finalized before it is checked at run time, though. |
12592 StorePointer(&raw_ptr()->bound_, value.raw()); | 12765 StorePointer(&raw_ptr()->bound_, value.raw()); |
12593 } | 12766 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12653 bounded_type = bounded_type.CloneUnfinalized(); | 12826 bounded_type = bounded_type.CloneUnfinalized(); |
12654 // No need to clone bound or type parameter, as they are not part of the | 12827 // No need to clone bound or type parameter, as they are not part of the |
12655 // finalization state of this bounded type. | 12828 // finalization state of this bounded type. |
12656 return BoundedType::New(bounded_type, | 12829 return BoundedType::New(bounded_type, |
12657 AbstractType::Handle(bound()), | 12830 AbstractType::Handle(bound()), |
12658 TypeParameter::Handle(type_parameter())); | 12831 TypeParameter::Handle(type_parameter())); |
12659 } | 12832 } |
12660 | 12833 |
12661 | 12834 |
12662 intptr_t BoundedType::Hash() const { | 12835 intptr_t BoundedType::Hash() const { |
12663 uword result = 0; | 12836 uword result = AbstractType::Handle(type()).Hash(); |
12664 result += AbstractType::Handle(type()).Hash(); | |
12665 // Do not include the hash of the bound, which could lead to cycles. | 12837 // Do not include the hash of the bound, which could lead to cycles. |
12666 TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 12838 result += TypeParameter::Handle(type_parameter()).Hash(); |
12667 if (!type_param.IsNull()) { | |
12668 result += type_param.Hash(); | |
12669 } | |
12670 return FinalizeHash(result); | 12839 return FinalizeHash(result); |
12671 } | 12840 } |
12672 | 12841 |
12673 | 12842 |
12674 RawBoundedType* BoundedType::New() { | 12843 RawBoundedType* BoundedType::New() { |
12675 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != | 12844 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != |
12676 Class::null()); | 12845 Class::null()); |
12677 RawObject* raw = Object::Allocate(BoundedType::kClassId, | 12846 RawObject* raw = Object::Allocate(BoundedType::kClassId, |
12678 BoundedType::InstanceSize(), | 12847 BoundedType::InstanceSize(), |
12679 Heap::kOld); | 12848 Heap::kOld); |
(...skipping 3507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16187 return "_MirrorReference"; | 16356 return "_MirrorReference"; |
16188 } | 16357 } |
16189 | 16358 |
16190 | 16359 |
16191 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 16360 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
16192 Instance::PrintToJSONStream(stream, ref); | 16361 Instance::PrintToJSONStream(stream, ref); |
16193 } | 16362 } |
16194 | 16363 |
16195 | 16364 |
16196 } // namespace dart | 16365 } // namespace dart |
OLD | NEW |