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 |