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/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
(...skipping 2843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2854 const TypeParameter& type_param = TypeParameter::Cast(type); | 2854 const TypeParameter& type_param = TypeParameter::Cast(type); |
2855 ASSERT(type_param.IsFinalized()); | 2855 ASSERT(type_param.IsFinalized()); |
2856 if ((type_param.index() != i)) { | 2856 if ((type_param.index() != i)) { |
2857 return false; | 2857 return false; |
2858 } | 2858 } |
2859 // If this type parameter specifies an upper bound, then the type argument | 2859 // If this type parameter specifies an upper bound, then the type argument |
2860 // vector does not really represent the identity vector. It cannot be | 2860 // vector does not really represent the identity vector. It cannot be |
2861 // substituted by the instantiator's type argument vector without checking | 2861 // substituted by the instantiator's type argument vector without checking |
2862 // the upper bound. | 2862 // the upper bound. |
2863 const AbstractType& bound = AbstractType::Handle(type_param.bound()); | 2863 const AbstractType& bound = AbstractType::Handle(type_param.bound()); |
2864 ASSERT(bound.IsFinalized()); | 2864 ASSERT(bound.IsResolved()); |
2865 if (!bound.IsObjectType() && !bound.IsDynamicType()) { | 2865 if (!bound.IsObjectType() && !bound.IsDynamicType()) { |
2866 return false; | 2866 return false; |
2867 } | 2867 } |
2868 } | 2868 } |
2869 return true; | 2869 return true; |
2870 } | 2870 } |
2871 | 2871 |
2872 | 2872 |
2873 bool TypeArguments::IsBounded() const { | 2873 bool TypeArguments::IsBounded() const { |
2874 AbstractType& type = AbstractType::Handle(); | 2874 AbstractType& type = AbstractType::Handle(); |
(...skipping 6381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9256 | 9256 |
9257 bool AbstractType::IsFunctionType() const { | 9257 bool AbstractType::IsFunctionType() const { |
9258 return HasResolvedTypeClass() && | 9258 return HasResolvedTypeClass() && |
9259 (type_class() == Type::Handle(Type::Function()).type_class()); | 9259 (type_class() == Type::Handle(Type::Function()).type_class()); |
9260 } | 9260 } |
9261 | 9261 |
9262 | 9262 |
9263 bool AbstractType::TypeTest(TypeTestKind test_kind, | 9263 bool AbstractType::TypeTest(TypeTestKind test_kind, |
9264 const AbstractType& other, | 9264 const AbstractType& other, |
9265 Error* malformed_error) const { | 9265 Error* malformed_error) const { |
9266 ASSERT(IsFinalized()); | 9266 ASSERT(IsResolved()); |
9267 ASSERT(other.IsFinalized()); | 9267 ASSERT(other.IsResolved()); |
9268 // In case the type checked in a type test is malformed, the code generator | 9268 // In case the type checked in a type test is malformed, the code generator |
9269 // may compile a throw instead of a run time call performing the type check. | 9269 // may compile a throw instead of a run time call performing the type check. |
9270 // However, in checked mode, a function type may include malformed result type | 9270 // However, in checked mode, a function type may include malformed result type |
9271 // and/or malformed parameter types, which will then be encountered here at | 9271 // and/or malformed parameter types, which will then be encountered here at |
9272 // run time. | 9272 // run time. |
9273 if (IsMalformed()) { | 9273 if (IsMalformed()) { |
9274 ASSERT(FLAG_enable_type_checks); | 9274 ASSERT(FLAG_enable_type_checks); |
9275 if ((malformed_error != NULL) && malformed_error->IsNull()) { | 9275 if ((malformed_error != NULL) && malformed_error->IsNull()) { |
9276 *malformed_error = this->malformed_error(); | 9276 *malformed_error = this->malformed_error(); |
9277 } | 9277 } |
(...skipping 16 matching lines...) Expand all Loading... |
9294 return false; // TODO(regis): We should return "maybe after instantiation". | 9294 return false; // TODO(regis): We should return "maybe after instantiation". |
9295 } | 9295 } |
9296 // Type parameters cannot be handled by Class::TypeTest(). | 9296 // Type parameters cannot be handled by Class::TypeTest(). |
9297 // When comparing two uninstantiated function types, one returning type | 9297 // When comparing two uninstantiated function types, one returning type |
9298 // parameter K, the other returning type parameter V, we cannot assume that K | 9298 // parameter K, the other returning type parameter V, we cannot assume that K |
9299 // is a subtype of V, or vice versa. We only return true if K equals V, as | 9299 // is a subtype of V, or vice versa. We only return true if K equals V, as |
9300 // defined by TypeParameter::Equals. | 9300 // defined by TypeParameter::Equals. |
9301 // The same rule applies when checking the upper bound of a still | 9301 // The same rule applies when checking the upper bound of a still |
9302 // uninstantiated type at compile time. Returning false will defer the test | 9302 // uninstantiated type at compile time. Returning false will defer the test |
9303 // to run time. | 9303 // to run time. |
9304 // We may think that some cases can be decided at compile time. | 9304 // There are however some cases can be decided at compile time. |
9305 // For example, with class A<K, V extends K>, new A<T, T> called from within | 9305 // For example, with class A<K, V extends K>, new A<T, T> called from within |
9306 // a class B<T> will never require a run time bound check, even if T is | 9306 // a class B<T> will never require a run time bound check, even if T is |
9307 // uninstantiated at compile time. | 9307 // uninstantiated at compile time. |
9308 // However, this is not true, because bounds are ignored in production mode, | |
9309 // and even if we are running in checked mode, we may generate a snapshot | |
9310 // that will be executed in production mode. | |
9311 if (IsTypeParameter()) { | 9308 if (IsTypeParameter()) { |
9312 const TypeParameter& type_param = TypeParameter::Cast(*this); | 9309 const TypeParameter& type_param = TypeParameter::Cast(*this); |
9313 if (other.IsTypeParameter()) { | 9310 if (other.IsTypeParameter()) { |
9314 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 9311 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
9315 if (type_param.Equals(other_type_param)) { | 9312 if (type_param.Equals(other_type_param)) { |
9316 return true; | 9313 return true; |
9317 } | 9314 } |
9318 } | 9315 } |
| 9316 const AbstractType& bound = AbstractType::Handle(type_param.bound()); |
| 9317 if (bound.IsMoreSpecificThan(other, malformed_error)) { |
| 9318 return true; |
| 9319 } |
9319 return false; // TODO(regis): We should return "maybe after instantiation". | 9320 return false; // TODO(regis): We should return "maybe after instantiation". |
9320 } | 9321 } |
9321 if (other.IsTypeParameter()) { | 9322 if (other.IsTypeParameter()) { |
9322 return false; // TODO(regis): We should return "maybe after instantiation". | 9323 return false; // TODO(regis): We should return "maybe after instantiation". |
9323 } | 9324 } |
9324 const Class& cls = Class::Handle(type_class()); | 9325 const Class& cls = Class::Handle(type_class()); |
9325 return cls.TypeTest(test_kind, | 9326 return cls.TypeTest(test_kind, |
9326 AbstractTypeArguments::Handle(arguments()), | 9327 AbstractTypeArguments::Handle(arguments()), |
9327 Class::Handle(other.type_class()), | 9328 Class::Handle(other.type_class()), |
9328 AbstractTypeArguments::Handle(other.arguments()), | 9329 AbstractTypeArguments::Handle(other.arguments()), |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9525 } | 9526 } |
9526 const AbstractTypeArguments& args = | 9527 const AbstractTypeArguments& args = |
9527 AbstractTypeArguments::Handle(arguments()); | 9528 AbstractTypeArguments::Handle(arguments()); |
9528 return args.IsNull() || args.IsInstantiated(); | 9529 return args.IsNull() || args.IsInstantiated(); |
9529 } | 9530 } |
9530 | 9531 |
9531 | 9532 |
9532 RawAbstractType* Type::InstantiateFrom( | 9533 RawAbstractType* Type::InstantiateFrom( |
9533 const AbstractTypeArguments& instantiator_type_arguments, | 9534 const AbstractTypeArguments& instantiator_type_arguments, |
9534 Error* malformed_error) const { | 9535 Error* malformed_error) const { |
9535 ASSERT(IsFinalized()); | 9536 ASSERT(IsResolved()); |
9536 ASSERT(!IsInstantiated()); | 9537 ASSERT(!IsInstantiated()); |
9537 // Return the uninstantiated type unchanged if malformed. No copy needed. | 9538 // Return the uninstantiated type unchanged if malformed. No copy needed. |
9538 if (IsMalformed()) { | 9539 if (IsMalformed()) { |
9539 return raw(); | 9540 return raw(); |
9540 } | 9541 } |
9541 AbstractTypeArguments& type_arguments = | 9542 AbstractTypeArguments& type_arguments = |
9542 AbstractTypeArguments::Handle(arguments()); | 9543 AbstractTypeArguments::Handle(arguments()); |
9543 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | 9544 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
9544 malformed_error); | 9545 malformed_error); |
9545 // Note that the type class has to be resolved at this time, but not | 9546 // Note that the type class has to be resolved at this time, but not |
(...skipping 11 matching lines...) Expand all Loading... |
9557 | 9558 |
9558 | 9559 |
9559 bool Type::Equals(const Instance& other) const { | 9560 bool Type::Equals(const Instance& other) const { |
9560 if (raw() == other.raw()) { | 9561 if (raw() == other.raw()) { |
9561 return true; | 9562 return true; |
9562 } | 9563 } |
9563 if (!other.IsType()) { | 9564 if (!other.IsType()) { |
9564 return false; | 9565 return false; |
9565 } | 9566 } |
9566 const Type& other_type = Type::Cast(other); | 9567 const Type& other_type = Type::Cast(other); |
9567 ASSERT(IsFinalized() && other_type.IsFinalized()); | 9568 ASSERT(IsResolved() && other_type.IsResolved()); |
9568 if (IsMalformed() || other_type.IsMalformed()) { | 9569 if (IsMalformed() || other_type.IsMalformed()) { |
9569 return false; | 9570 return false; |
9570 } | 9571 } |
9571 if (type_class() != other_type.type_class()) { | 9572 if (type_class() != other_type.type_class()) { |
9572 return false; | 9573 return false; |
9573 } | 9574 } |
| 9575 if (!IsFinalized() || !other_type.IsFinalized()) { |
| 9576 return false; |
| 9577 } |
9574 return AbstractTypeArguments::AreEqual( | 9578 return AbstractTypeArguments::AreEqual( |
9575 AbstractTypeArguments::Handle(arguments()), | 9579 AbstractTypeArguments::Handle(arguments()), |
9576 AbstractTypeArguments::Handle(other_type.arguments())); | 9580 AbstractTypeArguments::Handle(other_type.arguments())); |
9577 } | 9581 } |
9578 | 9582 |
9579 | 9583 |
9580 RawAbstractType* Type::Canonicalize() const { | 9584 RawAbstractType* Type::Canonicalize() const { |
9581 ASSERT(IsFinalized()); | 9585 ASSERT(IsFinalized()); |
9582 if (IsCanonical() || IsMalformed()) { | 9586 if (IsCanonical() || IsMalformed()) { |
9583 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); | 9587 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9773 } | 9777 } |
9774 | 9778 |
9775 | 9779 |
9776 RawAbstractType* TypeParameter::InstantiateFrom( | 9780 RawAbstractType* TypeParameter::InstantiateFrom( |
9777 const AbstractTypeArguments& instantiator_type_arguments, | 9781 const AbstractTypeArguments& instantiator_type_arguments, |
9778 Error* malformed_error) const { | 9782 Error* malformed_error) const { |
9779 ASSERT(IsFinalized()); | 9783 ASSERT(IsFinalized()); |
9780 if (instantiator_type_arguments.IsNull()) { | 9784 if (instantiator_type_arguments.IsNull()) { |
9781 return Type::DynamicType(); | 9785 return Type::DynamicType(); |
9782 } | 9786 } |
9783 // Bound checks should never appear in the instantiator type arguments. | 9787 // Bound checks may appear in the instantiator type arguments, as is the case |
9784 ASSERT(!AbstractType::Handle( | 9788 // with a pair of type parameters of the same class referring to each other |
9785 instantiator_type_arguments.TypeAt(index())).IsBoundedType()); | 9789 // via their bounds. |
9786 return instantiator_type_arguments.TypeAt(index()); | 9790 AbstractType& type_arg = AbstractType::Handle( |
| 9791 instantiator_type_arguments.TypeAt(index())); |
| 9792 if (type_arg.IsBoundedType()) { |
| 9793 const BoundedType& bounded_type = BoundedType::Cast(type_arg); |
| 9794 ASSERT(!bounded_type.IsInstantiated()); |
| 9795 ASSERT(AbstractType::Handle(bounded_type.bound()).IsInstantiated()); |
| 9796 type_arg = bounded_type.InstantiateFrom(AbstractTypeArguments::Handle(), |
| 9797 malformed_error); |
| 9798 } |
| 9799 return type_arg.raw(); |
9787 } | 9800 } |
9788 | 9801 |
9789 | 9802 |
9790 void TypeParameter::CheckBound(const AbstractType& bounded_type, | 9803 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
9791 const AbstractType& upper_bound, | 9804 const AbstractType& upper_bound, |
9792 Error* malformed_error) const { | 9805 Error* malformed_error) const { |
9793 ASSERT(malformed_error->IsNull()); | 9806 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); |
9794 ASSERT(bounded_type.IsFinalized()); | 9807 ASSERT(bounded_type.IsFinalized()); |
9795 ASSERT(upper_bound.IsFinalized()); | 9808 ASSERT(upper_bound.IsFinalized()); |
9796 ASSERT(!bounded_type.IsMalformed()); | 9809 ASSERT(!bounded_type.IsMalformed()); |
9797 if (bounded_type.IsSubtypeOf(upper_bound, malformed_error) || | 9810 if (bounded_type.IsSubtypeOf(upper_bound, malformed_error)) { |
9798 !malformed_error->IsNull()) { | 9811 return true; |
9799 return; | |
9800 } | 9812 } |
9801 // Report the bound error. | 9813 if ((malformed_error != NULL) && malformed_error->IsNull()) { |
9802 const String& bounded_type_name = String::Handle( | 9814 // Report the bound error. |
9803 bounded_type.UserVisibleName()); | 9815 const String& bounded_type_name = String::Handle( |
9804 const String& upper_bound_name = String::Handle( | 9816 bounded_type.UserVisibleName()); |
9805 upper_bound.UserVisibleName()); | 9817 const String& upper_bound_name = String::Handle( |
9806 const AbstractType& declared_bound = AbstractType::Handle(bound()); | 9818 upper_bound.UserVisibleName()); |
9807 const String& declared_bound_name = String::Handle( | 9819 const AbstractType& declared_bound = AbstractType::Handle(bound()); |
9808 declared_bound.UserVisibleName()); | 9820 const String& declared_bound_name = String::Handle( |
9809 const String& type_param_name = String::Handle(UserVisibleName()); | 9821 declared_bound.UserVisibleName()); |
9810 const Class& cls = Class::Handle(parameterized_class()); | 9822 const String& type_param_name = String::Handle(UserVisibleName()); |
9811 const String& class_name = String::Handle(cls.Name()); | 9823 const Class& cls = Class::Handle(parameterized_class()); |
9812 const Script& script = Script::Handle(cls.script()); | 9824 const String& class_name = String::Handle(cls.Name()); |
9813 // Since the bound may have been canonicalized, its token index is | 9825 const Script& script = Script::Handle(cls.script()); |
9814 // meaningless, therefore use the token index of this type parameter. | 9826 // Since the bound may have been canonicalized, its token index is |
9815 *malformed_error = FormatError( | 9827 // meaningless, therefore use the token index of this type parameter. |
9816 *malformed_error, | 9828 *malformed_error = FormatError( |
9817 script, | 9829 *malformed_error, |
9818 token_pos(), | 9830 script, |
9819 "type parameter '%s' of class '%s' must extend bound '%s', " | 9831 token_pos(), |
9820 "but type argument '%s' is not a subtype of '%s'\n", | 9832 "type parameter '%s' of class '%s' must extend bound '%s', " |
9821 type_param_name.ToCString(), | 9833 "but type argument '%s' is not a subtype of '%s'\n", |
9822 class_name.ToCString(), | 9834 type_param_name.ToCString(), |
9823 declared_bound_name.ToCString(), | 9835 class_name.ToCString(), |
9824 bounded_type_name.ToCString(), | 9836 declared_bound_name.ToCString(), |
9825 upper_bound_name.ToCString()); | 9837 bounded_type_name.ToCString(), |
| 9838 upper_bound_name.ToCString()); |
| 9839 } |
| 9840 return false; |
9826 } | 9841 } |
9827 | 9842 |
9828 | 9843 |
9829 intptr_t TypeParameter::Hash() const { | 9844 intptr_t TypeParameter::Hash() const { |
9830 ASSERT(IsFinalized()); | 9845 ASSERT(IsFinalized()); |
9831 uword result = 0; | 9846 uword result = 0; |
9832 result += Class::Handle(parameterized_class()).id(); | 9847 result += Class::Handle(parameterized_class()).id(); |
9833 // Do not include the hash of the bound, which could lead to cycles. | 9848 // Do not include the hash of the bound, which could lead to cycles. |
9834 result <<= index(); | 9849 result <<= index(); |
9835 return FinalizeHash(result); | 9850 return FinalizeHash(result); |
(...skipping 3219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13055 } | 13070 } |
13056 return result.raw(); | 13071 return result.raw(); |
13057 } | 13072 } |
13058 | 13073 |
13059 | 13074 |
13060 const char* WeakProperty::ToCString() const { | 13075 const char* WeakProperty::ToCString() const { |
13061 return "_WeakProperty"; | 13076 return "_WeakProperty"; |
13062 } | 13077 } |
13063 | 13078 |
13064 } // namespace dart | 13079 } // namespace dart |
OLD | NEW |