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

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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698