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 |