Chromium Code Reviews| 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 | |
| 29 static bool ErrorOnBadTypeEnabled() { | |
| 30 return FLAG_error_on_bad_type || Isolate::Current()->checked_mode(); | |
|
regis
2015/02/03 22:23:17
--checked does not include --error-on-bad-type or
| |
| 31 } | |
| 32 | |
| 33 | |
| 34 static bool ErrorOnBadOverrideEnabled() { | |
| 35 return FLAG_error_on_bad_override || Isolate::Current()->checked_mode(); | |
| 36 } | |
| 37 | |
| 38 | |
| 28 bool ClassFinalizer::AllClassesFinalized() { | 39 bool ClassFinalizer::AllClassesFinalized() { |
| 29 ObjectStore* object_store = Isolate::Current()->object_store(); | 40 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 30 const GrowableObjectArray& classes = | 41 const GrowableObjectArray& classes = |
| 31 GrowableObjectArray::Handle(object_store->pending_classes()); | 42 GrowableObjectArray::Handle(object_store->pending_classes()); |
| 32 return classes.Length() == 0; | 43 return classes.Length() == 0; |
| 33 } | 44 } |
| 34 | 45 |
| 35 | 46 |
| 36 // Removes optimized code once we load more classes, since --use_cha based | 47 // Removes optimized code once we load more classes, since --use_cha based |
| 37 // optimizations may have become invalid. | 48 // optimizations may have become invalid. |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 Script::Handle(target_class.script()), | 377 Script::Handle(target_class.script()), |
| 367 factory.token_pos(), | 378 factory.token_pos(), |
| 368 "class '%s' has no constructor or factory named '%s'", | 379 "class '%s' has no constructor or factory named '%s'", |
| 369 target_class_name.ToCString(), | 380 target_class_name.ToCString(), |
| 370 user_visible_target_name.ToCString()); | 381 user_visible_target_name.ToCString()); |
| 371 factory.SetRedirectionType(type); | 382 factory.SetRedirectionType(type); |
| 372 ASSERT(factory.RedirectionTarget() == Function::null()); | 383 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 373 return; | 384 return; |
| 374 } | 385 } |
| 375 | 386 |
| 376 if (FLAG_error_on_bad_override) { | 387 if (ErrorOnBadOverrideEnabled()) { |
| 377 // Verify that the target is compatible with the redirecting factory. | 388 // Verify that the target is compatible with the redirecting factory. |
| 378 Error& error = Error::Handle(); | 389 Error& error = Error::Handle(); |
| 379 if (!target.HasCompatibleParametersWith(factory, &error)) { | 390 if (!target.HasCompatibleParametersWith(factory, &error)) { |
| 380 const Script& script = Script::Handle(target_class.script()); | 391 const Script& script = Script::Handle(target_class.script()); |
| 381 type = NewFinalizedMalformedType( | 392 type = NewFinalizedMalformedType( |
| 382 error, script, target.token_pos(), | 393 error, script, target.token_pos(), |
| 383 "constructor '%s' has incompatible parameters with " | 394 "constructor '%s' has incompatible parameters with " |
| 384 "redirecting factory '%s'", | 395 "redirecting factory '%s'", |
| 385 String::Handle(target.name()).ToCString(), | 396 String::Handle(target.name()).ToCString(), |
| 386 String::Handle(factory.name()).ToCString()); | 397 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(); | 987 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 977 | 988 |
| 978 // Initialize the type argument vector. | 989 // Initialize the type argument vector. |
| 979 // Check the number of parsed type arguments, if any. | 990 // Check the number of parsed type arguments, if any. |
| 980 // Specifying no type arguments indicates a raw type, which is not an error. | 991 // 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. | 992 // However, type parameter bounds are checked below, even for a raw type. |
| 982 TypeArguments& arguments = | 993 TypeArguments& arguments = |
| 983 TypeArguments::Handle(isolate, parameterized_type.arguments()); | 994 TypeArguments::Handle(isolate, parameterized_type.arguments()); |
| 984 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 995 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 985 // Wrong number of type arguments. The type is mapped to the raw type. | 996 // Wrong number of type arguments. The type is mapped to the raw type. |
| 986 if (FLAG_error_on_bad_type) { | 997 if (ErrorOnBadTypeEnabled()) { |
| 987 const String& type_class_name = | 998 const String& type_class_name = |
| 988 String::Handle(isolate, type_class.Name()); | 999 String::Handle(isolate, type_class.Name()); |
| 989 ReportError(cls, parameterized_type.token_pos(), | 1000 ReportError(cls, parameterized_type.token_pos(), |
| 990 "wrong number of type arguments for class '%s'", | 1001 "wrong number of type arguments for class '%s'", |
| 991 type_class_name.ToCString()); | 1002 type_class_name.ToCString()); |
| 992 } | 1003 } |
| 993 // Make the type raw and continue without reporting any error. | 1004 // Make the type raw and continue without reporting any error. |
| 994 // A static warning should have been reported. | 1005 // A static warning should have been reported. |
| 995 arguments = TypeArguments::null(); | 1006 arguments = TypeArguments::null(); |
| 996 parameterized_type.set_arguments(arguments); | 1007 parameterized_type.set_arguments(arguments); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1347 error = type.error(); | 1358 error = type.error(); |
| 1348 } else { | 1359 } else { |
| 1349 ASSERT(type.IsInstantiated()); | 1360 ASSERT(type.IsInstantiated()); |
| 1350 } | 1361 } |
| 1351 const Instance& const_value = Instance::Handle(I, field.value()); | 1362 const Instance& const_value = Instance::Handle(I, field.value()); |
| 1352 if (!error.IsNull() || | 1363 if (!error.IsNull() || |
| 1353 (!type.IsDynamicType() && | 1364 (!type.IsDynamicType() && |
| 1354 !const_value.IsInstanceOf(type, | 1365 !const_value.IsInstanceOf(type, |
| 1355 Object::null_type_arguments(), | 1366 Object::null_type_arguments(), |
| 1356 &error))) { | 1367 &error))) { |
| 1357 if (FLAG_error_on_bad_type) { | 1368 if (ErrorOnBadTypeEnabled()) { |
| 1358 const AbstractType& const_value_type = AbstractType::Handle( | 1369 const AbstractType& const_value_type = AbstractType::Handle( |
| 1359 I, const_value.GetType()); | 1370 I, const_value.GetType()); |
| 1360 const String& const_value_type_name = String::Handle( | 1371 const String& const_value_type_name = String::Handle( |
| 1361 I, const_value_type.UserVisibleName()); | 1372 I, const_value_type.UserVisibleName()); |
| 1362 const String& type_name = String::Handle(I, type.UserVisibleName()); | 1373 const String& type_name = String::Handle(I, type.UserVisibleName()); |
| 1363 ReportErrors(error, cls, field.token_pos(), | 1374 ReportErrors(error, cls, field.token_pos(), |
| 1364 "error initializing static %s field '%s': " | 1375 "error initializing static %s field '%s': " |
| 1365 "type '%s' is not a subtype of type '%s'", | 1376 "type '%s' is not a subtype of type '%s'", |
| 1366 field.is_const() ? "const" : "final", | 1377 field.is_const() ? "const" : "final", |
| 1367 name.ToCString(), | 1378 name.ToCString(), |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1410 // interfaces. | 1421 // interfaces. |
| 1411 array = cls.functions(); | 1422 array = cls.functions(); |
| 1412 Function& function = Function::Handle(I); | 1423 Function& function = Function::Handle(I); |
| 1413 Function& overridden_function = Function::Handle(I); | 1424 Function& overridden_function = Function::Handle(I); |
| 1414 const intptr_t num_functions = array.Length(); | 1425 const intptr_t num_functions = array.Length(); |
| 1415 Error& error = Error::Handle(I); | 1426 Error& error = Error::Handle(I); |
| 1416 for (intptr_t i = 0; i < num_functions; i++) { | 1427 for (intptr_t i = 0; i < num_functions; i++) { |
| 1417 function ^= array.At(i); | 1428 function ^= array.At(i); |
| 1418 ResolveAndFinalizeSignature(cls, function); | 1429 ResolveAndFinalizeSignature(cls, function); |
| 1419 name = function.name(); | 1430 name = function.name(); |
| 1420 if (FLAG_error_on_bad_override && // Report signature conflicts only. | 1431 if (ErrorOnBadOverrideEnabled() && // Report signature conflicts only. |
| 1421 !function.is_static() && !function.IsConstructor()) { | 1432 !function.is_static() && !function.IsConstructor()) { |
| 1422 // A constructor cannot override anything. | 1433 // A constructor cannot override anything. |
| 1423 for (intptr_t i = 0; i < interfaces.Length(); i++) { | 1434 for (intptr_t i = 0; i < interfaces.Length(); i++) { |
| 1424 super_class ^= interfaces.At(i); | 1435 super_class ^= interfaces.At(i); |
| 1425 // Finalize superclass since overrides check relies on all members | 1436 // Finalize superclass since overrides check relies on all members |
| 1426 // of the superclass to be finalized. | 1437 // of the superclass to be finalized. |
| 1427 FinalizeClass(super_class); | 1438 FinalizeClass(super_class); |
| 1428 overridden_function = super_class.LookupDynamicFunction(name); | 1439 overridden_function = super_class.LookupDynamicFunction(name); |
| 1429 if (!overridden_function.IsNull() && | 1440 if (!overridden_function.IsNull() && |
| 1430 !function.HasCompatibleParametersWith(overridden_function, | 1441 !function.HasCompatibleParametersWith(overridden_function, |
| (...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2558 if (num_type_arguments > 0) { | 2569 if (num_type_arguments > 0) { |
| 2559 if (num_type_arguments == num_type_parameters) { | 2570 if (num_type_arguments == num_type_parameters) { |
| 2560 for (intptr_t i = 0; i < num_type_arguments; i++) { | 2571 for (intptr_t i = 0; i < num_type_arguments; i++) { |
| 2561 arg = type_args.TypeAt(i); | 2572 arg = type_args.TypeAt(i); |
| 2562 arg = arg.CloneUnfinalized(); | 2573 arg = arg.CloneUnfinalized(); |
| 2563 ASSERT(!arg.IsBeingFinalized()); | 2574 ASSERT(!arg.IsBeingFinalized()); |
| 2564 collected_args.Add(arg); | 2575 collected_args.Add(arg); |
| 2565 } | 2576 } |
| 2566 return; | 2577 return; |
| 2567 } | 2578 } |
| 2568 if (FLAG_error_on_bad_type) { | 2579 if (ErrorOnBadTypeEnabled()) { |
| 2569 const String& type_class_name = String::Handle(type_class.Name()); | 2580 const String& type_class_name = String::Handle(type_class.Name()); |
| 2570 ReportError(cls, type.token_pos(), | 2581 ReportError(cls, type.token_pos(), |
| 2571 "wrong number of type arguments for class '%s'", | 2582 "wrong number of type arguments for class '%s'", |
| 2572 type_class_name.ToCString()); | 2583 type_class_name.ToCString()); |
| 2573 } | 2584 } |
| 2574 // Discard provided type arguments and treat type as raw. | 2585 // Discard provided type arguments and treat type as raw. |
| 2575 } | 2586 } |
| 2576 // Fill arguments with type dynamic. | 2587 // Fill arguments with type dynamic. |
| 2577 for (intptr_t i = 0; i < num_type_parameters; i++) { | 2588 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 2578 arg = Type::DynamicType(); | 2589 arg = Type::DynamicType(); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2981 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, | 2992 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, |
| 2982 const Script& script, | 2993 const Script& script, |
| 2983 const Type& type, | 2994 const Type& type, |
| 2984 const char* format, | 2995 const char* format, |
| 2985 va_list args) { | 2996 va_list args) { |
| 2986 LanguageError& error = LanguageError::Handle( | 2997 LanguageError& error = LanguageError::Handle( |
| 2987 LanguageError::NewFormattedV( | 2998 LanguageError::NewFormattedV( |
| 2988 prev_error, script, type.token_pos(), | 2999 prev_error, script, type.token_pos(), |
| 2989 Report::kMalformedType, Heap::kOld, | 3000 Report::kMalformedType, Heap::kOld, |
| 2990 format, args)); | 3001 format, args)); |
| 2991 if (FLAG_error_on_bad_type) { | 3002 if (ErrorOnBadTypeEnabled()) { |
| 2992 ReportError(error); | 3003 ReportError(error); |
| 2993 } | 3004 } |
| 2994 type.set_error(error); | 3005 type.set_error(error); |
| 2995 // Make the type raw, since it may not be possible to | 3006 // Make the type raw, since it may not be possible to |
| 2996 // properly finalize its type arguments. | 3007 // properly finalize its type arguments. |
| 2997 type.set_type_class(Class::Handle(Object::dynamic_class())); | 3008 type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 2998 type.set_arguments(Object::null_type_arguments()); | 3009 type.set_arguments(Object::null_type_arguments()); |
| 2999 if (!type.IsFinalized()) { | 3010 if (!type.IsFinalized()) { |
| 3000 type.SetIsFinalized(); | 3011 type.SetIsFinalized(); |
| 3001 // Do not canonicalize malformed types, since they may not be resolved. | 3012 // 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, | 3054 const Type& type, |
| 3044 const char* format, ...) { | 3055 const char* format, ...) { |
| 3045 va_list args; | 3056 va_list args; |
| 3046 va_start(args, format); | 3057 va_start(args, format); |
| 3047 LanguageError& error = LanguageError::Handle( | 3058 LanguageError& error = LanguageError::Handle( |
| 3048 LanguageError::NewFormattedV( | 3059 LanguageError::NewFormattedV( |
| 3049 prev_error, script, type.token_pos(), | 3060 prev_error, script, type.token_pos(), |
| 3050 Report::kMalboundedType, Heap::kOld, | 3061 Report::kMalboundedType, Heap::kOld, |
| 3051 format, args)); | 3062 format, args)); |
| 3052 va_end(args); | 3063 va_end(args); |
| 3053 if (FLAG_error_on_bad_type) { | 3064 if (ErrorOnBadTypeEnabled()) { |
| 3054 ReportError(error); | 3065 ReportError(error); |
| 3055 } | 3066 } |
| 3056 type.set_error(error); | 3067 type.set_error(error); |
| 3057 if (!type.IsFinalized()) { | 3068 if (!type.IsFinalized()) { |
| 3058 type.SetIsFinalized(); | 3069 type.SetIsFinalized(); |
| 3059 // Do not canonicalize malbounded types. | 3070 // Do not canonicalize malbounded types. |
| 3060 } | 3071 } |
| 3061 } | 3072 } |
| 3062 | 3073 |
| 3063 | 3074 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3158 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3169 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3159 field ^= fields_array.At(0); | 3170 field ^= fields_array.At(0); |
| 3160 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3171 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3161 name ^= field.name(); | 3172 name ^= field.name(); |
| 3162 expected_name ^= String::New("_data"); | 3173 expected_name ^= String::New("_data"); |
| 3163 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3174 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3164 #endif | 3175 #endif |
| 3165 } | 3176 } |
| 3166 | 3177 |
| 3167 } // namespace dart | 3178 } // namespace dart |
| OLD | NEW |