| 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/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| 11 #include "vm/object_store.h" | 11 #include "vm/object_store.h" |
| 12 #include "vm/parser.h" | 12 #include "vm/parser.h" |
| 13 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 DEFINE_FLAG(bool, error_on_bad_override, false, | 17 DEFINE_FLAG(bool, error_on_bad_override, false, |
| 18 "Report error for bad overrides."); | 18 "Report error for bad overrides."); |
| 19 DEFINE_FLAG(bool, error_on_malformed_type, false, | 19 DEFINE_FLAG(bool, error_on_bad_type, false, |
| 20 "Report error for malformed types."); | 20 "Report error for malformed types."); |
| 21 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 21 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
| 22 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 22 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
| 23 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 23 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
| 24 DECLARE_FLAG(bool, enable_type_checks); | 24 DECLARE_FLAG(bool, enable_type_checks); |
| 25 DECLARE_FLAG(bool, use_cha); | 25 DECLARE_FLAG(bool, use_cha); |
| 26 | 26 |
| 27 bool ClassFinalizer::AllClassesFinalized() { | 27 bool ClassFinalizer::AllClassesFinalized() { |
| 28 ObjectStore* object_store = Isolate::Current()->object_store(); | 28 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 29 const GrowableObjectArray& classes = | 29 const GrowableObjectArray& classes = |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 const UnresolvedClass& unresolved_class = | 468 const UnresolvedClass& unresolved_class = |
| 469 UnresolvedClass::Handle(type.unresolved_class()); | 469 UnresolvedClass::Handle(type.unresolved_class()); |
| 470 Error& ambiguous_error = Error::Handle(); | 470 Error& ambiguous_error = Error::Handle(); |
| 471 const Class& type_class = | 471 const Class& type_class = |
| 472 Class::Handle(ResolveClass(cls, unresolved_class, &ambiguous_error)); | 472 Class::Handle(ResolveClass(cls, unresolved_class, &ambiguous_error)); |
| 473 | 473 |
| 474 // Replace unresolved class with resolved type class. | 474 // Replace unresolved class with resolved type class. |
| 475 const Type& parameterized_type = Type::Cast(type); | 475 const Type& parameterized_type = Type::Cast(type); |
| 476 if (type_class.IsNull()) { | 476 if (type_class.IsNull()) { |
| 477 if ((finalization == kCanonicalizeWellFormed) || | 477 if ((finalization == kCanonicalizeWellFormed) || |
| 478 FLAG_error_on_malformed_type) { | 478 FLAG_error_on_bad_type) { |
| 479 // The type class could not be resolved. The type is malformed. | 479 // The type class could not be resolved. The type is malformed. |
| 480 FinalizeMalformedType( | 480 FinalizeMalformedType( |
| 481 ambiguous_error, // May be null. | 481 ambiguous_error, // May be null. |
| 482 cls, | 482 cls, |
| 483 parameterized_type, | 483 parameterized_type, |
| 484 "cannot resolve class '%s' from '%s'", | 484 "cannot resolve class '%s' from '%s'", |
| 485 String::Handle(unresolved_class.Name()).ToCString(), | 485 String::Handle(unresolved_class.Name()).ToCString(), |
| 486 String::Handle(cls.Name()).ToCString()); | 486 String::Handle(cls.Name()).ToCString()); |
| 487 } else { | 487 } else { |
| 488 // Map the malformed type to dynamic and ignore type arguments. | 488 // Map the malformed type to dynamic and ignore type arguments. |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 790 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 791 // The type class has num_type_parameters type parameters. | 791 // The type class has num_type_parameters type parameters. |
| 792 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 792 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 793 | 793 |
| 794 // Initialize the type argument vector. | 794 // Initialize the type argument vector. |
| 795 // Check the number of parsed type arguments, if any. | 795 // Check the number of parsed type arguments, if any. |
| 796 // Specifying no type arguments indicates a raw type, which is not an error. | 796 // Specifying no type arguments indicates a raw type, which is not an error. |
| 797 // However, type parameter bounds are checked below, even for a raw type. | 797 // However, type parameter bounds are checked below, even for a raw type. |
| 798 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 798 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 799 // Wrong number of type arguments. The type is malformed. | 799 // Wrong number of type arguments. The type is malformed. |
| 800 if (FLAG_error_on_malformed_type) { | 800 if (FLAG_error_on_bad_type) { |
| 801 const Script& script = Script::Handle(cls.script()); | 801 const Script& script = Script::Handle(cls.script()); |
| 802 const String& type_class_name = String::Handle(type_class.Name()); | 802 const String& type_class_name = String::Handle(type_class.Name()); |
| 803 ReportError(Error::Handle(), // No previous error. | 803 ReportError(Error::Handle(), // No previous error. |
| 804 script, parameterized_type.token_pos(), | 804 script, parameterized_type.token_pos(), |
| 805 "wrong number of type arguments for class '%s'", | 805 "wrong number of type arguments for class '%s'", |
| 806 type_class_name.ToCString()); | 806 type_class_name.ToCString()); |
| 807 } | 807 } |
| 808 // Make the type raw and continue without reporting any error. | 808 // Make the type raw and continue without reporting any error. |
| 809 // A static warning should have been reported. | 809 // A static warning should have been reported. |
| 810 arguments = AbstractTypeArguments::null(); | 810 arguments = AbstractTypeArguments::null(); |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1134 malformed_error = type.malformed_error(); | 1134 malformed_error = type.malformed_error(); |
| 1135 } else { | 1135 } else { |
| 1136 ASSERT(type.IsInstantiated()); | 1136 ASSERT(type.IsInstantiated()); |
| 1137 } | 1137 } |
| 1138 const Instance& const_value = Instance::Handle(field.value()); | 1138 const Instance& const_value = Instance::Handle(field.value()); |
| 1139 if (!malformed_error.IsNull() || | 1139 if (!malformed_error.IsNull() || |
| 1140 (!type.IsDynamicType() && | 1140 (!type.IsDynamicType() && |
| 1141 !const_value.IsInstanceOf(type, | 1141 !const_value.IsInstanceOf(type, |
| 1142 AbstractTypeArguments::Handle(), | 1142 AbstractTypeArguments::Handle(), |
| 1143 &malformed_error))) { | 1143 &malformed_error))) { |
| 1144 if (FLAG_error_on_malformed_type) { | 1144 if (FLAG_error_on_bad_type) { |
| 1145 const AbstractType& const_value_type = AbstractType::Handle( | 1145 const AbstractType& const_value_type = AbstractType::Handle( |
| 1146 const_value.GetType()); | 1146 const_value.GetType()); |
| 1147 const String& const_value_type_name = String::Handle( | 1147 const String& const_value_type_name = String::Handle( |
| 1148 const_value_type.UserVisibleName()); | 1148 const_value_type.UserVisibleName()); |
| 1149 const String& type_name = String::Handle(type.UserVisibleName()); | 1149 const String& type_name = String::Handle(type.UserVisibleName()); |
| 1150 const Script& script = Script::Handle(cls.script()); | 1150 const Script& script = Script::Handle(cls.script()); |
| 1151 ReportError(malformed_error, script, field.token_pos(), | 1151 ReportError(malformed_error, script, field.token_pos(), |
| 1152 "error initializing static %s field '%s': " | 1152 "error initializing static %s field '%s': " |
| 1153 "type '%s' is not a subtype of type '%s'", | 1153 "type '%s' is not a subtype of type '%s'", |
| 1154 field.is_const() ? "const" : "final", | 1154 field.is_const() ? "const" : "final", |
| (...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2178 va_list args) { | 2178 va_list args) { |
| 2179 LanguageError& error = LanguageError::Handle(); | 2179 LanguageError& error = LanguageError::Handle(); |
| 2180 const Script& script = Script::Handle(cls.script()); | 2180 const Script& script = Script::Handle(cls.script()); |
| 2181 if (prev_error.IsNull()) { | 2181 if (prev_error.IsNull()) { |
| 2182 error ^= Parser::FormatError( | 2182 error ^= Parser::FormatError( |
| 2183 script, type.token_pos(), "Error", format, args); | 2183 script, type.token_pos(), "Error", format, args); |
| 2184 } else { | 2184 } else { |
| 2185 error ^= Parser::FormatErrorWithAppend( | 2185 error ^= Parser::FormatErrorWithAppend( |
| 2186 prev_error, script, type.token_pos(), "Error", format, args); | 2186 prev_error, script, type.token_pos(), "Error", format, args); |
| 2187 } | 2187 } |
| 2188 if (FLAG_error_on_malformed_type) { | 2188 if (FLAG_error_on_bad_type) { |
| 2189 ReportError(error); | 2189 ReportError(error); |
| 2190 } | 2190 } |
| 2191 type.set_malformed_error(error); | 2191 type.set_malformed_error(error); |
| 2192 // Make the type raw, since it may not be possible to | 2192 // Make the type raw, since it may not be possible to |
| 2193 // properly finalize its type arguments. | 2193 // properly finalize its type arguments. |
| 2194 type.set_type_class(Class::Handle(Object::dynamic_class())); | 2194 type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 2195 type.set_arguments(Object::null_abstract_type_arguments()); | 2195 type.set_arguments(Object::null_abstract_type_arguments()); |
| 2196 if (!type.IsFinalized()) { | 2196 if (!type.IsFinalized()) { |
| 2197 type.SetIsFinalized(); | 2197 type.SetIsFinalized(); |
| 2198 // Do not canonicalize malformed types, since they may not be resolved. | 2198 // Do not canonicalize malformed types, since they may not be resolved. |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2322 expected_name ^= String::New("_offset"); | 2322 expected_name ^= String::New("_offset"); |
| 2323 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2323 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2324 field ^= fields_array.At(2); | 2324 field ^= fields_array.At(2); |
| 2325 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2325 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2326 name ^= field.name(); | 2326 name ^= field.name(); |
| 2327 ASSERT(name.Equals("length")); | 2327 ASSERT(name.Equals("length")); |
| 2328 #endif | 2328 #endif |
| 2329 } | 2329 } |
| 2330 | 2330 |
| 2331 } // namespace dart | 2331 } // namespace dart |
| OLD | NEW |