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