| 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 2905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |