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

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

Issue 103913005: Introduce class TypeRef in the VM to fully support recursive types. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« runtime/lib/mirrors.cc ('K') | « runtime/vm/object.h ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698