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, | 18 DEFINE_FLAG(bool, error_on_bad_override, false, |
19 "Report error for bad overrides."); | 19 "Report error for bad overrides."); |
20 DEFINE_FLAG(bool, error_on_bad_type, false, | 20 DEFINE_FLAG(bool, error_on_bad_type, false, |
21 "Report error for malformed types."); | 21 "Report error for malformed types."); |
22 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 22 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
23 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 23 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
24 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 24 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
25 DECLARE_FLAG(bool, enable_type_checks); | 25 DECLARE_FLAG(bool, enable_type_checks); |
26 DECLARE_FLAG(bool, use_cha); | 26 DECLARE_FLAG(bool, use_cha); |
27 | 27 |
| 28 |
28 bool ClassFinalizer::AllClassesFinalized() { | 29 bool ClassFinalizer::AllClassesFinalized() { |
29 ObjectStore* object_store = Isolate::Current()->object_store(); | 30 ObjectStore* object_store = Isolate::Current()->object_store(); |
30 const GrowableObjectArray& classes = | 31 const GrowableObjectArray& classes = |
31 GrowableObjectArray::Handle(object_store->pending_classes()); | 32 GrowableObjectArray::Handle(object_store->pending_classes()); |
32 return classes.Length() == 0; | 33 return classes.Length() == 0; |
33 } | 34 } |
34 | 35 |
35 | 36 |
36 // Removes optimized code once we load more classes, since --use_cha based | 37 // Removes optimized code once we load more classes, since --use_cha based |
37 // optimizations may have become invalid. | 38 // optimizations may have become invalid. |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 Script::Handle(target_class.script()), | 367 Script::Handle(target_class.script()), |
367 factory.token_pos(), | 368 factory.token_pos(), |
368 "class '%s' has no constructor or factory named '%s'", | 369 "class '%s' has no constructor or factory named '%s'", |
369 target_class_name.ToCString(), | 370 target_class_name.ToCString(), |
370 user_visible_target_name.ToCString()); | 371 user_visible_target_name.ToCString()); |
371 factory.SetRedirectionType(type); | 372 factory.SetRedirectionType(type); |
372 ASSERT(factory.RedirectionTarget() == Function::null()); | 373 ASSERT(factory.RedirectionTarget() == Function::null()); |
373 return; | 374 return; |
374 } | 375 } |
375 | 376 |
376 if (FLAG_error_on_bad_override) { | 377 if (Isolate::Current()->ErrorOnBadOverrideEnabled()) { |
377 // Verify that the target is compatible with the redirecting factory. | 378 // Verify that the target is compatible with the redirecting factory. |
378 Error& error = Error::Handle(); | 379 Error& error = Error::Handle(); |
379 if (!target.HasCompatibleParametersWith(factory, &error)) { | 380 if (!target.HasCompatibleParametersWith(factory, &error)) { |
380 const Script& script = Script::Handle(target_class.script()); | 381 const Script& script = Script::Handle(target_class.script()); |
381 type = NewFinalizedMalformedType( | 382 type = NewFinalizedMalformedType( |
382 error, script, target.token_pos(), | 383 error, script, target.token_pos(), |
383 "constructor '%s' has incompatible parameters with " | 384 "constructor '%s' has incompatible parameters with " |
384 "redirecting factory '%s'", | 385 "redirecting factory '%s'", |
385 String::Handle(target.name()).ToCString(), | 386 String::Handle(target.name()).ToCString(), |
386 String::Handle(factory.name()).ToCString()); | 387 String::Handle(factory.name()).ToCString()); |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 977 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
977 | 978 |
978 // Initialize the type argument vector. | 979 // Initialize the type argument vector. |
979 // Check the number of parsed type arguments, if any. | 980 // Check the number of parsed type arguments, if any. |
980 // Specifying no type arguments indicates a raw type, which is not an error. | 981 // Specifying no type arguments indicates a raw type, which is not an error. |
981 // However, type parameter bounds are checked below, even for a raw type. | 982 // However, type parameter bounds are checked below, even for a raw type. |
982 TypeArguments& arguments = | 983 TypeArguments& arguments = |
983 TypeArguments::Handle(isolate, parameterized_type.arguments()); | 984 TypeArguments::Handle(isolate, parameterized_type.arguments()); |
984 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 985 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
985 // Wrong number of type arguments. The type is mapped to the raw type. | 986 // Wrong number of type arguments. The type is mapped to the raw type. |
986 if (FLAG_error_on_bad_type) { | 987 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { |
987 const String& type_class_name = | 988 const String& type_class_name = |
988 String::Handle(isolate, type_class.Name()); | 989 String::Handle(isolate, type_class.Name()); |
989 ReportError(cls, parameterized_type.token_pos(), | 990 ReportError(cls, parameterized_type.token_pos(), |
990 "wrong number of type arguments for class '%s'", | 991 "wrong number of type arguments for class '%s'", |
991 type_class_name.ToCString()); | 992 type_class_name.ToCString()); |
992 } | 993 } |
993 // Make the type raw and continue without reporting any error. | 994 // Make the type raw and continue without reporting any error. |
994 // A static warning should have been reported. | 995 // A static warning should have been reported. |
995 arguments = TypeArguments::null(); | 996 arguments = TypeArguments::null(); |
996 parameterized_type.set_arguments(arguments); | 997 parameterized_type.set_arguments(arguments); |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 error = type.error(); | 1348 error = type.error(); |
1348 } else { | 1349 } else { |
1349 ASSERT(type.IsInstantiated()); | 1350 ASSERT(type.IsInstantiated()); |
1350 } | 1351 } |
1351 const Instance& const_value = Instance::Handle(I, field.value()); | 1352 const Instance& const_value = Instance::Handle(I, field.value()); |
1352 if (!error.IsNull() || | 1353 if (!error.IsNull() || |
1353 (!type.IsDynamicType() && | 1354 (!type.IsDynamicType() && |
1354 !const_value.IsInstanceOf(type, | 1355 !const_value.IsInstanceOf(type, |
1355 Object::null_type_arguments(), | 1356 Object::null_type_arguments(), |
1356 &error))) { | 1357 &error))) { |
1357 if (FLAG_error_on_bad_type) { | 1358 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { |
1358 const AbstractType& const_value_type = AbstractType::Handle( | 1359 const AbstractType& const_value_type = AbstractType::Handle( |
1359 I, const_value.GetType()); | 1360 I, const_value.GetType()); |
1360 const String& const_value_type_name = String::Handle( | 1361 const String& const_value_type_name = String::Handle( |
1361 I, const_value_type.UserVisibleName()); | 1362 I, const_value_type.UserVisibleName()); |
1362 const String& type_name = String::Handle(I, type.UserVisibleName()); | 1363 const String& type_name = String::Handle(I, type.UserVisibleName()); |
1363 ReportErrors(error, cls, field.token_pos(), | 1364 ReportErrors(error, cls, field.token_pos(), |
1364 "error initializing static %s field '%s': " | 1365 "error initializing static %s field '%s': " |
1365 "type '%s' is not a subtype of type '%s'", | 1366 "type '%s' is not a subtype of type '%s'", |
1366 field.is_const() ? "const" : "final", | 1367 field.is_const() ? "const" : "final", |
1367 name.ToCString(), | 1368 name.ToCString(), |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 // interfaces. | 1411 // interfaces. |
1411 array = cls.functions(); | 1412 array = cls.functions(); |
1412 Function& function = Function::Handle(I); | 1413 Function& function = Function::Handle(I); |
1413 Function& overridden_function = Function::Handle(I); | 1414 Function& overridden_function = Function::Handle(I); |
1414 const intptr_t num_functions = array.Length(); | 1415 const intptr_t num_functions = array.Length(); |
1415 Error& error = Error::Handle(I); | 1416 Error& error = Error::Handle(I); |
1416 for (intptr_t i = 0; i < num_functions; i++) { | 1417 for (intptr_t i = 0; i < num_functions; i++) { |
1417 function ^= array.At(i); | 1418 function ^= array.At(i); |
1418 ResolveAndFinalizeSignature(cls, function); | 1419 ResolveAndFinalizeSignature(cls, function); |
1419 name = function.name(); | 1420 name = function.name(); |
1420 if (FLAG_error_on_bad_override && // Report signature conflicts only. | 1421 // Report signature conflicts only. |
| 1422 if (Isolate::Current()->ErrorOnBadOverrideEnabled() && |
1421 !function.is_static() && !function.IsConstructor()) { | 1423 !function.is_static() && !function.IsConstructor()) { |
1422 // A constructor cannot override anything. | 1424 // A constructor cannot override anything. |
1423 for (intptr_t i = 0; i < interfaces.Length(); i++) { | 1425 for (intptr_t i = 0; i < interfaces.Length(); i++) { |
1424 super_class ^= interfaces.At(i); | 1426 super_class ^= interfaces.At(i); |
1425 // Finalize superclass since overrides check relies on all members | 1427 // Finalize superclass since overrides check relies on all members |
1426 // of the superclass to be finalized. | 1428 // of the superclass to be finalized. |
1427 FinalizeClass(super_class); | 1429 FinalizeClass(super_class); |
1428 overridden_function = super_class.LookupDynamicFunction(name); | 1430 overridden_function = super_class.LookupDynamicFunction(name); |
1429 if (!overridden_function.IsNull() && | 1431 if (!overridden_function.IsNull() && |
1430 !function.HasCompatibleParametersWith(overridden_function, | 1432 !function.HasCompatibleParametersWith(overridden_function, |
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2558 if (num_type_arguments > 0) { | 2560 if (num_type_arguments > 0) { |
2559 if (num_type_arguments == num_type_parameters) { | 2561 if (num_type_arguments == num_type_parameters) { |
2560 for (intptr_t i = 0; i < num_type_arguments; i++) { | 2562 for (intptr_t i = 0; i < num_type_arguments; i++) { |
2561 arg = type_args.TypeAt(i); | 2563 arg = type_args.TypeAt(i); |
2562 arg = arg.CloneUnfinalized(); | 2564 arg = arg.CloneUnfinalized(); |
2563 ASSERT(!arg.IsBeingFinalized()); | 2565 ASSERT(!arg.IsBeingFinalized()); |
2564 collected_args.Add(arg); | 2566 collected_args.Add(arg); |
2565 } | 2567 } |
2566 return; | 2568 return; |
2567 } | 2569 } |
2568 if (FLAG_error_on_bad_type) { | 2570 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { |
2569 const String& type_class_name = String::Handle(type_class.Name()); | 2571 const String& type_class_name = String::Handle(type_class.Name()); |
2570 ReportError(cls, type.token_pos(), | 2572 ReportError(cls, type.token_pos(), |
2571 "wrong number of type arguments for class '%s'", | 2573 "wrong number of type arguments for class '%s'", |
2572 type_class_name.ToCString()); | 2574 type_class_name.ToCString()); |
2573 } | 2575 } |
2574 // Discard provided type arguments and treat type as raw. | 2576 // Discard provided type arguments and treat type as raw. |
2575 } | 2577 } |
2576 // Fill arguments with type dynamic. | 2578 // Fill arguments with type dynamic. |
2577 for (intptr_t i = 0; i < num_type_parameters; i++) { | 2579 for (intptr_t i = 0; i < num_type_parameters; i++) { |
2578 arg = Type::DynamicType(); | 2580 arg = Type::DynamicType(); |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2981 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, | 2983 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, |
2982 const Script& script, | 2984 const Script& script, |
2983 const Type& type, | 2985 const Type& type, |
2984 const char* format, | 2986 const char* format, |
2985 va_list args) { | 2987 va_list args) { |
2986 LanguageError& error = LanguageError::Handle( | 2988 LanguageError& error = LanguageError::Handle( |
2987 LanguageError::NewFormattedV( | 2989 LanguageError::NewFormattedV( |
2988 prev_error, script, type.token_pos(), | 2990 prev_error, script, type.token_pos(), |
2989 Report::kMalformedType, Heap::kOld, | 2991 Report::kMalformedType, Heap::kOld, |
2990 format, args)); | 2992 format, args)); |
2991 if (FLAG_error_on_bad_type) { | 2993 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { |
2992 ReportError(error); | 2994 ReportError(error); |
2993 } | 2995 } |
2994 type.set_error(error); | 2996 type.set_error(error); |
2995 // Make the type raw, since it may not be possible to | 2997 // Make the type raw, since it may not be possible to |
2996 // properly finalize its type arguments. | 2998 // properly finalize its type arguments. |
2997 type.set_type_class(Class::Handle(Object::dynamic_class())); | 2999 type.set_type_class(Class::Handle(Object::dynamic_class())); |
2998 type.set_arguments(Object::null_type_arguments()); | 3000 type.set_arguments(Object::null_type_arguments()); |
2999 if (!type.IsFinalized()) { | 3001 if (!type.IsFinalized()) { |
3000 type.SetIsFinalized(); | 3002 type.SetIsFinalized(); |
3001 // Do not canonicalize malformed types, since they may not be resolved. | 3003 // Do not canonicalize malformed types, since they may not be resolved. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 const Type& type, | 3045 const Type& type, |
3044 const char* format, ...) { | 3046 const char* format, ...) { |
3045 va_list args; | 3047 va_list args; |
3046 va_start(args, format); | 3048 va_start(args, format); |
3047 LanguageError& error = LanguageError::Handle( | 3049 LanguageError& error = LanguageError::Handle( |
3048 LanguageError::NewFormattedV( | 3050 LanguageError::NewFormattedV( |
3049 prev_error, script, type.token_pos(), | 3051 prev_error, script, type.token_pos(), |
3050 Report::kMalboundedType, Heap::kOld, | 3052 Report::kMalboundedType, Heap::kOld, |
3051 format, args)); | 3053 format, args)); |
3052 va_end(args); | 3054 va_end(args); |
3053 if (FLAG_error_on_bad_type) { | 3055 if (Isolate::Current()->ErrorOnBadTypeEnabled()) { |
3054 ReportError(error); | 3056 ReportError(error); |
3055 } | 3057 } |
3056 type.set_error(error); | 3058 type.set_error(error); |
3057 if (!type.IsFinalized()) { | 3059 if (!type.IsFinalized()) { |
3058 type.SetIsFinalized(); | 3060 type.SetIsFinalized(); |
3059 // Do not canonicalize malbounded types. | 3061 // Do not canonicalize malbounded types. |
3060 } | 3062 } |
3061 } | 3063 } |
3062 | 3064 |
3063 | 3065 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3158 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3160 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3159 field ^= fields_array.At(0); | 3161 field ^= fields_array.At(0); |
3160 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3162 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3161 name ^= field.name(); | 3163 name ^= field.name(); |
3162 expected_name ^= String::New("_data"); | 3164 expected_name ^= String::New("_data"); |
3163 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3165 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3164 #endif | 3166 #endif |
3165 } | 3167 } |
3166 | 3168 |
3167 } // namespace dart | 3169 } // namespace dart |
OLD | NEW |