OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 #include "vm/assert.h" | 8 #include "vm/assert.h" |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 if (interface_class.IsMoreSpecificThan(interface_args, | 1278 if (interface_class.IsMoreSpecificThan(interface_args, |
1279 other, | 1279 other, |
1280 other_type_arguments)) { | 1280 other_type_arguments)) { |
1281 return true; | 1281 return true; |
1282 } | 1282 } |
1283 } | 1283 } |
1284 } | 1284 } |
1285 if (IsSignatureClass() && other.IsSignatureClass()) { | 1285 if (IsSignatureClass() && other.IsSignatureClass()) { |
1286 const Function& fun = Function::Handle(signature_function()); | 1286 const Function& fun = Function::Handle(signature_function()); |
1287 const Function& other_fun = Function::Handle(other.signature_function()); | 1287 const Function& other_fun = Function::Handle(other.signature_function()); |
1288 // TODO(regis): We need to consider the type arguments. | 1288 return fun.IsSubtypeOf(type_arguments, |
1289 return fun.IsSubtypeOf(other_fun); | 1289 other_fun, |
| 1290 other_type_arguments); |
1290 } | 1291 } |
| 1292 |
1291 if (is_interface()) { | 1293 if (is_interface()) { |
1292 // We already checked the case where 'other' is an interface. Now, 'this', | 1294 // We already checked the case where 'other' is an interface. Now, 'this', |
1293 // an interface, cannot be more specific than a class, except class Object, | 1295 // an interface, cannot be more specific than a class, except class Object, |
1294 // because although Object is not considered an interface by the vm, it is | 1296 // because although Object is not considered an interface by the vm, it is |
1295 // one. In other words, all classes implementing this interface also extend | 1297 // one. In other words, all classes implementing this interface also extend |
1296 // class Object. An interface is also more specific than the VarType. | 1298 // class Object. An interface is also more specific than the VarType. |
1297 return (other.IsVarClass() || other.IsObjectClass()); | 1299 return (other.IsVarClass() || other.IsObjectClass()); |
1298 } | 1300 } |
1299 const Class& super_class = Class::Handle(SuperClass()); | 1301 const Class& super_class = Class::Handle(SuperClass()); |
1300 if (super_class.IsNull()) { | 1302 if (super_class.IsNull()) { |
(...skipping 11 matching lines...) Expand all Loading... |
1312 bool Class::IsTopLevel() const { | 1314 bool Class::IsTopLevel() const { |
1313 return String::Handle(Name()).Length() == 0; | 1315 return String::Handle(Name()).Length() == 0; |
1314 } | 1316 } |
1315 | 1317 |
1316 | 1318 |
1317 bool Class::TestType(TypeTestKind test, | 1319 bool Class::TestType(TypeTestKind test, |
1318 const TypeArguments& type_arguments, | 1320 const TypeArguments& type_arguments, |
1319 const Class& other, | 1321 const Class& other, |
1320 const TypeArguments& other_type_arguments) const { | 1322 const TypeArguments& other_type_arguments) const { |
1321 if (test == kIsAssignableTo) { | 1323 if (test == kIsAssignableTo) { |
1322 // TODO(regis): We do not follow the guide that says that "a type T is | 1324 // The spec states that "a type T is assignable to a type S if T is a |
1323 // assignable to a type S if T is a subtype of S or S is a subtype of T", | 1325 // subtype of S or S is a subtype of T". This is from the perspective of a |
1324 // since this would lead to heap pollution. We only apply that rule to | 1326 // static checker, which does not know the actual type of the assigned |
1325 // parameter types when checking assignability of function types. | 1327 // value. However, this type information is available at run time in checked |
1326 // Revisit if necessary. | 1328 // mode. We therefore apply a more restrictive subtype check, which prevents |
| 1329 // heap pollution. We only keep the assignability check when assigning |
| 1330 // values of a function type. |
1327 if (IsSignatureClass() && other.IsSignatureClass()) { | 1331 if (IsSignatureClass() && other.IsSignatureClass()) { |
1328 const Function& src_fun = Function::Handle(signature_function()); | 1332 const Function& src_fun = Function::Handle(signature_function()); |
1329 const Function& dst_fun = Function::Handle(other.signature_function()); | 1333 const Function& dst_fun = Function::Handle(other.signature_function()); |
1330 // TODO(regis): We need to consider the type arguments. | 1334 return src_fun.IsAssignableTo(type_arguments, |
1331 return src_fun.IsAssignableTo(dst_fun); | 1335 dst_fun, |
| 1336 other_type_arguments); |
1332 } | 1337 } |
1333 // Continue with a subtype test. | 1338 // Continue with a subtype test. |
1334 test = kIsSubtypeOf; | 1339 test = kIsSubtypeOf; |
1335 } | 1340 } |
1336 ASSERT(test == kIsSubtypeOf); | 1341 ASSERT(test == kIsSubtypeOf); |
1337 | 1342 |
1338 // Check for "more specific" relation. | 1343 // Check for "more specific" relation. |
1339 if (IsMoreSpecificThan(type_arguments, other, other_type_arguments)) { | 1344 if (IsMoreSpecificThan(type_arguments, other, other_type_arguments)) { |
1340 return true; | 1345 return true; |
1341 } | 1346 } |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1773 return HasResolvedTypeClass() && | 1778 return HasResolvedTypeClass() && |
1774 (type_class() == Type::Handle(Type::FunctionInterface()).type_class()); | 1779 (type_class() == Type::Handle(Type::FunctionInterface()).type_class()); |
1775 } | 1780 } |
1776 | 1781 |
1777 | 1782 |
1778 bool Type::IsMoreSpecificThan(const Type& other) const { | 1783 bool Type::IsMoreSpecificThan(const Type& other) const { |
1779 ASSERT(IsFinalized()); | 1784 ASSERT(IsFinalized()); |
1780 ASSERT(other.IsFinalized()); | 1785 ASSERT(other.IsFinalized()); |
1781 // Type parameters cannot be handled by Class::IsMoreSpecificThan(). | 1786 // Type parameters cannot be handled by Class::IsMoreSpecificThan(). |
1782 if (IsTypeParameter() || other.IsTypeParameter()) { | 1787 if (IsTypeParameter() || other.IsTypeParameter()) { |
1783 // TODO(regis): Revisit this temporary workaround. See issue 5474672. | 1788 return IsTypeParameter() && other.IsTypeParameter() && |
1784 return | 1789 (Index() == other.Index()); |
1785 (!IsTypeParameter() && other.IsTypeParameter()) || | |
1786 (IsTypeParameter() && other.IsTypeParameter() && | |
1787 (Index() == other.Index())); | |
1788 } | 1790 } |
1789 const Class& cls = Class::Handle(type_class()); | 1791 const Class& cls = Class::Handle(type_class()); |
1790 return cls.IsMoreSpecificThan(TypeArguments::Handle(arguments()), | 1792 return cls.IsMoreSpecificThan(TypeArguments::Handle(arguments()), |
1791 Class::Handle(other.type_class()), | 1793 Class::Handle(other.type_class()), |
1792 TypeArguments::Handle(other.arguments())); | 1794 TypeArguments::Handle(other.arguments())); |
1793 } | 1795 } |
1794 | 1796 |
1795 | 1797 |
1796 bool Type::Test(TypeTestKind test, const Type& other) const { | 1798 bool Type::Test(TypeTestKind test, const Type& other) const { |
1797 ASSERT(IsFinalized()); | 1799 ASSERT(IsFinalized()); |
1798 ASSERT(other.IsFinalized()); | 1800 ASSERT(other.IsFinalized()); |
1799 // Type parameters cannot be handled by Class::TestType(). | 1801 // Type parameters cannot be handled by Class::TestType(). |
1800 if (IsTypeParameter() || other.IsTypeParameter()) { | 1802 if (IsTypeParameter() || other.IsTypeParameter()) { |
1801 // TODO(regis): Revisit this temporary workaround. See issue 5474672. | 1803 return IsTypeParameter() && other.IsTypeParameter() && |
1802 return | 1804 (Index() == other.Index()); |
1803 (!IsTypeParameter() && other.IsTypeParameter()) || | |
1804 (IsTypeParameter() && other.IsTypeParameter() && | |
1805 (Index() == other.Index())); | |
1806 } | 1805 } |
1807 const Class& cls = Class::Handle(type_class()); | 1806 const Class& cls = Class::Handle(type_class()); |
1808 if (test == kIsSubtypeOf) { | 1807 if (test == kIsSubtypeOf) { |
1809 return cls.IsSubtypeOf(TypeArguments::Handle(arguments()), | 1808 return cls.IsSubtypeOf(TypeArguments::Handle(arguments()), |
1810 Class::Handle(other.type_class()), | 1809 Class::Handle(other.type_class()), |
1811 TypeArguments::Handle(other.arguments())); | 1810 TypeArguments::Handle(other.arguments())); |
1812 } else { | 1811 } else { |
1813 ASSERT(test == kIsAssignableTo); | 1812 ASSERT(test == kIsAssignableTo); |
1814 return cls.IsAssignableTo(TypeArguments::Handle(arguments()), | 1813 return cls.IsAssignableTo(TypeArguments::Handle(arguments()), |
1815 Class::Handle(other.type_class()), | 1814 Class::Handle(other.type_class()), |
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2712 } | 2711 } |
2713 } | 2712 } |
2714 if (!found_param_name) { | 2713 if (!found_param_name) { |
2715 return false; | 2714 return false; |
2716 } | 2715 } |
2717 } | 2716 } |
2718 return true; | 2717 return true; |
2719 } | 2718 } |
2720 | 2719 |
2721 | 2720 |
2722 bool Function::TestType(TypeTestKind test, const Function& other) const { | 2721 bool Function::TestType(TypeTestKind test, |
| 2722 const TypeArguments& type_arguments, |
| 2723 const Function& other, |
| 2724 const TypeArguments& other_type_arguments) const { |
2723 const intptr_t num_fixed_params = num_fixed_parameters(); | 2725 const intptr_t num_fixed_params = num_fixed_parameters(); |
2724 const intptr_t num_opt_params = num_optional_parameters(); | 2726 const intptr_t num_opt_params = num_optional_parameters(); |
2725 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 2727 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |
2726 const intptr_t other_num_opt_params = other.num_optional_parameters(); | 2728 const intptr_t other_num_opt_params = other.num_optional_parameters(); |
2727 if ((num_fixed_params != other_num_fixed_params) || | 2729 if ((num_fixed_params != other_num_fixed_params) || |
2728 ((test == Type::kIsSubtypeOf) && | 2730 ((test == Type::kIsSubtypeOf) && |
2729 (num_opt_params < other_num_opt_params))) { | 2731 (num_opt_params < other_num_opt_params))) { |
2730 return false; | 2732 return false; |
2731 } | 2733 } |
2732 // TODO(regis): We currently ignore type parameters. We need to consider the | |
2733 // parameter type upper bound, if any. | |
2734 // Note that unless we use this code to check function overrides at compile | |
2735 // time, all parameter types should be instantiated and we can remove code | |
2736 // checking for type parameters. | |
2737 | |
2738 // Check the result type. | 2734 // Check the result type. |
2739 const Type& other_res_type = Type::Handle(other.result_type()); | 2735 Type& other_res_type = Type::Handle(other.result_type()); |
2740 if (!other_res_type.IsTypeParameter() && | 2736 if (!other_res_type.IsInstantiated()) { |
2741 !other_res_type.IsVarType() && | 2737 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, 0); |
2742 !other_res_type.IsVoidType()) { | 2738 } |
2743 const Type& res_type = Type::Handle(result_type()); | 2739 if (!other_res_type.IsVarType() && !other_res_type.IsVoidType()) { |
2744 if (!res_type.IsTypeParameter() && | 2740 Type& res_type = Type::Handle(result_type()); |
2745 !res_type.IsVarType() && | 2741 if (!res_type.IsInstantiated()) { |
2746 (res_type.IsVoidType() || !res_type.IsSubtypeOf(other_res_type)) && | 2742 res_type = res_type.InstantiateFrom(type_arguments, 0); |
2747 ((test == Type::kIsSubtypeOf) || | 2743 } |
2748 (!other_res_type.IsSubtypeOf(res_type)))) { | 2744 if (!res_type.IsVarType() && |
| 2745 (res_type.IsVoidType() || !res_type.IsAssignableTo(other_res_type))) { |
2749 return false; | 2746 return false; |
2750 } | 2747 } |
2751 } | 2748 } |
2752 // Check the types of fixed parameters. | 2749 // Check the types of fixed parameters. |
2753 Type& param_type = Type::Handle(); | 2750 Type& param_type = Type::Handle(); |
2754 Type& other_param_type = Type::Handle(); | 2751 Type& other_param_type = Type::Handle(); |
2755 for (intptr_t i = 0; i < num_fixed_params; i++) { | 2752 for (intptr_t i = 0; i < num_fixed_params; i++) { |
2756 param_type = ParameterTypeAt(i); | 2753 param_type = ParameterTypeAt(i); |
2757 if (param_type.IsTypeParameter() || param_type.IsVarType()) { | 2754 if (!param_type.IsInstantiated()) { |
| 2755 param_type = param_type.InstantiateFrom(type_arguments, 0); |
| 2756 } |
| 2757 if (param_type.IsVarType()) { |
2758 continue; | 2758 continue; |
2759 } | 2759 } |
2760 other_param_type = other.ParameterTypeAt(i); | 2760 other_param_type = other.ParameterTypeAt(i); |
2761 if (other_param_type.IsTypeParameter() || other_param_type.IsVarType()) { | 2761 if (!other_param_type.IsInstantiated()) { |
| 2762 other_param_type = |
| 2763 other_param_type.InstantiateFrom(other_type_arguments, 0); |
| 2764 } |
| 2765 if (other_param_type.IsVarType()) { |
2762 continue; | 2766 continue; |
2763 } | 2767 } |
2764 // Subtyping and assignability rules are identical when applied to parameter | 2768 // Subtyping and assignability rules are identical when applied to parameter |
2765 // types. | 2769 // types. |
2766 ASSERT((test == Type::kIsSubtypeOf) || (test == Type::kIsAssignableTo)); | 2770 ASSERT((test == Type::kIsSubtypeOf) || (test == Type::kIsAssignableTo)); |
2767 if (!param_type.IsSubtypeOf(other_param_type) && | 2771 if (!param_type.IsSubtypeOf(other_param_type) && |
2768 !other_param_type.IsSubtypeOf(param_type)) { | 2772 !other_param_type.IsSubtypeOf(param_type)) { |
2769 return false; | 2773 return false; |
2770 } | 2774 } |
2771 } | 2775 } |
2772 // Check the names and types of optional parameters. | 2776 // Check the names and types of optional parameters. |
2773 // First, check that for each optional named parameter of type T of the other | 2777 // First, check that for each optional named parameter of type T of the other |
2774 // function type, there exists an optional named parameter of this function | 2778 // function type, there exists an optional named parameter of this function |
2775 // type with an identical name and with a Type S that is a subtype or | 2779 // type with an identical name and with a Type S that is a subtype or |
2776 // supertype of T. | 2780 // supertype of T. |
2777 // Note that SetParameterNameAt() guarantees that names are symbols, so we can | 2781 // Note that SetParameterNameAt() guarantees that names are symbols, so we can |
2778 // compare their raw pointers. | 2782 // compare their raw pointers. |
2779 const int num_params = num_fixed_params + num_opt_params; | 2783 const int num_params = num_fixed_params + num_opt_params; |
2780 const int other_num_params = other_num_fixed_params + other_num_opt_params; | 2784 const int other_num_params = other_num_fixed_params + other_num_opt_params; |
2781 bool is_subtype = true; | 2785 bool is_subtype = true; |
2782 bool found_param_name; | 2786 bool found_param_name; |
2783 String& other_param_name = String::Handle(); | 2787 String& other_param_name = String::Handle(); |
2784 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { | 2788 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { |
2785 other_param_name = other.ParameterNameAt(i); | 2789 other_param_name = other.ParameterNameAt(i); |
2786 found_param_name = false; | 2790 found_param_name = false; |
2787 for (intptr_t j = num_fixed_params; j < num_params; j++) { | 2791 for (intptr_t j = num_fixed_params; j < num_params; j++) { |
2788 if (ParameterNameAt(j) == other_param_name.raw()) { | 2792 if (ParameterNameAt(j) == other_param_name.raw()) { |
2789 found_param_name = true; | 2793 found_param_name = true; |
2790 param_type = ParameterTypeAt(j); | 2794 param_type = ParameterTypeAt(j); |
2791 if (param_type.IsTypeParameter() || param_type.IsVarType()) { | 2795 if (!param_type.IsInstantiated()) { |
| 2796 param_type = param_type.InstantiateFrom(type_arguments, 0); |
| 2797 } |
| 2798 if (param_type.IsVarType()) { |
2792 break; | 2799 break; |
2793 } | 2800 } |
2794 other_param_type = other.ParameterTypeAt(i); | 2801 other_param_type = other.ParameterTypeAt(i); |
2795 if (other_param_type.IsTypeParameter() || | 2802 if (!other_param_type.IsInstantiated()) { |
2796 other_param_type.IsVarType()) { | 2803 other_param_type = |
| 2804 other_param_type.InstantiateFrom(other_type_arguments, 0); |
| 2805 } |
| 2806 if (other_param_type.IsVarType()) { |
2797 break; | 2807 break; |
2798 } | 2808 } |
2799 if (!param_type.IsSubtypeOf(other_param_type) && | 2809 if (!param_type.IsSubtypeOf(other_param_type) && |
2800 !other_param_type.IsSubtypeOf(param_type)) { | 2810 !other_param_type.IsSubtypeOf(param_type)) { |
2801 is_subtype = false; | 2811 is_subtype = false; |
2802 } | 2812 } |
2803 break; | 2813 break; |
2804 } | 2814 } |
2805 } | 2815 } |
2806 if (!found_param_name) { | 2816 if (!found_param_name) { |
(...skipping 16 matching lines...) Expand all Loading... |
2823 ASSERT(test == Type::kIsAssignableTo); | 2833 ASSERT(test == Type::kIsAssignableTo); |
2824 String& param_name = String::Handle(); | 2834 String& param_name = String::Handle(); |
2825 is_subtype = true; | 2835 is_subtype = true; |
2826 for (intptr_t i = num_fixed_params; i < num_params; i++) { | 2836 for (intptr_t i = num_fixed_params; i < num_params; i++) { |
2827 param_name = ParameterNameAt(i); | 2837 param_name = ParameterNameAt(i); |
2828 found_param_name = false; | 2838 found_param_name = false; |
2829 for (intptr_t j = other_num_fixed_params; j < other_num_params; j++) { | 2839 for (intptr_t j = other_num_fixed_params; j < other_num_params; j++) { |
2830 if (other.ParameterNameAt(j) == param_name.raw()) { | 2840 if (other.ParameterNameAt(j) == param_name.raw()) { |
2831 found_param_name = true; | 2841 found_param_name = true; |
2832 other_param_type = other.ParameterTypeAt(j); | 2842 other_param_type = other.ParameterTypeAt(j); |
2833 if (other_param_type.IsTypeParameter() || | 2843 if (!other_param_type.IsInstantiated()) { |
2834 other_param_type.IsVarType()) { | 2844 other_param_type = |
| 2845 other_param_type.InstantiateFrom(other_type_arguments, 0); |
| 2846 } |
| 2847 if (other_param_type.IsVarType()) { |
2835 break; | 2848 break; |
2836 } | 2849 } |
2837 param_type = ParameterTypeAt(i); | 2850 param_type = ParameterTypeAt(i); |
2838 if (param_type.IsTypeParameter() || param_type.IsVarType()) { | 2851 if (!param_type.IsInstantiated()) { |
| 2852 param_type = param_type.InstantiateFrom(type_arguments, 0); |
| 2853 } |
| 2854 if (param_type.IsVarType()) { |
2839 break; | 2855 break; |
2840 } | 2856 } |
2841 if (!other_param_type.IsSubtypeOf(param_type) && | 2857 if (!other_param_type.IsSubtypeOf(param_type) && |
2842 !param_type.IsSubtypeOf(other_param_type)) { | 2858 !param_type.IsSubtypeOf(other_param_type)) { |
2843 return false; | 2859 return false; |
2844 } | 2860 } |
2845 break; | 2861 break; |
2846 } | 2862 } |
2847 } | 2863 } |
2848 if (!found_param_name) { | 2864 if (!found_param_name) { |
(...skipping 3935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6784 const String& str = String::Handle(pattern()); | 6800 const String& str = String::Handle(pattern()); |
6785 const char* format = "JSRegExp: pattern=%s flags=%s"; | 6801 const char* format = "JSRegExp: pattern=%s flags=%s"; |
6786 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 6802 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
6787 char* chars = reinterpret_cast<char*>( | 6803 char* chars = reinterpret_cast<char*>( |
6788 Isolate::Current()->current_zone()->Allocate(len + 1)); | 6804 Isolate::Current()->current_zone()->Allocate(len + 1)); |
6789 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 6805 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
6790 return chars; | 6806 return chars; |
6791 } | 6807 } |
6792 | 6808 |
6793 } // namespace dart | 6809 } // namespace dart |
OLD | NEW |