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/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, | 51 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, |
52 "Huge method cutoff in tokens: Disables optimizations for huge methods."); | 52 "Huge method cutoff in tokens: Disables optimizations for huge methods."); |
53 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, | 53 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, |
54 "Huge method cutoff in unoptimized code size (in bytes)."); | 54 "Huge method cutoff in unoptimized code size (in bytes)."); |
55 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, | 55 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, |
56 "Throw an exception when the result of an integer calculation will not " | 56 "Throw an exception when the result of an integer calculation will not " |
57 "fit into a javascript integer."); | 57 "fit into a javascript integer."); |
58 DECLARE_FLAG(bool, trace_compiler); | 58 DECLARE_FLAG(bool, trace_compiler); |
59 DECLARE_FLAG(bool, eliminate_type_checks); | 59 DECLARE_FLAG(bool, eliminate_type_checks); |
60 DECLARE_FLAG(bool, enable_type_checks); | 60 DECLARE_FLAG(bool, enable_type_checks); |
| 61 DECLARE_FLAG(bool, error_on_bad_override); |
61 | 62 |
62 static const char* kGetterPrefix = "get:"; | 63 static const char* kGetterPrefix = "get:"; |
63 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); | 64 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |
64 static const char* kSetterPrefix = "set:"; | 65 static const char* kSetterPrefix = "set:"; |
65 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); | 66 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |
66 | 67 |
67 cpp_vtable Object::handle_vtable_ = 0; | 68 cpp_vtable Object::handle_vtable_ = 0; |
68 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 }; | 69 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 }; |
69 cpp_vtable Smi::handle_vtable_ = 0; | 70 cpp_vtable Smi::handle_vtable_ = 0; |
70 | 71 |
(...skipping 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1918 // Prefinalized classes have a VM internal representation and no Dart fields. | 1919 // Prefinalized classes have a VM internal representation and no Dart fields. |
1919 // Their instance size is precomputed and field offsets are known. | 1920 // Their instance size is precomputed and field offsets are known. |
1920 if (!is_prefinalized()) { | 1921 if (!is_prefinalized()) { |
1921 // Compute offsets of instance fields and instance size. | 1922 // Compute offsets of instance fields and instance size. |
1922 CalculateFieldOffsets(); | 1923 CalculateFieldOffsets(); |
1923 } | 1924 } |
1924 set_is_finalized(); | 1925 set_is_finalized(); |
1925 } | 1926 } |
1926 | 1927 |
1927 | 1928 |
1928 static const char* FormatPatchError(const char* format, const Object& obj) { | 1929 static RawError* FormatError(const Error& prev_error, |
1929 const char* msg = obj.ToCString(); | 1930 const Script& script, |
1930 intptr_t len = OS::SNPrint(NULL, 0, format, msg) + 1; | 1931 intptr_t token_pos, |
1931 char* result = Isolate::Current()->current_zone()->Alloc<char>(len); | 1932 const char* format, ...) { |
1932 OS::SNPrint(result, len, format, msg); | 1933 va_list args; |
1933 return result; | 1934 va_start(args, format); |
| 1935 if (prev_error.IsNull()) { |
| 1936 return Parser::FormatError(script, token_pos, "Error", format, args); |
| 1937 } else { |
| 1938 return Parser::FormatErrorWithAppend(prev_error, script, token_pos, |
| 1939 "Error", format, args); |
| 1940 } |
1934 } | 1941 } |
1935 | 1942 |
1936 | 1943 |
1937 // Apply the members from the patch class to the original class. | 1944 // Apply the members from the patch class to the original class. |
1938 const char* Class::ApplyPatch(const Class& patch) const { | 1945 bool Class::ApplyPatch(const Class& patch, Error* error) const { |
| 1946 ASSERT(error != NULL); |
1939 ASSERT(!is_finalized()); | 1947 ASSERT(!is_finalized()); |
1940 // Shared handles used during the iteration. | 1948 // Shared handles used during the iteration. |
1941 String& member_name = String::Handle(); | 1949 String& member_name = String::Handle(); |
1942 | 1950 |
1943 const PatchClass& patch_class = | 1951 const PatchClass& patch_class = |
1944 PatchClass::Handle(PatchClass::New(*this, patch)); | 1952 PatchClass::Handle(PatchClass::New(*this, patch)); |
1945 | 1953 |
1946 Array& orig_list = Array::Handle(functions()); | 1954 Array& orig_list = Array::Handle(functions()); |
1947 intptr_t orig_len = orig_list.Length(); | 1955 intptr_t orig_len = orig_list.Length(); |
1948 Array& patch_list = Array::Handle(patch.functions()); | 1956 Array& patch_list = Array::Handle(patch.functions()); |
(...skipping 19 matching lines...) Expand all Loading... |
1968 member_name ^= orig_func.name(); | 1976 member_name ^= orig_func.name(); |
1969 func = patch.LookupFunction(member_name); | 1977 func = patch.LookupFunction(member_name); |
1970 if (func.IsNull()) { | 1978 if (func.IsNull()) { |
1971 // Non-patched function is preserved, all patched functions are added in | 1979 // Non-patched function is preserved, all patched functions are added in |
1972 // the loop below. | 1980 // the loop below. |
1973 // However, an implicitly created constructor should not be preserved if | 1981 // However, an implicitly created constructor should not be preserved if |
1974 // the patch provides a constructor or a factory. Wait for now. | 1982 // the patch provides a constructor or a factory. Wait for now. |
1975 if (orig_func.raw() != orig_implicit_ctor.raw()) { | 1983 if (orig_func.raw() != orig_implicit_ctor.raw()) { |
1976 new_functions.Add(orig_func); | 1984 new_functions.Add(orig_func); |
1977 } | 1985 } |
1978 } else if (!func.HasCompatibleParametersWith(orig_func) && | 1986 } else if (func.UserVisibleSignature() != |
1979 !(func.IsFactory() && orig_func.IsConstructor() && | 1987 orig_func.UserVisibleSignature()) { |
1980 (func.num_fixed_parameters() + 1 == | 1988 // Compare user visible signatures to ignore different implicit parameters |
1981 orig_func.num_fixed_parameters()))) { | 1989 // when patching a constructor with a factory. |
1982 return FormatPatchError("mismatched parameters: %s", member_name); | 1990 *error = FormatError(*error, // No previous error. |
| 1991 Script::Handle(patch.script()), func.token_pos(), |
| 1992 "signature mismatch: '%s'", member_name.ToCString()); |
| 1993 return false; |
1983 } | 1994 } |
1984 } | 1995 } |
1985 for (intptr_t i = 0; i < patch_len; i++) { | 1996 for (intptr_t i = 0; i < patch_len; i++) { |
1986 func ^= patch_list.At(i); | 1997 func ^= patch_list.At(i); |
1987 if (func.IsConstructor() || func.IsFactory()) { | 1998 if (func.IsConstructor() || func.IsFactory()) { |
1988 // Do not preserve the original implicit constructor, if any. | 1999 // Do not preserve the original implicit constructor, if any. |
1989 orig_implicit_ctor = Function::null(); | 2000 orig_implicit_ctor = Function::null(); |
1990 } | 2001 } |
1991 func.set_owner(patch_class); | 2002 func.set_owner(patch_class); |
1992 new_functions.Add(func); | 2003 new_functions.Add(func); |
(...skipping 17 matching lines...) Expand all Loading... |
2010 new_list = Array::New(patch_len + orig_len); | 2021 new_list = Array::New(patch_len + orig_len); |
2011 for (intptr_t i = 0; i < patch_len; i++) { | 2022 for (intptr_t i = 0; i < patch_len; i++) { |
2012 field ^= patch_list.At(i); | 2023 field ^= patch_list.At(i); |
2013 field.set_owner(*this); | 2024 field.set_owner(*this); |
2014 member_name = field.name(); | 2025 member_name = field.name(); |
2015 // TODO(iposva): Verify non-public fields only. | 2026 // TODO(iposva): Verify non-public fields only. |
2016 | 2027 |
2017 // Verify no duplicate additions. | 2028 // Verify no duplicate additions. |
2018 orig_field ^= LookupField(member_name); | 2029 orig_field ^= LookupField(member_name); |
2019 if (!orig_field.IsNull()) { | 2030 if (!orig_field.IsNull()) { |
2020 return FormatPatchError("duplicate field: %s", member_name); | 2031 *error = FormatError(*error, // No previous error. |
| 2032 Script::Handle(patch.script()), field.token_pos(), |
| 2033 "duplicate field: %s", member_name.ToCString()); |
| 2034 return false; |
2021 } | 2035 } |
2022 new_list.SetAt(i, field); | 2036 new_list.SetAt(i, field); |
2023 } | 2037 } |
2024 for (intptr_t i = 0; i < orig_len; i++) { | 2038 for (intptr_t i = 0; i < orig_len; i++) { |
2025 field ^= orig_list.At(i); | 2039 field ^= orig_list.At(i); |
2026 new_list.SetAt(patch_len + i, field); | 2040 new_list.SetAt(patch_len + i, field); |
2027 } | 2041 } |
2028 SetFields(new_list); | 2042 SetFields(new_list); |
2029 | 2043 |
2030 // The functions and fields in the patch class are no longer needed. | 2044 // The functions and fields in the patch class are no longer needed. |
2031 patch.SetFunctions(Object::empty_array()); | 2045 patch.SetFunctions(Object::empty_array()); |
2032 patch.SetFields(Object::empty_array()); | 2046 patch.SetFields(Object::empty_array()); |
2033 return NULL; | 2047 return true; |
2034 } | 2048 } |
2035 | 2049 |
2036 | 2050 |
2037 // Ensure that top level parsing of the class has been done. | 2051 // Ensure that top level parsing of the class has been done. |
2038 RawError* Class::EnsureIsFinalized(Isolate* isolate) const { | 2052 RawError* Class::EnsureIsFinalized(Isolate* isolate) const { |
2039 // Finalized classes have already been parsed. | 2053 // Finalized classes have already been parsed. |
2040 if (is_finalized()) { | 2054 if (is_finalized()) { |
2041 return Error::null(); | 2055 return Error::null(); |
2042 } | 2056 } |
2043 ASSERT(isolate != NULL); | 2057 ASSERT(isolate != NULL); |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3131 } | 3145 } |
3132 type_class = type.type_class(); | 3146 type_class = type.type_class(); |
3133 if (!type_class.IsDynamicClass()) { | 3147 if (!type_class.IsDynamicClass()) { |
3134 return false; | 3148 return false; |
3135 } | 3149 } |
3136 } | 3150 } |
3137 return true; | 3151 return true; |
3138 } | 3152 } |
3139 | 3153 |
3140 | 3154 |
3141 static RawError* FormatError(const Error& prev_error, | |
3142 const Script& script, | |
3143 intptr_t token_pos, | |
3144 const char* format, ...) { | |
3145 va_list args; | |
3146 va_start(args, format); | |
3147 if (prev_error.IsNull()) { | |
3148 return Parser::FormatError(script, token_pos, "Error", format, args); | |
3149 } else { | |
3150 return Parser::FormatErrorWithAppend(prev_error, script, token_pos, | |
3151 "Error", format, args); | |
3152 } | |
3153 } | |
3154 | |
3155 | |
3156 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind, | 3155 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind, |
3157 const AbstractTypeArguments& other, | 3156 const AbstractTypeArguments& other, |
3158 intptr_t len, | 3157 intptr_t len, |
3159 Error* malformed_error) const { | 3158 Error* malformed_error) const { |
3160 ASSERT(Length() >= len); | 3159 ASSERT(Length() >= len); |
3161 ASSERT(!other.IsNull()); | 3160 ASSERT(!other.IsNull()); |
3162 ASSERT(other.Length() >= len); | 3161 ASSERT(other.Length() >= len); |
3163 AbstractType& type = AbstractType::Handle(); | 3162 AbstractType& type = AbstractType::Handle(); |
3164 AbstractType& other_type = AbstractType::Handle(); | 3163 AbstractType& other_type = AbstractType::Handle(); |
3165 for (intptr_t i = 0; i < len; i++) { | 3164 for (intptr_t i = 0; i < len; i++) { |
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4365 } | 4364 } |
4366 | 4365 |
4367 | 4366 |
4368 const char* Function::ToFullyQualifiedCString() const { | 4367 const char* Function::ToFullyQualifiedCString() const { |
4369 char* chars = NULL; | 4368 char* chars = NULL; |
4370 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); | 4369 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); |
4371 return chars; | 4370 return chars; |
4372 } | 4371 } |
4373 | 4372 |
4374 | 4373 |
4375 bool Function::HasCompatibleParametersWith(const Function& other) const { | 4374 bool Function::HasCompatibleParametersWith(const Function& other, |
4376 const intptr_t num_fixed_params = num_fixed_parameters(); | 4375 Error* error) const { |
4377 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); | 4376 ASSERT(FLAG_error_on_bad_override); |
4378 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 4377 // Check that this function's signature type is a subtype of the other |
4379 const intptr_t other_num_opt_pos_params = | 4378 // function's signature type. |
4380 other.NumOptionalPositionalParameters(); | 4379 if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(), |
4381 // A generative constructor may be compared to a redirecting factory and be | 4380 other, Object::null_abstract_type_arguments(), error)) { |
4382 // compatible although it has an additional phase parameter. | 4381 // For more informative error reporting, use the location of the other |
4383 const intptr_t num_ignored_params = | 4382 // function here, since the caller will use the location of this function. |
4384 (other.IsRedirectingFactory() && IsConstructor()) ? 1 : 0; | 4383 *error = FormatError( |
4385 // The default values of optional parameters can differ. | 4384 *error, // A malformed error if non null. |
4386 // This function requires the same arguments or less and accepts the same | 4385 Script::Handle(other.script()), |
4387 // arguments or more. | 4386 other.token_pos(), |
4388 if (((num_fixed_params - num_ignored_params) > other_num_fixed_params) || | 4387 "signature type '%s' of function '%s' is not a subtype of signature " |
4389 ((num_fixed_params - num_ignored_params) + num_opt_pos_params < | 4388 "type '%s' of function '%s'", |
4390 other_num_fixed_params + other_num_opt_pos_params)) { | 4389 String::Handle(UserVisibleSignature()).ToCString(), |
| 4390 String::Handle(UserVisibleName()).ToCString(), |
| 4391 String::Handle(other.UserVisibleSignature()).ToCString(), |
| 4392 String::Handle(other.UserVisibleName()).ToCString()); |
4391 return false; | 4393 return false; |
4392 } | 4394 } |
| 4395 // We should also check that if the other function explicitly specifies a |
| 4396 // default value for a formal parameter, this function does not specify a |
| 4397 // different default value for the same parameter. However, this check is not |
| 4398 // possible in the current implementation, because the default parameter |
| 4399 // values are not stored in the Function object, but discarded after a |
| 4400 // function is compiled. |
4393 return true; | 4401 return true; |
4394 } | 4402 } |
4395 | 4403 |
4396 | 4404 |
4397 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter | 4405 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter |
4398 // of this function is a subtype or a supertype of the type of the specified | 4406 // of this function is a subtype or a supertype of the type of the specified |
4399 // parameter of the other function. | 4407 // parameter of the other function. |
4400 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified | 4408 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified |
4401 // parameter of this function is more specific than the type of the specified | 4409 // parameter of this function is more specific than the type of the specified |
4402 // parameter of the other function. | 4410 // parameter of the other function. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4452 const intptr_t num_fixed_params = num_fixed_parameters(); | 4460 const intptr_t num_fixed_params = num_fixed_parameters(); |
4453 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); | 4461 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); |
4454 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); | 4462 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); |
4455 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 4463 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |
4456 const intptr_t other_num_opt_pos_params = | 4464 const intptr_t other_num_opt_pos_params = |
4457 other.NumOptionalPositionalParameters(); | 4465 other.NumOptionalPositionalParameters(); |
4458 const intptr_t other_num_opt_named_params = | 4466 const intptr_t other_num_opt_named_params = |
4459 other.NumOptionalNamedParameters(); | 4467 other.NumOptionalNamedParameters(); |
4460 // This function requires the same arguments or less and accepts the same | 4468 // This function requires the same arguments or less and accepts the same |
4461 // arguments or more. | 4469 // arguments or more. |
4462 if ((num_fixed_params > other_num_fixed_params) || | 4470 // A generative constructor may be compared to a redirecting factory and be |
4463 (num_fixed_params + num_opt_pos_params < | 4471 // compatible although it has an additional phase parameter. |
4464 other_num_fixed_params + other_num_opt_pos_params) || | 4472 // More generally, we can ignore implicit parameters. |
| 4473 const intptr_t num_ignored_params = NumImplicitParameters(); |
| 4474 const intptr_t other_num_ignored_params = other.NumImplicitParameters(); |
| 4475 if (((num_fixed_params - num_ignored_params) > |
| 4476 (other_num_fixed_params - other_num_ignored_params)) || |
| 4477 ((num_fixed_params - num_ignored_params + num_opt_pos_params) < |
| 4478 (other_num_fixed_params - other_num_ignored_params + |
| 4479 other_num_opt_pos_params)) || |
4465 (num_opt_named_params < other_num_opt_named_params)) { | 4480 (num_opt_named_params < other_num_opt_named_params)) { |
4466 return false; | 4481 return false; |
4467 } | 4482 } |
4468 // Check the result type. | 4483 // Check the result type. |
4469 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); | 4484 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); |
4470 if (!other_res_type.IsInstantiated()) { | 4485 if (!other_res_type.IsInstantiated()) { |
4471 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, | 4486 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, |
4472 malformed_error); | 4487 malformed_error); |
4473 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); | 4488 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); |
4474 } | 4489 } |
(...skipping 12 matching lines...) Expand all Loading... |
4487 return false; | 4502 return false; |
4488 } | 4503 } |
4489 } else { | 4504 } else { |
4490 ASSERT(test_kind == kIsMoreSpecificThan); | 4505 ASSERT(test_kind == kIsMoreSpecificThan); |
4491 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { | 4506 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { |
4492 return false; | 4507 return false; |
4493 } | 4508 } |
4494 } | 4509 } |
4495 } | 4510 } |
4496 // Check the types of fixed and optional positional parameters. | 4511 // Check the types of fixed and optional positional parameters. |
4497 for (intptr_t i = 0; | 4512 for (intptr_t i = 0; i < (other_num_fixed_params - other_num_ignored_params + |
4498 i < other_num_fixed_params + other_num_opt_pos_params; i++) { | 4513 other_num_opt_pos_params); i++) { |
4499 if (!TestParameterType(test_kind, | 4514 if (!TestParameterType(test_kind, |
4500 i, i, type_arguments, other, other_type_arguments, | 4515 i + num_ignored_params, i + other_num_ignored_params, |
| 4516 type_arguments, other, other_type_arguments, |
4501 malformed_error)) { | 4517 malformed_error)) { |
4502 return false; | 4518 return false; |
4503 } | 4519 } |
4504 } | 4520 } |
4505 // Check the names and types of optional named parameters. | 4521 // Check the names and types of optional named parameters. |
4506 if (other_num_opt_named_params == 0) { | 4522 if (other_num_opt_named_params == 0) { |
4507 return true; | 4523 return true; |
4508 } | 4524 } |
4509 // Check that for each optional named parameter of type T of the other | 4525 // Check that for each optional named parameter of type T of the other |
4510 // function type, there exists an optional named parameter of this function | 4526 // function type, there exists an optional named parameter of this function |
(...skipping 10099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14610 } | 14626 } |
14611 | 14627 |
14612 | 14628 |
14613 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 14629 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
14614 stream->OpenObject(); | 14630 stream->OpenObject(); |
14615 stream->CloseObject(); | 14631 stream->CloseObject(); |
14616 } | 14632 } |
14617 | 14633 |
14618 | 14634 |
14619 } // namespace dart | 14635 } // namespace dart |
OLD | NEW |