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

Side by Side Diff: runtime/vm/object.cc

Issue 22685007: Implement updated method overriding rules in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698