| 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 15433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15444 if (other.IsMalbounded()) { | 15444 if (other.IsMalbounded()) { |
| 15445 ASSERT(Isolate::Current()->type_checks()); | 15445 ASSERT(Isolate::Current()->type_checks()); |
| 15446 if ((bound_error != NULL) && bound_error->IsNull()) { | 15446 if ((bound_error != NULL) && bound_error->IsNull()) { |
| 15447 *bound_error = other.error(); | 15447 *bound_error = other.error(); |
| 15448 } | 15448 } |
| 15449 return false; | 15449 return false; |
| 15450 } | 15450 } |
| 15451 if (other.IsObjectType() || other.IsDynamicType()) { | 15451 if (other.IsObjectType() || other.IsDynamicType()) { |
| 15452 return true; | 15452 return true; |
| 15453 } | 15453 } |
| 15454 Zone* zone = Thread::Current()->zone(); |
| 15454 if (IsBoundedType() || other.IsBoundedType()) { | 15455 if (IsBoundedType() || other.IsBoundedType()) { |
| 15455 if (Equals(other)) { | 15456 if (Equals(other)) { |
| 15456 return true; | 15457 return true; |
| 15457 } | 15458 } |
| 15458 // Redundant check if other type is equal to the upper bound of this type. | 15459 // Redundant check if other type is equal to the upper bound of this type. |
| 15459 if (IsBoundedType() && | 15460 if (IsBoundedType() && |
| 15460 AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) { | 15461 AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) { |
| 15461 return true; | 15462 return true; |
| 15462 } | 15463 } |
| 15463 return false; // TODO(regis): We should return "maybe after instantiation". | 15464 // Bound checking at run time occurs when allocating an instance of a |
| 15465 // generic bounded type using a valid instantiator. The instantiator is |
| 15466 // the type of an instance successfully allocated, i.e. not containing |
| 15467 // unchecked bounds anymore. |
| 15468 // Therefore, when performing a type test at compile time (what is happening |
| 15469 // here), it is safe to ignore the bounds, since they will not exist at run |
| 15470 // time anymore. |
| 15471 if (IsBoundedType()) { |
| 15472 const AbstractType& bounded_type = |
| 15473 AbstractType::Handle(zone, BoundedType::Cast(*this).type()); |
| 15474 return bounded_type.TypeTest(test_kind, |
| 15475 other, |
| 15476 bound_error, |
| 15477 bound_trail, |
| 15478 space); |
| 15479 } |
| 15480 const AbstractType& other_bounded_type = |
| 15481 AbstractType::Handle(zone, BoundedType::Cast(other).type()); |
| 15482 return TypeTest(test_kind, |
| 15483 other_bounded_type, |
| 15484 bound_error, |
| 15485 bound_trail, |
| 15486 space); |
| 15464 } | 15487 } |
| 15465 Zone* zone = Thread::Current()->zone(); | |
| 15466 // Type parameters cannot be handled by Class::TypeTest(). | 15488 // Type parameters cannot be handled by Class::TypeTest(). |
| 15467 // When comparing two uninstantiated function types, one returning type | 15489 // When comparing two uninstantiated function types, one returning type |
| 15468 // parameter K, the other returning type parameter V, we cannot assume that K | 15490 // parameter K, the other returning type parameter V, we cannot assume that K |
| 15469 // is a subtype of V, or vice versa. We only return true if K equals V, as | 15491 // is a subtype of V, or vice versa. We only return true if K equals V, as |
| 15470 // defined by TypeParameter::Equals. | 15492 // defined by TypeParameter::Equals. |
| 15471 // The same rule applies when checking the upper bound of a still | 15493 // The same rule applies when checking the upper bound of a still |
| 15472 // uninstantiated type at compile time. Returning false will defer the test | 15494 // uninstantiated type at compile time. Returning false will defer the test |
| 15473 // to run time. | 15495 // to run time. |
| 15474 // There are however some cases that can be decided at compile time. | 15496 // There are however some cases that can be decided at compile time. |
| 15475 // For example, with class A<K, V extends K>, new A<T, T> called from within | 15497 // For example, with class A<K, V extends K>, new A<T, T> called from within |
| (...skipping 6419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21895 return UserTag::null(); | 21917 return UserTag::null(); |
| 21896 } | 21918 } |
| 21897 | 21919 |
| 21898 | 21920 |
| 21899 const char* UserTag::ToCString() const { | 21921 const char* UserTag::ToCString() const { |
| 21900 const String& tag_label = String::Handle(label()); | 21922 const String& tag_label = String::Handle(label()); |
| 21901 return tag_label.ToCString(); | 21923 return tag_label.ToCString(); |
| 21902 } | 21924 } |
| 21903 | 21925 |
| 21904 } // namespace dart | 21926 } // namespace dart |
| OLD | NEW |