| 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 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 array.SetAt(kInitialCanonicalTypeArgumentsSize, Smi::Handle(Smi::New(0))); | 695 array.SetAt(kInitialCanonicalTypeArgumentsSize, Smi::Handle(Smi::New(0))); |
| 696 object_store->set_canonical_type_arguments(array); | 696 object_store->set_canonical_type_arguments(array); |
| 697 | 697 |
| 698 // Setup type class early in the process. | 698 // Setup type class early in the process. |
| 699 cls = Class::New<Type>(); | 699 cls = Class::New<Type>(); |
| 700 object_store->set_type_class(cls); | 700 object_store->set_type_class(cls); |
| 701 | 701 |
| 702 cls = Class::New<TypeParameter>(); | 702 cls = Class::New<TypeParameter>(); |
| 703 object_store->set_type_parameter_class(cls); | 703 object_store->set_type_parameter_class(cls); |
| 704 | 704 |
| 705 cls = Class::New<BoundedType>(); |
| 706 object_store->set_bounded_type_class(cls); |
| 707 |
| 705 // Pre-allocate the OneByteString class needed by the symbol table. | 708 // Pre-allocate the OneByteString class needed by the symbol table. |
| 706 cls = Class::NewStringClass(kOneByteStringCid); | 709 cls = Class::NewStringClass(kOneByteStringCid); |
| 707 object_store->set_one_byte_string_class(cls); | 710 object_store->set_one_byte_string_class(cls); |
| 708 | 711 |
| 709 // Pre-allocate the TwoByteString class needed by the symbol table. | 712 // Pre-allocate the TwoByteString class needed by the symbol table. |
| 710 cls = Class::NewStringClass(kTwoByteStringCid); | 713 cls = Class::NewStringClass(kTwoByteStringCid); |
| 711 object_store->set_two_byte_string_class(cls); | 714 object_store->set_two_byte_string_class(cls); |
| 712 | 715 |
| 713 // Setup the symbol table for the symbols created in the isolate. | 716 // Setup the symbol table for the symbols created in the isolate. |
| 714 Symbols::SetupSymbolTable(isolate); | 717 Symbols::SetupSymbolTable(isolate); |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 // This is done to allow bootstrapping of reading classes from the snapshot. | 1089 // This is done to allow bootstrapping of reading classes from the snapshot. |
| 1087 cls = Class::New<Instance>(kInstanceCid); | 1090 cls = Class::New<Instance>(kInstanceCid); |
| 1088 object_store->set_object_class(cls); | 1091 object_store->set_object_class(cls); |
| 1089 | 1092 |
| 1090 cls = Class::New<Type>(); | 1093 cls = Class::New<Type>(); |
| 1091 object_store->set_type_class(cls); | 1094 object_store->set_type_class(cls); |
| 1092 | 1095 |
| 1093 cls = Class::New<TypeParameter>(); | 1096 cls = Class::New<TypeParameter>(); |
| 1094 object_store->set_type_parameter_class(cls); | 1097 object_store->set_type_parameter_class(cls); |
| 1095 | 1098 |
| 1099 cls = Class::New<BoundedType>(); |
| 1100 object_store->set_bounded_type_class(cls); |
| 1101 |
| 1096 cls = Class::New<Array>(); | 1102 cls = Class::New<Array>(); |
| 1097 object_store->set_array_class(cls); | 1103 object_store->set_array_class(cls); |
| 1098 | 1104 |
| 1099 cls = Class::New<ImmutableArray>(); | 1105 cls = Class::New<ImmutableArray>(); |
| 1100 object_store->set_immutable_array_class(cls); | 1106 object_store->set_immutable_array_class(cls); |
| 1101 | 1107 |
| 1102 cls = Class::New<GrowableObjectArray>(); | 1108 cls = Class::New<GrowableObjectArray>(); |
| 1103 object_store->set_growable_object_array_class(cls); | 1109 object_store->set_growable_object_array_class(cls); |
| 1104 | 1110 |
| 1105 cls = Class::New<Float32x4>(); | 1111 cls = Class::New<Float32x4>(); |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1656 // More efficient than calling NumTypeArguments(). | 1662 // More efficient than calling NumTypeArguments(). |
| 1657 return type_arguments_field_offset() != kNoTypeArguments; | 1663 return type_arguments_field_offset() != kNoTypeArguments; |
| 1658 } else { | 1664 } else { |
| 1659 // No need to check NumTypeArguments() if class has type parameters. | 1665 // No need to check NumTypeArguments() if class has type parameters. |
| 1660 return (NumTypeParameters() > 0) || (NumTypeArguments() > 0); | 1666 return (NumTypeParameters() > 0) || (NumTypeArguments() > 0); |
| 1661 } | 1667 } |
| 1662 } | 1668 } |
| 1663 | 1669 |
| 1664 | 1670 |
| 1665 RawClass* Class::SuperClass() const { | 1671 RawClass* Class::SuperClass() const { |
| 1666 const Type& sup_type = Type::Handle(super_type()); | 1672 const AbstractType& sup_type = AbstractType::Handle(super_type()); |
| 1667 if (sup_type.IsNull()) { | 1673 if (sup_type.IsNull()) { |
| 1668 return Class::null(); | 1674 return Class::null(); |
| 1669 } | 1675 } |
| 1670 return sup_type.type_class(); | 1676 return sup_type.type_class(); |
| 1671 } | 1677 } |
| 1672 | 1678 |
| 1673 | 1679 |
| 1674 void Class::set_super_type(const Type& value) const { | 1680 void Class::set_super_type(const AbstractType& value) const { |
| 1681 ASSERT(value.IsNull() || value.IsType() || value.IsBoundedType()); |
| 1675 StorePointer(&raw_ptr()->super_type_, value.raw()); | 1682 StorePointer(&raw_ptr()->super_type_, value.raw()); |
| 1676 } | 1683 } |
| 1677 | 1684 |
| 1678 | 1685 |
| 1679 // Return a TypeParameter if the type_name is a type parameter of this class. | 1686 // Return a TypeParameter if the type_name is a type parameter of this class. |
| 1680 // Return null otherwise. | 1687 // Return null otherwise. |
| 1681 RawTypeParameter* Class::LookupTypeParameter(const String& type_name, | 1688 RawTypeParameter* Class::LookupTypeParameter(const String& type_name, |
| 1682 intptr_t token_pos) const { | 1689 intptr_t token_pos) const { |
| 1683 ASSERT(!type_name.IsNull()); | 1690 ASSERT(!type_name.IsNull()); |
| 1684 const TypeArguments& type_params = TypeArguments::Handle(type_parameters()); | 1691 const TypeArguments& type_params = TypeArguments::Handle(type_parameters()); |
| 1685 if (!type_params.IsNull()) { | 1692 if (!type_params.IsNull()) { |
| 1686 intptr_t num_type_params = type_params.Length(); | 1693 intptr_t num_type_params = type_params.Length(); |
| 1687 TypeParameter& type_param = TypeParameter::Handle(); | 1694 TypeParameter& type_param = TypeParameter::Handle(); |
| 1688 String& type_param_name = String::Handle(); | 1695 String& type_param_name = String::Handle(); |
| 1689 // TODO(regis): We do not copy the bound (= type_param.bound()), since | |
| 1690 // we are not able to finalize the bounds of type parameter references | |
| 1691 // without getting into cycles. Revisit. | |
| 1692 const AbstractType& bound = AbstractType::Handle( | |
| 1693 Isolate::Current()->object_store()->object_type()); | |
| 1694 for (intptr_t i = 0; i < num_type_params; i++) { | 1696 for (intptr_t i = 0; i < num_type_params; i++) { |
| 1695 type_param ^= type_params.TypeAt(i); | 1697 type_param ^= type_params.TypeAt(i); |
| 1696 type_param_name = type_param.name(); | 1698 type_param_name = type_param.name(); |
| 1697 if (type_param_name.Equals(type_name)) { | 1699 if (type_param_name.Equals(type_name)) { |
| 1698 intptr_t index = type_param.index(); | 1700 return type_param.raw(); |
| 1699 // Create a non-finalized new TypeParameter with the given token_pos. | |
| 1700 if (type_param.IsFinalized()) { | |
| 1701 // The index was adjusted during finalization. Revert. | |
| 1702 index -= NumTypeArguments() - num_type_params; | |
| 1703 } else { | |
| 1704 ASSERT(type_param.index() == i); | |
| 1705 } | |
| 1706 return TypeParameter::New(*this, index, type_name, bound, token_pos); | |
| 1707 } | 1701 } |
| 1708 } | 1702 } |
| 1709 } | 1703 } |
| 1710 return TypeParameter::null(); | 1704 return TypeParameter::null(); |
| 1711 } | 1705 } |
| 1712 | 1706 |
| 1713 | 1707 |
| 1714 void Class::CalculateFieldOffsets() const { | 1708 void Class::CalculateFieldOffsets() const { |
| 1715 Array& flds = Array::Handle(fields()); | 1709 Array& flds = Array::Handle(fields()); |
| 1716 const Class& super = Class::Handle(SuperClass()); | 1710 const Class& super = Class::Handle(SuperClass()); |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2237 return true; | 2231 return true; |
| 2238 } | 2232 } |
| 2239 } | 2233 } |
| 2240 } | 2234 } |
| 2241 // Check for 'direct super type' specified in the implements clause | 2235 // Check for 'direct super type' specified in the implements clause |
| 2242 // and check for transitivity at the same time. | 2236 // and check for transitivity at the same time. |
| 2243 Array& interfaces = Array::Handle(this->interfaces()); | 2237 Array& interfaces = Array::Handle(this->interfaces()); |
| 2244 AbstractType& interface = AbstractType::Handle(); | 2238 AbstractType& interface = AbstractType::Handle(); |
| 2245 Class& interface_class = Class::Handle(); | 2239 Class& interface_class = Class::Handle(); |
| 2246 AbstractTypeArguments& interface_args = AbstractTypeArguments::Handle(); | 2240 AbstractTypeArguments& interface_args = AbstractTypeArguments::Handle(); |
| 2241 Error& args_malformed_error = Error::Handle(); |
| 2247 for (intptr_t i = 0; i < interfaces.Length(); i++) { | 2242 for (intptr_t i = 0; i < interfaces.Length(); i++) { |
| 2248 interface ^= interfaces.At(i); | 2243 interface ^= interfaces.At(i); |
| 2249 interface_class = interface.type_class(); | 2244 interface_class = interface.type_class(); |
| 2250 interface_args = interface.arguments(); | 2245 interface_args = interface.arguments(); |
| 2251 if (!interface_args.IsNull() && !interface_args.IsInstantiated()) { | 2246 if (!interface_args.IsNull() && !interface_args.IsInstantiated()) { |
| 2252 // This type class implements an interface that is parameterized with | 2247 // This type class implements an interface that is parameterized with |
| 2253 // generic type(s), e.g. it implements List<T>. | 2248 // generic type(s), e.g. it implements List<T>. |
| 2254 // The uninstantiated type T must be instantiated using the type | 2249 // The uninstantiated type T must be instantiated using the type |
| 2255 // parameters of this type before performing the type test. | 2250 // parameters of this type before performing the type test. |
| 2256 // The type arguments of this type that are referred to by the type | 2251 // The type arguments of this type that are referred to by the type |
| 2257 // parameters of the interface are at the end of the type vector, | 2252 // parameters of the interface are at the end of the type vector, |
| 2258 // after the type arguments of the super type of this type. | 2253 // after the type arguments of the super type of this type. |
| 2259 // The index of the type parameters is adjusted upon finalization. | 2254 // The index of the type parameters is adjusted upon finalization. |
| 2260 ASSERT(interface.IsFinalized()); | 2255 ASSERT(interface.IsFinalized()); |
| 2261 interface_args = interface_args.InstantiateFrom(type_arguments); | 2256 args_malformed_error = Error::null(); |
| 2262 // In checked mode, verify that the instantiated interface type | 2257 interface_args = interface_args.InstantiateFrom(type_arguments, |
| 2263 // arguments are within the bounds specified by the interface class. | 2258 &args_malformed_error); |
| 2264 // Note that the additional bounds check in checked mode may lead to a | 2259 if (!args_malformed_error.IsNull()) { |
| 2265 // dynamic type error, but it will never change the result of the type | 2260 // Return the first malformed error to the caller if it requests it. |
| 2266 // check from true in production mode to false in checked mode. | 2261 if ((malformed_error != NULL) && malformed_error->IsNull()) { |
| 2267 if (FLAG_enable_type_checks && !interface_args.IsNull()) { | 2262 *malformed_error = args_malformed_error.raw(); |
| 2268 // Pass type_arguments as bounds instantiator. | |
| 2269 if (!interface_args.IsWithinBoundsOf(interface_class, | |
| 2270 type_arguments, | |
| 2271 malformed_error)) { | |
| 2272 continue; | |
| 2273 } | 2263 } |
| 2264 continue; // Another interface may work better. |
| 2274 } | 2265 } |
| 2275 } | 2266 } |
| 2276 if (interface_class.TypeTest(test_kind, | 2267 if (interface_class.TypeTest(test_kind, |
| 2277 interface_args, | 2268 interface_args, |
| 2278 other, | 2269 other, |
| 2279 other_type_arguments, | 2270 other_type_arguments, |
| 2280 malformed_error)) { | 2271 malformed_error)) { |
| 2281 return true; | 2272 return true; |
| 2282 } | 2273 } |
| 2283 } | 2274 } |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2687 } | 2678 } |
| 2688 | 2679 |
| 2689 | 2680 |
| 2690 bool AbstractTypeArguments::IsUninstantiatedIdentity() const { | 2681 bool AbstractTypeArguments::IsUninstantiatedIdentity() const { |
| 2691 // AbstractTypeArguments is an abstract class. | 2682 // AbstractTypeArguments is an abstract class. |
| 2692 UNREACHABLE(); | 2683 UNREACHABLE(); |
| 2693 return false; | 2684 return false; |
| 2694 } | 2685 } |
| 2695 | 2686 |
| 2696 | 2687 |
| 2688 bool AbstractTypeArguments::IsBounded() const { |
| 2689 // AbstractTypeArguments is an abstract class. |
| 2690 UNREACHABLE(); |
| 2691 return false; |
| 2692 } |
| 2693 |
| 2694 |
| 2697 static intptr_t FinalizeHash(uword hash) { | 2695 static intptr_t FinalizeHash(uword hash) { |
| 2698 hash += hash << 3; | 2696 hash += hash << 3; |
| 2699 hash ^= hash >> 11; | 2697 hash ^= hash >> 11; |
| 2700 hash += hash << 15; | 2698 hash += hash << 15; |
| 2701 return hash; | 2699 return hash; |
| 2702 } | 2700 } |
| 2703 | 2701 |
| 2704 | 2702 |
| 2705 intptr_t AbstractTypeArguments::Hash() const { | 2703 intptr_t AbstractTypeArguments::Hash() const { |
| 2706 if (IsNull()) return 0; | 2704 if (IsNull()) return 0; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2778 return other_arguments.IsDynamicTypes(false, other_arguments.Length()); | 2776 return other_arguments.IsDynamicTypes(false, other_arguments.Length()); |
| 2779 } | 2777 } |
| 2780 if (other_arguments.IsNull()) { | 2778 if (other_arguments.IsNull()) { |
| 2781 return arguments.IsDynamicTypes(false, arguments.Length()); | 2779 return arguments.IsDynamicTypes(false, arguments.Length()); |
| 2782 } | 2780 } |
| 2783 return arguments.Equals(other_arguments); | 2781 return arguments.Equals(other_arguments); |
| 2784 } | 2782 } |
| 2785 | 2783 |
| 2786 | 2784 |
| 2787 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( | 2785 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( |
| 2788 const AbstractTypeArguments& instantiator_type_arguments) const { | 2786 const AbstractTypeArguments& instantiator_type_arguments, |
| 2787 Error* malformed_error) const { |
| 2789 // AbstractTypeArguments is an abstract class. | 2788 // AbstractTypeArguments is an abstract class. |
| 2790 UNREACHABLE(); | 2789 UNREACHABLE(); |
| 2791 return NULL; | 2790 return NULL; |
| 2792 } | 2791 } |
| 2793 | 2792 |
| 2794 | 2793 |
| 2795 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, | 2794 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, |
| 2796 intptr_t len) const { | 2795 intptr_t len) const { |
| 2797 ASSERT(Length() >= len); | 2796 ASSERT(Length() >= len); |
| 2798 AbstractType& type = AbstractType::Handle(); | 2797 AbstractType& type = AbstractType::Handle(); |
| 2799 Class& type_class = Class::Handle(); | 2798 Class& type_class = Class::Handle(); |
| 2800 for (intptr_t i = 0; i < len; i++) { | 2799 for (intptr_t i = 0; i < len; i++) { |
| 2801 type = TypeAt(i); | 2800 type = TypeAt(i); |
| 2802 ASSERT(!type.IsNull()); | 2801 ASSERT(!type.IsNull()); |
| 2803 if (!type.HasResolvedTypeClass()) { | 2802 if (!type.HasResolvedTypeClass()) { |
| 2804 if (raw_instantiated && type.IsTypeParameter()) { | 2803 if (raw_instantiated && type.IsTypeParameter()) { |
| 2805 // An uninstantiated type parameter is equivalent to dynamic. | 2804 // An uninstantiated type parameter is equivalent to dynamic (even in |
| 2805 // the presence of a malformed bound in checked mode). |
| 2806 continue; | 2806 continue; |
| 2807 } | 2807 } |
| 2808 ASSERT((!raw_instantiated && type.IsTypeParameter()) || | 2808 ASSERT((!raw_instantiated && type.IsTypeParameter()) || |
| 2809 type.IsBoundedType() || |
| 2809 type.IsMalformed()); | 2810 type.IsMalformed()); |
| 2810 return false; | 2811 return false; |
| 2811 } | 2812 } |
| 2812 type_class = type.type_class(); | 2813 type_class = type.type_class(); |
| 2813 if (!type_class.IsDynamicClass()) { | 2814 if (!type_class.IsDynamicClass()) { |
| 2814 return false; | 2815 return false; |
| 2815 } | 2816 } |
| 2816 } | 2817 } |
| 2817 return true; | 2818 return true; |
| 2818 } | 2819 } |
| 2819 | 2820 |
| 2820 | 2821 |
| 2821 static RawError* FormatError(const Error& prev_error, | 2822 static RawError* FormatError(const Error& prev_error, |
| 2822 const Script& script, | 2823 const Script& script, |
| 2823 intptr_t token_pos, | 2824 intptr_t token_pos, |
| 2824 const char* format, ...) { | 2825 const char* format, ...) { |
| 2825 va_list args; | 2826 va_list args; |
| 2826 va_start(args, format); | 2827 va_start(args, format); |
| 2827 if (prev_error.IsNull()) { | 2828 if (prev_error.IsNull()) { |
| 2828 return Parser::FormatError(script, token_pos, "Error", format, args); | 2829 return Parser::FormatError(script, token_pos, "Error", format, args); |
| 2829 } else { | 2830 } else { |
| 2830 return Parser::FormatErrorWithAppend(prev_error, script, token_pos, | 2831 return Parser::FormatErrorWithAppend(prev_error, script, token_pos, |
| 2831 "Error", format, args); | 2832 "Error", format, args); |
| 2832 } | 2833 } |
| 2833 } | 2834 } |
| 2834 | 2835 |
| 2835 | 2836 |
| 2836 bool AbstractTypeArguments::IsWithinBoundsOf( | |
| 2837 const Class& cls, | |
| 2838 const AbstractTypeArguments& bounds_instantiator, | |
| 2839 Error* malformed_error) const { | |
| 2840 ASSERT(FLAG_enable_type_checks); | |
| 2841 // This function may be called at compile time on (partially) uninstantiated | |
| 2842 // type arguments and may return true, in which case a run time bounds check | |
| 2843 // can be avoided. | |
| 2844 ASSERT(Length() >= cls.NumTypeArguments()); | |
| 2845 const intptr_t num_type_params = cls.NumTypeParameters(); | |
| 2846 const intptr_t offset = cls.NumTypeArguments() - num_type_params; | |
| 2847 AbstractType& this_type_arg = AbstractType::Handle(); | |
| 2848 AbstractType& cls_type_arg = AbstractType::Handle(); | |
| 2849 AbstractType& bound = AbstractType::Handle(); | |
| 2850 const TypeArguments& cls_type_params = | |
| 2851 TypeArguments::Handle(cls.type_parameters()); | |
| 2852 ASSERT((cls_type_params.IsNull() && (num_type_params == 0)) || | |
| 2853 (cls_type_params.Length() == num_type_params)); | |
| 2854 for (intptr_t i = 0; i < num_type_params; i++) { | |
| 2855 cls_type_arg = cls_type_params.TypeAt(i); | |
| 2856 const TypeParameter& cls_type_param = TypeParameter::Cast(cls_type_arg); | |
| 2857 bound = cls_type_param.bound(); | |
| 2858 if (!bound.IsDynamicType()) { | |
| 2859 this_type_arg = TypeAt(offset + i); | |
| 2860 Error& malformed_bound_error = Error::Handle(); | |
| 2861 if (bound.IsMalformed()) { | |
| 2862 malformed_bound_error = bound.malformed_error(); | |
| 2863 } else if (!bound.IsInstantiated()) { | |
| 2864 bound = bound.InstantiateFrom(bounds_instantiator); | |
| 2865 } | |
| 2866 if (!malformed_bound_error.IsNull() || | |
| 2867 !this_type_arg.IsSubtypeOf(bound, malformed_error)) { | |
| 2868 // Ignore this bound error if another malformed error was already | |
| 2869 // reported for this type test. | |
| 2870 if ((malformed_error != NULL) && malformed_error->IsNull()) { | |
| 2871 const String& type_arg_name = | |
| 2872 String::Handle(this_type_arg.UserVisibleName()); | |
| 2873 const String& class_name = String::Handle(cls.Name()); | |
| 2874 const String& bound_name = String::Handle(bound.UserVisibleName()); | |
| 2875 const Script& script = Script::Handle(cls.script()); | |
| 2876 // Since the bound was canonicalized, its token index was lost, | |
| 2877 // therefore, use the token index of the corresponding type parameter. | |
| 2878 *malformed_error ^= FormatError(malformed_bound_error, | |
| 2879 script, cls_type_param.token_pos(), | |
| 2880 "type argument '%s' does not " | |
| 2881 "extend bound '%s' of '%s'\n", | |
| 2882 type_arg_name.ToCString(), | |
| 2883 bound_name.ToCString(), | |
| 2884 class_name.ToCString()); | |
| 2885 } | |
| 2886 return false; | |
| 2887 } | |
| 2888 } | |
| 2889 } | |
| 2890 const Class& super_class = Class::Handle(cls.SuperClass()); | |
| 2891 if (!super_class.IsNull() && | |
| 2892 !IsWithinBoundsOf(super_class, bounds_instantiator, malformed_error)) { | |
| 2893 return false; | |
| 2894 } | |
| 2895 return true; | |
| 2896 } | |
| 2897 | |
| 2898 | |
| 2899 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind, | 2837 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind, |
| 2900 const AbstractTypeArguments& other, | 2838 const AbstractTypeArguments& other, |
| 2901 intptr_t len, | 2839 intptr_t len, |
| 2902 Error* malformed_error) const { | 2840 Error* malformed_error) const { |
| 2903 ASSERT(Length() >= len); | 2841 ASSERT(Length() >= len); |
| 2904 ASSERT(!other.IsNull()); | 2842 ASSERT(!other.IsNull()); |
| 2905 ASSERT(other.Length() >= len); | 2843 ASSERT(other.Length() >= len); |
| 2906 AbstractType& type = AbstractType::Handle(); | 2844 AbstractType& type = AbstractType::Handle(); |
| 2907 AbstractType& other_type = AbstractType::Handle(); | 2845 AbstractType& other_type = AbstractType::Handle(); |
| 2908 for (intptr_t i = 0; i < len; i++) { | 2846 for (intptr_t i = 0; i < len; i++) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2976 bool TypeArguments::IsUninstantiatedIdentity() const { | 2914 bool TypeArguments::IsUninstantiatedIdentity() const { |
| 2977 ASSERT(!IsInstantiated()); | 2915 ASSERT(!IsInstantiated()); |
| 2978 AbstractType& type = AbstractType::Handle(); | 2916 AbstractType& type = AbstractType::Handle(); |
| 2979 intptr_t num_types = Length(); | 2917 intptr_t num_types = Length(); |
| 2980 for (intptr_t i = 0; i < num_types; i++) { | 2918 for (intptr_t i = 0; i < num_types; i++) { |
| 2981 type = TypeAt(i); | 2919 type = TypeAt(i); |
| 2982 if (!type.IsTypeParameter()) { | 2920 if (!type.IsTypeParameter()) { |
| 2983 return false; | 2921 return false; |
| 2984 } | 2922 } |
| 2985 const TypeParameter& type_param = TypeParameter::Cast(type); | 2923 const TypeParameter& type_param = TypeParameter::Cast(type); |
| 2924 ASSERT(type_param.IsFinalized()); |
| 2986 if ((type_param.index() != i)) { | 2925 if ((type_param.index() != i)) { |
| 2987 return false; | 2926 return false; |
| 2988 } | 2927 } |
| 2928 // If this type parameter specifies an upper bound, then the type argument |
| 2929 // vector does not really represent the identity vector. It cannot be |
| 2930 // substituted by the instantiator's type argument vector without checking |
| 2931 // the upper bound. |
| 2932 const AbstractType& bound = AbstractType::Handle(type_param.bound()); |
| 2933 ASSERT(bound.IsFinalized()); |
| 2934 if (!bound.IsObjectType() && !bound.IsDynamicType()) { |
| 2935 return false; |
| 2936 } |
| 2989 } | 2937 } |
| 2990 return true; | 2938 return true; |
| 2991 } | 2939 } |
| 2992 | 2940 |
| 2993 | 2941 |
| 2942 bool TypeArguments::IsBounded() const { |
| 2943 AbstractType& type = AbstractType::Handle(); |
| 2944 intptr_t num_types = Length(); |
| 2945 for (intptr_t i = 0; i < num_types; i++) { |
| 2946 type = TypeAt(i); |
| 2947 if (type.IsBoundedType()) { |
| 2948 return true; |
| 2949 } |
| 2950 if (type.IsTypeParameter()) { |
| 2951 const AbstractType& bound = AbstractType::Handle( |
| 2952 TypeParameter::Cast(type).bound()); |
| 2953 if (!bound.IsObjectType() && !bound.IsDynamicType()) { |
| 2954 return true; |
| 2955 } |
| 2956 continue; |
| 2957 } |
| 2958 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( |
| 2959 Type::Cast(type).arguments()); |
| 2960 if (!type_args.IsNull() && type_args.IsBounded()) { |
| 2961 return true; |
| 2962 } |
| 2963 } |
| 2964 return false; |
| 2965 } |
| 2966 |
| 2967 |
| 2994 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( | 2968 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( |
| 2995 const AbstractTypeArguments& instantiator_type_arguments) const { | 2969 const AbstractTypeArguments& instantiator_type_arguments, |
| 2970 Error* malformed_error) const { |
| 2996 ASSERT(!IsInstantiated()); | 2971 ASSERT(!IsInstantiated()); |
| 2997 if (!instantiator_type_arguments.IsNull() && | 2972 if (!instantiator_type_arguments.IsNull() && |
| 2998 IsUninstantiatedIdentity() && | 2973 IsUninstantiatedIdentity() && |
| 2999 (instantiator_type_arguments.Length() == Length())) { | 2974 (instantiator_type_arguments.Length() == Length())) { |
| 3000 return instantiator_type_arguments.raw(); | 2975 return instantiator_type_arguments.raw(); |
| 3001 } | 2976 } |
| 3002 const intptr_t num_types = Length(); | 2977 const intptr_t num_types = Length(); |
| 3003 TypeArguments& instantiated_array = | 2978 TypeArguments& instantiated_array = |
| 3004 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); | 2979 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); |
| 3005 AbstractType& type = AbstractType::Handle(); | 2980 AbstractType& type = AbstractType::Handle(); |
| 3006 for (intptr_t i = 0; i < num_types; i++) { | 2981 for (intptr_t i = 0; i < num_types; i++) { |
| 3007 type = TypeAt(i); | 2982 type = TypeAt(i); |
| 3008 if (!type.IsInstantiated()) { | 2983 if (!type.IsInstantiated()) { |
| 3009 type = type.InstantiateFrom(instantiator_type_arguments); | 2984 type = type.InstantiateFrom(instantiator_type_arguments, malformed_error); |
| 3010 } | 2985 } |
| 3011 instantiated_array.SetTypeAt(i, type); | 2986 instantiated_array.SetTypeAt(i, type); |
| 3012 } | 2987 } |
| 3013 return instantiated_array.raw(); | 2988 return instantiated_array.raw(); |
| 3014 } | 2989 } |
| 3015 | 2990 |
| 3016 | 2991 |
| 3017 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { | 2992 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { |
| 3018 if (len < 0 || len > kMaxElements) { | 2993 if (len < 0 || len > kMaxElements) { |
| 3019 // This should be caught before we reach here. | 2994 // This should be caught before we reach here. |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3173 } | 3148 } |
| 3174 | 3149 |
| 3175 | 3150 |
| 3176 intptr_t InstantiatedTypeArguments::Length() const { | 3151 intptr_t InstantiatedTypeArguments::Length() const { |
| 3177 return AbstractTypeArguments::Handle( | 3152 return AbstractTypeArguments::Handle( |
| 3178 uninstantiated_type_arguments()).Length(); | 3153 uninstantiated_type_arguments()).Length(); |
| 3179 } | 3154 } |
| 3180 | 3155 |
| 3181 | 3156 |
| 3182 RawAbstractType* InstantiatedTypeArguments::TypeAt(intptr_t index) const { | 3157 RawAbstractType* InstantiatedTypeArguments::TypeAt(intptr_t index) const { |
| 3183 const AbstractType& type = AbstractType::Handle( | 3158 AbstractType& type = AbstractType::Handle(AbstractTypeArguments::Handle( |
| 3184 AbstractTypeArguments::Handle( | 3159 uninstantiated_type_arguments()).TypeAt(index)); |
| 3185 uninstantiated_type_arguments()).TypeAt(index)); | |
| 3186 if (!type.IsInstantiated()) { | 3160 if (!type.IsInstantiated()) { |
| 3187 const AbstractTypeArguments& instantiator_type_args = | 3161 const AbstractTypeArguments& instantiator_type_args = |
| 3188 AbstractTypeArguments::Handle(instantiator_type_arguments()); | 3162 AbstractTypeArguments::Handle(instantiator_type_arguments()); |
| 3189 return type.InstantiateFrom(instantiator_type_args); | 3163 Error& malformed_error = Error::Handle(); |
| 3164 type = type.InstantiateFrom(instantiator_type_args, &malformed_error); |
| 3165 // InstantiatedTypeArguments cannot include unchecked bounds. |
| 3166 // In the presence of unchecked bounds, no InstantiatedTypeArguments are |
| 3167 // allocated, but the type arguments are instantiated individually and their |
| 3168 // bounds are checked. |
| 3169 ASSERT(malformed_error.IsNull()); |
| 3190 } | 3170 } |
| 3191 return type.raw(); | 3171 return type.raw(); |
| 3192 } | 3172 } |
| 3193 | 3173 |
| 3194 | 3174 |
| 3195 void InstantiatedTypeArguments::SetTypeAt(intptr_t index, | 3175 void InstantiatedTypeArguments::SetTypeAt(intptr_t index, |
| 3196 const AbstractType& value) const { | 3176 const AbstractType& value) const { |
| 3197 // We only replace individual argument types during resolution at compile | 3177 // We only replace individual argument types during resolution at compile |
| 3198 // time, when no type parameters are instantiated yet. | 3178 // time, when no type parameters are instantiated yet. |
| 3199 UNREACHABLE(); | 3179 UNREACHABLE(); |
| (...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3977 TypeTestKind test_kind, | 3957 TypeTestKind test_kind, |
| 3978 intptr_t parameter_position, | 3958 intptr_t parameter_position, |
| 3979 intptr_t other_parameter_position, | 3959 intptr_t other_parameter_position, |
| 3980 const AbstractTypeArguments& type_arguments, | 3960 const AbstractTypeArguments& type_arguments, |
| 3981 const Function& other, | 3961 const Function& other, |
| 3982 const AbstractTypeArguments& other_type_arguments, | 3962 const AbstractTypeArguments& other_type_arguments, |
| 3983 Error* malformed_error) const { | 3963 Error* malformed_error) const { |
| 3984 AbstractType& other_param_type = | 3964 AbstractType& other_param_type = |
| 3985 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); | 3965 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); |
| 3986 if (!other_param_type.IsInstantiated()) { | 3966 if (!other_param_type.IsInstantiated()) { |
| 3987 other_param_type = other_param_type.InstantiateFrom(other_type_arguments); | 3967 other_param_type = other_param_type.InstantiateFrom(other_type_arguments, |
| 3968 malformed_error); |
| 3969 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); |
| 3988 } | 3970 } |
| 3989 if (other_param_type.IsDynamicType()) { | 3971 if (other_param_type.IsDynamicType()) { |
| 3990 return true; | 3972 return true; |
| 3991 } | 3973 } |
| 3992 AbstractType& param_type = | 3974 AbstractType& param_type = |
| 3993 AbstractType::Handle(ParameterTypeAt(parameter_position)); | 3975 AbstractType::Handle(ParameterTypeAt(parameter_position)); |
| 3994 if (!param_type.IsInstantiated()) { | 3976 if (!param_type.IsInstantiated()) { |
| 3995 param_type = param_type.InstantiateFrom(type_arguments); | 3977 param_type = param_type.InstantiateFrom(type_arguments, malformed_error); |
| 3978 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); |
| 3996 } | 3979 } |
| 3997 if (param_type.IsDynamicType()) { | 3980 if (param_type.IsDynamicType()) { |
| 3998 return test_kind == kIsSubtypeOf; | 3981 return test_kind == kIsSubtypeOf; |
| 3999 } | 3982 } |
| 4000 if (test_kind == kIsSubtypeOf) { | 3983 if (test_kind == kIsSubtypeOf) { |
| 4001 if (!param_type.IsSubtypeOf(other_param_type, malformed_error) && | 3984 if (!param_type.IsSubtypeOf(other_param_type, malformed_error) && |
| 4002 !other_param_type.IsSubtypeOf(param_type, malformed_error)) { | 3985 !other_param_type.IsSubtypeOf(param_type, malformed_error)) { |
| 4003 return false; | 3986 return false; |
| 4004 } | 3987 } |
| 4005 } else { | 3988 } else { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4026 const intptr_t other_num_opt_named_params = | 4009 const intptr_t other_num_opt_named_params = |
| 4027 other.NumOptionalNamedParameters(); | 4010 other.NumOptionalNamedParameters(); |
| 4028 if ((num_fixed_params != other_num_fixed_params) || | 4011 if ((num_fixed_params != other_num_fixed_params) || |
| 4029 (num_opt_pos_params < other_num_opt_pos_params) || | 4012 (num_opt_pos_params < other_num_opt_pos_params) || |
| 4030 (num_opt_named_params < other_num_opt_named_params)) { | 4013 (num_opt_named_params < other_num_opt_named_params)) { |
| 4031 return false; | 4014 return false; |
| 4032 } | 4015 } |
| 4033 // Check the result type. | 4016 // Check the result type. |
| 4034 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); | 4017 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); |
| 4035 if (!other_res_type.IsInstantiated()) { | 4018 if (!other_res_type.IsInstantiated()) { |
| 4036 other_res_type = other_res_type.InstantiateFrom(other_type_arguments); | 4019 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, |
| 4020 malformed_error); |
| 4021 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); |
| 4037 } | 4022 } |
| 4038 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { | 4023 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { |
| 4039 AbstractType& res_type = AbstractType::Handle(result_type()); | 4024 AbstractType& res_type = AbstractType::Handle(result_type()); |
| 4040 if (!res_type.IsInstantiated()) { | 4025 if (!res_type.IsInstantiated()) { |
| 4041 res_type = res_type.InstantiateFrom(type_arguments); | 4026 res_type = res_type.InstantiateFrom(type_arguments, malformed_error); |
| 4027 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); |
| 4042 } | 4028 } |
| 4043 if (res_type.IsVoidType()) { | 4029 if (res_type.IsVoidType()) { |
| 4044 return false; | 4030 return false; |
| 4045 } | 4031 } |
| 4046 if (test_kind == kIsSubtypeOf) { | 4032 if (test_kind == kIsSubtypeOf) { |
| 4047 if (!res_type.IsSubtypeOf(other_res_type, malformed_error) && | 4033 if (!res_type.IsSubtypeOf(other_res_type, malformed_error) && |
| 4048 !other_res_type.IsSubtypeOf(res_type, malformed_error)) { | 4034 !other_res_type.IsSubtypeOf(res_type, malformed_error)) { |
| 4049 return false; | 4035 return false; |
| 4050 } | 4036 } |
| 4051 } else { | 4037 } else { |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4343 pieces.Add(Symbols::LParen()); | 4329 pieces.Add(Symbols::LParen()); |
| 4344 intptr_t i = 0; | 4330 intptr_t i = 0; |
| 4345 if (name_visibility == kUserVisibleName) { | 4331 if (name_visibility == kUserVisibleName) { |
| 4346 // Hide implicit parameters. | 4332 // Hide implicit parameters. |
| 4347 i = NumImplicitParameters(); | 4333 i = NumImplicitParameters(); |
| 4348 } | 4334 } |
| 4349 while (i < num_fixed_params) { | 4335 while (i < num_fixed_params) { |
| 4350 param_type = ParameterTypeAt(i); | 4336 param_type = ParameterTypeAt(i); |
| 4351 ASSERT(!param_type.IsNull()); | 4337 ASSERT(!param_type.IsNull()); |
| 4352 if (instantiate && !param_type.IsInstantiated()) { | 4338 if (instantiate && !param_type.IsInstantiated()) { |
| 4353 param_type = param_type.InstantiateFrom(instantiator); | 4339 param_type = param_type.InstantiateFrom(instantiator, NULL); |
| 4354 } | 4340 } |
| 4355 name = param_type.BuildName(name_visibility); | 4341 name = param_type.BuildName(name_visibility); |
| 4356 pieces.Add(name); | 4342 pieces.Add(name); |
| 4357 if (i != (num_params - 1)) { | 4343 if (i != (num_params - 1)) { |
| 4358 pieces.Add(Symbols::CommaSpace()); | 4344 pieces.Add(Symbols::CommaSpace()); |
| 4359 } | 4345 } |
| 4360 i++; | 4346 i++; |
| 4361 } | 4347 } |
| 4362 if (num_opt_params > 0) { | 4348 if (num_opt_params > 0) { |
| 4363 if (num_opt_pos_params > 0) { | 4349 if (num_opt_pos_params > 0) { |
| 4364 pieces.Add(Symbols::LBracket()); | 4350 pieces.Add(Symbols::LBracket()); |
| 4365 } else { | 4351 } else { |
| 4366 pieces.Add(Symbols::LBrace()); | 4352 pieces.Add(Symbols::LBrace()); |
| 4367 } | 4353 } |
| 4368 for (intptr_t i = num_fixed_params; i < num_params; i++) { | 4354 for (intptr_t i = num_fixed_params; i < num_params; i++) { |
| 4369 // The parameter name of an optional positional parameter does not need | 4355 // The parameter name of an optional positional parameter does not need |
| 4370 // to be part of the signature, since it is not used. | 4356 // to be part of the signature, since it is not used. |
| 4371 if (num_opt_named_params > 0) { | 4357 if (num_opt_named_params > 0) { |
| 4372 name = ParameterNameAt(i); | 4358 name = ParameterNameAt(i); |
| 4373 pieces.Add(name); | 4359 pieces.Add(name); |
| 4374 pieces.Add(Symbols::ColonSpace()); | 4360 pieces.Add(Symbols::ColonSpace()); |
| 4375 } | 4361 } |
| 4376 param_type = ParameterTypeAt(i); | 4362 param_type = ParameterTypeAt(i); |
| 4377 if (instantiate && !param_type.IsInstantiated()) { | 4363 if (instantiate && !param_type.IsInstantiated()) { |
| 4378 param_type = param_type.InstantiateFrom(instantiator); | 4364 param_type = param_type.InstantiateFrom(instantiator, NULL); |
| 4379 } | 4365 } |
| 4380 ASSERT(!param_type.IsNull()); | 4366 ASSERT(!param_type.IsNull()); |
| 4381 name = param_type.BuildName(name_visibility); | 4367 name = param_type.BuildName(name_visibility); |
| 4382 pieces.Add(name); | 4368 pieces.Add(name); |
| 4383 if (i != (num_params - 1)) { | 4369 if (i != (num_params - 1)) { |
| 4384 pieces.Add(Symbols::CommaSpace()); | 4370 pieces.Add(Symbols::CommaSpace()); |
| 4385 } | 4371 } |
| 4386 } | 4372 } |
| 4387 if (num_opt_pos_params > 0) { | 4373 if (num_opt_pos_params > 0) { |
| 4388 pieces.Add(Symbols::RBracket()); | 4374 pieces.Add(Symbols::RBracket()); |
| 4389 } else { | 4375 } else { |
| 4390 pieces.Add(Symbols::RBrace()); | 4376 pieces.Add(Symbols::RBrace()); |
| 4391 } | 4377 } |
| 4392 } | 4378 } |
| 4393 pieces.Add(Symbols::RParenArrow()); | 4379 pieces.Add(Symbols::RParenArrow()); |
| 4394 AbstractType& res_type = AbstractType::Handle(result_type()); | 4380 AbstractType& res_type = AbstractType::Handle(result_type()); |
| 4395 if (instantiate && !res_type.IsInstantiated()) { | 4381 if (instantiate && !res_type.IsInstantiated()) { |
| 4396 res_type = res_type.InstantiateFrom(instantiator); | 4382 res_type = res_type.InstantiateFrom(instantiator, NULL); |
| 4397 } | 4383 } |
| 4398 name = res_type.BuildName(name_visibility); | 4384 name = res_type.BuildName(name_visibility); |
| 4399 pieces.Add(name); | 4385 pieces.Add(name); |
| 4400 const Array& strings = Array::Handle(Array::MakeArray(pieces)); | 4386 const Array& strings = Array::Handle(Array::MakeArray(pieces)); |
| 4401 return Symbols::New(String::Handle(String::ConcatAll(strings))); | 4387 return Symbols::New(String::Handle(String::ConcatAll(strings))); |
| 4402 } | 4388 } |
| 4403 | 4389 |
| 4404 | 4390 |
| 4405 bool Function::HasInstantiatedSignature() const { | 4391 bool Function::HasInstantiatedSignature() const { |
| 4406 AbstractType& type = AbstractType::Handle(result_type()); | 4392 AbstractType& type = AbstractType::Handle(result_type()); |
| (...skipping 4395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8802 const intptr_t num_type_arguments = cls.NumTypeArguments(); | 8788 const intptr_t num_type_arguments = cls.NumTypeArguments(); |
| 8803 if (num_type_arguments > 0) { | 8789 if (num_type_arguments > 0) { |
| 8804 type_arguments = GetTypeArguments(); | 8790 type_arguments = GetTypeArguments(); |
| 8805 if (!type_arguments.IsNull() && !type_arguments.IsCanonical()) { | 8791 if (!type_arguments.IsNull() && !type_arguments.IsCanonical()) { |
| 8806 type_arguments = type_arguments.Canonicalize(); | 8792 type_arguments = type_arguments.Canonicalize(); |
| 8807 SetTypeArguments(type_arguments); | 8793 SetTypeArguments(type_arguments); |
| 8808 } | 8794 } |
| 8809 // Verify that the number of type arguments in the instance matches the | 8795 // Verify that the number of type arguments in the instance matches the |
| 8810 // number of type arguments expected by the instance class. | 8796 // number of type arguments expected by the instance class. |
| 8811 // A discrepancy is allowed for closures, which borrow the type argument | 8797 // A discrepancy is allowed for closures, which borrow the type argument |
| 8812 // vector of their instantiator, which may be of a super class of the class | 8798 // vector of their instantiator, which may be of a subclass of the class |
| 8813 // defining the closure. Truncating the vector to the correct length on | 8799 // defining the closure. Truncating the vector to the correct length on |
| 8814 // instantiation is unnecessary. The vector may therefore be longer. | 8800 // instantiation is unnecessary. The vector may therefore be longer. |
| 8815 ASSERT(type_arguments.IsNull() || | 8801 ASSERT(type_arguments.IsNull() || |
| 8816 (type_arguments.Length() == num_type_arguments) || | 8802 (type_arguments.Length() == num_type_arguments) || |
| 8817 (cls.IsSignatureClass() && | 8803 (cls.IsSignatureClass() && |
| 8818 (type_arguments.Length() > num_type_arguments))); | 8804 (type_arguments.Length() > num_type_arguments))); |
| 8819 } | 8805 } |
| 8820 Class& other_class = Class::Handle(); | 8806 Class& other_class = Class::Handle(); |
| 8821 AbstractTypeArguments& other_type_arguments = AbstractTypeArguments::Handle(); | 8807 AbstractTypeArguments& other_type_arguments = AbstractTypeArguments::Handle(); |
| 8822 // In case 'other' is not instantiated, we could simply call | 8808 // Note that we may encounter a bound error in checked mode. |
| 8823 // other.InstantiateFrom(other_instantiator), however, we can save the | 8809 if (!other.IsInstantiated()) { |
| 8824 // allocation of a new AbstractType by inlining the code. | 8810 const AbstractType& instantiated_other = AbstractType::Handle( |
| 8825 if (other.IsTypeParameter()) { | 8811 other.InstantiateFrom(other_instantiator, malformed_error)); |
| 8826 if (other_instantiator.IsNull()) { | 8812 if ((malformed_error != NULL) && !malformed_error->IsNull()) { |
| 8827 // An uninstantiated type parameter is equivalent to dynamic. | 8813 ASSERT(FLAG_enable_type_checks); |
| 8828 return true; | 8814 return false; |
| 8829 } | |
| 8830 const TypeParameter& other_type_param = TypeParameter::Cast(other); | |
| 8831 AbstractType& instantiated_other = AbstractType::Handle( | |
| 8832 other_instantiator.TypeAt(other_type_param.index())); | |
| 8833 if (instantiated_other.IsDynamicType() || | |
| 8834 instantiated_other.IsTypeParameter()) { | |
| 8835 return true; | |
| 8836 } | 8815 } |
| 8837 other_class = instantiated_other.type_class(); | 8816 other_class = instantiated_other.type_class(); |
| 8838 other_type_arguments = instantiated_other.arguments(); | 8817 other_type_arguments = instantiated_other.arguments(); |
| 8839 } else { | 8818 } else { |
| 8840 other_class = other.type_class(); | 8819 other_class = other.type_class(); |
| 8841 other_type_arguments = other.arguments(); | 8820 other_type_arguments = other.arguments(); |
| 8842 if (!other_type_arguments.IsNull() && | |
| 8843 !other_type_arguments.IsInstantiated()) { | |
| 8844 other_type_arguments = | |
| 8845 other_type_arguments.InstantiateFrom(other_instantiator); | |
| 8846 } | |
| 8847 } | 8821 } |
| 8848 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, | 8822 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, |
| 8849 malformed_error); | 8823 malformed_error); |
| 8850 } | 8824 } |
| 8851 | 8825 |
| 8852 | 8826 |
| 8853 void Instance::SetNativeField(int index, intptr_t value) const { | 8827 void Instance::SetNativeField(int index, intptr_t value) const { |
| 8854 ASSERT(IsValidNativeIndex(index)); | 8828 ASSERT(IsValidNativeIndex(index)); |
| 8855 Object& native_fields = Object::Handle(*NativeFieldsAddr()); | 8829 Object& native_fields = Object::Handle(*NativeFieldsAddr()); |
| 8856 if (native_fields.IsNull()) { | 8830 if (native_fields.IsNull()) { |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9030 | 9004 |
| 9031 | 9005 |
| 9032 void AbstractType::set_malformed_error(const Error& value) const { | 9006 void AbstractType::set_malformed_error(const Error& value) const { |
| 9033 // AbstractType is an abstract class. | 9007 // AbstractType is an abstract class. |
| 9034 UNREACHABLE(); | 9008 UNREACHABLE(); |
| 9035 } | 9009 } |
| 9036 | 9010 |
| 9037 | 9011 |
| 9038 bool AbstractType::Equals(const Instance& other) const { | 9012 bool AbstractType::Equals(const Instance& other) const { |
| 9039 // AbstractType is an abstract class. | 9013 // AbstractType is an abstract class. |
| 9040 UNREACHABLE(); | 9014 ASSERT(raw() == AbstractType::null()); |
| 9041 return false; | 9015 return other.IsNull(); |
| 9042 } | 9016 } |
| 9043 | 9017 |
| 9044 | 9018 |
| 9045 RawAbstractType* AbstractType::InstantiateFrom( | 9019 RawAbstractType* AbstractType::InstantiateFrom( |
| 9046 const AbstractTypeArguments& instantiator_type_arguments) const { | 9020 const AbstractTypeArguments& instantiator_type_arguments, |
| 9021 Error* malformed_error) const { |
| 9047 // AbstractType is an abstract class. | 9022 // AbstractType is an abstract class. |
| 9048 UNREACHABLE(); | 9023 UNREACHABLE(); |
| 9049 return NULL; | 9024 return NULL; |
| 9050 } | 9025 } |
| 9051 | 9026 |
| 9052 | 9027 |
| 9053 RawAbstractType* AbstractType::Canonicalize() const { | 9028 RawAbstractType* AbstractType::Canonicalize() const { |
| 9054 // AbstractType is an abstract class. | 9029 // AbstractType is an abstract class. |
| 9055 UNREACHABLE(); | 9030 UNREACHABLE(); |
| 9056 return NULL; | 9031 return NULL; |
| 9057 } | 9032 } |
| 9058 | 9033 |
| 9059 | 9034 |
| 9060 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 9035 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
| 9036 if (IsBoundedType()) { |
| 9037 // TODO(regis): Should the bound be visible in the name for debug purposes |
| 9038 // if name_visibility is kInternalName? |
| 9039 const AbstractType& type = AbstractType::Handle( |
| 9040 BoundedType::Cast(*this).type()); |
| 9041 return type.BuildName(name_visibility); |
| 9042 } |
| 9061 if (IsTypeParameter()) { | 9043 if (IsTypeParameter()) { |
| 9062 return TypeParameter::Cast(*this).name(); | 9044 return TypeParameter::Cast(*this).name(); |
| 9063 } | 9045 } |
| 9064 // If the type is still being finalized, we may be reporting an error about | 9046 // If the type is still being finalized, we may be reporting an error about |
| 9065 // a malformed type, so proceed with caution. | 9047 // a malformed type, so proceed with caution. |
| 9066 const AbstractTypeArguments& args = | 9048 const AbstractTypeArguments& args = |
| 9067 AbstractTypeArguments::Handle(arguments()); | 9049 AbstractTypeArguments::Handle(arguments()); |
| 9068 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); | 9050 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); |
| 9069 String& class_name = String::Handle(); | 9051 String& class_name = String::Handle(); |
| 9070 intptr_t first_type_param_index; | 9052 intptr_t first_type_param_index; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9189 // and/or malformed parameter types, which will then be encountered here at | 9171 // and/or malformed parameter types, which will then be encountered here at |
| 9190 // run time. | 9172 // run time. |
| 9191 if (IsMalformed()) { | 9173 if (IsMalformed()) { |
| 9192 ASSERT(FLAG_enable_type_checks); | 9174 ASSERT(FLAG_enable_type_checks); |
| 9193 if ((malformed_error != NULL) && malformed_error->IsNull()) { | 9175 if ((malformed_error != NULL) && malformed_error->IsNull()) { |
| 9194 *malformed_error = this->malformed_error(); | 9176 *malformed_error = this->malformed_error(); |
| 9195 } | 9177 } |
| 9196 return false; | 9178 return false; |
| 9197 } | 9179 } |
| 9198 if (other.IsMalformed()) { | 9180 if (other.IsMalformed()) { |
| 9199 ASSERT(FLAG_enable_type_checks); | 9181 // Note that 'other' may represent an unresolved bound that is checked at |
| 9182 // compile time, even in production mode, in which case the resulting |
| 9183 // BoundedType is ignored at run time if in production mode. |
| 9184 // Therefore, we cannot assert that we are in checked mode here. |
| 9200 if ((malformed_error != NULL) && malformed_error->IsNull()) { | 9185 if ((malformed_error != NULL) && malformed_error->IsNull()) { |
| 9201 *malformed_error = other.malformed_error(); | 9186 *malformed_error = other.malformed_error(); |
| 9202 } | 9187 } |
| 9203 return false; | 9188 return false; |
| 9204 } | 9189 } |
| 9205 // AbstractType parameters cannot be handled by Class::TypeTest(). | 9190 if (IsBoundedType() || other.IsBoundedType()) { |
| 9191 if (Equals(other)) { |
| 9192 return true; |
| 9193 } |
| 9194 return false; // TODO(regis): We should return "maybe after instantiation". |
| 9195 } |
| 9196 // Type parameters cannot be handled by Class::TypeTest(). |
| 9206 // When comparing two uninstantiated function types, one returning type | 9197 // When comparing two uninstantiated function types, one returning type |
| 9207 // parameter K, the other returning type parameter V, we cannot assume that K | 9198 // parameter K, the other returning type parameter V, we cannot assume that K |
| 9208 // is a subtype of V, or vice versa. We only return true if K == V, i.e. if | 9199 // is a subtype of V, or vice versa. We only return true if K equals V, as |
| 9209 // they have the same index (both are finalized, so their indices are | 9200 // defined by TypeParameter::Equals. |
| 9210 // comparable). | 9201 // The same rule applies when checking the upper bound of a still |
| 9211 // The same rule applies When checking the upper bound of a still | |
| 9212 // uninstantiated type at compile time. Returning false will defer the test | 9202 // uninstantiated type at compile time. Returning false will defer the test |
| 9213 // to run time. But there are cases where it can be decided at compile time. | 9203 // to run time. |
| 9204 // We may think that some cases can be decided at compile time. |
| 9214 // For example, with class A<K, V extends K>, new A<T, T> called from within | 9205 // For example, with class A<K, V extends K>, new A<T, T> called from within |
| 9215 // a class B<T> will never require a run time bounds check, even it T is | 9206 // a class B<T> will never require a run time bound check, even if T is |
| 9216 // uninstantiated at compile time. | 9207 // uninstantiated at compile time. |
| 9208 // However, this is not true, because bounds are ignored in production mode, |
| 9209 // and even if we are running in checked mode, we may generate a snapshot |
| 9210 // that will be executed in production mode. |
| 9217 if (IsTypeParameter()) { | 9211 if (IsTypeParameter()) { |
| 9218 const TypeParameter& type_param = TypeParameter::Cast(*this); | 9212 const TypeParameter& type_param = TypeParameter::Cast(*this); |
| 9219 if (other.IsTypeParameter()) { | 9213 if (other.IsTypeParameter()) { |
| 9220 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 9214 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
| 9221 return type_param.index() == other_type_param.index(); | 9215 if (type_param.Equals(other_type_param)) { |
| 9222 } else if (FLAG_enable_type_checks) { | |
| 9223 // In checked mode, if the upper bound of this type is more specific than | |
| 9224 // the other type, then this type is more specific than the other type. | |
| 9225 const AbstractType& type_param_bound = | |
| 9226 AbstractType::Handle(type_param.bound()); | |
| 9227 if (type_param_bound.IsMoreSpecificThan(other, malformed_error)) { | |
| 9228 return true; | 9216 return true; |
| 9229 } | 9217 } |
| 9230 } | 9218 } |
| 9231 return false; | 9219 return false; // TODO(regis): We should return "maybe after instantiation". |
| 9232 } | 9220 } |
| 9233 if (other.IsTypeParameter()) { | 9221 if (other.IsTypeParameter()) { |
| 9234 return false; | 9222 return false; // TODO(regis): We should return "maybe after instantiation". |
| 9235 } | 9223 } |
| 9236 const Class& cls = Class::Handle(type_class()); | 9224 const Class& cls = Class::Handle(type_class()); |
| 9237 return cls.TypeTest(test_kind, | 9225 return cls.TypeTest(test_kind, |
| 9238 AbstractTypeArguments::Handle(arguments()), | 9226 AbstractTypeArguments::Handle(arguments()), |
| 9239 Class::Handle(other.type_class()), | 9227 Class::Handle(other.type_class()), |
| 9240 AbstractTypeArguments::Handle(other.arguments()), | 9228 AbstractTypeArguments::Handle(other.arguments()), |
| 9241 malformed_error); | 9229 malformed_error); |
| 9242 } | 9230 } |
| 9243 | 9231 |
| 9244 | 9232 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9435 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { | 9423 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { |
| 9436 return false; | 9424 return false; |
| 9437 } | 9425 } |
| 9438 const AbstractTypeArguments& args = | 9426 const AbstractTypeArguments& args = |
| 9439 AbstractTypeArguments::Handle(arguments()); | 9427 AbstractTypeArguments::Handle(arguments()); |
| 9440 return args.IsNull() || args.IsInstantiated(); | 9428 return args.IsNull() || args.IsInstantiated(); |
| 9441 } | 9429 } |
| 9442 | 9430 |
| 9443 | 9431 |
| 9444 RawAbstractType* Type::InstantiateFrom( | 9432 RawAbstractType* Type::InstantiateFrom( |
| 9445 const AbstractTypeArguments& instantiator_type_arguments) const { | 9433 const AbstractTypeArguments& instantiator_type_arguments, |
| 9434 Error* malformed_error) const { |
| 9446 ASSERT(IsFinalized()); | 9435 ASSERT(IsFinalized()); |
| 9447 ASSERT(!IsInstantiated()); | 9436 ASSERT(!IsInstantiated()); |
| 9437 // Return the uninstantiated type unchanged if malformed. No copy needed. |
| 9438 if (IsMalformed()) { |
| 9439 return raw(); |
| 9440 } |
| 9448 AbstractTypeArguments& type_arguments = | 9441 AbstractTypeArguments& type_arguments = |
| 9449 AbstractTypeArguments::Handle(arguments()); | 9442 AbstractTypeArguments::Handle(arguments()); |
| 9450 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments); | 9443 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
| 9444 malformed_error); |
| 9451 const Class& cls = Class::Handle(type_class()); | 9445 const Class& cls = Class::Handle(type_class()); |
| 9452 ASSERT(cls.is_finalized()); | 9446 ASSERT(cls.is_finalized()); |
| 9447 // This uninstantiated type is not modified, as it can be instantiated |
| 9448 // with different instantiators. |
| 9453 Type& instantiated_type = Type::Handle( | 9449 Type& instantiated_type = Type::Handle( |
| 9454 Type::New(cls, type_arguments, token_pos())); | 9450 Type::New(cls, type_arguments, token_pos())); |
| 9455 ASSERT(type_arguments.IsNull() || | 9451 ASSERT(type_arguments.IsNull() || |
| 9456 (type_arguments.Length() == cls.NumTypeArguments())); | 9452 (type_arguments.Length() == cls.NumTypeArguments())); |
| 9457 instantiated_type.SetIsFinalized(); | 9453 instantiated_type.SetIsFinalized(); |
| 9458 return instantiated_type.raw(); | 9454 return instantiated_type.raw(); |
| 9459 } | 9455 } |
| 9460 | 9456 |
| 9461 | 9457 |
| 9462 bool Type::Equals(const Instance& other) const { | 9458 bool Type::Equals(const Instance& other) const { |
| 9463 if (raw() == other.raw()) { | 9459 if (raw() == other.raw()) { |
| 9464 return true; | 9460 return true; |
| 9465 } | 9461 } |
| 9466 if (!other.IsType()) { | 9462 if (!other.IsType()) { |
| 9467 return false; | 9463 return false; |
| 9468 } | 9464 } |
| 9469 const AbstractType& other_type = AbstractType::Cast(other); | 9465 const Type& other_type = Type::Cast(other); |
| 9470 ASSERT(IsFinalized() && other_type.IsFinalized()); | 9466 ASSERT(IsFinalized() && other_type.IsFinalized()); |
| 9471 if (IsMalformed() || other_type.IsMalformed()) { | 9467 if (IsMalformed() || other_type.IsMalformed()) { |
| 9472 return false; | 9468 return false; |
| 9473 } | 9469 } |
| 9474 if (type_class() != other_type.type_class()) { | 9470 if (type_class() != other_type.type_class()) { |
| 9475 return false; | 9471 return false; |
| 9476 } | 9472 } |
| 9477 return AbstractTypeArguments::AreEqual( | 9473 return AbstractTypeArguments::AreEqual( |
| 9478 AbstractTypeArguments::Handle(arguments()), | 9474 AbstractTypeArguments::Handle(arguments()), |
| 9479 AbstractTypeArguments::Handle(other_type.arguments())); | 9475 AbstractTypeArguments::Handle(other_type.arguments())); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9625 } | 9621 } |
| 9626 | 9622 |
| 9627 | 9623 |
| 9628 void TypeParameter::set_is_finalized() const { | 9624 void TypeParameter::set_is_finalized() const { |
| 9629 ASSERT(!IsFinalized()); | 9625 ASSERT(!IsFinalized()); |
| 9630 set_type_state(RawTypeParameter::kFinalizedUninstantiated); | 9626 set_type_state(RawTypeParameter::kFinalizedUninstantiated); |
| 9631 } | 9627 } |
| 9632 | 9628 |
| 9633 | 9629 |
| 9634 bool TypeParameter::Equals(const Instance& other) const { | 9630 bool TypeParameter::Equals(const Instance& other) const { |
| 9631 ASSERT(IsFinalized()); |
| 9635 if (raw() == other.raw()) { | 9632 if (raw() == other.raw()) { |
| 9636 return true; | 9633 return true; |
| 9637 } | 9634 } |
| 9638 if (!other.IsTypeParameter()) { | 9635 if (!other.IsTypeParameter()) { |
| 9639 return false; | 9636 return false; |
| 9640 } | 9637 } |
| 9641 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 9638 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
| 9642 if (IsFinalized() != other_type_param.IsFinalized()) { | 9639 ASSERT(other_type_param.IsFinalized()); |
| 9643 return false; | |
| 9644 } | |
| 9645 if (parameterized_class() != other_type_param.parameterized_class()) { | 9640 if (parameterized_class() != other_type_param.parameterized_class()) { |
| 9646 return false; | 9641 return false; |
| 9647 } | 9642 } |
| 9648 if (index() != other_type_param.index()) { | 9643 if (index() != other_type_param.index()) { |
| 9649 return false; | 9644 return false; |
| 9650 } | 9645 } |
| 9651 return true; | 9646 return true; |
| 9652 } | 9647 } |
| 9653 | 9648 |
| 9654 | 9649 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 9667 void TypeParameter::set_name(const String& value) const { | 9662 void TypeParameter::set_name(const String& value) const { |
| 9668 ASSERT(value.IsSymbol()); | 9663 ASSERT(value.IsSymbol()); |
| 9669 StorePointer(&raw_ptr()->name_, value.raw()); | 9664 StorePointer(&raw_ptr()->name_, value.raw()); |
| 9670 } | 9665 } |
| 9671 | 9666 |
| 9672 | 9667 |
| 9673 void TypeParameter::set_bound(const AbstractType& value) const { | 9668 void TypeParameter::set_bound(const AbstractType& value) const { |
| 9674 StorePointer(&raw_ptr()->bound_, value.raw()); | 9669 StorePointer(&raw_ptr()->bound_, value.raw()); |
| 9675 } | 9670 } |
| 9676 | 9671 |
| 9672 |
| 9677 RawAbstractType* TypeParameter::InstantiateFrom( | 9673 RawAbstractType* TypeParameter::InstantiateFrom( |
| 9678 const AbstractTypeArguments& instantiator_type_arguments) const { | 9674 const AbstractTypeArguments& instantiator_type_arguments, |
| 9675 Error* malformed_error) const { |
| 9679 ASSERT(IsFinalized()); | 9676 ASSERT(IsFinalized()); |
| 9680 if (instantiator_type_arguments.IsNull()) { | 9677 if (instantiator_type_arguments.IsNull()) { |
| 9681 return Type::DynamicType(); | 9678 return Type::DynamicType(); |
| 9682 } | 9679 } |
| 9680 // Bound checks should never appear in the instantiator type arguments. |
| 9681 ASSERT(!AbstractType::Handle( |
| 9682 instantiator_type_arguments.TypeAt(index())).IsBoundedType()); |
| 9683 return instantiator_type_arguments.TypeAt(index()); | 9683 return instantiator_type_arguments.TypeAt(index()); |
| 9684 } | 9684 } |
| 9685 | 9685 |
| 9686 | 9686 |
| 9687 void TypeParameter::CheckBound(const AbstractType& bounded_type, |
| 9688 const AbstractType& upper_bound, |
| 9689 Error* malformed_error) const { |
| 9690 ASSERT(malformed_error->IsNull()); |
| 9691 ASSERT(bounded_type.IsFinalized()); |
| 9692 ASSERT(upper_bound.IsFinalized()); |
| 9693 ASSERT(!bounded_type.IsMalformed()); |
| 9694 if (bounded_type.IsSubtypeOf(upper_bound, malformed_error) || |
| 9695 !malformed_error->IsNull()) { |
| 9696 return; |
| 9697 } |
| 9698 // Report the bound error. |
| 9699 const String& bounded_type_name = String::Handle( |
| 9700 bounded_type.UserVisibleName()); |
| 9701 const String& upper_bound_name = String::Handle( |
| 9702 upper_bound.UserVisibleName()); |
| 9703 const AbstractType& declared_bound = AbstractType::Handle(bound()); |
| 9704 const String& declared_bound_name = String::Handle( |
| 9705 declared_bound.UserVisibleName()); |
| 9706 const String& type_param_name = String::Handle(UserVisibleName()); |
| 9707 const Class& cls = Class::Handle(parameterized_class()); |
| 9708 const String& class_name = String::Handle(cls.Name()); |
| 9709 const Script& script = Script::Handle(cls.script()); |
| 9710 // Since the bound may have been canonicalized, its token index is |
| 9711 // meaningless, therefore use the token index of this type parameter. |
| 9712 *malformed_error = FormatError( |
| 9713 *malformed_error, |
| 9714 script, |
| 9715 token_pos(), |
| 9716 "type parameter '%s' of class '%s' must extend bound '%s', " |
| 9717 "but type argument '%s' is not a subtype of '%s'\n", |
| 9718 type_param_name.ToCString(), |
| 9719 class_name.ToCString(), |
| 9720 declared_bound_name.ToCString(), |
| 9721 bounded_type_name.ToCString(), |
| 9722 upper_bound_name.ToCString()); |
| 9723 } |
| 9724 |
| 9725 |
| 9687 intptr_t TypeParameter::Hash() const { | 9726 intptr_t TypeParameter::Hash() const { |
| 9688 ASSERT(IsFinalized()); | 9727 ASSERT(IsFinalized()); |
| 9689 uword result = 0; | 9728 uword result = 0; |
| 9690 result += Class::Handle(parameterized_class()).id(); | 9729 result += Class::Handle(parameterized_class()).id(); |
| 9730 // Do not include the hash of the bound, which could lead to cycles. |
| 9691 result <<= index(); | 9731 result <<= index(); |
| 9692 return FinalizeHash(result); | 9732 return FinalizeHash(result); |
| 9693 } | 9733 } |
| 9694 | 9734 |
| 9695 | 9735 |
| 9696 RawTypeParameter* TypeParameter::New() { | 9736 RawTypeParameter* TypeParameter::New() { |
| 9697 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != | 9737 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != |
| 9698 Class::null()); | 9738 Class::null()); |
| 9699 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 9739 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
| 9700 TypeParameter::InstanceSize(), | 9740 TypeParameter::InstanceSize(), |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9739 const Class& cls = Class::Handle(parameterized_class()); | 9779 const Class& cls = Class::Handle(parameterized_class()); |
| 9740 const char* cls_cstr = | 9780 const char* cls_cstr = |
| 9741 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); | 9781 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); |
| 9742 intptr_t len = OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr) + 1; | 9782 intptr_t len = OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr) + 1; |
| 9743 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 9783 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 9744 OS::SNPrint(chars, len, format, name_cstr, index(), cls_cstr); | 9784 OS::SNPrint(chars, len, format, name_cstr, index(), cls_cstr); |
| 9745 return chars; | 9785 return chars; |
| 9746 } | 9786 } |
| 9747 | 9787 |
| 9748 | 9788 |
| 9789 bool BoundedType::IsMalformed() const { |
| 9790 return FLAG_enable_type_checks && AbstractType::Handle(bound()).IsMalformed(); |
| 9791 } |
| 9792 |
| 9793 |
| 9794 RawError* BoundedType::malformed_error() const { |
| 9795 ASSERT(FLAG_enable_type_checks); |
| 9796 return AbstractType::Handle(bound()).malformed_error(); |
| 9797 } |
| 9798 |
| 9799 |
| 9800 bool BoundedType::Equals(const Instance& other) const { |
| 9801 // BoundedType are not canonicalized, because their bound may get finalized |
| 9802 // after the BoundedType is created and initialized. |
| 9803 if (raw() == other.raw()) { |
| 9804 return true; |
| 9805 } |
| 9806 if (!other.IsBoundedType()) { |
| 9807 return false; |
| 9808 } |
| 9809 const BoundedType& other_bounded = BoundedType::Cast(other); |
| 9810 if (type_parameter() != other_bounded.type_parameter()) { |
| 9811 // Not a structural compare. |
| 9812 // Note that a deep comparison of bounds could lead to cycles. |
| 9813 return false; |
| 9814 } |
| 9815 const AbstractType& this_type = AbstractType::Handle(type()); |
| 9816 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); |
| 9817 if (!this_type.Equals(other_type)) { |
| 9818 return false; |
| 9819 } |
| 9820 const AbstractType& this_bound = AbstractType::Handle(bound()); |
| 9821 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); |
| 9822 return this_bound.IsFinalized() && |
| 9823 other_bound.IsFinalized() && |
| 9824 this_bound.Equals(other_bound); |
| 9825 } |
| 9826 |
| 9827 |
| 9828 void BoundedType::set_type(const AbstractType& value) const { |
| 9829 ASSERT(value.IsFinalized()); |
| 9830 ASSERT(!value.IsMalformed()); |
| 9831 StorePointer(&raw_ptr()->type_, value.raw()); |
| 9832 } |
| 9833 |
| 9834 |
| 9835 void BoundedType::set_bound(const AbstractType& value) const { |
| 9836 // The bound may still be unfinalized because of legal cycles. |
| 9837 // It must be finalized before it is checked at run time, though. |
| 9838 StorePointer(&raw_ptr()->bound_, value.raw()); |
| 9839 } |
| 9840 |
| 9841 |
| 9842 void BoundedType::set_type_parameter(const TypeParameter& value) const { |
| 9843 // A null type parameter is set when marking a type malformed because of a |
| 9844 // bound error at compile time. |
| 9845 ASSERT(value.IsNull() || value.IsFinalized()); |
| 9846 StorePointer(&raw_ptr()->type_parameter_, value.raw()); |
| 9847 } |
| 9848 |
| 9849 |
| 9850 void BoundedType::set_is_being_checked(bool value) const { |
| 9851 raw_ptr()->is_being_checked_ = value; |
| 9852 } |
| 9853 |
| 9854 |
| 9855 RawAbstractType* BoundedType::InstantiateFrom( |
| 9856 const AbstractTypeArguments& instantiator_type_arguments, |
| 9857 Error* malformed_error) const { |
| 9858 ASSERT(IsFinalized()); |
| 9859 AbstractType& bounded_type = AbstractType::Handle(type()); |
| 9860 if (!bounded_type.IsInstantiated()) { |
| 9861 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, |
| 9862 malformed_error); |
| 9863 } |
| 9864 if (FLAG_enable_type_checks && |
| 9865 malformed_error->IsNull() && |
| 9866 !is_being_checked()) { |
| 9867 // Avoid endless recursion while checking and instantiating bound. |
| 9868 set_is_being_checked(true); |
| 9869 AbstractType& upper_bound = AbstractType::Handle(bound()); |
| 9870 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); |
| 9871 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
| 9872 if (!upper_bound.IsInstantiated()) { |
| 9873 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, |
| 9874 malformed_error); |
| 9875 } |
| 9876 if (malformed_error->IsNull()) { |
| 9877 type_param.CheckBound(bounded_type, upper_bound, malformed_error); |
| 9878 } |
| 9879 set_is_being_checked(false); |
| 9880 } |
| 9881 return bounded_type.raw(); |
| 9882 } |
| 9883 |
| 9884 |
| 9885 intptr_t BoundedType::Hash() const { |
| 9886 uword result = 0; |
| 9887 result += AbstractType::Handle(type()).Hash(); |
| 9888 // Do not include the hash of the bound, which could lead to cycles. |
| 9889 TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
| 9890 if (!type_param.IsNull()) { |
| 9891 result += type_param.Hash(); |
| 9892 } |
| 9893 return FinalizeHash(result); |
| 9894 } |
| 9895 |
| 9896 |
| 9897 RawBoundedType* BoundedType::New() { |
| 9898 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != |
| 9899 Class::null()); |
| 9900 RawObject* raw = Object::Allocate(BoundedType::kClassId, |
| 9901 BoundedType::InstanceSize(), |
| 9902 Heap::kOld); |
| 9903 return reinterpret_cast<RawBoundedType*>(raw); |
| 9904 } |
| 9905 |
| 9906 |
| 9907 RawBoundedType* BoundedType::New(const AbstractType& type, |
| 9908 const AbstractType& bound, |
| 9909 const TypeParameter& type_parameter) { |
| 9910 const BoundedType& result = BoundedType::Handle(BoundedType::New()); |
| 9911 result.set_type(type); |
| 9912 result.set_bound(bound); |
| 9913 result.set_type_parameter(type_parameter); |
| 9914 result.set_is_being_checked(false); |
| 9915 return result.raw(); |
| 9916 } |
| 9917 |
| 9918 |
| 9919 const char* BoundedType::ToCString() const { |
| 9920 const char* format = "BoundedType: type %s; bound: %s; class: %s"; |
| 9921 const char* type_cstr = String::Handle(AbstractType::Handle( |
| 9922 type()).Name()).ToCString(); |
| 9923 const char* bound_cstr = String::Handle(AbstractType::Handle( |
| 9924 bound()).Name()).ToCString(); |
| 9925 const Class& cls = Class::Handle(TypeParameter::Handle( |
| 9926 type_parameter()).parameterized_class()); |
| 9927 const char* cls_cstr = |
| 9928 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); |
| 9929 intptr_t len = OS::SNPrint( |
| 9930 NULL, 0, format, type_cstr, bound_cstr, cls_cstr) + 1; |
| 9931 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 9932 OS::SNPrint(chars, len, format, type_cstr, bound_cstr, cls_cstr); |
| 9933 return chars; |
| 9934 } |
| 9935 |
| 9936 |
| 9749 const char* Number::ToCString() const { | 9937 const char* Number::ToCString() const { |
| 9750 // Number is an interface. No instances of Number should exist. | 9938 // Number is an interface. No instances of Number should exist. |
| 9751 UNREACHABLE(); | 9939 UNREACHABLE(); |
| 9752 return "Number"; | 9940 return "Number"; |
| 9753 } | 9941 } |
| 9754 | 9942 |
| 9755 | 9943 |
| 9756 const char* Integer::ToCString() const { | 9944 const char* Integer::ToCString() const { |
| 9757 // Integer is an interface. No instances of Integer should exist. | 9945 // Integer is an interface. No instances of Integer should exist. |
| 9758 UNREACHABLE(); | 9946 UNREACHABLE(); |
| (...skipping 3438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13197 } | 13385 } |
| 13198 return result.raw(); | 13386 return result.raw(); |
| 13199 } | 13387 } |
| 13200 | 13388 |
| 13201 | 13389 |
| 13202 const char* WeakProperty::ToCString() const { | 13390 const char* WeakProperty::ToCString() const { |
| 13203 return "_WeakProperty"; | 13391 return "_WeakProperty"; |
| 13204 } | 13392 } |
| 13205 | 13393 |
| 13206 } // namespace dart | 13394 } // namespace dart |
| OLD | NEW |