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/become.h" | 10 #include "vm/become.h" |
(...skipping 3723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3734 Zone* zone = Thread::Current()->zone(); | 3734 Zone* zone = Thread::Current()->zone(); |
3735 Class& thsi = Class::Handle(zone, cls.raw()); | 3735 Class& thsi = Class::Handle(zone, cls.raw()); |
3736 while (true) { | 3736 while (true) { |
3737 ASSERT(!thsi.IsVoidClass()); | 3737 ASSERT(!thsi.IsVoidClass()); |
3738 // Check for DynamicType. | 3738 // Check for DynamicType. |
3739 // Each occurrence of DynamicType in type T is interpreted as the dynamic | 3739 // Each occurrence of DynamicType in type T is interpreted as the dynamic |
3740 // type, a supertype of all types. | 3740 // type, a supertype of all types. |
3741 if (other.IsDynamicClass()) { | 3741 if (other.IsDynamicClass()) { |
3742 return true; | 3742 return true; |
3743 } | 3743 } |
| 3744 // Check for NullType, which, as of Dart 1.5, is a subtype of (and is more |
| 3745 // specific than) any type. Note that the null instance is not handled here. |
| 3746 if (thsi.IsNullClass()) { |
| 3747 return true; |
| 3748 } |
3744 // In the case of a subtype test, each occurrence of DynamicType in type S | 3749 // In the case of a subtype test, each occurrence of DynamicType in type S |
3745 // is interpreted as the bottom type, a subtype of all types. | 3750 // is interpreted as the bottom type, a subtype of all types. |
3746 // However, DynamicType is not more specific than any type. | 3751 // However, DynamicType is not more specific than any type. |
3747 if (thsi.IsDynamicClass()) { | 3752 if (thsi.IsDynamicClass()) { |
3748 return test_kind == Class::kIsSubtypeOf; | 3753 return test_kind == Class::kIsSubtypeOf; |
3749 } | 3754 } |
3750 // Check for NullType, which is only a subtype of ObjectType, of | |
3751 // DynamicType, or of itself, and which is more specific than any type. | |
3752 if (thsi.IsNullClass()) { | |
3753 // We already checked for other.IsDynamicClass() above. | |
3754 return (test_kind == Class::kIsMoreSpecificThan) || | |
3755 other.IsObjectClass() || other.IsNullClass(); | |
3756 } | |
3757 // Check for ObjectType. Any type that is not NullType or DynamicType | 3755 // Check for ObjectType. Any type that is not NullType or DynamicType |
3758 // (already checked above), is more specific than ObjectType. | 3756 // (already checked above), is more specific than ObjectType. |
3759 if (other.IsObjectClass()) { | 3757 if (other.IsObjectClass()) { |
3760 return true; | 3758 return true; |
3761 } | 3759 } |
3762 // Check for reflexivity. | 3760 // Check for reflexivity. |
3763 if (thsi.raw() == other.raw()) { | 3761 if (thsi.raw() == other.raw()) { |
3764 const intptr_t num_type_params = thsi.NumTypeParameters(); | 3762 const intptr_t num_type_params = thsi.NumTypeParameters(); |
3765 if (num_type_params == 0) { | 3763 if (num_type_params == 0) { |
3766 return true; | 3764 return true; |
(...skipping 12081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15848 if (call.IsSubtypeOf(type_arguments, other_signature, | 15846 if (call.IsSubtypeOf(type_arguments, other_signature, |
15849 other_type_arguments, bound_error, Heap::kOld)) { | 15847 other_type_arguments, bound_error, Heap::kOld)) { |
15850 return true; | 15848 return true; |
15851 } | 15849 } |
15852 } | 15850 } |
15853 } | 15851 } |
15854 if (!instantiated_other.IsType()) { | 15852 if (!instantiated_other.IsType()) { |
15855 return false; | 15853 return false; |
15856 } | 15854 } |
15857 other_class = instantiated_other.type_class(); | 15855 other_class = instantiated_other.type_class(); |
| 15856 if (IsNull()) { |
| 15857 ASSERT(cls.IsNullClass()); |
| 15858 // As of Dart 1.5, the null instance and Null type are handled differently. |
| 15859 // We already checked for other.IsDynamicType(). |
| 15860 return other_class.IsNullClass() || other_class.IsObjectClass(); |
| 15861 } |
15858 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, | 15862 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, |
15859 bound_error, NULL, Heap::kOld); | 15863 bound_error, NULL, Heap::kOld); |
15860 } | 15864 } |
15861 | 15865 |
15862 | 15866 |
15863 bool Instance::OperatorEquals(const Instance& other) const { | 15867 bool Instance::OperatorEquals(const Instance& other) const { |
15864 // TODO(koda): Optimize for all builtin classes and all classes | 15868 // TODO(koda): Optimize for all builtin classes and all classes |
15865 // that do not override operator==. | 15869 // that do not override operator==. |
15866 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); | 15870 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); |
15867 } | 15871 } |
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16547 } | 16551 } |
16548 return false; | 16552 return false; |
16549 } | 16553 } |
16550 if (other.IsMalbounded()) { | 16554 if (other.IsMalbounded()) { |
16551 ASSERT(Isolate::Current()->type_checks()); | 16555 ASSERT(Isolate::Current()->type_checks()); |
16552 if ((bound_error != NULL) && bound_error->IsNull()) { | 16556 if ((bound_error != NULL) && bound_error->IsNull()) { |
16553 *bound_error = other.error(); | 16557 *bound_error = other.error(); |
16554 } | 16558 } |
16555 return false; | 16559 return false; |
16556 } | 16560 } |
16557 if (other.IsObjectType() || other.IsDynamicType()) { | 16561 // Any type is a subtype of (and is more specific than) Object and dynamic. |
| 16562 // As of Dart 1.5, the Null type is a subtype of (and is more specific than) |
| 16563 // any type. |
| 16564 if (other.IsObjectType() || other.IsDynamicType() || IsNullType()) { |
16558 return true; | 16565 return true; |
16559 } | 16566 } |
16560 Zone* zone = Thread::Current()->zone(); | 16567 Zone* zone = Thread::Current()->zone(); |
16561 if (IsBoundedType() || other.IsBoundedType()) { | 16568 if (IsBoundedType() || other.IsBoundedType()) { |
16562 if (Equals(other)) { | 16569 if (Equals(other)) { |
16563 return true; | 16570 return true; |
16564 } | 16571 } |
16565 // Redundant check if other type is equal to the upper bound of this type. | 16572 // Redundant check if other type is equal to the upper bound of this type. |
16566 if (IsBoundedType() && | 16573 if (IsBoundedType() && |
16567 AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) { | 16574 AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) { |
(...skipping 6407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22975 return UserTag::null(); | 22982 return UserTag::null(); |
22976 } | 22983 } |
22977 | 22984 |
22978 | 22985 |
22979 const char* UserTag::ToCString() const { | 22986 const char* UserTag::ToCString() const { |
22980 const String& tag_label = String::Handle(label()); | 22987 const String& tag_label = String::Handle(label()); |
22981 return tag_label.ToCString(); | 22988 return tag_label.ToCString(); |
22982 } | 22989 } |
22983 | 22990 |
22984 } // namespace dart | 22991 } // namespace dart |
OLD | NEW |