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 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3572 return Smi::Value(raw_ptr()->length_); | 3583 return Smi::Value(raw_ptr()->length_); |
3573 } | 3584 } |
3574 | 3585 |
3575 | 3586 |
3576 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { | 3587 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { |
3577 return *TypeAddr(index); | 3588 return *TypeAddr(index); |
3578 } | 3589 } |
3579 | 3590 |
3580 | 3591 |
3581 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { | 3592 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { |
3582 ASSERT(!IsCanonical()); | 3593 const AbstractType& type_arg = AbstractType::Handle(TypeAt(index)); |
3583 StorePointer(TypeAddr(index), value.raw()); | 3594 if (type_arg.IsTypeRef()) { |
3595 if (value.raw() != type_arg.raw()) { | |
3596 TypeRef::Cast(type_arg).set_type(value); | |
3597 } | |
3598 } else { | |
3599 StorePointer(TypeAddr(index), value.raw()); | |
3600 } | |
3584 } | 3601 } |
3585 | 3602 |
3586 | 3603 |
3587 bool TypeArguments::IsResolved() const { | 3604 bool TypeArguments::IsResolved() const { |
3588 AbstractType& type = AbstractType::Handle(); | 3605 AbstractType& type = AbstractType::Handle(); |
3589 const intptr_t num_types = Length(); | 3606 const intptr_t num_types = Length(); |
3590 for (intptr_t i = 0; i < num_types; i++) { | 3607 for (intptr_t i = 0; i < num_types; i++) { |
3591 type = TypeAt(i); | 3608 type = TypeAt(i); |
3592 if (!type.IsResolved()) { | 3609 if (!type.IsResolved()) { |
3593 return false; | 3610 return false; |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3908 const Array& table = Array::Handle(isolate, | 3925 const Array& table = Array::Handle(isolate, |
3909 object_store->canonical_type_arguments()); | 3926 object_store->canonical_type_arguments()); |
3910 ASSERT(table.Length() > 0); | 3927 ASSERT(table.Length() > 0); |
3911 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, | 3928 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, |
3912 table, | 3929 table, |
3913 *this, | 3930 *this, |
3914 Hash()); | 3931 Hash()); |
3915 TypeArguments& result = TypeArguments::Handle(isolate); | 3932 TypeArguments& result = TypeArguments::Handle(isolate); |
3916 result ^= table.At(index); | 3933 result ^= table.At(index); |
3917 if (result.IsNull()) { | 3934 if (result.IsNull()) { |
3935 // Canonicalize each type argument. | |
3936 const intptr_t num_types = Length(); | |
3937 AbstractType& type = AbstractType::Handle(); | |
siva
2013/12/11 21:14:08
AbstractType::Handle(isolate);
as you already have
regis
2013/12/11 22:47:46
Done.
| |
3938 for (intptr_t i = 0; i < num_types; i++) { | |
3939 type = TypeAt(i); | |
3940 type = type.Canonicalize(); | |
3941 SetTypeAt(i, type); | |
3942 } | |
3918 // Make sure we have an old space object and add it to the table. | 3943 // Make sure we have an old space object and add it to the table. |
3919 if (this->IsNew()) { | 3944 if (this->IsNew()) { |
3920 result ^= Object::Clone(*this, Heap::kOld); | 3945 result ^= Object::Clone(*this, Heap::kOld); |
3921 } else { | 3946 } else { |
3922 result ^= this->raw(); | 3947 result ^= this->raw(); |
3923 } | 3948 } |
3924 ASSERT(result.IsOld()); | 3949 ASSERT(result.IsOld()); |
3925 InsertIntoCanonicalTypeArguments(isolate, table, result, index); | 3950 InsertIntoCanonicalTypeArguments(isolate, table, result, index); |
3926 } | 3951 } |
3927 ASSERT(result.Equals(*this)); | 3952 ASSERT(result.Equals(*this)); |
(...skipping 7599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11527 | 11552 |
11528 | 11553 |
11529 void AbstractType::set_error(const LanguageError& value) const { | 11554 void AbstractType::set_error(const LanguageError& value) const { |
11530 // AbstractType is an abstract class. | 11555 // AbstractType is an abstract class. |
11531 UNREACHABLE(); | 11556 UNREACHABLE(); |
11532 } | 11557 } |
11533 | 11558 |
11534 | 11559 |
11535 bool AbstractType::Equals(const Instance& other) const { | 11560 bool AbstractType::Equals(const Instance& other) const { |
11536 // AbstractType is an abstract class. | 11561 // AbstractType is an abstract class. |
11537 ASSERT(raw() == AbstractType::null()); | 11562 UNREACHABLE(); |
11538 return other.IsNull(); | 11563 return false; |
11539 } | 11564 } |
11540 | 11565 |
11541 | 11566 |
11542 RawAbstractType* AbstractType::InstantiateFrom( | 11567 RawAbstractType* AbstractType::InstantiateFrom( |
11543 const AbstractTypeArguments& instantiator_type_arguments, | 11568 const AbstractTypeArguments& instantiator_type_arguments, |
11544 Error* bound_error) const { | 11569 Error* bound_error) const { |
11545 // AbstractType is an abstract class. | 11570 // AbstractType is an abstract class. |
11546 UNREACHABLE(); | 11571 UNREACHABLE(); |
11547 return NULL; | 11572 return NULL; |
11548 } | 11573 } |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12018 ASSERT(!unresolved_class.IsNull()); | 12043 ASSERT(!unresolved_class.IsNull()); |
12019 return unresolved_class.raw(); | 12044 return unresolved_class.raw(); |
12020 #else | 12045 #else |
12021 ASSERT(!Object::Handle(raw_ptr()->type_class_).IsNull()); | 12046 ASSERT(!Object::Handle(raw_ptr()->type_class_).IsNull()); |
12022 ASSERT(Object::Handle(raw_ptr()->type_class_).IsUnresolvedClass()); | 12047 ASSERT(Object::Handle(raw_ptr()->type_class_).IsUnresolvedClass()); |
12023 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); | 12048 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); |
12024 #endif | 12049 #endif |
12025 } | 12050 } |
12026 | 12051 |
12027 | 12052 |
12028 RawString* Type::TypeClassName() const { | |
12029 if (HasResolvedTypeClass()) { | |
12030 const Class& cls = Class::Handle(type_class()); | |
12031 return cls.Name(); | |
12032 } else { | |
12033 const UnresolvedClass& cls = UnresolvedClass::Handle(unresolved_class()); | |
12034 return cls.Name(); | |
12035 } | |
12036 } | |
12037 | |
12038 | |
12039 RawAbstractTypeArguments* Type::arguments() const { | 12053 RawAbstractTypeArguments* Type::arguments() const { |
12040 return raw_ptr()->arguments_; | 12054 return raw_ptr()->arguments_; |
12041 } | 12055 } |
12042 | 12056 |
12043 | 12057 |
12044 bool Type::IsInstantiated() const { | 12058 bool Type::IsInstantiated() const { |
12045 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { | 12059 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { |
12046 return true; | 12060 return true; |
12047 } | 12061 } |
12048 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { | 12062 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { |
12049 return false; | 12063 return false; |
12050 } | 12064 } |
12051 const AbstractTypeArguments& args = | 12065 const AbstractTypeArguments& args = |
12052 AbstractTypeArguments::Handle(arguments()); | 12066 AbstractTypeArguments::Handle(arguments()); |
12053 return args.IsNull() || args.IsInstantiated(); | 12067 return args.IsNull() || args.IsInstantiated(); |
12054 } | 12068 } |
12055 | 12069 |
12056 | 12070 |
12057 RawAbstractType* Type::InstantiateFrom( | 12071 RawAbstractType* Type::InstantiateFrom( |
12058 const AbstractTypeArguments& instantiator_type_arguments, | 12072 const AbstractTypeArguments& instantiator_type_arguments, |
12059 Error* bound_error) const { | 12073 Error* bound_error) const { |
12060 ASSERT(IsResolved()); | 12074 ASSERT(IsFinalized() || IsBeingFinalized()); |
12061 ASSERT(!IsInstantiated()); | 12075 ASSERT(!IsInstantiated()); |
12062 // Return the uninstantiated type unchanged if malformed. No copy needed. | 12076 // Return the uninstantiated type unchanged if malformed. No copy needed. |
12063 if (IsMalformed()) { | 12077 if (IsMalformed()) { |
12064 return raw(); | 12078 return raw(); |
12065 } | 12079 } |
12066 AbstractTypeArguments& type_arguments = | 12080 AbstractTypeArguments& type_arguments = |
12067 AbstractTypeArguments::Handle(arguments()); | 12081 AbstractTypeArguments::Handle(arguments()); |
12068 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | 12082 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
12069 bound_error); | 12083 bound_error); |
12070 // Note that the type class has to be resolved at this time, but not | 12084 // Note that the type class has to be resolved at this time, but not |
12071 // necessarily finalized yet. We may be checking bounds at compile time. | 12085 // necessarily finalized yet. We may be checking bounds at compile time. |
12072 const Class& cls = Class::Handle(type_class()); | 12086 const Class& cls = Class::Handle(type_class()); |
12073 // This uninstantiated type is not modified, as it can be instantiated | 12087 // This uninstantiated type is not modified, as it can be instantiated |
12074 // with different instantiators. | 12088 // with different instantiators. |
12075 Type& instantiated_type = Type::Handle( | 12089 Type& instantiated_type = Type::Handle( |
12076 Type::New(cls, type_arguments, token_pos())); | 12090 Type::New(cls, type_arguments, token_pos())); |
12077 ASSERT(type_arguments.IsNull() || | 12091 ASSERT(type_arguments.IsNull() || |
12078 (type_arguments.Length() == cls.NumTypeArguments())); | 12092 (type_arguments.Length() == cls.NumTypeArguments())); |
12079 instantiated_type.SetIsFinalized(); | 12093 instantiated_type.SetIsFinalized(); |
12080 return instantiated_type.raw(); | 12094 return instantiated_type.raw(); |
12081 } | 12095 } |
12082 | 12096 |
12083 | 12097 |
12084 bool Type::Equals(const Instance& other) const { | 12098 bool Type::Equals(const Instance& other) const { |
12085 ASSERT(!IsNull()); | 12099 ASSERT(!IsNull()); |
12086 if (raw() == other.raw()) { | 12100 if (raw() == other.raw()) { |
12087 return true; | 12101 return true; |
12088 } | 12102 } |
12103 if (other.IsTypeRef()) { | |
12104 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | |
12105 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | |
12106 } | |
12089 if (!other.IsType()) { | 12107 if (!other.IsType()) { |
12090 return false; | 12108 return false; |
12091 } | 12109 } |
12092 const Type& other_type = Type::Cast(other); | 12110 const Type& other_type = Type::Cast(other); |
12093 ASSERT(IsResolved() && other_type.IsResolved()); | 12111 ASSERT(IsResolved() && other_type.IsResolved()); |
12094 if (IsMalformed() || other_type.IsMalformed()) { | 12112 if (IsMalformed() || other_type.IsMalformed()) { |
12095 return false; | 12113 return false; |
12096 } | 12114 } |
12097 if (type_class() != other_type.type_class()) { | 12115 if (type_class() != other_type.type_class()) { |
12098 return false; | 12116 return false; |
12099 } | 12117 } |
12100 if (!IsFinalized() || !other_type.IsFinalized()) { | 12118 if (!IsFinalized() || !other_type.IsFinalized()) { |
12101 return false; | 12119 return false; |
12102 } | 12120 } |
12103 if (arguments() == other_type.arguments()) { | 12121 if (arguments() == other_type.arguments()) { |
12104 return true; | 12122 return true; |
12105 } | 12123 } |
12106 const Class& cls = Class::Handle(type_class()); | 12124 const Class& cls = Class::Handle(type_class()); |
12125 const intptr_t num_type_params = cls.NumTypeParameters(); | |
12126 if (num_type_params == 0) { | |
12127 // Shortcut unnecessary handle allocation below. | |
12128 return true; | |
12129 } | |
12130 const intptr_t num_type_args = cls.NumTypeArguments(); | |
12131 const intptr_t from_index = num_type_args - num_type_params; | |
12107 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( | 12132 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( |
12108 arguments()); | 12133 arguments()); |
12109 const AbstractTypeArguments& other_type_args = AbstractTypeArguments::Handle( | 12134 const AbstractTypeArguments& other_type_args = AbstractTypeArguments::Handle( |
12110 other_type.arguments()); | 12135 other_type.arguments()); |
12111 const intptr_t num_type_args = cls.NumTypeArguments(); | |
12112 const intptr_t num_type_params = cls.NumTypeParameters(); | |
12113 const intptr_t from_index = num_type_args - num_type_params; | |
12114 if (type_args.IsNull()) { | 12136 if (type_args.IsNull()) { |
12115 return other_type_args.IsRaw(from_index, num_type_params); | 12137 return other_type_args.IsRaw(from_index, num_type_params); |
12116 } | 12138 } |
12117 if (other_type_args.IsNull()) { | 12139 if (other_type_args.IsNull()) { |
12118 return type_args.IsRaw(from_index, num_type_params); | 12140 return type_args.IsRaw(from_index, num_type_params); |
12119 } | 12141 } |
12120 ASSERT(type_args.Length() >= (from_index + num_type_params)); | 12142 ASSERT(type_args.Length() >= (from_index + num_type_params)); |
12121 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); | 12143 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); |
12122 AbstractType& type_arg = AbstractType::Handle(); | 12144 AbstractType& type_arg = AbstractType::Handle(); |
12123 AbstractType& other_type_arg = AbstractType::Handle(); | 12145 AbstractType& other_type_arg = AbstractType::Handle(); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12310 return "Unresolved Type"; | 12332 return "Unresolved Type"; |
12311 } | 12333 } |
12312 } | 12334 } |
12313 | 12335 |
12314 | 12336 |
12315 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { | 12337 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { |
12316 JSONObject jsobj(stream); | 12338 JSONObject jsobj(stream); |
12317 } | 12339 } |
12318 | 12340 |
12319 | 12341 |
12342 bool TypeRef::IsInstantiated() const { | |
12343 if (is_being_checked()) { | |
12344 return true; | |
12345 } | |
12346 set_is_being_checked(true); | |
12347 const bool result = AbstractType::Handle(type()).IsInstantiated(); | |
12348 set_is_being_checked(false); | |
12349 return result; | |
12350 } | |
12351 | |
12352 | |
12353 bool TypeRef::Equals(const Instance& other) const { | |
12354 // TODO(regis): Use trail instead of mark bit. | |
12355 if (raw() == other.raw()) { | |
12356 return true; | |
12357 } | |
12358 if (is_being_checked()) { | |
12359 return true; | |
12360 } | |
12361 set_is_being_checked(true); | |
12362 const bool result = AbstractType::Handle(type()).Equals(other); | |
12363 set_is_being_checked(false); | |
12364 return result; | |
12365 } | |
12366 | |
12367 | |
12368 RawAbstractType* TypeRef::InstantiateFrom( | |
12369 const AbstractTypeArguments& instantiator_type_arguments, | |
12370 Error* bound_error) const { | |
12371 const AbstractType& ref_type = AbstractType::Handle(type()); | |
12372 // TODO(regis): Use trail instead of mark bit plus temporary redirection, | |
12373 // because it could be marked for another reason. | |
12374 if (is_being_checked()) { | |
12375 ASSERT(ref_type.IsTypeRef()); | |
12376 return ref_type.raw(); | |
12377 } | |
12378 set_is_being_checked(true); | |
12379 ASSERT(!ref_type.IsTypeRef()); | |
12380 const TypeRef& instantiated_type_ref = TypeRef::Handle( | |
12381 TypeRef::New(ref_type)); | |
12382 // TODO(regis): instantiated_type_ref should be stored in the trail instead. | |
12383 set_type(instantiated_type_ref); | |
12384 const AbstractType& instantiated_ref_type = AbstractType::Handle( | |
12385 ref_type.InstantiateFrom(instantiator_type_arguments, bound_error)); | |
12386 instantiated_type_ref.set_type(instantiated_ref_type); | |
12387 set_type(ref_type); | |
12388 set_is_being_checked(false); | |
12389 return instantiated_type_ref.raw(); | |
12390 } | |
12391 | |
12392 | |
12393 void TypeRef::set_type(const AbstractType& value) const { | |
12394 ASSERT(value.HasResolvedTypeClass()); | |
12395 StorePointer(&raw_ptr()->type_, value.raw()); | |
12396 } | |
12397 | |
12398 | |
12399 void TypeRef::set_is_being_checked(bool value) const { | |
12400 raw_ptr()->is_being_checked_ = value; | |
12401 } | |
12402 | |
12403 | |
12404 // This function only canonicalizes the referenced type, but not the TypeRef | |
12405 // itself, since it cannot be canonical by definition. | |
12406 // Consider the type Derived, where class Derived extends Base<Derived>. | |
12407 // The first type argument of its flattened type argument vector is Derived, | |
12408 // i.e. itself, but pointer equality is not possible. | |
12409 RawAbstractType* TypeRef::Canonicalize() const { | |
12410 // TODO(regis): Use trail, not mark bit. | |
12411 if (is_being_checked()) { | |
12412 return raw(); | |
12413 } | |
12414 set_is_being_checked(true); | |
12415 AbstractType& ref_type = AbstractType::Handle(type()); | |
12416 ASSERT(!ref_type.IsTypeRef()); | |
12417 ref_type = ref_type.Canonicalize(); | |
12418 set_type(ref_type); | |
12419 // No need to call SetCanonical(), since a TypeRef cannot be canonical by | |
12420 // definition. | |
12421 set_is_being_checked(false); | |
12422 // We return the referenced type instead of the TypeRef in order to provide | |
12423 // pointer equality in simple cases, e.g. in language/f_bounded_equality_test. | |
12424 return ref_type.raw(); | |
12425 } | |
12426 | |
12427 | |
12428 intptr_t TypeRef::Hash() const { | |
12429 // Do not calculate the hash of the referenced type to avoid cycles. | |
12430 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); | |
12431 return FinalizeHash(result); | |
siva
2013/12/11 21:14:08
indentation is off
regis
2013/12/11 22:47:46
Done.
| |
12432 } | |
12433 | |
12434 | |
12435 RawTypeRef* TypeRef::New() { | |
12436 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); | |
12437 RawObject* raw = Object::Allocate(TypeRef::kClassId, | |
12438 TypeRef::InstanceSize(), | |
12439 Heap::kOld); | |
12440 return reinterpret_cast<RawTypeRef*>(raw); | |
12441 } | |
12442 | |
12443 | |
12444 RawTypeRef* TypeRef::New(const AbstractType& type) { | |
12445 const TypeRef& result = TypeRef::Handle(TypeRef::New()); | |
12446 result.set_type(type); | |
12447 result.set_is_being_checked(false); | |
12448 return result.raw(); | |
12449 } | |
12450 | |
12451 | |
12452 const char* TypeRef::ToCString() const { | |
12453 const char* format = "TypeRef: %s%s"; | |
12454 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( | |
12455 type()).type_class()).Name()).ToCString(); | |
12456 const char* args_cstr = (AbstractType::Handle( | |
12457 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>"; | |
12458 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; | |
12459 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | |
12460 OS::SNPrint(chars, len, format, type_cstr, args_cstr); | |
12461 return chars; | |
12462 } | |
12463 | |
12464 | |
12465 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { | |
12466 JSONObject jsobj(stream); | |
12467 } | |
12468 | |
12469 | |
12320 void TypeParameter::set_is_finalized() const { | 12470 void TypeParameter::set_is_finalized() const { |
12321 ASSERT(!IsFinalized()); | 12471 ASSERT(!IsFinalized()); |
12322 set_type_state(RawTypeParameter::kFinalizedUninstantiated); | 12472 set_type_state(RawTypeParameter::kFinalizedUninstantiated); |
12323 } | 12473 } |
12324 | 12474 |
12325 | 12475 |
12326 bool TypeParameter::Equals(const Instance& other) const { | 12476 bool TypeParameter::Equals(const Instance& other) const { |
12327 if (raw() == other.raw()) { | 12477 if (raw() == other.raw()) { |
12328 return true; | 12478 return true; |
12329 } | 12479 } |
12480 if (other.IsTypeRef()) { | |
12481 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | |
12482 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | |
12483 } | |
12330 if (!other.IsTypeParameter()) { | 12484 if (!other.IsTypeParameter()) { |
12331 return false; | 12485 return false; |
12332 } | 12486 } |
12333 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 12487 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
12334 if (parameterized_class() != other_type_param.parameterized_class()) { | 12488 if (parameterized_class() != other_type_param.parameterized_class()) { |
12335 return false; | 12489 return false; |
12336 } | 12490 } |
12337 if (IsFinalized() == other_type_param.IsFinalized()) { | 12491 if (IsFinalized() == other_type_param.IsFinalized()) { |
12338 return index() == other_type_param.index(); | 12492 return index() == other_type_param.index(); |
12339 } | 12493 } |
(...skipping 24 matching lines...) Expand all Loading... | |
12364 } | 12518 } |
12365 | 12519 |
12366 | 12520 |
12367 RawAbstractType* TypeParameter::InstantiateFrom( | 12521 RawAbstractType* TypeParameter::InstantiateFrom( |
12368 const AbstractTypeArguments& instantiator_type_arguments, | 12522 const AbstractTypeArguments& instantiator_type_arguments, |
12369 Error* bound_error) const { | 12523 Error* bound_error) const { |
12370 ASSERT(IsFinalized()); | 12524 ASSERT(IsFinalized()); |
12371 if (instantiator_type_arguments.IsNull()) { | 12525 if (instantiator_type_arguments.IsNull()) { |
12372 return Type::DynamicType(); | 12526 return Type::DynamicType(); |
12373 } | 12527 } |
12374 return instantiator_type_arguments.TypeAt(index()); | 12528 const AbstractType& type_arg = AbstractType::Handle( |
12529 instantiator_type_arguments.TypeAt(index())); | |
12530 // There is no need to canonicalize the instantiated type parameter, since all | |
12531 // type arguments are canonicalized at type finalization time. It would be too | |
12532 // early to canonicalize the returned type argument here, since instantiation | |
12533 // not only happens at run time, but also during type finalization. | |
12534 // However, if the type argument is a reference to a canonical type, we | |
12535 // return the referenced canonical type instead of the type reference to | |
12536 // provide pointer equality in some simple cases, e.g. in | |
12537 // language/f_bounded_equality_test. | |
12538 if (type_arg.IsTypeRef()) { | |
12539 const AbstractType& ref_type = AbstractType::Handle( | |
12540 TypeRef::Cast(type_arg).type()); | |
12541 if (ref_type.IsCanonical()) { | |
12542 return ref_type.raw(); | |
12543 } | |
12544 } | |
12545 return type_arg.raw(); | |
12375 } | 12546 } |
12376 | 12547 |
12377 | 12548 |
12378 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 12549 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
12379 const AbstractType& upper_bound, | 12550 const AbstractType& upper_bound, |
12380 Error* bound_error) const { | 12551 Error* bound_error) const { |
12381 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 12552 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
12382 ASSERT(bounded_type.IsFinalized()); | 12553 ASSERT(bounded_type.IsFinalized()); |
12383 ASSERT(upper_bound.IsFinalized()); | 12554 ASSERT(upper_bound.IsFinalized()); |
12384 ASSERT(!bounded_type.IsMalformed()); | 12555 ASSERT(!bounded_type.IsMalformed()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12429 return TypeParameter::New(Class::Handle(parameterized_class()), | 12600 return TypeParameter::New(Class::Handle(parameterized_class()), |
12430 index(), | 12601 index(), |
12431 String::Handle(name()), | 12602 String::Handle(name()), |
12432 AbstractType::Handle(bound()), | 12603 AbstractType::Handle(bound()), |
12433 token_pos()); | 12604 token_pos()); |
12434 } | 12605 } |
12435 | 12606 |
12436 | 12607 |
12437 intptr_t TypeParameter::Hash() const { | 12608 intptr_t TypeParameter::Hash() const { |
12438 ASSERT(IsFinalized()); | 12609 ASSERT(IsFinalized()); |
12439 uword result = 0; | 12610 uword result = Class::Handle(parameterized_class()).id(); |
12440 result += Class::Handle(parameterized_class()).id(); | |
12441 // Do not include the hash of the bound, which could lead to cycles. | 12611 // Do not include the hash of the bound, which could lead to cycles. |
12442 result <<= index(); | 12612 result <<= index(); |
12443 return FinalizeHash(result); | 12613 return FinalizeHash(result); |
12444 } | 12614 } |
12445 | 12615 |
12446 | 12616 |
12447 RawTypeParameter* TypeParameter::New() { | 12617 RawTypeParameter* TypeParameter::New() { |
12448 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != | 12618 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != |
12449 Class::null()); | 12619 Class::null()); |
12450 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 12620 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12521 return AbstractType::Handle(type()).error(); | 12691 return AbstractType::Handle(type()).error(); |
12522 } | 12692 } |
12523 | 12693 |
12524 | 12694 |
12525 bool BoundedType::Equals(const Instance& other) const { | 12695 bool BoundedType::Equals(const Instance& other) const { |
12526 // BoundedType are not canonicalized, because their bound may get finalized | 12696 // BoundedType are not canonicalized, because their bound may get finalized |
12527 // after the BoundedType is created and initialized. | 12697 // after the BoundedType is created and initialized. |
12528 if (raw() == other.raw()) { | 12698 if (raw() == other.raw()) { |
12529 return true; | 12699 return true; |
12530 } | 12700 } |
12701 if (other.IsTypeRef()) { | |
12702 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | |
12703 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | |
12704 } | |
12531 if (!other.IsBoundedType()) { | 12705 if (!other.IsBoundedType()) { |
12532 return false; | 12706 return false; |
12533 } | 12707 } |
12534 const BoundedType& other_bounded = BoundedType::Cast(other); | 12708 const BoundedType& other_bounded = BoundedType::Cast(other); |
12535 if (type_parameter() != other_bounded.type_parameter()) { | 12709 if (type_parameter() != other_bounded.type_parameter()) { |
12536 // Not a structural compare. | 12710 // Not a structural compare. |
12537 // Note that a deep comparison of bounds could lead to cycles. | 12711 // Note that a deep comparison of bounds could lead to cycles. |
12538 return false; | 12712 return false; |
12539 } | 12713 } |
12540 const AbstractType& this_type = AbstractType::Handle(type()); | 12714 const AbstractType& this_type = AbstractType::Handle(type()); |
12541 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); | 12715 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); |
12542 if (!this_type.Equals(other_type)) { | 12716 if (!this_type.Equals(other_type)) { |
12543 return false; | 12717 return false; |
12544 } | 12718 } |
12545 const AbstractType& this_bound = AbstractType::Handle(bound()); | 12719 const AbstractType& this_bound = AbstractType::Handle(bound()); |
12546 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); | 12720 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); |
12547 return this_bound.IsFinalized() && | 12721 return this_bound.IsFinalized() && |
12548 other_bound.IsFinalized() && | 12722 other_bound.IsFinalized() && |
12549 this_bound.Equals(other_bound); | 12723 this_bound.Equals(other_bound); |
12550 } | 12724 } |
12551 | 12725 |
12552 | 12726 |
12553 void BoundedType::set_type(const AbstractType& value) const { | 12727 void BoundedType::set_type(const AbstractType& value) const { |
12554 ASSERT(value.IsFinalized()); | 12728 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); |
12555 ASSERT(!value.IsMalformed()); | 12729 ASSERT(!value.IsMalformed()); |
12556 StorePointer(&raw_ptr()->type_, value.raw()); | 12730 StorePointer(&raw_ptr()->type_, value.raw()); |
12557 } | 12731 } |
12558 | 12732 |
12559 | 12733 |
12560 void BoundedType::set_bound(const AbstractType& value) const { | 12734 void BoundedType::set_bound(const AbstractType& value) const { |
12561 // The bound may still be unfinalized because of legal cycles. | 12735 // The bound may still be unfinalized because of legal cycles. |
12562 // It must be finalized before it is checked at run time, though. | 12736 // It must be finalized before it is checked at run time, though. |
12563 StorePointer(&raw_ptr()->bound_, value.raw()); | 12737 StorePointer(&raw_ptr()->bound_, value.raw()); |
12564 } | 12738 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12624 bounded_type = bounded_type.CloneUnfinalized(); | 12798 bounded_type = bounded_type.CloneUnfinalized(); |
12625 // No need to clone bound or type parameter, as they are not part of the | 12799 // No need to clone bound or type parameter, as they are not part of the |
12626 // finalization state of this bounded type. | 12800 // finalization state of this bounded type. |
12627 return BoundedType::New(bounded_type, | 12801 return BoundedType::New(bounded_type, |
12628 AbstractType::Handle(bound()), | 12802 AbstractType::Handle(bound()), |
12629 TypeParameter::Handle(type_parameter())); | 12803 TypeParameter::Handle(type_parameter())); |
12630 } | 12804 } |
12631 | 12805 |
12632 | 12806 |
12633 intptr_t BoundedType::Hash() const { | 12807 intptr_t BoundedType::Hash() const { |
12634 uword result = 0; | 12808 uword result = AbstractType::Handle(type()).Hash(); |
12635 result += AbstractType::Handle(type()).Hash(); | |
12636 // Do not include the hash of the bound, which could lead to cycles. | 12809 // Do not include the hash of the bound, which could lead to cycles. |
12637 TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 12810 result += TypeParameter::Handle(type_parameter()).Hash(); |
12638 if (!type_param.IsNull()) { | |
12639 result += type_param.Hash(); | |
12640 } | |
12641 return FinalizeHash(result); | 12811 return FinalizeHash(result); |
12642 } | 12812 } |
12643 | 12813 |
12644 | 12814 |
12645 RawBoundedType* BoundedType::New() { | 12815 RawBoundedType* BoundedType::New() { |
12646 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != | 12816 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != |
12647 Class::null()); | 12817 Class::null()); |
12648 RawObject* raw = Object::Allocate(BoundedType::kClassId, | 12818 RawObject* raw = Object::Allocate(BoundedType::kClassId, |
12649 BoundedType::InstanceSize(), | 12819 BoundedType::InstanceSize(), |
12650 Heap::kOld); | 12820 Heap::kOld); |
(...skipping 3507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16158 return "_MirrorReference"; | 16328 return "_MirrorReference"; |
16159 } | 16329 } |
16160 | 16330 |
16161 | 16331 |
16162 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 16332 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
16163 Instance::PrintToJSONStream(stream, ref); | 16333 Instance::PrintToJSONStream(stream, ref); |
16164 } | 16334 } |
16165 | 16335 |
16166 | 16336 |
16167 } // namespace dart | 16337 } // namespace dart |
OLD | NEW |