| 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 |