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

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

Issue 8391007: Complete generic closure type checking. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 1 month 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') | tests/co19/co19-runtime.status » ('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) 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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698