OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
(...skipping 19 matching lines...) Expand all Loading... | |
30 #include "vm/scopes.h" | 30 #include "vm/scopes.h" |
31 #include "vm/stack_frame.h" | 31 #include "vm/stack_frame.h" |
32 #include "vm/symbols.h" | 32 #include "vm/symbols.h" |
33 #include "vm/timer.h" | 33 #include "vm/timer.h" |
34 #include "vm/unicode.h" | 34 #include "vm/unicode.h" |
35 | 35 |
36 namespace dart { | 36 namespace dart { |
37 | 37 |
38 DEFINE_FLAG(bool, generate_gdb_symbols, false, | 38 DEFINE_FLAG(bool, generate_gdb_symbols, false, |
39 "Generate symbols of generated dart functions for debugging with GDB"); | 39 "Generate symbols of generated dart functions for debugging with GDB"); |
40 DEFINE_FLAG(bool, reject_named_argument_as_positional, false, | |
41 "Enforce new rules for optional parameters and disallow passing of named " | |
42 "arguments to optional positional formal parameters"); | |
40 DEFINE_FLAG(bool, show_internal_names, false, | 43 DEFINE_FLAG(bool, show_internal_names, false, |
41 "Show names of internal classes (e.g. \"OneByteString\") in error messages " | 44 "Show names of internal classes (e.g. \"OneByteString\") in error messages " |
42 "instead of showing the corresponding interface names (e.g. \"String\")"); | 45 "instead of showing the corresponding interface names (e.g. \"String\")"); |
43 DECLARE_FLAG(bool, trace_compiler); | 46 DECLARE_FLAG(bool, trace_compiler); |
44 DECLARE_FLAG(bool, enable_type_checks); | 47 DECLARE_FLAG(bool, enable_type_checks); |
45 | 48 |
46 static const char* kGetterPrefix = "get:"; | 49 static const char* kGetterPrefix = "get:"; |
47 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); | 50 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |
48 static const char* kSetterPrefix = "set:"; | 51 static const char* kSetterPrefix = "set:"; |
49 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); | 52 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |
(...skipping 3811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3861 StorePointer(&raw_ptr()->parameter_names_, value.raw()); | 3864 StorePointer(&raw_ptr()->parameter_names_, value.raw()); |
3862 } | 3865 } |
3863 | 3866 |
3864 | 3867 |
3865 void Function::set_kind(RawFunction::Kind value) const { | 3868 void Function::set_kind(RawFunction::Kind value) const { |
3866 uword bits = raw_ptr()->kind_tag_; | 3869 uword bits = raw_ptr()->kind_tag_; |
3867 raw_ptr()->kind_tag_ = KindBits::update(value, bits); | 3870 raw_ptr()->kind_tag_ = KindBits::update(value, bits); |
3868 } | 3871 } |
3869 | 3872 |
3870 | 3873 |
3871 void Function::set_is_static(bool is_static) const { | 3874 void Function::set_is_static(bool value) const { |
3872 uword bits = raw_ptr()->kind_tag_; | 3875 uword bits = raw_ptr()->kind_tag_; |
3873 raw_ptr()->kind_tag_ = StaticBit::update(is_static, bits); | 3876 raw_ptr()->kind_tag_ = StaticBit::update(value, bits); |
3874 } | 3877 } |
3875 | 3878 |
3876 | 3879 |
3877 void Function::set_is_const(bool is_const) const { | 3880 void Function::set_is_const(bool value) const { |
3878 uword bits = raw_ptr()->kind_tag_; | 3881 uword bits = raw_ptr()->kind_tag_; |
3879 raw_ptr()->kind_tag_ = ConstBit::update(is_const, bits); | 3882 raw_ptr()->kind_tag_ = ConstBit::update(value, bits); |
3880 } | 3883 } |
3881 | 3884 |
3882 | 3885 |
3883 void Function::set_is_external(bool is_external) const { | 3886 void Function::set_is_external(bool value) const { |
3884 uword bits = raw_ptr()->kind_tag_; | 3887 uword bits = raw_ptr()->kind_tag_; |
3885 raw_ptr()->kind_tag_ = ExternalBit::update(is_external, bits); | 3888 raw_ptr()->kind_tag_ = ExternalBit::update(value, bits); |
3886 } | 3889 } |
3887 | 3890 |
3888 | 3891 |
3889 void Function::set_token_pos(intptr_t pos) const { | 3892 void Function::set_token_pos(intptr_t value) const { |
3890 ASSERT(pos >= 0); | 3893 ASSERT(value >= 0); |
3891 raw_ptr()->token_pos_ = pos; | 3894 raw_ptr()->token_pos_ = value; |
3892 } | 3895 } |
3893 | 3896 |
3894 | 3897 |
3895 void Function::set_kind_tag(intptr_t value) const { | 3898 void Function::set_kind_tag(intptr_t value) const { |
3896 raw_ptr()->kind_tag_ = value; | 3899 raw_ptr()->kind_tag_ = value; |
3897 } | 3900 } |
3898 | 3901 |
3899 | 3902 |
3900 void Function::set_num_fixed_parameters(intptr_t n) const { | 3903 void Function::set_num_fixed_parameters(intptr_t value) const { |
3901 ASSERT(n >= 0); | 3904 ASSERT(value >= 0); |
3902 raw_ptr()->num_fixed_parameters_ = n; | 3905 raw_ptr()->num_fixed_parameters_ = value; |
3903 } | 3906 } |
3904 | 3907 |
3905 | 3908 |
3906 void Function::set_num_optional_parameters(intptr_t n) const { | 3909 void Function::set_num_optional_positional_parameters(intptr_t value) const { |
3907 ASSERT(n >= 0); | 3910 ASSERT(value >= 0); |
hausner
2012/09/07 00:23:29
I believe optional positional and optional named p
regis
2012/09/07 01:11:33
Good point. I added an assert here and below.
| |
3908 raw_ptr()->num_optional_parameters_ = n; | 3911 raw_ptr()->num_optional_positional_parameters_ = value; |
3912 } | |
3913 | |
3914 | |
3915 void Function::set_num_optional_named_parameters(intptr_t value) const { | |
3916 ASSERT(value >= 0); | |
3917 raw_ptr()->num_optional_named_parameters_ = value; | |
3909 } | 3918 } |
3910 | 3919 |
3911 | 3920 |
3912 bool Function::is_optimizable() const { | 3921 bool Function::is_optimizable() const { |
3913 return OptimizableBit::decode(raw_ptr()->kind_tag_) && | 3922 return OptimizableBit::decode(raw_ptr()->kind_tag_) && |
3914 (script() != Script::null()) && | 3923 (script() != Script::null()) && |
3915 !is_native(); | 3924 !is_native(); |
3916 } | 3925 } |
3917 | 3926 |
3918 | 3927 |
(...skipping 15 matching lines...) Expand all Loading... | |
3934 } | 3943 } |
3935 | 3944 |
3936 | 3945 |
3937 void Function::set_is_abstract(bool value) const { | 3946 void Function::set_is_abstract(bool value) const { |
3938 uword bits = raw_ptr()->kind_tag_; | 3947 uword bits = raw_ptr()->kind_tag_; |
3939 raw_ptr()->kind_tag_ = AbstractBit::update(value, bits); | 3948 raw_ptr()->kind_tag_ = AbstractBit::update(value, bits); |
3940 } | 3949 } |
3941 | 3950 |
3942 | 3951 |
3943 intptr_t Function::NumberOfParameters() const { | 3952 intptr_t Function::NumberOfParameters() const { |
3944 return num_fixed_parameters() + num_optional_parameters(); | 3953 return num_fixed_parameters() + |
3954 num_optional_positional_parameters() + num_optional_named_parameters(); | |
3945 } | 3955 } |
3946 | 3956 |
3947 | 3957 |
3948 intptr_t Function::NumberOfImplicitParameters() const { | 3958 intptr_t Function::NumberOfImplicitParameters() const { |
3949 if (kind() == RawFunction::kConstructor) { | 3959 if (kind() == RawFunction::kConstructor) { |
3950 if (is_static()) { | 3960 if (is_static()) { |
3951 ASSERT(IsFactory()); | 3961 ASSERT(IsFactory()); |
3952 return 1; // Type arguments. | 3962 return 1; // Type arguments. |
3953 } else { | 3963 } else { |
3954 ASSERT(IsConstructor()); | 3964 ASSERT(IsConstructor()); |
3955 return 2; // Instance, phase. | 3965 return 2; // Instance, phase. |
3956 } | 3966 } |
3957 } | 3967 } |
3958 if (!is_static() && (kind() != RawFunction::kClosureFunction)) { | 3968 if (!is_static() && (kind() != RawFunction::kClosureFunction)) { |
3959 // Closure functions defined inside instance (i.e. non-static) functions are | 3969 // Closure functions defined inside instance (i.e. non-static) functions are |
3960 // marked as non-static, but they do not have a receiver. | 3970 // marked as non-static, but they do not have a receiver. |
3961 return 1; // Receiver. | 3971 return 1; // Receiver. |
3962 } | 3972 } |
3963 return 0; // No implicit parameters. | 3973 return 0; // No implicit parameters. |
3964 } | 3974 } |
3965 | 3975 |
3966 | 3976 |
3977 void Function::SetNumberOfParameters(intptr_t num_fixed_parameters, | |
3978 intptr_t num_optional_parameters, | |
3979 bool are_optional_positional) const { | |
3980 set_num_fixed_parameters(num_fixed_parameters); | |
3981 if (are_optional_positional) { | |
3982 set_num_optional_positional_parameters(num_optional_parameters); | |
3983 set_num_optional_named_parameters(0); | |
3984 } else { | |
3985 set_num_optional_positional_parameters(0); | |
3986 set_num_optional_named_parameters(num_optional_parameters); | |
3987 } | |
3988 } | |
3989 | |
3990 | |
3967 bool Function::AreValidArgumentCounts(int num_arguments, | 3991 bool Function::AreValidArgumentCounts(int num_arguments, |
3968 int num_named_arguments, | 3992 int num_named_arguments, |
3969 String* error_message) const { | 3993 String* error_message) const { |
3994 if (FLAG_reject_named_argument_as_positional) { | |
3995 if (num_named_arguments > num_optional_named_parameters()) { | |
3996 if (error_message != NULL) { | |
3997 const intptr_t kMessageBufferSize = 64; | |
3998 char message_buffer[kMessageBufferSize]; | |
3999 OS::SNPrint(message_buffer, | |
4000 kMessageBufferSize, | |
4001 "%d named passed, at most %"Pd" expected", | |
4002 num_named_arguments, | |
4003 num_optional_named_parameters()); | |
4004 *error_message = String::New(message_buffer); | |
4005 } | |
4006 return false; // Too many named arguments. | |
4007 } | |
4008 const int num_pos_args = num_arguments - num_named_arguments; | |
4009 const int num_opt_pos_params = num_optional_positional_parameters(); | |
4010 const int num_pos_params = num_fixed_parameters() + num_opt_pos_params; | |
4011 if (num_pos_args > num_pos_params) { | |
4012 if (error_message != NULL) { | |
4013 const intptr_t kMessageBufferSize = 64; | |
4014 char message_buffer[kMessageBufferSize]; | |
4015 // Hide implicit parameters to the user. | |
4016 const intptr_t num_hidden_params = NumberOfImplicitParameters(); | |
4017 OS::SNPrint(message_buffer, | |
4018 kMessageBufferSize, | |
4019 "%"Pd"%s passed, %s%"Pd" expected", | |
4020 num_pos_args - num_hidden_params, | |
4021 num_opt_pos_params > 0 ? " positional" : "", | |
4022 num_opt_pos_params > 0 ? "at most " : "", | |
4023 num_pos_params - num_hidden_params); | |
4024 *error_message = String::New(message_buffer); | |
4025 } | |
4026 return false; // Too many fixed and/or positional arguments. | |
4027 } | |
4028 if (num_pos_args < num_fixed_parameters()) { | |
4029 if (error_message != NULL) { | |
4030 const intptr_t kMessageBufferSize = 64; | |
4031 char message_buffer[kMessageBufferSize]; | |
4032 // Hide implicit parameters to the user. | |
4033 const intptr_t num_hidden_params = NumberOfImplicitParameters(); | |
4034 OS::SNPrint(message_buffer, | |
4035 kMessageBufferSize, | |
4036 "%"Pd"%s passed, %s%"Pd" expected", | |
4037 num_pos_args - num_hidden_params, | |
4038 num_opt_pos_params > 0 ? " positional" : "", | |
4039 num_opt_pos_params > 0 ? "at least " : "", | |
4040 num_fixed_parameters() - num_hidden_params); | |
4041 *error_message = String::New(message_buffer); | |
4042 } | |
4043 return false; // Too few fixed and/or positional arguments. | |
4044 } | |
4045 return true; | |
4046 } | |
4047 | |
4048 // TODO(regis): Remove the following code once the flag is removed. | |
4049 | |
3970 if (num_arguments > NumberOfParameters()) { | 4050 if (num_arguments > NumberOfParameters()) { |
3971 if (error_message != NULL) { | 4051 if (error_message != NULL) { |
3972 const intptr_t kMessageBufferSize = 64; | 4052 const intptr_t kMessageBufferSize = 64; |
3973 char message_buffer[kMessageBufferSize]; | 4053 char message_buffer[kMessageBufferSize]; |
3974 // Hide implicit parameters to the user. | 4054 // Hide implicit parameters to the user. |
3975 const intptr_t num_hidden_params = NumberOfImplicitParameters(); | 4055 const intptr_t num_hidden_params = NumberOfImplicitParameters(); |
3976 OS::SNPrint(message_buffer, | 4056 OS::SNPrint(message_buffer, |
3977 kMessageBufferSize, | 4057 kMessageBufferSize, |
3978 "%"Pd" passed, %s%"Pd" expected", | 4058 "%"Pd" passed, %s%"Pd" expected", |
3979 num_arguments - num_hidden_params, | 4059 num_arguments - num_hidden_params, |
3980 num_optional_parameters() > 0 ? "at most " : "", | 4060 HasOptionalParameters() ? "at most " : "", |
3981 NumberOfParameters() - num_hidden_params); | 4061 NumberOfParameters() - num_hidden_params); |
3982 *error_message = String::New(message_buffer); | 4062 *error_message = String::New(message_buffer); |
3983 } | 4063 } |
3984 return false; // Too many arguments. | 4064 return false; // Too many arguments. |
3985 } | 4065 } |
3986 const int num_positional_args = num_arguments - num_named_arguments; | 4066 const int num_positional_args = num_arguments - num_named_arguments; |
3987 if (num_positional_args < num_fixed_parameters()) { | 4067 if (num_positional_args < num_fixed_parameters()) { |
3988 if (error_message != NULL) { | 4068 if (error_message != NULL) { |
3989 const intptr_t kMessageBufferSize = 64; | 4069 const intptr_t kMessageBufferSize = 64; |
3990 char message_buffer[kMessageBufferSize]; | 4070 char message_buffer[kMessageBufferSize]; |
3991 // Hide implicit parameters to the user. | 4071 // Hide implicit parameters to the user. |
3992 const intptr_t num_hidden_params = NumberOfImplicitParameters(); | 4072 const intptr_t num_hidden_params = NumberOfImplicitParameters(); |
3993 OS::SNPrint(message_buffer, | 4073 OS::SNPrint(message_buffer, |
3994 kMessageBufferSize, | 4074 kMessageBufferSize, |
3995 "%"Pd" %spassed, %"Pd" expected", | 4075 "%"Pd" %spassed, %"Pd" expected", |
3996 num_positional_args - num_hidden_params, | 4076 num_positional_args - num_hidden_params, |
3997 num_optional_parameters() > 0 ? "positional " : "", | 4077 HasOptionalParameters() ? "positional " : "", |
3998 num_fixed_parameters() - num_hidden_params); | 4078 num_fixed_parameters() - num_hidden_params); |
3999 *error_message = String::New(message_buffer); | 4079 *error_message = String::New(message_buffer); |
4000 } | 4080 } |
4001 return false; // Too few arguments. | 4081 return false; // Too few arguments. |
4002 } | 4082 } |
4003 return true; | 4083 return true; |
4004 } | 4084 } |
4005 | 4085 |
4006 | 4086 |
4007 bool Function::AreValidArguments(int num_arguments, | 4087 bool Function::AreValidArguments(int num_arguments, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4095 | 4175 |
4096 | 4176 |
4097 const char* Function::ToFullyQualifiedCString() const { | 4177 const char* Function::ToFullyQualifiedCString() const { |
4098 char* chars = NULL; | 4178 char* chars = NULL; |
4099 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); | 4179 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); |
4100 return chars; | 4180 return chars; |
4101 } | 4181 } |
4102 | 4182 |
4103 | 4183 |
4104 bool Function::HasCompatibleParametersWith(const Function& other) const { | 4184 bool Function::HasCompatibleParametersWith(const Function& other) const { |
4185 const intptr_t num_fixed_params = num_fixed_parameters(); | |
4186 const intptr_t num_opt_pos_params = num_optional_positional_parameters(); | |
4187 const intptr_t num_opt_named_params = num_optional_named_parameters(); | |
4188 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | |
4189 const intptr_t other_num_opt_pos_params = | |
4190 other.num_optional_positional_parameters(); | |
4191 const intptr_t other_num_opt_named_params = | |
4192 other.num_optional_named_parameters(); | |
4193 if (FLAG_reject_named_argument_as_positional) { | |
4194 // The default values of optional parameters can differ. | |
4195 if ((num_fixed_params != other_num_fixed_params) || | |
4196 (num_opt_pos_params < other_num_opt_pos_params) || | |
4197 (num_opt_named_params < other_num_opt_named_params)) { | |
4198 return false; | |
4199 } | |
4200 if (other_num_opt_named_params == 0) { | |
4201 return true; | |
4202 } | |
4203 // Check that for each optional named parameter of the other function there | |
4204 // exists an optional named parameter of this function with an identical | |
4205 // name. | |
4206 // Note that SetParameterNameAt() guarantees that names are symbols, so we | |
4207 // can compare their raw pointers. | |
4208 const int num_params = num_fixed_params + num_opt_named_params; | |
4209 const int other_num_params = | |
4210 other_num_fixed_params + other_num_opt_named_params; | |
4211 bool found_param_name; | |
4212 String& other_param_name = String::Handle(); | |
4213 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { | |
4214 other_param_name = other.ParameterNameAt(i); | |
4215 found_param_name = false; | |
4216 for (intptr_t j = num_fixed_params; j < num_params; j++) { | |
4217 if (ParameterNameAt(j) == other_param_name.raw()) { | |
4218 found_param_name = true; | |
4219 break; | |
4220 } | |
4221 } | |
4222 if (!found_param_name) { | |
4223 return false; | |
4224 } | |
4225 } | |
4226 return true; | |
4227 } | |
4228 | |
4229 // TODO(regis): Remove the following code once the flag is removed. | |
4230 | |
4105 // The default values of optional parameters can differ. | 4231 // The default values of optional parameters can differ. |
4106 const intptr_t num_fixed_params = num_fixed_parameters(); | 4232 const intptr_t num_opt_params = num_opt_pos_params + num_opt_named_params; |
4107 const intptr_t num_opt_params = num_optional_parameters(); | 4233 const intptr_t other_num_opt_params = |
4108 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 4234 other_num_opt_pos_params + other_num_opt_named_params; |
4109 const intptr_t other_num_opt_params = other.num_optional_parameters(); | |
4110 if ((num_fixed_params != other_num_fixed_params) || | 4235 if ((num_fixed_params != other_num_fixed_params) || |
4111 (num_opt_params < other_num_opt_params)) { | 4236 (num_opt_params < other_num_opt_params)) { |
4112 return false; | 4237 return false; |
4113 } | 4238 } |
4114 // Check that for each optional named parameter of the other function there is | 4239 // Check that for each optional named parameter of the other function there is |
4115 // a corresponding optional named parameter of this function with an identical | 4240 // a corresponding optional named parameter of this function with an identical |
4116 // name at the same position. | 4241 // name at the same position. |
4117 // Note that SetParameterNameAt() guarantees that names are symbols, so we can | 4242 // Note that SetParameterNameAt() guarantees that names are symbols, so we can |
4118 // compare their raw pointers. | 4243 // compare their raw pointers. |
4119 const int other_num_params = other_num_fixed_params + other_num_opt_params; | 4244 const int other_num_params = other_num_fixed_params + other_num_opt_params; |
4120 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { | 4245 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { |
4121 const String& other_param_name = String::Handle(other.ParameterNameAt(i)); | 4246 const String& other_param_name = String::Handle(other.ParameterNameAt(i)); |
4247 ASSERT(other_param_name.IsSymbol()); | |
4248 ASSERT(String::Handle(ParameterNameAt(i)).IsSymbol()); | |
4122 if (ParameterNameAt(i) != other_param_name.raw()) { | 4249 if (ParameterNameAt(i) != other_param_name.raw()) { |
4123 return false; | 4250 return false; |
4124 } | 4251 } |
4125 } | 4252 } |
4126 return true; | 4253 return true; |
4127 } | 4254 } |
4128 | 4255 |
4129 | 4256 |
4130 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter | 4257 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter |
4131 // of this function is a subtype or a supertype of the type of the corresponding | 4258 // of this function is a subtype or a supertype of the type of the specified |
4132 // parameter of the other function. | 4259 // parameter of the other function. |
4133 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified | 4260 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified |
4134 // parameter of this function is more specific than the type of the | 4261 // parameter of this function is more specific than the type of the specified |
4135 // corresponding parameter of the other function. | 4262 // parameter of the other function. |
4136 // Note that we do not apply contravariance of parameter types, but covariance | 4263 // Note that we do not apply contravariance of parameter types, but covariance |
4137 // of both parameter types and result type. | 4264 // of both parameter types and result type. |
4138 bool Function::TestParameterType( | 4265 bool Function::TestParameterType( |
4139 TypeTestKind test_kind, | 4266 TypeTestKind test_kind, |
4140 intptr_t parameter_position, | 4267 intptr_t parameter_position, |
4268 intptr_t other_parameter_position, | |
4141 const AbstractTypeArguments& type_arguments, | 4269 const AbstractTypeArguments& type_arguments, |
4142 const Function& other, | 4270 const Function& other, |
4143 const AbstractTypeArguments& other_type_arguments, | 4271 const AbstractTypeArguments& other_type_arguments, |
4144 Error* malformed_error) const { | 4272 Error* malformed_error) const { |
4145 AbstractType& other_param_type = | 4273 AbstractType& other_param_type = |
4146 AbstractType::Handle(other.ParameterTypeAt(parameter_position)); | 4274 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); |
4147 if (!other_param_type.IsInstantiated()) { | 4275 if (!other_param_type.IsInstantiated()) { |
4148 other_param_type = other_param_type.InstantiateFrom(other_type_arguments); | 4276 other_param_type = other_param_type.InstantiateFrom(other_type_arguments); |
4149 } | 4277 } |
4150 if (other_param_type.IsDynamicType()) { | 4278 if (other_param_type.IsDynamicType()) { |
4151 return true; | 4279 return true; |
4152 } | 4280 } |
4153 AbstractType& param_type = | 4281 AbstractType& param_type = |
4154 AbstractType::Handle(ParameterTypeAt(parameter_position)); | 4282 AbstractType::Handle(ParameterTypeAt(parameter_position)); |
4155 if (!param_type.IsInstantiated()) { | 4283 if (!param_type.IsInstantiated()) { |
4156 param_type = param_type.InstantiateFrom(type_arguments); | 4284 param_type = param_type.InstantiateFrom(type_arguments); |
(...skipping 15 matching lines...) Expand all Loading... | |
4172 return true; | 4300 return true; |
4173 } | 4301 } |
4174 | 4302 |
4175 | 4303 |
4176 bool Function::TypeTest(TypeTestKind test_kind, | 4304 bool Function::TypeTest(TypeTestKind test_kind, |
4177 const AbstractTypeArguments& type_arguments, | 4305 const AbstractTypeArguments& type_arguments, |
4178 const Function& other, | 4306 const Function& other, |
4179 const AbstractTypeArguments& other_type_arguments, | 4307 const AbstractTypeArguments& other_type_arguments, |
4180 Error* malformed_error) const { | 4308 Error* malformed_error) const { |
4181 const intptr_t num_fixed_params = num_fixed_parameters(); | 4309 const intptr_t num_fixed_params = num_fixed_parameters(); |
4182 const intptr_t num_opt_params = num_optional_parameters(); | 4310 const intptr_t num_opt_pos_params = num_optional_positional_parameters(); |
4311 const intptr_t num_opt_named_params = num_optional_named_parameters(); | |
4183 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 4312 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |
4184 const intptr_t other_num_opt_params = other.num_optional_parameters(); | 4313 const intptr_t other_num_opt_pos_params = |
4314 other.num_optional_positional_parameters(); | |
4315 const intptr_t other_num_opt_named_params = | |
4316 other.num_optional_named_parameters(); | |
4185 if ((num_fixed_params != other_num_fixed_params) || | 4317 if ((num_fixed_params != other_num_fixed_params) || |
4186 (num_opt_params < other_num_opt_params)) { | 4318 (num_opt_pos_params < other_num_opt_pos_params) || |
4319 (num_opt_named_params < other_num_opt_named_params)) { | |
4187 return false; | 4320 return false; |
4188 } | 4321 } |
4189 // Check the result type. | 4322 // Check the result type. |
4190 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); | 4323 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); |
4191 if (!other_res_type.IsInstantiated()) { | 4324 if (!other_res_type.IsInstantiated()) { |
4192 other_res_type = other_res_type.InstantiateFrom(other_type_arguments); | 4325 other_res_type = other_res_type.InstantiateFrom(other_type_arguments); |
4193 } | 4326 } |
4194 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { | 4327 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { |
4195 AbstractType& res_type = AbstractType::Handle(result_type()); | 4328 AbstractType& res_type = AbstractType::Handle(result_type()); |
4196 if (!res_type.IsInstantiated()) { | 4329 if (!res_type.IsInstantiated()) { |
4197 res_type = res_type.InstantiateFrom(type_arguments); | 4330 res_type = res_type.InstantiateFrom(type_arguments); |
4198 } | 4331 } |
4199 if (res_type.IsVoidType()) { | 4332 if (res_type.IsVoidType()) { |
4200 return false; | 4333 return false; |
4201 } | 4334 } |
4202 if (test_kind == kIsSubtypeOf) { | 4335 if (test_kind == kIsSubtypeOf) { |
4203 if (!res_type.IsSubtypeOf(other_res_type, malformed_error) && | 4336 if (!res_type.IsSubtypeOf(other_res_type, malformed_error) && |
4204 !other_res_type.IsSubtypeOf(res_type, malformed_error)) { | 4337 !other_res_type.IsSubtypeOf(res_type, malformed_error)) { |
4205 return false; | 4338 return false; |
4206 } | 4339 } |
4207 } else { | 4340 } else { |
4208 ASSERT(test_kind == kIsMoreSpecificThan); | 4341 ASSERT(test_kind == kIsMoreSpecificThan); |
4209 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { | 4342 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { |
4210 return false; | 4343 return false; |
4211 } | 4344 } |
4212 } | 4345 } |
4213 } | 4346 } |
4347 if (FLAG_reject_named_argument_as_positional) { | |
4348 // Check the types of fixed and optional positional parameters. | |
4349 for (intptr_t i = 0; i < num_fixed_params + other_num_opt_pos_params; i++) { | |
4350 if (!TestParameterType(test_kind, | |
4351 i, i, type_arguments, other, other_type_arguments, | |
4352 malformed_error)) { | |
4353 return false; | |
4354 } | |
4355 } | |
4356 // Check the names and types of optional named parameters. | |
4357 if (other_num_opt_named_params == 0) { | |
4358 return true; | |
4359 } | |
4360 // Check that for each optional named parameter of type T of the other | |
4361 // function type, there exists an optional named parameter of this function | |
4362 // type with an identical name and with a type S that is a either a subtype | |
4363 // or supertype of T (if test_kind == kIsSubtypeOf) or that is more specific | |
4364 // than T (if test_kind == kIsMoreSpecificThan). | |
4365 // Note that SetParameterNameAt() guarantees that names are symbols, so we | |
4366 // can compare their raw pointers. | |
4367 const int num_params = num_fixed_params + num_opt_named_params; | |
4368 const int other_num_params = | |
4369 other_num_fixed_params + other_num_opt_named_params; | |
4370 bool found_param_name; | |
4371 String& other_param_name = String::Handle(); | |
4372 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { | |
4373 other_param_name = other.ParameterNameAt(i); | |
4374 ASSERT(other_param_name.IsSymbol()); | |
4375 found_param_name = false; | |
4376 for (intptr_t j = num_fixed_params; j < num_params; j++) { | |
4377 ASSERT(String::Handle(ParameterNameAt(j)).IsSymbol()); | |
4378 if (ParameterNameAt(j) == other_param_name.raw()) { | |
4379 found_param_name = true; | |
4380 if (!TestParameterType(test_kind, | |
4381 j, i, | |
4382 type_arguments, other, other_type_arguments, | |
4383 malformed_error)) { | |
4384 return false; | |
4385 } | |
4386 break; | |
4387 } | |
4388 } | |
4389 if (!found_param_name) { | |
4390 return false; | |
4391 } | |
4392 } | |
4393 } | |
4394 | |
4395 // TODO(regis): Remove the following code once the flag is removed. | |
4396 | |
4214 // Check the types of fixed parameters. | 4397 // Check the types of fixed parameters. |
4215 for (intptr_t i = 0; i < num_fixed_params; i++) { | 4398 for (intptr_t i = 0; i < num_fixed_params; i++) { |
4216 if (!TestParameterType(test_kind, | 4399 if (!TestParameterType(test_kind, |
4217 i, type_arguments, other, other_type_arguments, | 4400 i, i, type_arguments, other, other_type_arguments, |
4218 malformed_error)) { | 4401 malformed_error)) { |
4219 return false; | 4402 return false; |
4220 } | 4403 } |
4221 } | 4404 } |
4222 // Check the names and types of optional parameters. | 4405 // Check the names and types of optional parameters. |
4223 // Check that for each optional named parameter of type T of the other | 4406 // Check that for each optional named parameter of type T of the other |
4224 // function type, there is a corresponding optional named parameter of this | 4407 // function type, there is a corresponding optional named parameter of this |
4225 // function at the same position with an identical name and with a type S | 4408 // function at the same position with an identical name and with a type S |
4226 // that is a either a subtype or supertype of T (if test_kind == kIsSubtypeOf) | 4409 // that is a either a subtype or supertype of T (if test_kind == kIsSubtypeOf) |
4227 // or that is more specific than T (if test_kind == kIsMoreSpecificThan). | 4410 // or that is more specific than T (if test_kind == kIsMoreSpecificThan). |
4228 // Note that SetParameterNameAt() guarantees that names are symbols, so we | 4411 // Note that SetParameterNameAt() guarantees that names are symbols, so we |
4229 // can compare their raw pointers. | 4412 // can compare their raw pointers. |
4230 const intptr_t other_num_params = | 4413 const intptr_t other_num_params = other_num_fixed_params + |
4231 other_num_fixed_params + other_num_opt_params; | 4414 other_num_opt_pos_params + other_num_opt_named_params; |
4232 String& other_param_name = String::Handle(); | 4415 String& other_param_name = String::Handle(); |
4233 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { | 4416 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { |
4234 other_param_name = other.ParameterNameAt(i); | 4417 other_param_name = other.ParameterNameAt(i); |
4418 ASSERT(other_param_name.IsSymbol()); | |
4419 ASSERT(String::Handle(ParameterNameAt(i)).IsSymbol()); | |
4235 if ((ParameterNameAt(i) != other_param_name.raw()) || | 4420 if ((ParameterNameAt(i) != other_param_name.raw()) || |
4236 !TestParameterType(test_kind, | 4421 !TestParameterType(test_kind, |
4237 i, type_arguments, other, other_type_arguments, | 4422 i, i, type_arguments, other, other_type_arguments, |
4238 malformed_error)) { | 4423 malformed_error)) { |
4239 return false; | 4424 return false; |
4240 } | 4425 } |
4241 } | 4426 } |
4242 return true; | 4427 return true; |
4243 } | 4428 } |
4244 | 4429 |
4245 | 4430 |
4246 bool Function::IsImplicitClosureFunction() const { | 4431 bool Function::IsImplicitClosureFunction() const { |
4247 if (!IsClosureFunction()) { | 4432 if (!IsClosureFunction()) { |
(...skipping 30 matching lines...) Expand all Loading... | |
4278 result.set_name(name); | 4463 result.set_name(name); |
4279 result.set_kind(kind); | 4464 result.set_kind(kind); |
4280 result.set_is_static(is_static); | 4465 result.set_is_static(is_static); |
4281 result.set_is_const(is_const); | 4466 result.set_is_const(is_const); |
4282 result.set_is_abstract(is_abstract); | 4467 result.set_is_abstract(is_abstract); |
4283 result.set_is_external(is_external); | 4468 result.set_is_external(is_external); |
4284 result.set_owner(owner); | 4469 result.set_owner(owner); |
4285 result.set_token_pos(token_pos); | 4470 result.set_token_pos(token_pos); |
4286 result.set_end_token_pos(token_pos); | 4471 result.set_end_token_pos(token_pos); |
4287 result.set_num_fixed_parameters(0); | 4472 result.set_num_fixed_parameters(0); |
4288 result.set_num_optional_parameters(0); | 4473 result.set_num_optional_positional_parameters(0); |
4474 result.set_num_optional_named_parameters(0); | |
4289 result.set_usage_counter(0); | 4475 result.set_usage_counter(0); |
4290 result.set_deoptimization_counter(0); | 4476 result.set_deoptimization_counter(0); |
4291 result.set_is_optimizable(true); | 4477 result.set_is_optimizable(true); |
4292 result.set_has_finally(false); | 4478 result.set_has_finally(false); |
4293 result.set_is_native(false); | 4479 result.set_is_native(false); |
4294 return result.raw(); | 4480 return result.raw(); |
4295 } | 4481 } |
4296 | 4482 |
4297 | 4483 |
4298 RawFunction* Function::NewClosureFunction(const String& name, | 4484 RawFunction* Function::NewClosureFunction(const String& name, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4337 } | 4523 } |
4338 closure_function.set_context_scope(context_scope); | 4524 closure_function.set_context_scope(context_scope); |
4339 | 4525 |
4340 // Set closure function's result type to this result type. | 4526 // Set closure function's result type to this result type. |
4341 closure_function.set_result_type(AbstractType::Handle(result_type())); | 4527 closure_function.set_result_type(AbstractType::Handle(result_type())); |
4342 | 4528 |
4343 // Set closure function's formal parameters to this formal parameters, | 4529 // Set closure function's formal parameters to this formal parameters, |
4344 // removing the receiver if this is an instance method. | 4530 // removing the receiver if this is an instance method. |
4345 const int has_receiver = is_static() ? 0 : 1; | 4531 const int has_receiver = is_static() ? 0 : 1; |
4346 const int num_fixed_params = num_fixed_parameters() - has_receiver; | 4532 const int num_fixed_params = num_fixed_parameters() - has_receiver; |
4347 const int num_optional_params = num_optional_parameters(); | 4533 const int num_opt_pos_params = num_optional_positional_parameters(); |
4348 const int num_params = num_fixed_params + num_optional_params; | 4534 const int num_opt_named_params = num_optional_named_parameters(); |
4535 const int num_params = | |
4536 num_fixed_params + num_opt_pos_params + num_opt_named_params; | |
4349 closure_function.set_num_fixed_parameters(num_fixed_params); | 4537 closure_function.set_num_fixed_parameters(num_fixed_params); |
4350 closure_function.set_num_optional_parameters(num_optional_params); | 4538 closure_function.set_num_optional_positional_parameters(num_opt_pos_params); |
4539 closure_function.set_num_optional_named_parameters(num_opt_named_params); | |
4351 closure_function.set_parameter_types(Array::Handle(Array::New(num_params, | 4540 closure_function.set_parameter_types(Array::Handle(Array::New(num_params, |
4352 Heap::kOld))); | 4541 Heap::kOld))); |
4353 closure_function.set_parameter_names(Array::Handle(Array::New(num_params, | 4542 closure_function.set_parameter_names(Array::Handle(Array::New(num_params, |
4354 Heap::kOld))); | 4543 Heap::kOld))); |
4355 AbstractType& param_type = AbstractType::Handle(); | 4544 AbstractType& param_type = AbstractType::Handle(); |
4356 String& param_name = String::Handle(); | 4545 String& param_name = String::Handle(); |
4357 for (int i = 0; i < num_params; i++) { | 4546 for (int i = 0; i < num_params; i++) { |
4358 param_type = ParameterTypeAt(i + has_receiver); | 4547 param_type = ParameterTypeAt(i + has_receiver); |
4359 closure_function.SetParameterTypeAt(i, param_type); | 4548 closure_function.SetParameterTypeAt(i, param_type); |
4360 param_name = ParameterNameAt(i + has_receiver); | 4549 param_name = ParameterNameAt(i + has_receiver); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4396 NameVisibility name_visibility, | 4585 NameVisibility name_visibility, |
4397 const AbstractTypeArguments& instantiator) const { | 4586 const AbstractTypeArguments& instantiator) const { |
4398 const GrowableObjectArray& pieces = | 4587 const GrowableObjectArray& pieces = |
4399 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4588 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
4400 const String& kCommaSpace = String::Handle(Symbols::New(", ")); | 4589 const String& kCommaSpace = String::Handle(Symbols::New(", ")); |
4401 const String& kColonSpace = String::Handle(Symbols::New(": ")); | 4590 const String& kColonSpace = String::Handle(Symbols::New(": ")); |
4402 const String& kLParen = String::Handle(Symbols::New("(")); | 4591 const String& kLParen = String::Handle(Symbols::New("(")); |
4403 const String& kRParen = String::Handle(Symbols::New(") => ")); | 4592 const String& kRParen = String::Handle(Symbols::New(") => ")); |
4404 const String& kLBracket = String::Handle(Symbols::New("[")); | 4593 const String& kLBracket = String::Handle(Symbols::New("[")); |
4405 const String& kRBracket = String::Handle(Symbols::New("]")); | 4594 const String& kRBracket = String::Handle(Symbols::New("]")); |
4595 const String& kLBrace = String::Handle(Symbols::New("{")); | |
4596 const String& kRBrace = String::Handle(Symbols::New("}")); | |
4406 String& name = String::Handle(); | 4597 String& name = String::Handle(); |
4407 if (!instantiate && !is_static()) { | 4598 if (!instantiate && !is_static()) { |
4408 // Prefix the signature with its type parameters, if any (e.g. "<K, V>"). | 4599 // Prefix the signature with its type parameters, if any (e.g. "<K, V>"). |
4409 // The signature of static functions cannot be type parameterized. | 4600 // The signature of static functions cannot be type parameterized. |
4410 const String& kSpaceExtendsSpace = | 4601 const String& kSpaceExtendsSpace = |
4411 String::Handle(Symbols::New(" extends ")); | 4602 String::Handle(Symbols::New(" extends ")); |
4412 const String& kLAngleBracket = String::Handle(Symbols::New("<")); | 4603 const String& kLAngleBracket = String::Handle(Symbols::New("<")); |
4413 const String& kRAngleBracket = String::Handle(Symbols::New(">")); | 4604 const String& kRAngleBracket = String::Handle(Symbols::New(">")); |
4414 const Class& function_class = Class::Handle(Owner()); | 4605 const Class& function_class = Class::Handle(Owner()); |
4415 ASSERT(!function_class.IsNull()); | 4606 ASSERT(!function_class.IsNull()); |
(...skipping 17 matching lines...) Expand all Loading... | |
4433 if (i < num_type_parameters - 1) { | 4624 if (i < num_type_parameters - 1) { |
4434 pieces.Add(kCommaSpace); | 4625 pieces.Add(kCommaSpace); |
4435 } | 4626 } |
4436 } | 4627 } |
4437 pieces.Add(kRAngleBracket); | 4628 pieces.Add(kRAngleBracket); |
4438 } | 4629 } |
4439 } | 4630 } |
4440 AbstractType& param_type = AbstractType::Handle(); | 4631 AbstractType& param_type = AbstractType::Handle(); |
4441 const intptr_t num_params = NumberOfParameters(); | 4632 const intptr_t num_params = NumberOfParameters(); |
4442 const intptr_t num_fixed_params = num_fixed_parameters(); | 4633 const intptr_t num_fixed_params = num_fixed_parameters(); |
4443 const intptr_t num_opt_params = num_optional_parameters(); | 4634 const intptr_t num_opt_pos_params = num_optional_positional_parameters(); |
4635 const intptr_t num_opt_named_params = num_optional_named_parameters(); | |
4636 const intptr_t num_opt_params = num_opt_pos_params + num_opt_named_params; | |
4444 ASSERT((num_fixed_params + num_opt_params) == num_params); | 4637 ASSERT((num_fixed_params + num_opt_params) == num_params); |
4445 pieces.Add(kLParen); | 4638 pieces.Add(kLParen); |
4446 for (intptr_t i = 0; i < num_fixed_params; i++) { | 4639 for (intptr_t i = 0; i < num_fixed_params; i++) { |
4447 param_type = ParameterTypeAt(i); | 4640 param_type = ParameterTypeAt(i); |
4448 ASSERT(!param_type.IsNull()); | 4641 ASSERT(!param_type.IsNull()); |
4449 if (instantiate && !param_type.IsInstantiated()) { | 4642 if (instantiate && !param_type.IsInstantiated()) { |
4450 param_type = param_type.InstantiateFrom(instantiator); | 4643 param_type = param_type.InstantiateFrom(instantiator); |
4451 } | 4644 } |
4452 name = param_type.BuildName(name_visibility); | 4645 name = param_type.BuildName(name_visibility); |
4453 pieces.Add(name); | 4646 pieces.Add(name); |
4454 if (i != (num_params - 1)) { | 4647 if (i != (num_params - 1)) { |
4455 pieces.Add(kCommaSpace); | 4648 pieces.Add(kCommaSpace); |
4456 } | 4649 } |
4457 } | 4650 } |
4458 if (num_opt_params > 0) { | 4651 if (num_opt_params > 0) { |
4459 pieces.Add(kLBracket); | 4652 if (num_opt_pos_params > 0) { |
4653 pieces.Add(kLBracket); | |
4654 } else { | |
4655 pieces.Add(kLBrace); | |
4656 } | |
4460 for (intptr_t i = num_fixed_params; i < num_params; i++) { | 4657 for (intptr_t i = num_fixed_params; i < num_params; i++) { |
4461 name = ParameterNameAt(i); | 4658 // The parameter name of an optional positional parameter does not need |
4462 pieces.Add(name); | 4659 // to be part of the signature, since it is not used. |
4463 pieces.Add(kColonSpace); | 4660 if (!FLAG_reject_named_argument_as_positional || |
4661 (num_opt_named_params > 0)) { | |
4662 name = ParameterNameAt(i); | |
4663 pieces.Add(name); | |
4664 pieces.Add(kColonSpace); | |
4665 } | |
4464 param_type = ParameterTypeAt(i); | 4666 param_type = ParameterTypeAt(i); |
4465 if (instantiate && !param_type.IsInstantiated()) { | 4667 if (instantiate && !param_type.IsInstantiated()) { |
4466 param_type = param_type.InstantiateFrom(instantiator); | 4668 param_type = param_type.InstantiateFrom(instantiator); |
4467 } | 4669 } |
4468 ASSERT(!param_type.IsNull()); | 4670 ASSERT(!param_type.IsNull()); |
4469 name = param_type.BuildName(name_visibility); | 4671 name = param_type.BuildName(name_visibility); |
4470 pieces.Add(name); | 4672 pieces.Add(name); |
4471 if (i != (num_params - 1)) { | 4673 if (i != (num_params - 1)) { |
4472 pieces.Add(kCommaSpace); | 4674 pieces.Add(kCommaSpace); |
4473 } | 4675 } |
4474 } | 4676 } |
4475 pieces.Add(kRBracket); | 4677 if (num_opt_pos_params > 0) { |
4678 pieces.Add(kRBracket); | |
4679 } else { | |
4680 pieces.Add(kRBrace); | |
4681 } | |
4476 } | 4682 } |
4477 pieces.Add(kRParen); | 4683 pieces.Add(kRParen); |
4478 AbstractType& res_type = AbstractType::Handle(result_type()); | 4684 AbstractType& res_type = AbstractType::Handle(result_type()); |
4479 if (instantiate && !res_type.IsInstantiated()) { | 4685 if (instantiate && !res_type.IsInstantiated()) { |
4480 res_type = res_type.InstantiateFrom(instantiator); | 4686 res_type = res_type.InstantiateFrom(instantiator); |
4481 } | 4687 } |
4482 name = res_type.BuildName(name_visibility); | 4688 name = res_type.BuildName(name_visibility); |
4483 pieces.Add(name); | 4689 pieces.Add(name); |
4484 const Array& strings = Array::Handle(Array::MakeArray(pieces)); | 4690 const Array& strings = Array::Handle(Array::MakeArray(pieces)); |
4485 return Symbols::New(String::Handle(String::ConcatAll(strings))); | 4691 return Symbols::New(String::Handle(String::ConcatAll(strings))); |
(...skipping 6716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11202 } | 11408 } |
11203 return result.raw(); | 11409 return result.raw(); |
11204 } | 11410 } |
11205 | 11411 |
11206 | 11412 |
11207 const char* WeakProperty::ToCString() const { | 11413 const char* WeakProperty::ToCString() const { |
11208 return "_WeakProperty"; | 11414 return "_WeakProperty"; |
11209 } | 11415 } |
11210 | 11416 |
11211 } // namespace dart | 11417 } // namespace dart |
OLD | NEW |