| 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 3858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3869 Array& interfaces = Array::Handle(zone, thsi.interfaces()); | 3869 Array& interfaces = Array::Handle(zone, thsi.interfaces()); |
| 3870 AbstractType& interface = AbstractType::Handle(zone); | 3870 AbstractType& interface = AbstractType::Handle(zone); |
| 3871 Class& interface_class = Class::Handle(zone); | 3871 Class& interface_class = Class::Handle(zone); |
| 3872 TypeArguments& interface_args = TypeArguments::Handle(zone); | 3872 TypeArguments& interface_args = TypeArguments::Handle(zone); |
| 3873 Error& error = Error::Handle(zone); | 3873 Error& error = Error::Handle(zone); |
| 3874 for (intptr_t i = 0; i < interfaces.Length(); i++) { | 3874 for (intptr_t i = 0; i < interfaces.Length(); i++) { |
| 3875 interface ^= interfaces.At(i); | 3875 interface ^= interfaces.At(i); |
| 3876 if (!interface.IsFinalized()) { | 3876 if (!interface.IsFinalized()) { |
| 3877 // We may be checking bounds at finalization time and can encounter | 3877 // We may be checking bounds at finalization time and can encounter |
| 3878 // a still unfinalized interface. | 3878 // a still unfinalized interface. |
| 3879 if (interface.IsBeingFinalized()) { |
| 3880 // Interface is part of a still unfinalized recursive type graph. |
| 3881 // Skip it. The caller will create a bounded type to be checked at |
| 3882 // runtime if this type test returns false at compile time. |
| 3883 continue; |
| 3884 } |
| 3879 ClassFinalizer::FinalizeType( | 3885 ClassFinalizer::FinalizeType( |
| 3880 thsi, interface, ClassFinalizer::kCanonicalize); | 3886 thsi, interface, ClassFinalizer::kCanonicalize); |
| 3881 interfaces.SetAt(i, interface); | 3887 interfaces.SetAt(i, interface); |
| 3882 } | 3888 } |
| 3883 if (interface.IsMalbounded()) { | 3889 if (interface.IsMalbounded()) { |
| 3884 // Return the first bound error to the caller if it requests it. | 3890 // Return the first bound error to the caller if it requests it. |
| 3885 if ((bound_error != NULL) && bound_error->IsNull()) { | 3891 if ((bound_error != NULL) && bound_error->IsNull()) { |
| 3886 *bound_error = interface.error(); | 3892 *bound_error = interface.error(); |
| 3887 } | 3893 } |
| 3888 continue; // Another interface may work better. | 3894 continue; // Another interface may work better. |
| (...skipping 11617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15506 // Build the bound name without causing divergence. | 15512 // Build the bound name without causing divergence. |
| 15507 const AbstractType& bound = AbstractType::Handle( | 15513 const AbstractType& bound = AbstractType::Handle( |
| 15508 zone, BoundedType::Cast(*this).bound()); | 15514 zone, BoundedType::Cast(*this).bound()); |
| 15509 String& bound_name = String::Handle(zone); | 15515 String& bound_name = String::Handle(zone); |
| 15510 if (bound.IsTypeParameter()) { | 15516 if (bound.IsTypeParameter()) { |
| 15511 bound_name = TypeParameter::Cast(bound).name(); | 15517 bound_name = TypeParameter::Cast(bound).name(); |
| 15512 pieces.Add(bound_name); | 15518 pieces.Add(bound_name); |
| 15513 } else if (bound.IsType()) { | 15519 } else if (bound.IsType()) { |
| 15514 const Class& cls = Class::Handle(zone, Type::Cast(bound).type_class()); | 15520 const Class& cls = Class::Handle(zone, Type::Cast(bound).type_class()); |
| 15515 bound_name = cls.Name(); | 15521 bound_name = cls.Name(); |
| 15522 pieces.Add(bound_name); |
| 15516 if (Type::Cast(bound).arguments() != TypeArguments::null()) { | 15523 if (Type::Cast(bound).arguments() != TypeArguments::null()) { |
| 15517 pieces.Add(bound_name); | |
| 15518 pieces.Add(Symbols::OptimizedOut()); | 15524 pieces.Add(Symbols::OptimizedOut()); |
| 15519 } | 15525 } |
| 15520 } else { | 15526 } else { |
| 15521 pieces.Add(Symbols::OptimizedOut()); | 15527 pieces.Add(Symbols::OptimizedOut()); |
| 15522 } | 15528 } |
| 15523 return Symbols::FromConcatAll(pieces); | 15529 return Symbols::FromConcatAll(pieces); |
| 15524 } | 15530 } |
| 15525 if (IsTypeParameter()) { | 15531 if (IsTypeParameter()) { |
| 15526 return TypeParameter::Cast(*this).name(); | 15532 return TypeParameter::Cast(*this).name(); |
| 15527 } | 15533 } |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15720 ASSERT(Isolate::Current()->flags().type_checks()); | 15726 ASSERT(Isolate::Current()->flags().type_checks()); |
| 15721 if ((bound_error != NULL) && bound_error->IsNull()) { | 15727 if ((bound_error != NULL) && bound_error->IsNull()) { |
| 15722 *bound_error = other.error(); | 15728 *bound_error = other.error(); |
| 15723 } | 15729 } |
| 15724 return false; | 15730 return false; |
| 15725 } | 15731 } |
| 15726 if (IsBoundedType() || other.IsBoundedType()) { | 15732 if (IsBoundedType() || other.IsBoundedType()) { |
| 15727 if (Equals(other)) { | 15733 if (Equals(other)) { |
| 15728 return true; | 15734 return true; |
| 15729 } | 15735 } |
| 15736 // Redundant check if other type is equal to the upper bound of this type. |
| 15737 if (IsBoundedType() && |
| 15738 AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) { |
| 15739 return true; |
| 15740 } |
| 15730 return false; // TODO(regis): We should return "maybe after instantiation". | 15741 return false; // TODO(regis): We should return "maybe after instantiation". |
| 15731 } | 15742 } |
| 15732 // Type parameters cannot be handled by Class::TypeTest(). | 15743 // Type parameters cannot be handled by Class::TypeTest(). |
| 15733 // When comparing two uninstantiated function types, one returning type | 15744 // When comparing two uninstantiated function types, one returning type |
| 15734 // parameter K, the other returning type parameter V, we cannot assume that K | 15745 // parameter K, the other returning type parameter V, we cannot assume that K |
| 15735 // is a subtype of V, or vice versa. We only return true if K equals V, as | 15746 // is a subtype of V, or vice versa. We only return true if K equals V, as |
| 15736 // defined by TypeParameter::Equals. | 15747 // defined by TypeParameter::Equals. |
| 15737 // The same rule applies when checking the upper bound of a still | 15748 // The same rule applies when checking the upper bound of a still |
| 15738 // uninstantiated type at compile time. Returning false will defer the test | 15749 // uninstantiated type at compile time. Returning false will defer the test |
| 15739 // to run time. | 15750 // to run time. |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16137 if (from_index > 0) { | 16148 if (from_index > 0) { |
| 16138 // Verify that the type arguments of the super class match, since they | 16149 // Verify that the type arguments of the super class match, since they |
| 16139 // depend solely on the type parameters that were just verified to match. | 16150 // depend solely on the type parameters that were just verified to match. |
| 16140 ASSERT(type_args.Length() >= (from_index + num_type_params)); | 16151 ASSERT(type_args.Length() >= (from_index + num_type_params)); |
| 16141 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); | 16152 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); |
| 16142 AbstractType& type_arg = AbstractType::Handle(zone); | 16153 AbstractType& type_arg = AbstractType::Handle(zone); |
| 16143 AbstractType& other_type_arg = AbstractType::Handle(zone); | 16154 AbstractType& other_type_arg = AbstractType::Handle(zone); |
| 16144 for (intptr_t i = 0; i < from_index; i++) { | 16155 for (intptr_t i = 0; i < from_index; i++) { |
| 16145 type_arg = type_args.TypeAt(i); | 16156 type_arg = type_args.TypeAt(i); |
| 16146 other_type_arg = other_type_args.TypeAt(i); | 16157 other_type_arg = other_type_args.TypeAt(i); |
| 16158 // Ignore bounds of bounded types. |
| 16159 while (type_arg.IsBoundedType()) { |
| 16160 type_arg = BoundedType::Cast(type_arg).type(); |
| 16161 } |
| 16162 while (other_type_arg.IsBoundedType()) { |
| 16163 other_type_arg = BoundedType::Cast(other_type_arg).type(); |
| 16164 } |
| 16147 ASSERT(type_arg.IsEquivalent(other_type_arg, trail)); | 16165 ASSERT(type_arg.IsEquivalent(other_type_arg, trail)); |
| 16148 } | 16166 } |
| 16149 } | 16167 } |
| 16150 #endif | 16168 #endif |
| 16151 return true; | 16169 return true; |
| 16152 } | 16170 } |
| 16153 | 16171 |
| 16154 | 16172 |
| 16155 bool Type::IsRecursive() const { | 16173 bool Type::IsRecursive() const { |
| 16156 return TypeArguments::Handle(arguments()).IsRecursive(); | 16174 return TypeArguments::Handle(arguments()).IsRecursive(); |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16966 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); | 16984 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); |
| 16967 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 16985 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
| 16968 if (!upper_bound.IsInstantiated()) { | 16986 if (!upper_bound.IsInstantiated()) { |
| 16969 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, | 16987 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, |
| 16970 bound_error, | 16988 bound_error, |
| 16971 trail, | 16989 trail, |
| 16972 space); | 16990 space); |
| 16973 // Instantiated upper_bound may not be finalized. See comment above. | 16991 // Instantiated upper_bound may not be finalized. See comment above. |
| 16974 } | 16992 } |
| 16975 if (bound_error->IsNull()) { | 16993 if (bound_error->IsNull()) { |
| 16976 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && | 16994 if (bounded_type.IsBeingFinalized() || |
| 16977 bound_error->IsNull()) { | 16995 upper_bound.IsBeingFinalized() || |
| 16996 (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && |
| 16997 bound_error->IsNull())) { |
| 16978 // We cannot determine yet whether the bounded_type is below the | 16998 // We cannot determine yet whether the bounded_type is below the |
| 16979 // upper_bound, because one or both of them is still uninstantiated. | 16999 // upper_bound, because one or both of them is still being finalized or |
| 16980 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); | 17000 // uninstantiated. |
| 16981 // Postpone bound check by returning a new BoundedType with partially | 17001 ASSERT(bounded_type.IsBeingFinalized() || |
| 16982 // instantiated bounded_type and upper_bound, but keeping type_param. | 17002 upper_bound.IsBeingFinalized() || |
| 17003 !bounded_type.IsInstantiated() || |
| 17004 !upper_bound.IsInstantiated()); |
| 17005 // Postpone bound check by returning a new BoundedType with unfinalized |
| 17006 // or partially instantiated bounded_type and upper_bound, but keeping |
| 17007 // type_param. |
| 16983 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); | 17008 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); |
| 16984 } | 17009 } |
| 16985 } | 17010 } |
| 16986 } | 17011 } |
| 16987 return bounded_type.raw(); | 17012 return bounded_type.raw(); |
| 16988 } | 17013 } |
| 16989 | 17014 |
| 16990 | 17015 |
| 16991 RawAbstractType* BoundedType::CloneUnfinalized() const { | 17016 RawAbstractType* BoundedType::CloneUnfinalized() const { |
| 16992 if (IsFinalized()) { | 17017 if (IsFinalized()) { |
| (...skipping 5040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 22033 return tag_label.ToCString(); | 22058 return tag_label.ToCString(); |
| 22034 } | 22059 } |
| 22035 | 22060 |
| 22036 | 22061 |
| 22037 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 22062 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 22038 Instance::PrintJSONImpl(stream, ref); | 22063 Instance::PrintJSONImpl(stream, ref); |
| 22039 } | 22064 } |
| 22040 | 22065 |
| 22041 | 22066 |
| 22042 } // namespace dart | 22067 } // namespace dart |
| OLD | NEW |