| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| 11 #include "vm/longjump.h" | 11 #include "vm/longjump.h" |
| 12 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
| 13 #include "vm/report.h" | 13 #include "vm/report.h" |
| 14 #include "vm/symbols.h" | 14 #include "vm/symbols.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 DEFINE_FLAG(bool, error_on_bad_override, false, | |
| 19 "Report error for bad overrides."); | |
| 20 DEFINE_FLAG(bool, error_on_bad_type, false, | |
| 21 "Report error for malformed types."); | |
| 22 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 18 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
| 23 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 19 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
| 24 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 20 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
| 25 DECLARE_FLAG(bool, use_cha_deopt); | 21 DECLARE_FLAG(bool, use_cha_deopt); |
| 26 | 22 |
| 27 | 23 |
| 28 bool ClassFinalizer::AllClassesFinalized() { | 24 bool ClassFinalizer::AllClassesFinalized() { |
| 29 ObjectStore* object_store = Isolate::Current()->object_store(); | 25 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 30 const GrowableObjectArray& classes = | 26 const GrowableObjectArray& classes = |
| 31 GrowableObjectArray::Handle(object_store->pending_classes()); | 27 GrowableObjectArray::Handle(object_store->pending_classes()); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 Script::Handle(target_class.script()), | 366 Script::Handle(target_class.script()), |
| 371 factory.token_pos(), | 367 factory.token_pos(), |
| 372 "class '%s' has no constructor or factory named '%s'", | 368 "class '%s' has no constructor or factory named '%s'", |
| 373 target_class_name.ToCString(), | 369 target_class_name.ToCString(), |
| 374 user_visible_target_name.ToCString()); | 370 user_visible_target_name.ToCString()); |
| 375 factory.SetRedirectionType(type); | 371 factory.SetRedirectionType(type); |
| 376 ASSERT(factory.RedirectionTarget() == Function::null()); | 372 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 377 return; | 373 return; |
| 378 } | 374 } |
| 379 | 375 |
| 380 if (Isolate::Current()->ErrorOnBadOverrideEnabled()) { | 376 if (Isolate::Current()->flags().error_on_bad_override()) { |
| 381 // Verify that the target is compatible with the redirecting factory. | 377 // Verify that the target is compatible with the redirecting factory. |
| 382 Error& error = Error::Handle(); | 378 Error& error = Error::Handle(); |
| 383 if (!target.HasCompatibleParametersWith(factory, &error)) { | 379 if (!target.HasCompatibleParametersWith(factory, &error)) { |
| 384 const Script& script = Script::Handle(target_class.script()); | 380 const Script& script = Script::Handle(target_class.script()); |
| 385 type = NewFinalizedMalformedType( | 381 type = NewFinalizedMalformedType( |
| 386 error, script, target.token_pos(), | 382 error, script, target.token_pos(), |
| 387 "constructor '%s' has incompatible parameters with " | 383 "constructor '%s' has incompatible parameters with " |
| 388 "redirecting factory '%s'", | 384 "redirecting factory '%s'", |
| 389 String::Handle(target.name()).ToCString(), | 385 String::Handle(target.name()).ToCString(), |
| 390 String::Handle(factory.name()).ToCString()); | 386 String::Handle(factory.name()).ToCString()); |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 989 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 994 | 990 |
| 995 // Initialize the type argument vector. | 991 // Initialize the type argument vector. |
| 996 // Check the number of parsed type arguments, if any. | 992 // Check the number of parsed type arguments, if any. |
| 997 // Specifying no type arguments indicates a raw type, which is not an error. | 993 // Specifying no type arguments indicates a raw type, which is not an error. |
| 998 // However, type parameter bounds are checked below, even for a raw type. | 994 // However, type parameter bounds are checked below, even for a raw type. |
| 999 TypeArguments& arguments = | 995 TypeArguments& arguments = |
| 1000 TypeArguments::Handle(isolate, parameterized_type.arguments()); | 996 TypeArguments::Handle(isolate, parameterized_type.arguments()); |
| 1001 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 997 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 1002 // Wrong number of type arguments. The type is mapped to the raw type. | 998 // Wrong number of type arguments. The type is mapped to the raw type. |
| 1003 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { | 999 if (Isolate::Current()->flags().error_on_bad_type()) { |
| 1004 const String& type_class_name = | 1000 const String& type_class_name = |
| 1005 String::Handle(isolate, type_class.Name()); | 1001 String::Handle(isolate, type_class.Name()); |
| 1006 ReportError(cls, parameterized_type.token_pos(), | 1002 ReportError(cls, parameterized_type.token_pos(), |
| 1007 "wrong number of type arguments for class '%s'", | 1003 "wrong number of type arguments for class '%s'", |
| 1008 type_class_name.ToCString()); | 1004 type_class_name.ToCString()); |
| 1009 } | 1005 } |
| 1010 // Make the type raw and continue without reporting any error. | 1006 // Make the type raw and continue without reporting any error. |
| 1011 // A static warning should have been reported. | 1007 // A static warning should have been reported. |
| 1012 arguments = TypeArguments::null(); | 1008 arguments = TypeArguments::null(); |
| 1013 parameterized_type.set_arguments(arguments); | 1009 parameterized_type.set_arguments(arguments); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 error = type.error(); | 1360 error = type.error(); |
| 1365 } else { | 1361 } else { |
| 1366 ASSERT(type.IsInstantiated()); | 1362 ASSERT(type.IsInstantiated()); |
| 1367 } | 1363 } |
| 1368 const Instance& const_value = Instance::Handle(I, field.value()); | 1364 const Instance& const_value = Instance::Handle(I, field.value()); |
| 1369 if (!error.IsNull() || | 1365 if (!error.IsNull() || |
| 1370 (!type.IsDynamicType() && | 1366 (!type.IsDynamicType() && |
| 1371 !const_value.IsInstanceOf(type, | 1367 !const_value.IsInstanceOf(type, |
| 1372 Object::null_type_arguments(), | 1368 Object::null_type_arguments(), |
| 1373 &error))) { | 1369 &error))) { |
| 1374 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { | 1370 if (Isolate::Current()->flags().error_on_bad_type()) { |
| 1375 const AbstractType& const_value_type = AbstractType::Handle( | 1371 const AbstractType& const_value_type = AbstractType::Handle( |
| 1376 I, const_value.GetType()); | 1372 I, const_value.GetType()); |
| 1377 const String& const_value_type_name = String::Handle( | 1373 const String& const_value_type_name = String::Handle( |
| 1378 I, const_value_type.UserVisibleName()); | 1374 I, const_value_type.UserVisibleName()); |
| 1379 const String& type_name = String::Handle(I, type.UserVisibleName()); | 1375 const String& type_name = String::Handle(I, type.UserVisibleName()); |
| 1380 ReportErrors(error, cls, field.token_pos(), | 1376 ReportErrors(error, cls, field.token_pos(), |
| 1381 "error initializing static %s field '%s': " | 1377 "error initializing static %s field '%s': " |
| 1382 "type '%s' is not a subtype of type '%s'", | 1378 "type '%s' is not a subtype of type '%s'", |
| 1383 field.is_const() ? "const" : "final", | 1379 field.is_const() ? "const" : "final", |
| 1384 name.ToCString(), | 1380 name.ToCString(), |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1428 array = cls.functions(); | 1424 array = cls.functions(); |
| 1429 Function& function = Function::Handle(I); | 1425 Function& function = Function::Handle(I); |
| 1430 Function& overridden_function = Function::Handle(I); | 1426 Function& overridden_function = Function::Handle(I); |
| 1431 const intptr_t num_functions = array.Length(); | 1427 const intptr_t num_functions = array.Length(); |
| 1432 Error& error = Error::Handle(I); | 1428 Error& error = Error::Handle(I); |
| 1433 for (intptr_t i = 0; i < num_functions; i++) { | 1429 for (intptr_t i = 0; i < num_functions; i++) { |
| 1434 function ^= array.At(i); | 1430 function ^= array.At(i); |
| 1435 ResolveAndFinalizeSignature(cls, function); | 1431 ResolveAndFinalizeSignature(cls, function); |
| 1436 name = function.name(); | 1432 name = function.name(); |
| 1437 // Report signature conflicts only. | 1433 // Report signature conflicts only. |
| 1438 if (Isolate::Current()->ErrorOnBadOverrideEnabled() && | 1434 if (Isolate::Current()->flags().error_on_bad_override() && |
| 1439 !function.is_static() && !function.IsGenerativeConstructor()) { | 1435 !function.is_static() && !function.IsGenerativeConstructor()) { |
| 1440 // A constructor cannot override anything. | 1436 // A constructor cannot override anything. |
| 1441 for (intptr_t i = 0; i < interfaces.Length(); i++) { | 1437 for (intptr_t i = 0; i < interfaces.Length(); i++) { |
| 1442 super_class ^= interfaces.At(i); | 1438 super_class ^= interfaces.At(i); |
| 1443 // Finalize superclass since overrides check relies on all members | 1439 // Finalize superclass since overrides check relies on all members |
| 1444 // of the superclass to be finalized. | 1440 // of the superclass to be finalized. |
| 1445 FinalizeClass(super_class); | 1441 FinalizeClass(super_class); |
| 1446 overridden_function = super_class.LookupDynamicFunction(name); | 1442 overridden_function = super_class.LookupDynamicFunction(name); |
| 1447 if (!overridden_function.IsNull() && | 1443 if (!overridden_function.IsNull() && |
| 1448 !function.HasCompatibleParametersWith(overridden_function, | 1444 !function.HasCompatibleParametersWith(overridden_function, |
| (...skipping 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2588 if (num_type_arguments > 0) { | 2584 if (num_type_arguments > 0) { |
| 2589 if (num_type_arguments == num_type_parameters) { | 2585 if (num_type_arguments == num_type_parameters) { |
| 2590 for (intptr_t i = 0; i < num_type_arguments; i++) { | 2586 for (intptr_t i = 0; i < num_type_arguments; i++) { |
| 2591 arg = type_args.TypeAt(i); | 2587 arg = type_args.TypeAt(i); |
| 2592 arg = arg.CloneUnfinalized(); | 2588 arg = arg.CloneUnfinalized(); |
| 2593 ASSERT(!arg.IsBeingFinalized()); | 2589 ASSERT(!arg.IsBeingFinalized()); |
| 2594 collected_args.Add(arg); | 2590 collected_args.Add(arg); |
| 2595 } | 2591 } |
| 2596 return; | 2592 return; |
| 2597 } | 2593 } |
| 2598 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { | 2594 if (Isolate::Current()->flags().error_on_bad_type()) { |
| 2599 const String& type_class_name = String::Handle(type_class.Name()); | 2595 const String& type_class_name = String::Handle(type_class.Name()); |
| 2600 ReportError(cls, type.token_pos(), | 2596 ReportError(cls, type.token_pos(), |
| 2601 "wrong number of type arguments for class '%s'", | 2597 "wrong number of type arguments for class '%s'", |
| 2602 type_class_name.ToCString()); | 2598 type_class_name.ToCString()); |
| 2603 } | 2599 } |
| 2604 // Discard provided type arguments and treat type as raw. | 2600 // Discard provided type arguments and treat type as raw. |
| 2605 } | 2601 } |
| 2606 // Fill arguments with type dynamic. | 2602 // Fill arguments with type dynamic. |
| 2607 for (intptr_t i = 0; i < num_type_parameters; i++) { | 2603 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 2608 arg = Type::DynamicType(); | 2604 arg = Type::DynamicType(); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3011 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, | 3007 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, |
| 3012 const Script& script, | 3008 const Script& script, |
| 3013 const Type& type, | 3009 const Type& type, |
| 3014 const char* format, | 3010 const char* format, |
| 3015 va_list args) { | 3011 va_list args) { |
| 3016 LanguageError& error = LanguageError::Handle( | 3012 LanguageError& error = LanguageError::Handle( |
| 3017 LanguageError::NewFormattedV( | 3013 LanguageError::NewFormattedV( |
| 3018 prev_error, script, type.token_pos(), | 3014 prev_error, script, type.token_pos(), |
| 3019 Report::kMalformedType, Heap::kOld, | 3015 Report::kMalformedType, Heap::kOld, |
| 3020 format, args)); | 3016 format, args)); |
| 3021 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { | 3017 if (Isolate::Current()->flags().error_on_bad_type()) { |
| 3022 ReportError(error); | 3018 ReportError(error); |
| 3023 } | 3019 } |
| 3024 type.set_error(error); | 3020 type.set_error(error); |
| 3025 // Make the type raw, since it may not be possible to | 3021 // Make the type raw, since it may not be possible to |
| 3026 // properly finalize its type arguments. | 3022 // properly finalize its type arguments. |
| 3027 type.set_type_class(Class::Handle(Object::dynamic_class())); | 3023 type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 3028 type.set_arguments(Object::null_type_arguments()); | 3024 type.set_arguments(Object::null_type_arguments()); |
| 3029 if (!type.IsFinalized()) { | 3025 if (!type.IsFinalized()) { |
| 3030 type.SetIsFinalized(); | 3026 type.SetIsFinalized(); |
| 3031 // Do not canonicalize malformed types, since they may not be resolved. | 3027 // Do not canonicalize malformed types, since they may not be resolved. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3073 const Type& type, | 3069 const Type& type, |
| 3074 const char* format, ...) { | 3070 const char* format, ...) { |
| 3075 va_list args; | 3071 va_list args; |
| 3076 va_start(args, format); | 3072 va_start(args, format); |
| 3077 LanguageError& error = LanguageError::Handle( | 3073 LanguageError& error = LanguageError::Handle( |
| 3078 LanguageError::NewFormattedV( | 3074 LanguageError::NewFormattedV( |
| 3079 prev_error, script, type.token_pos(), | 3075 prev_error, script, type.token_pos(), |
| 3080 Report::kMalboundedType, Heap::kOld, | 3076 Report::kMalboundedType, Heap::kOld, |
| 3081 format, args)); | 3077 format, args)); |
| 3082 va_end(args); | 3078 va_end(args); |
| 3083 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { | 3079 if (Isolate::Current()->flags().error_on_bad_type()) { |
| 3084 ReportError(error); | 3080 ReportError(error); |
| 3085 } | 3081 } |
| 3086 type.set_error(error); | 3082 type.set_error(error); |
| 3087 if (!type.IsFinalized()) { | 3083 if (!type.IsFinalized()) { |
| 3088 type.SetIsFinalized(); | 3084 type.SetIsFinalized(); |
| 3089 // Do not canonicalize malbounded types. | 3085 // Do not canonicalize malbounded types. |
| 3090 } | 3086 } |
| 3091 } | 3087 } |
| 3092 | 3088 |
| 3093 | 3089 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3188 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3184 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3189 field ^= fields_array.At(0); | 3185 field ^= fields_array.At(0); |
| 3190 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3186 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3191 name ^= field.name(); | 3187 name ^= field.name(); |
| 3192 expected_name ^= String::New("_data"); | 3188 expected_name ^= String::New("_data"); |
| 3193 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3189 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3194 #endif | 3190 #endif |
| 3195 } | 3191 } |
| 3196 | 3192 |
| 3197 } // namespace dart | 3193 } // namespace dart |
| OLD | NEW |