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

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
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 if (ParameterNameAt(i) != other.ParameterNameAt(i)) {
srdjan 2011/11/29 01:01:59 This is tricky, you are holding onto raw pointers
regis 2011/11/29 01:48:21 Done.
2936 found_param_name = false;
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; 2934 return false;
2945 } 2935 }
2946 } 2936 }
2947 return true; 2937 return true;
2948 } 2938 }
2939
2940
2941 bool Function::CheckParameters(const TypeArguments& type_arguments,
2942 const Function& other,
2943 const TypeArguments& other_type_arguments,
2944 intptr_t from_parameter,
2945 intptr_t to_parameter,
2946 bool check_names) const {
srdjan 2011/11/29 01:01:59 I think this method has too many arguments. I sugg
regis 2011/11/29 01:48:21 I simplified the code by keeping the loop in TestT
2947 Type& param_type = Type::Handle();
2948 Type& other_param_type = Type::Handle();
2949 for (intptr_t i = from_parameter; i < to_parameter; i++) {
2950 if (check_names && (ParameterNameAt(i) != other.ParameterNameAt(i))) {
srdjan 2011/11/29 01:01:59 ditto about holding onto raw objects.
regis 2011/11/29 01:48:21 Done.
2951 return false;
2952 }
2953 param_type = ParameterTypeAt(i);
2954 if (!param_type.IsInstantiated()) {
2955 param_type = param_type.InstantiateFrom(type_arguments, 0);
2956 }
2957 if (param_type.IsDynamicType()) {
2958 continue;
2959 }
2960 other_param_type = other.ParameterTypeAt(i);
2961 if (!other_param_type.IsInstantiated()) {
2962 other_param_type =
2963 other_param_type.InstantiateFrom(other_type_arguments, 0);
2964 }
2965 if (other_param_type.IsDynamicType()) {
2966 continue;
2967 }
2968 if (!param_type.IsSubtypeOf(other_param_type) &&
2969 !other_param_type.IsSubtypeOf(param_type)) {
2970 return false;
2971 }
2972 }
2973 return true;
2974 }
2949 2975
2950 2976
2951 bool Function::TestType(TypeTestKind test, 2977 bool Function::TestType(TypeTestKind test,
2952 const TypeArguments& type_arguments, 2978 const TypeArguments& type_arguments,
2953 const Function& other, 2979 const Function& other,
2954 const TypeArguments& other_type_arguments) const { 2980 const TypeArguments& other_type_arguments) const {
2955 const intptr_t num_fixed_params = num_fixed_parameters(); 2981 const intptr_t num_fixed_params = num_fixed_parameters();
2956 const intptr_t num_opt_params = num_optional_parameters(); 2982 const intptr_t num_opt_params = num_optional_parameters();
2957 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); 2983 const intptr_t other_num_fixed_params = other.num_fixed_parameters();
2958 const intptr_t other_num_opt_params = other.num_optional_parameters(); 2984 const intptr_t other_num_opt_params = other.num_optional_parameters();
2959 if ((num_fixed_params != other_num_fixed_params) || 2985 if ((num_fixed_params != other_num_fixed_params) ||
2960 ((test == Type::kIsSubtypeOf) && 2986 ((test == Type::kIsSubtypeOf) &&
2961 (num_opt_params < other_num_opt_params))) { 2987 (num_opt_params < other_num_opt_params))) {
2962 return false; 2988 return false;
2963 } 2989 }
2964 // Check the result type. 2990 // Check the result type.
2965 Type& other_res_type = Type::Handle(other.result_type()); 2991 Type& other_res_type = Type::Handle(other.result_type());
2966 if (!other_res_type.IsInstantiated()) { 2992 if (!other_res_type.IsInstantiated()) {
2967 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, 0); 2993 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, 0);
2968 } 2994 }
2969 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { 2995 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
2970 Type& res_type = Type::Handle(result_type()); 2996 Type& res_type = Type::Handle(result_type());
2971 if (!res_type.IsInstantiated()) { 2997 if (!res_type.IsInstantiated()) {
2972 res_type = res_type.InstantiateFrom(type_arguments, 0); 2998 res_type = res_type.InstantiateFrom(type_arguments, 0);
2973 } 2999 }
2974 if (!res_type.IsDynamicType() && 3000 if (!res_type.IsDynamicType() &&
2975 (res_type.IsVoidType() || !res_type.IsAssignableTo(other_res_type))) { 3001 (res_type.IsVoidType() ||
3002 !(res_type.IsSubtypeOf(other_res_type) ||
3003 other_res_type.IsSubtypeOf(res_type)))) {
2976 return false; 3004 return false;
2977 } 3005 }
2978 } 3006 }
2979 // Check the types of fixed parameters. 3007 // Check the types of fixed parameters.
2980 Type& param_type = Type::Handle(); 3008 if (!CheckParameters(type_arguments,
2981 Type& other_param_type = Type::Handle(); 3009 other,
2982 for (intptr_t i = 0; i < num_fixed_params; i++) { 3010 other_type_arguments,
2983 param_type = ParameterTypeAt(i); 3011 0,
2984 if (!param_type.IsInstantiated()) { 3012 num_fixed_params,
2985 param_type = param_type.InstantiateFrom(type_arguments, 0); 3013 /* check_names = */ false)) {
2986 } 3014 return false;
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 }
3005 } 3015 }
3006 // Check the names and types of optional parameters. 3016 // Check the names and types of optional parameters.
3007 // First, check that for each optional named parameter of type T of the other 3017 if (num_opt_params >= other_num_opt_params) {
3008 // function type, there exists an optional named parameter of this function 3018 // 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 3019 // function type, there is a corresponding optional named parameter of this
3010 // supertype of T. 3020 // 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 3021 // that is a subtype or supertype of T.
3012 // compare their raw pointers. 3022 // Note that SetParameterNameAt() guarantees that names are symbols, so we
3013 const int num_params = num_fixed_params + num_opt_params; 3023 // can compare their raw pointers.
3014 const int other_num_params = other_num_fixed_params + other_num_opt_params; 3024 return CheckParameters(type_arguments,
3015 bool is_subtype = true; 3025 other,
3016 bool found_param_name; 3026 other_type_arguments,
3017 String& other_param_name = String::Handle(); 3027 other_num_fixed_params,
3018 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { 3028 other_num_fixed_params + other_num_opt_params,
3019 other_param_name = other.ParameterNameAt(i); 3029 /* check_names = */ true);
3020 found_param_name = false;
3021 for (intptr_t j = num_fixed_params; j < num_params; j++) {
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 }
3045 }
3046 if (!found_param_name) {
3047 is_subtype = false;
3048 break;
3049 }
3050 } 3030 }
3051 // If this first checking step succeeds, return true, otherwise, this function 3031 ASSERT((test == Type::kIsAssignableTo) &&
3052 // type is not a subtype of the other function type. 3032 (num_opt_params < other_num_opt_params));
3053 if (is_subtype) {
3054 return true;
3055 }
3056 if (test == Type::kIsSubtypeOf) {
3057 return false;
3058 }
3059 // To verify that this function type is assignable to the other function type, 3033 // 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 3034 // 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 3035 // type, there is a corresponding optional named parameter of the other
3062 // this function type. 3036 // function at the same position with an identical name and with a Type S that
3063 ASSERT(test == Type::kIsAssignableTo); 3037 // is a subtype or supertype of T.
3064 String& param_name = String::Handle(); 3038 // Note that SetParameterNameAt() guarantees that names are symbols, so we
3065 is_subtype = true; 3039 // can compare their raw pointers.
3066 for (intptr_t i = num_fixed_params; i < num_params; i++) { 3040 return CheckParameters(type_arguments,
3067 param_name = ParameterNameAt(i); 3041 other,
3068 found_param_name = false; 3042 other_type_arguments,
3069 for (intptr_t j = other_num_fixed_params; j < other_num_params; j++) { 3043 num_fixed_params,
3070 if (other.ParameterNameAt(j) == param_name.raw()) { 3044 num_fixed_params + num_opt_params,
3071 found_param_name = true; 3045 /* check_names = */ 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;
3096 }
3097 }
3098 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;
3105 } 3052 }
3106 const Function& parent = Function::Handle(parent_function()); 3053 const Function& parent = Function::Handle(parent_function());
3107 return parent.raw_ptr()->implicit_closure_function_ == raw(); 3054 return parent.raw_ptr()->implicit_closure_function_ == raw();
3108 } 3055 }
(...skipping 4157 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
« runtime/vm/object.h ('K') | « 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