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

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

Issue 8664015: Update function type checking in VM after spec change (issue 444): (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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 2905 matching lines...) Expand 10 before | Expand all | Expand 10 after
2916 bool Function::HasCompatibleParametersWith(const Function& other) const { 2916 bool Function::HasCompatibleParametersWith(const Function& other) const {
2917 // The default values of optional parameters can differ. 2917 // The default values of optional parameters can differ.
2918 const intptr_t num_fixed_params = num_fixed_parameters(); 2918 const intptr_t num_fixed_params = num_fixed_parameters();
2919 const intptr_t num_opt_params = num_optional_parameters(); 2919 const intptr_t num_opt_params = num_optional_parameters();
2920 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); 2920 const intptr_t other_num_fixed_params = other.num_fixed_parameters();
2921 const intptr_t other_num_opt_params = other.num_optional_parameters(); 2921 const intptr_t other_num_opt_params = other.num_optional_parameters();
2922 if ((num_fixed_params != other_num_fixed_params) || 2922 if ((num_fixed_params != other_num_fixed_params) ||
2923 (num_opt_params < other_num_opt_params)) { 2923 (num_opt_params < other_num_opt_params)) {
2924 return false; 2924 return false;
2925 } 2925 }
2926 // Check that for each optional named parameter of the other function, there 2926 // Check that for each optional named parameter of the other function there is
2927 // exists an optional named parameter of this function with an identical name. 2927 // a corresponding optional named parameter of this function with an identical
2928 // name at the same position.
2928 // Note that SetParameterNameAt() guarantees that names are symbols, so we can 2929 // Note that SetParameterNameAt() guarantees that names are symbols, so we can
2929 // compare their raw pointers. 2930 // compare their raw pointers.
2930 const int num_params = num_fixed_params + num_opt_params;
2931 const int other_num_params = other_num_fixed_params + other_num_opt_params; 2931 const int other_num_params = other_num_fixed_params + other_num_opt_params;
2932 bool found_param_name;
2933 String& other_param_name = String::Handle();
2934 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { 2932 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) {
2935 other_param_name = other.ParameterNameAt(i); 2933 const String& other_param_name = String::Handle(other.ParameterNameAt(i));
2936 found_param_name = false; 2934 if (ParameterNameAt(i) != other_param_name.raw()) {
2937 for (intptr_t j = num_fixed_params; j < num_params; j++) {
2938 if (ParameterNameAt(j) == other_param_name.raw()) {
2939 found_param_name = true;
2940 break;
2941 }
2942 }
2943 if (!found_param_name) {
2944 return false; 2935 return false;
2945 } 2936 }
2946 } 2937 }
2947 return true; 2938 return true;
2948 } 2939 }
2949 2940
2950 2941
2942 bool Function::TestParameterType(
2943 intptr_t parameter_position,
2944 const TypeArguments& type_arguments,
2945 const Function& other,
2946 const TypeArguments& other_type_arguments) const {
2947 Type& param_type = Type::Handle(ParameterTypeAt(parameter_position));
2948 if (!param_type.IsInstantiated()) {
2949 param_type = param_type.InstantiateFrom(type_arguments, 0);
2950 }
2951 if (param_type.IsDynamicType()) {
2952 return true;
2953 }
2954 Type& other_param_type =
2955 Type::Handle(other.ParameterTypeAt(parameter_position));
2956 if (!other_param_type.IsInstantiated()) {
2957 other_param_type =
2958 other_param_type.InstantiateFrom(other_type_arguments, 0);
2959 }
2960 if (other_param_type.IsDynamicType()) {
2961 return true;
2962 }
2963 if (!param_type.IsSubtypeOf(other_param_type) &&
2964 !other_param_type.IsSubtypeOf(param_type)) {
2965 return false;
2966 }
2967 return true;
2968 }
2969
2970
2951 bool Function::TestType(TypeTestKind test, 2971 bool Function::TestType(TypeTestKind test,
2952 const TypeArguments& type_arguments, 2972 const TypeArguments& type_arguments,
2953 const Function& other, 2973 const Function& other,
2954 const TypeArguments& other_type_arguments) const { 2974 const TypeArguments& other_type_arguments) const {
2955 const intptr_t num_fixed_params = num_fixed_parameters(); 2975 const intptr_t num_fixed_params = num_fixed_parameters();
2956 const intptr_t num_opt_params = num_optional_parameters(); 2976 const intptr_t num_opt_params = num_optional_parameters();
2957 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); 2977 const intptr_t other_num_fixed_params = other.num_fixed_parameters();
2958 const intptr_t other_num_opt_params = other.num_optional_parameters(); 2978 const intptr_t other_num_opt_params = other.num_optional_parameters();
2959 if ((num_fixed_params != other_num_fixed_params) || 2979 if ((num_fixed_params != other_num_fixed_params) ||
2960 ((test == Type::kIsSubtypeOf) && 2980 ((test == Type::kIsSubtypeOf) &&
2961 (num_opt_params < other_num_opt_params))) { 2981 (num_opt_params < other_num_opt_params))) {
2962 return false; 2982 return false;
2963 } 2983 }
2964 // Check the result type. 2984 // Check the result type.
2965 Type& other_res_type = Type::Handle(other.result_type()); 2985 Type& other_res_type = Type::Handle(other.result_type());
2966 if (!other_res_type.IsInstantiated()) { 2986 if (!other_res_type.IsInstantiated()) {
2967 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, 0); 2987 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, 0);
2968 } 2988 }
2969 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { 2989 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
2970 Type& res_type = Type::Handle(result_type()); 2990 Type& res_type = Type::Handle(result_type());
2971 if (!res_type.IsInstantiated()) { 2991 if (!res_type.IsInstantiated()) {
2972 res_type = res_type.InstantiateFrom(type_arguments, 0); 2992 res_type = res_type.InstantiateFrom(type_arguments, 0);
2973 } 2993 }
2974 if (!res_type.IsDynamicType() && 2994 if (!res_type.IsDynamicType() &&
2975 (res_type.IsVoidType() || !res_type.IsAssignableTo(other_res_type))) { 2995 (res_type.IsVoidType() ||
2996 !(res_type.IsSubtypeOf(other_res_type) ||
2997 other_res_type.IsSubtypeOf(res_type)))) {
2976 return false; 2998 return false;
2977 } 2999 }
2978 } 3000 }
2979 // Check the types of fixed parameters. 3001 // Check the types of fixed parameters.
2980 Type& param_type = Type::Handle();
2981 Type& other_param_type = Type::Handle();
2982 for (intptr_t i = 0; i < num_fixed_params; i++) { 3002 for (intptr_t i = 0; i < num_fixed_params; i++) {
2983 param_type = ParameterTypeAt(i); 3003 if (!TestParameterType(i, type_arguments, other, other_type_arguments)) {
2984 if (!param_type.IsInstantiated()) {
2985 param_type = param_type.InstantiateFrom(type_arguments, 0);
2986 }
2987 if (param_type.IsDynamicType()) {
2988 continue;
2989 }
2990 other_param_type = other.ParameterTypeAt(i);
2991 if (!other_param_type.IsInstantiated()) {
2992 other_param_type =
2993 other_param_type.InstantiateFrom(other_type_arguments, 0);
2994 }
2995 if (other_param_type.IsDynamicType()) {
2996 continue;
2997 }
2998 // Subtyping and assignability rules are identical when applied to parameter
2999 // types.
3000 ASSERT((test == Type::kIsSubtypeOf) || (test == Type::kIsAssignableTo));
3001 if (!param_type.IsSubtypeOf(other_param_type) &&
3002 !other_param_type.IsSubtypeOf(param_type)) {
3003 return false; 3004 return false;
3004 } 3005 }
3005 } 3006 }
3006 // Check the names and types of optional parameters. 3007 // Check the names and types of optional parameters.
3007 // First, check that for each optional named parameter of type T of the other 3008 if (num_opt_params >= other_num_opt_params) {
3008 // function type, there exists an optional named parameter of this function 3009 // Check that for each optional named parameter of type T of the other
3009 // type with an identical name and with a Type S that is a subtype or 3010 // function type, there is a corresponding optional named parameter of this
3010 // supertype of T. 3011 // function at the same position with an identical name and with a Type S
3011 // Note that SetParameterNameAt() guarantees that names are symbols, so we can 3012 // that is a subtype or supertype of T.
3012 // compare their raw pointers. 3013 // Note that SetParameterNameAt() guarantees that names are symbols, so we
3013 const int num_params = num_fixed_params + num_opt_params; 3014 // can compare their raw pointers.
3014 const int other_num_params = other_num_fixed_params + other_num_opt_params; 3015 const intptr_t other_num_params =
3015 bool is_subtype = true; 3016 other_num_fixed_params + other_num_opt_params;
3016 bool found_param_name; 3017 String& other_param_name = String::Handle();
3017 String& other_param_name = String::Handle(); 3018 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) {
3018 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { 3019 other_param_name = other.ParameterNameAt(i);
3019 other_param_name = other.ParameterNameAt(i); 3020 if ((ParameterNameAt(i) != other_param_name.raw()) ||
3020 found_param_name = false; 3021 !TestParameterType(i, type_arguments, other, other_type_arguments)) {
3021 for (intptr_t j = num_fixed_params; j < num_params; j++) { 3022 return false;
3022 if (ParameterNameAt(j) == other_param_name.raw()) {
3023 found_param_name = true;
3024 param_type = ParameterTypeAt(j);
3025 if (!param_type.IsInstantiated()) {
3026 param_type = param_type.InstantiateFrom(type_arguments, 0);
3027 }
3028 if (param_type.IsDynamicType()) {
3029 break;
3030 }
3031 other_param_type = other.ParameterTypeAt(i);
3032 if (!other_param_type.IsInstantiated()) {
3033 other_param_type =
3034 other_param_type.InstantiateFrom(other_type_arguments, 0);
3035 }
3036 if (other_param_type.IsDynamicType()) {
3037 break;
3038 }
3039 if (!param_type.IsSubtypeOf(other_param_type) &&
3040 !other_param_type.IsSubtypeOf(param_type)) {
3041 is_subtype = false;
3042 }
3043 break;
3044 } 3023 }
3045 } 3024 }
3046 if (!found_param_name) {
3047 is_subtype = false;
3048 break;
3049 }
3050 }
3051 // If this first checking step succeeds, return true, otherwise, this function
3052 // type is not a subtype of the other function type.
3053 if (is_subtype) {
3054 return true; 3025 return true;
3055 } 3026 }
3056 if (test == Type::kIsSubtypeOf) { 3027 ASSERT((test == Type::kIsAssignableTo) &&
3057 return false; 3028 (num_opt_params < other_num_opt_params));
3058 }
3059 // To verify that this function type is assignable to the other function type, 3029 // To verify that this function type is assignable to the other function type,
3060 // i.e whether the other function type is a subtype of this function type, we 3030 // check that for each optional named parameter of type T of this function
3061 // repeat the checking step above after swapping the other function type with 3031 // type, there is a corresponding optional named parameter of the other
3062 // this function type. 3032 // function at the same position with an identical name and with a Type S that
3063 ASSERT(test == Type::kIsAssignableTo); 3033 // is a subtype or supertype of T.
3064 String& param_name = String::Handle(); 3034 // Note that SetParameterNameAt() guarantees that names are symbols, so we
3065 is_subtype = true; 3035 // can compare their raw pointers.
3036 const intptr_t num_params = num_fixed_params + num_opt_params;
3037 String& other_param_name = String::Handle();
3066 for (intptr_t i = num_fixed_params; i < num_params; i++) { 3038 for (intptr_t i = num_fixed_params; i < num_params; i++) {
3067 param_name = ParameterNameAt(i); 3039 other_param_name = other.ParameterNameAt(i);
3068 found_param_name = false; 3040 if ((ParameterNameAt(i) != other_param_name.raw()) ||
3069 for (intptr_t j = other_num_fixed_params; j < other_num_params; j++) { 3041 !TestParameterType(i, type_arguments, other, other_type_arguments)) {
3070 if (other.ParameterNameAt(j) == param_name.raw()) {
3071 found_param_name = true;
3072 other_param_type = other.ParameterTypeAt(j);
3073 if (!other_param_type.IsInstantiated()) {
3074 other_param_type =
3075 other_param_type.InstantiateFrom(other_type_arguments, 0);
3076 }
3077 if (other_param_type.IsDynamicType()) {
3078 break;
3079 }
3080 param_type = ParameterTypeAt(i);
3081 if (!param_type.IsInstantiated()) {
3082 param_type = param_type.InstantiateFrom(type_arguments, 0);
3083 }
3084 if (param_type.IsDynamicType()) {
3085 break;
3086 }
3087 if (!other_param_type.IsSubtypeOf(param_type) &&
3088 !param_type.IsSubtypeOf(other_param_type)) {
3089 return false;
3090 }
3091 break;
3092 }
3093 }
3094 if (!found_param_name) {
3095 return false; 3042 return false;
3096 } 3043 }
3097 } 3044 }
3098 return true; 3045 return true;
3099 } 3046 }
3100 3047
3101 3048
3102 bool Function::IsImplicitClosureFunction() const { 3049 bool Function::IsImplicitClosureFunction() const {
3103 if (!IsClosureFunction()) { 3050 if (!IsClosureFunction()) {
3104 return false; 3051 return false;
(...skipping 4161 matching lines...) Expand 10 before | Expand all | Expand 10 after
7266 const String& str = String::Handle(pattern()); 7213 const String& str = String::Handle(pattern());
7267 const char* format = "JSRegExp: pattern=%s flags=%s"; 7214 const char* format = "JSRegExp: pattern=%s flags=%s";
7268 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 7215 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
7269 char* chars = reinterpret_cast<char*>( 7216 char* chars = reinterpret_cast<char*>(
7270 Isolate::Current()->current_zone()->Allocate(len + 1)); 7217 Isolate::Current()->current_zone()->Allocate(len + 1));
7271 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 7218 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
7272 return chars; 7219 return chars;
7273 } 7220 }
7274 7221
7275 } // namespace dart 7222 } // 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