| 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 |