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

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