Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(432)

Side by Side Diff: runtime/vm/object.cc

Issue 12473002: Complete implementation of bounds checking in the vm, by introducing a vm object (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698