Chromium Code Reviews| 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 |