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 1829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 // Prefinalized classes have a VM internal representation and no Dart fields. | 1901 // Prefinalized classes have a VM internal representation and no Dart fields. |
1901 // Their instance size is precomputed and field offsets are known. | 1902 // Their instance size is precomputed and field offsets are known. |
1902 if (!is_prefinalized()) { | 1903 if (!is_prefinalized()) { |
1903 // Compute offsets of instance fields and instance size. | 1904 // Compute offsets of instance fields and instance size. |
1904 CalculateFieldOffsets(); | 1905 CalculateFieldOffsets(); |
1905 } | 1906 } |
1906 set_is_finalized(); | 1907 set_is_finalized(); |
1907 } | 1908 } |
1908 | 1909 |
1909 | 1910 |
1910 static const char* FormatPatchError(const char* format, const Object& obj) { | 1911 static RawError* FormatError(const Error& prev_error, |
1911 const char* msg = obj.ToCString(); | 1912 const Script& script, |
1912 intptr_t len = OS::SNPrint(NULL, 0, format, msg) + 1; | 1913 intptr_t token_pos, |
1913 char* result = Isolate::Current()->current_zone()->Alloc<char>(len); | 1914 const char* format, ...) { |
1914 OS::SNPrint(result, len, format, msg); | 1915 va_list args; |
1915 return result; | 1916 va_start(args, format); |
| 1917 if (prev_error.IsNull()) { |
| 1918 return Parser::FormatError(script, token_pos, "Error", format, args); |
| 1919 } else { |
| 1920 return Parser::FormatErrorWithAppend(prev_error, script, token_pos, |
| 1921 "Error", format, args); |
| 1922 } |
1916 } | 1923 } |
1917 | 1924 |
1918 | 1925 |
1919 // Apply the members from the patch class to the original class. | 1926 // Apply the members from the patch class to the original class. |
1920 const char* Class::ApplyPatch(const Class& patch) const { | 1927 bool Class::ApplyPatch(const Class& patch, Error* error) const { |
| 1928 ASSERT(error != NULL); |
1921 ASSERT(!is_finalized()); | 1929 ASSERT(!is_finalized()); |
1922 // Shared handles used during the iteration. | 1930 // Shared handles used during the iteration. |
1923 String& member_name = String::Handle(); | 1931 String& member_name = String::Handle(); |
1924 | 1932 |
1925 const PatchClass& patch_class = | 1933 const PatchClass& patch_class = |
1926 PatchClass::Handle(PatchClass::New(*this, patch)); | 1934 PatchClass::Handle(PatchClass::New(*this, patch)); |
1927 | 1935 |
1928 Array& orig_list = Array::Handle(functions()); | 1936 Array& orig_list = Array::Handle(functions()); |
1929 intptr_t orig_len = orig_list.Length(); | 1937 intptr_t orig_len = orig_list.Length(); |
1930 Array& patch_list = Array::Handle(patch.functions()); | 1938 Array& patch_list = Array::Handle(patch.functions()); |
(...skipping 19 matching lines...) Expand all Loading... |
1950 member_name ^= orig_func.name(); | 1958 member_name ^= orig_func.name(); |
1951 func = patch.LookupFunction(member_name); | 1959 func = patch.LookupFunction(member_name); |
1952 if (func.IsNull()) { | 1960 if (func.IsNull()) { |
1953 // Non-patched function is preserved, all patched functions are added in | 1961 // Non-patched function is preserved, all patched functions are added in |
1954 // the loop below. | 1962 // the loop below. |
1955 // However, an implicitly created constructor should not be preserved if | 1963 // However, an implicitly created constructor should not be preserved if |
1956 // the patch provides a constructor or a factory. Wait for now. | 1964 // the patch provides a constructor or a factory. Wait for now. |
1957 if (orig_func.raw() != orig_implicit_ctor.raw()) { | 1965 if (orig_func.raw() != orig_implicit_ctor.raw()) { |
1958 new_functions.Add(orig_func); | 1966 new_functions.Add(orig_func); |
1959 } | 1967 } |
1960 } else if (!func.HasCompatibleParametersWith(orig_func) && | 1968 } else if (func.UserVisibleSignature() != |
1961 !(func.IsFactory() && orig_func.IsConstructor() && | 1969 orig_func.UserVisibleSignature()) { |
1962 (func.num_fixed_parameters() + 1 == | 1970 // Compare user visible signatures to ignore different implicit parameters |
1963 orig_func.num_fixed_parameters()))) { | 1971 // when patching a constructor with a factory. |
1964 return FormatPatchError("mismatched parameters: %s", member_name); | 1972 *error = FormatError(*error, // No previous error. |
| 1973 Script::Handle(patch.script()), func.token_pos(), |
| 1974 "signature mismatch: '%s'", member_name.ToCString()); |
| 1975 return false; |
1965 } | 1976 } |
1966 } | 1977 } |
1967 for (intptr_t i = 0; i < patch_len; i++) { | 1978 for (intptr_t i = 0; i < patch_len; i++) { |
1968 func ^= patch_list.At(i); | 1979 func ^= patch_list.At(i); |
1969 if (func.IsConstructor() || func.IsFactory()) { | 1980 if (func.IsConstructor() || func.IsFactory()) { |
1970 // Do not preserve the original implicit constructor, if any. | 1981 // Do not preserve the original implicit constructor, if any. |
1971 orig_implicit_ctor = Function::null(); | 1982 orig_implicit_ctor = Function::null(); |
1972 } | 1983 } |
1973 func.set_owner(patch_class); | 1984 func.set_owner(patch_class); |
1974 new_functions.Add(func); | 1985 new_functions.Add(func); |
(...skipping 17 matching lines...) Expand all Loading... |
1992 new_list = Array::New(patch_len + orig_len); | 2003 new_list = Array::New(patch_len + orig_len); |
1993 for (intptr_t i = 0; i < patch_len; i++) { | 2004 for (intptr_t i = 0; i < patch_len; i++) { |
1994 field ^= patch_list.At(i); | 2005 field ^= patch_list.At(i); |
1995 field.set_owner(*this); | 2006 field.set_owner(*this); |
1996 member_name = field.name(); | 2007 member_name = field.name(); |
1997 // TODO(iposva): Verify non-public fields only. | 2008 // TODO(iposva): Verify non-public fields only. |
1998 | 2009 |
1999 // Verify no duplicate additions. | 2010 // Verify no duplicate additions. |
2000 orig_field ^= LookupField(member_name); | 2011 orig_field ^= LookupField(member_name); |
2001 if (!orig_field.IsNull()) { | 2012 if (!orig_field.IsNull()) { |
2002 return FormatPatchError("duplicate field: %s", member_name); | 2013 *error = FormatError(*error, // No previous error. |
| 2014 Script::Handle(patch.script()), field.token_pos(), |
| 2015 "duplicate field: %s", member_name.ToCString()); |
| 2016 return false; |
2003 } | 2017 } |
2004 new_list.SetAt(i, field); | 2018 new_list.SetAt(i, field); |
2005 } | 2019 } |
2006 for (intptr_t i = 0; i < orig_len; i++) { | 2020 for (intptr_t i = 0; i < orig_len; i++) { |
2007 field ^= orig_list.At(i); | 2021 field ^= orig_list.At(i); |
2008 new_list.SetAt(patch_len + i, field); | 2022 new_list.SetAt(patch_len + i, field); |
2009 } | 2023 } |
2010 SetFields(new_list); | 2024 SetFields(new_list); |
2011 | 2025 |
2012 // The functions and fields in the patch class are no longer needed. | 2026 // The functions and fields in the patch class are no longer needed. |
2013 patch.SetFunctions(Object::empty_array()); | 2027 patch.SetFunctions(Object::empty_array()); |
2014 patch.SetFields(Object::empty_array()); | 2028 patch.SetFields(Object::empty_array()); |
2015 return NULL; | 2029 return true; |
2016 } | 2030 } |
2017 | 2031 |
2018 | 2032 |
2019 // Ensure that top level parsing of the class has been done. | 2033 // Ensure that top level parsing of the class has been done. |
2020 RawError* Class::EnsureIsFinalized(Isolate* isolate) const { | 2034 RawError* Class::EnsureIsFinalized(Isolate* isolate) const { |
2021 // Finalized classes have already been parsed. | 2035 // Finalized classes have already been parsed. |
2022 if (is_finalized()) { | 2036 if (is_finalized()) { |
2023 return Error::null(); | 2037 return Error::null(); |
2024 } | 2038 } |
2025 ASSERT(isolate != NULL); | 2039 ASSERT(isolate != NULL); |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3113 } | 3127 } |
3114 type_class = type.type_class(); | 3128 type_class = type.type_class(); |
3115 if (!type_class.IsDynamicClass()) { | 3129 if (!type_class.IsDynamicClass()) { |
3116 return false; | 3130 return false; |
3117 } | 3131 } |
3118 } | 3132 } |
3119 return true; | 3133 return true; |
3120 } | 3134 } |
3121 | 3135 |
3122 | 3136 |
3123 static RawError* FormatError(const Error& prev_error, | |
3124 const Script& script, | |
3125 intptr_t token_pos, | |
3126 const char* format, ...) { | |
3127 va_list args; | |
3128 va_start(args, format); | |
3129 if (prev_error.IsNull()) { | |
3130 return Parser::FormatError(script, token_pos, "Error", format, args); | |
3131 } else { | |
3132 return Parser::FormatErrorWithAppend(prev_error, script, token_pos, | |
3133 "Error", format, args); | |
3134 } | |
3135 } | |
3136 | |
3137 | |
3138 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind, | 3137 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind, |
3139 const AbstractTypeArguments& other, | 3138 const AbstractTypeArguments& other, |
3140 intptr_t len, | 3139 intptr_t len, |
3141 Error* malformed_error) const { | 3140 Error* malformed_error) const { |
3142 ASSERT(Length() >= len); | 3141 ASSERT(Length() >= len); |
3143 ASSERT(!other.IsNull()); | 3142 ASSERT(!other.IsNull()); |
3144 ASSERT(other.Length() >= len); | 3143 ASSERT(other.Length() >= len); |
3145 AbstractType& type = AbstractType::Handle(); | 3144 AbstractType& type = AbstractType::Handle(); |
3146 AbstractType& other_type = AbstractType::Handle(); | 3145 AbstractType& other_type = AbstractType::Handle(); |
3147 for (intptr_t i = 0; i < len; i++) { | 3146 for (intptr_t i = 0; i < len; i++) { |
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4347 } | 4346 } |
4348 | 4347 |
4349 | 4348 |
4350 const char* Function::ToFullyQualifiedCString() const { | 4349 const char* Function::ToFullyQualifiedCString() const { |
4351 char* chars = NULL; | 4350 char* chars = NULL; |
4352 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); | 4351 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); |
4353 return chars; | 4352 return chars; |
4354 } | 4353 } |
4355 | 4354 |
4356 | 4355 |
4357 bool Function::HasCompatibleParametersWith(const Function& other) const { | 4356 bool Function::HasCompatibleParametersWith(const Function& other, |
4358 const intptr_t num_fixed_params = num_fixed_parameters(); | 4357 Error* error) const { |
4359 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); | 4358 ASSERT(FLAG_error_on_bad_override); |
4360 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 4359 // Check that this function's signature type is a subtype of the other |
4361 const intptr_t other_num_opt_pos_params = | 4360 // function's signature type. |
4362 other.NumOptionalPositionalParameters(); | 4361 if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(), |
4363 // A generative constructor may be compared to a redirecting factory and be | 4362 other, Object::null_abstract_type_arguments(), error)) { |
4364 // compatible although it has an additional phase parameter. | 4363 // For more informative error reporting, use the location of the other |
4365 const intptr_t num_ignored_params = | 4364 // function here, since the caller will use the location of this function. |
4366 (other.IsRedirectingFactory() && IsConstructor()) ? 1 : 0; | 4365 *error = FormatError( |
4367 // The default values of optional parameters can differ. | 4366 *error, // A malformed error if non null. |
4368 // This function requires the same arguments or less and accepts the same | 4367 Script::Handle(other.script()), |
4369 // arguments or more. | 4368 other.token_pos(), |
4370 if (((num_fixed_params - num_ignored_params) > other_num_fixed_params) || | 4369 "signature type '%s' of function '%s' is not a subtype of signature " |
4371 ((num_fixed_params - num_ignored_params) + num_opt_pos_params < | 4370 "type '%s' of function '%s'", |
4372 other_num_fixed_params + other_num_opt_pos_params)) { | 4371 String::Handle(UserVisibleSignature()).ToCString(), |
| 4372 String::Handle(UserVisibleName()).ToCString(), |
| 4373 String::Handle(other.UserVisibleSignature()).ToCString(), |
| 4374 String::Handle(other.UserVisibleName()).ToCString()); |
4373 return false; | 4375 return false; |
4374 } | 4376 } |
| 4377 // We should also check that if the other function explicitly specifies a |
| 4378 // default value for a formal parameter, this function does not specify a |
| 4379 // different default value for the same parameter. However, this check is not |
| 4380 // possible in the current implementation, because the default parameter |
| 4381 // values are not stored in the Function object, but discarded after a |
| 4382 // function is compiled. |
4375 return true; | 4383 return true; |
4376 } | 4384 } |
4377 | 4385 |
4378 | 4386 |
4379 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter | 4387 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter |
4380 // of this function is a subtype or a supertype of the type of the specified | 4388 // of this function is a subtype or a supertype of the type of the specified |
4381 // parameter of the other function. | 4389 // parameter of the other function. |
4382 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified | 4390 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified |
4383 // parameter of this function is more specific than the type of the specified | 4391 // parameter of this function is more specific than the type of the specified |
4384 // parameter of the other function. | 4392 // parameter of the other function. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4434 const intptr_t num_fixed_params = num_fixed_parameters(); | 4442 const intptr_t num_fixed_params = num_fixed_parameters(); |
4435 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); | 4443 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); |
4436 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); | 4444 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); |
4437 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 4445 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |
4438 const intptr_t other_num_opt_pos_params = | 4446 const intptr_t other_num_opt_pos_params = |
4439 other.NumOptionalPositionalParameters(); | 4447 other.NumOptionalPositionalParameters(); |
4440 const intptr_t other_num_opt_named_params = | 4448 const intptr_t other_num_opt_named_params = |
4441 other.NumOptionalNamedParameters(); | 4449 other.NumOptionalNamedParameters(); |
4442 // This function requires the same arguments or less and accepts the same | 4450 // This function requires the same arguments or less and accepts the same |
4443 // arguments or more. | 4451 // arguments or more. |
4444 if ((num_fixed_params > other_num_fixed_params) || | 4452 // A generative constructor may be compared to a redirecting factory and be |
4445 (num_fixed_params + num_opt_pos_params < | 4453 // compatible although it has an additional phase parameter. |
4446 other_num_fixed_params + other_num_opt_pos_params) || | 4454 // More generally, we can ignore implicit parameters. |
| 4455 const intptr_t num_ignored_params = NumImplicitParameters(); |
| 4456 const intptr_t other_num_ignored_params = other.NumImplicitParameters(); |
| 4457 if (((num_fixed_params - num_ignored_params) > |
| 4458 (other_num_fixed_params - other_num_ignored_params)) || |
| 4459 ((num_fixed_params - num_ignored_params + num_opt_pos_params) < |
| 4460 (other_num_fixed_params - other_num_ignored_params + |
| 4461 other_num_opt_pos_params)) || |
4447 (num_opt_named_params < other_num_opt_named_params)) { | 4462 (num_opt_named_params < other_num_opt_named_params)) { |
4448 return false; | 4463 return false; |
4449 } | 4464 } |
4450 // Check the result type. | 4465 // Check the result type. |
4451 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); | 4466 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); |
4452 if (!other_res_type.IsInstantiated()) { | 4467 if (!other_res_type.IsInstantiated()) { |
4453 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, | 4468 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, |
4454 malformed_error); | 4469 malformed_error); |
4455 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); | 4470 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); |
4456 } | 4471 } |
(...skipping 12 matching lines...) Expand all Loading... |
4469 return false; | 4484 return false; |
4470 } | 4485 } |
4471 } else { | 4486 } else { |
4472 ASSERT(test_kind == kIsMoreSpecificThan); | 4487 ASSERT(test_kind == kIsMoreSpecificThan); |
4473 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { | 4488 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { |
4474 return false; | 4489 return false; |
4475 } | 4490 } |
4476 } | 4491 } |
4477 } | 4492 } |
4478 // Check the types of fixed and optional positional parameters. | 4493 // Check the types of fixed and optional positional parameters. |
4479 for (intptr_t i = 0; | 4494 for (intptr_t i = 0; i < (other_num_fixed_params - other_num_ignored_params + |
4480 i < other_num_fixed_params + other_num_opt_pos_params; i++) { | 4495 other_num_opt_pos_params); i++) { |
4481 if (!TestParameterType(test_kind, | 4496 if (!TestParameterType(test_kind, |
4482 i, i, type_arguments, other, other_type_arguments, | 4497 i + num_ignored_params, i + other_num_ignored_params, |
| 4498 type_arguments, other, other_type_arguments, |
4483 malformed_error)) { | 4499 malformed_error)) { |
4484 return false; | 4500 return false; |
4485 } | 4501 } |
4486 } | 4502 } |
4487 // Check the names and types of optional named parameters. | 4503 // Check the names and types of optional named parameters. |
4488 if (other_num_opt_named_params == 0) { | 4504 if (other_num_opt_named_params == 0) { |
4489 return true; | 4505 return true; |
4490 } | 4506 } |
4491 // Check that for each optional named parameter of type T of the other | 4507 // Check that for each optional named parameter of type T of the other |
4492 // function type, there exists an optional named parameter of this function | 4508 // function type, there exists an optional named parameter of this function |
(...skipping 10093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14586 } | 14602 } |
14587 | 14603 |
14588 | 14604 |
14589 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 14605 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
14590 stream->OpenObject(); | 14606 stream->OpenObject(); |
14591 stream->CloseObject(); | 14607 stream->CloseObject(); |
14592 } | 14608 } |
14593 | 14609 |
14594 | 14610 |
14595 } // namespace dart | 14611 } // namespace dart |
OLD | NEW |