Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/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" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 while (class_function.IsNull()) { | 159 while (class_function.IsNull()) { |
| 160 test_class = test_class.SuperClass(); | 160 test_class = test_class.SuperClass(); |
| 161 if (test_class.IsNull()) break; | 161 if (test_class.IsNull()) break; |
| 162 class_function = test_class.LookupDynamicFunction(function_name); | 162 class_function = test_class.LookupDynamicFunction(function_name); |
| 163 } | 163 } |
| 164 if (class_function.IsNull()) { | 164 if (class_function.IsNull()) { |
| 165 OS::Print("%s implements '%s' missing: '%s'\n", | 165 OS::Print("%s implements '%s' missing: '%s'\n", |
| 166 class_name.ToCString(), | 166 class_name.ToCString(), |
| 167 interface_name.ToCString(), | 167 interface_name.ToCString(), |
| 168 function_name.ToCString()); | 168 function_name.ToCString()); |
| 169 } else if (!class_function.IsSubtypeOf(TypeArguments::Handle(), | 169 } else { |
| 170 Error& malformed_error = Error::Handle(); | |
| 171 if (!class_function.IsSubtypeOf(TypeArguments::Handle(), | |
| 170 interface_function, | 172 interface_function, |
| 171 TypeArguments::Handle())) { | 173 TypeArguments::Handle(), |
| 172 OS::Print("The type of instance method '%s' in class '%s' is not a " | 174 &malformed_error)) { |
| 173 "subtype of the type of '%s' in interface '%s'\n", | 175 if (!malformed_error.IsNull()) { |
| 174 function_name.ToCString(), | 176 OS::Print("%s\n", malformed_error.ToErrorCString()); |
|
srdjan
2012/03/07 00:41:23
Shouldn't this be going to PrintErr?
regis
2012/03/07 02:22:38
Done.
| |
| 175 class_name.ToCString(), | 177 } |
| 176 function_name.ToCString(), | 178 OS::Print("The type of instance method '%s' in class '%s' is not a " |
| 177 interface_name.ToCString()); | 179 "subtype of the type of '%s' in interface '%s'\n", |
| 180 function_name.ToCString(), | |
| 181 class_name.ToCString(), | |
| 182 function_name.ToCString(), | |
| 183 interface_name.ToCString()); | |
| 184 } | |
| 178 } | 185 } |
| 179 } | 186 } |
| 180 } | 187 } |
| 181 } | 188 } |
| 182 #else | 189 #else |
| 183 | 190 |
| 184 void ClassFinalizer::VerifyClassImplements(const Class& cls) {} | 191 void ClassFinalizer::VerifyClassImplements(const Class& cls) {} |
| 185 | 192 |
| 186 #endif | 193 #endif |
| 187 | 194 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 Class::Handle(ResolveClass(cls, unresolved_class)); | 453 Class::Handle(ResolveClass(cls, unresolved_class)); |
| 447 | 454 |
| 448 // Replace unresolved class with resolved type class. | 455 // Replace unresolved class with resolved type class. |
| 449 ASSERT(type.IsType()); | 456 ASSERT(type.IsType()); |
| 450 Type& parameterized_type = Type::Handle(); | 457 Type& parameterized_type = Type::Handle(); |
| 451 parameterized_type ^= type.raw(); | 458 parameterized_type ^= type.raw(); |
| 452 if (!type_class.IsNull()) { | 459 if (!type_class.IsNull()) { |
| 453 parameterized_type.set_type_class(Object::Handle(type_class.raw())); | 460 parameterized_type.set_type_class(Object::Handle(type_class.raw())); |
| 454 } else { | 461 } else { |
| 455 // The type class could not be resolved. The type is malformed. | 462 // The type class could not be resolved. The type is malformed. |
| 456 FinalizeMalformedType(cls, parameterized_type, finalization, | 463 FinalizeMalformedType(Error::Handle(), // No previous error. |
| 464 cls, parameterized_type, finalization, | |
| 457 "cannot resolve class name '%s' from '%s'", | 465 "cannot resolve class name '%s' from '%s'", |
| 458 String::Handle(unresolved_class.Name()).ToCString(), | 466 String::Handle(unresolved_class.Name()).ToCString(), |
| 459 String::Handle(cls.Name()).ToCString()); | 467 String::Handle(cls.Name()).ToCString()); |
| 460 return; | 468 return; |
| 461 } | 469 } |
| 462 } | 470 } |
| 463 | 471 |
| 464 // Resolve type arguments, if any. | 472 // Resolve type arguments, if any. |
| 465 const AbstractTypeArguments& arguments = | 473 const AbstractTypeArguments& arguments = |
| 466 AbstractTypeArguments::Handle(type.arguments()); | 474 AbstractTypeArguments::Handle(type.arguments()); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 546 return type_parameter.raw(); | 554 return type_parameter.raw(); |
| 547 } | 555 } |
| 548 | 556 |
| 549 // At this point, we can only have a parameterized_type. | 557 // At this point, we can only have a parameterized_type. |
| 550 Type& parameterized_type = Type::Handle(); | 558 Type& parameterized_type = Type::Handle(); |
| 551 parameterized_type ^= type.raw(); | 559 parameterized_type ^= type.raw(); |
| 552 | 560 |
| 553 if (parameterized_type.IsBeingFinalized()) { | 561 if (parameterized_type.IsBeingFinalized()) { |
| 554 // Self reference detected. The type is malformed. | 562 // Self reference detected. The type is malformed. |
| 555 FinalizeMalformedType( | 563 FinalizeMalformedType( |
| 564 Error::Handle(), // No previous error. | |
| 556 cls, parameterized_type, finalization, | 565 cls, parameterized_type, finalization, |
| 557 "type '%s' illegally refers to itself", | 566 "type '%s' illegally refers to itself", |
| 558 String::Handle(parameterized_type.Name()).ToCString()); | 567 String::Handle(parameterized_type.Name()).ToCString()); |
| 559 return parameterized_type.raw(); | 568 return parameterized_type.raw(); |
| 560 } | 569 } |
| 561 | 570 |
| 562 // Mark type as being finalized in order to detect illegal self reference. | 571 // Mark type as being finalized in order to detect illegal self reference. |
| 563 parameterized_type.set_is_being_finalized(); | 572 parameterized_type.set_is_being_finalized(); |
| 564 | 573 |
| 565 // Finalize the current type arguments of the type, which are still the | 574 // Finalize the current type arguments of the type, which are still the |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 605 // The type class has num_type_parameters type parameters. | 614 // The type class has num_type_parameters type parameters. |
| 606 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 615 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 607 | 616 |
| 608 // Initialize the type argument vector. | 617 // Initialize the type argument vector. |
| 609 // Check the number of parsed type arguments, if any. | 618 // Check the number of parsed type arguments, if any. |
| 610 // Specifying no type arguments indicates a raw type, which is not an error. | 619 // Specifying no type arguments indicates a raw type, which is not an error. |
| 611 // However, type parameter bounds are checked below, even for a raw type. | 620 // However, type parameter bounds are checked below, even for a raw type. |
| 612 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 621 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 613 // Wrong number of type arguments. The type is malformed. | 622 // Wrong number of type arguments. The type is malformed. |
| 614 FinalizeMalformedType( | 623 FinalizeMalformedType( |
| 624 Error::Handle(), // No previous error. | |
| 615 cls, parameterized_type, finalization, | 625 cls, parameterized_type, finalization, |
| 616 "wrong number of type arguments in type '%s'", | 626 "wrong number of type arguments in type '%s'", |
| 617 String::Handle(parameterized_type.Name()).ToCString()); | 627 String::Handle(parameterized_type.Name()).ToCString()); |
| 618 return parameterized_type.raw(); | 628 return parameterized_type.raw(); |
| 619 } | 629 } |
| 620 // The full type argument vector consists of the type arguments of the | 630 // The full type argument vector consists of the type arguments of the |
| 621 // super types of type_class, which may be initialized from the parsed | 631 // super types of type_class, which may be initialized from the parsed |
| 622 // type arguments, followed by the parsed type arguments. | 632 // type arguments, followed by the parsed type arguments. |
| 623 if (num_type_arguments > 0) { | 633 if (num_type_arguments > 0) { |
| 624 TypeArguments& full_arguments = TypeArguments::Handle( | 634 TypeArguments& full_arguments = TypeArguments::Handle( |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 645 FinalizeTypeArguments(type_class, full_arguments, finalization); | 655 FinalizeTypeArguments(type_class, full_arguments, finalization); |
| 646 } | 656 } |
| 647 // FinalizeTypeArguments can modify 'full_arguments', | 657 // FinalizeTypeArguments can modify 'full_arguments', |
| 648 // canonicalize afterwards. | 658 // canonicalize afterwards. |
| 649 full_arguments ^= full_arguments.Canonicalize(); | 659 full_arguments ^= full_arguments.Canonicalize(); |
| 650 parameterized_type.set_arguments(full_arguments); | 660 parameterized_type.set_arguments(full_arguments); |
| 651 | 661 |
| 652 // Mark the type as finalized. | 662 // Mark the type as finalized. |
| 653 parameterized_type.set_is_finalized(); | 663 parameterized_type.set_is_finalized(); |
| 654 | 664 |
| 655 // No need to verify the upper bounds of the finalized type arguments, since | 665 // Upper bounds of the finalized type arguments are only verified in checked |
| 656 // bound errors are static type errors, which are not reported by the VM. | 666 // mode, since bound errors are never reported by the vm in production mode. |
| 667 if (FLAG_enable_type_checks && full_arguments.IsInstantiated()) { | |
| 668 ResolveAndFinalizeUpperBounds(type_class); | |
| 669 Error& malformed_error = Error::Handle(); | |
| 670 // Pass the full type argument vector as the bounds instantiator. | |
| 671 if (!full_arguments.IsWithinBoundsOf(type_class, | |
| 672 full_arguments, | |
| 673 &malformed_error)) { | |
| 674 ASSERT(!malformed_error.IsNull()); | |
| 675 // The type argument vector of the type is not within bounds. The type | |
| 676 // is malformed. Prepend malformed_error to new malformed type error in | |
| 677 // order to report both locations. | |
| 678 FinalizeMalformedType( | |
| 679 malformed_error, | |
| 680 cls, parameterized_type, finalization, | |
| 681 "type arguments of type '%s' are not within bounds", | |
| 682 String::Handle(parameterized_type.Name()).ToCString()); | |
| 683 return parameterized_type.raw(); | |
| 684 } | |
| 685 } | |
| 657 } else { | 686 } else { |
| 658 parameterized_type.set_is_finalized(); | 687 parameterized_type.set_is_finalized(); |
| 659 } | 688 } |
| 660 return parameterized_type.Canonicalize(); | 689 return parameterized_type.Canonicalize(); |
| 661 } | 690 } |
| 662 | 691 |
| 663 | 692 |
| 664 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 693 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 665 const Function& function) { | 694 const Function& function) { |
| 666 // Resolve result type. | 695 // Resolve result type. |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1166 const Array& fields_array = Array::Handle(cls.fields()); | 1195 const Array& fields_array = Array::Handle(cls.fields()); |
| 1167 Field& field = Field::Handle(); | 1196 Field& field = Field::Handle(); |
| 1168 len = fields_array.Length(); | 1197 len = fields_array.Length(); |
| 1169 for (intptr_t i = 0; i < len; i++) { | 1198 for (intptr_t i = 0; i < len; i++) { |
| 1170 field ^= fields_array.At(i); | 1199 field ^= fields_array.At(i); |
| 1171 OS::Print(" %s\n", field.ToCString()); | 1200 OS::Print(" %s\n", field.ToCString()); |
| 1172 } | 1201 } |
| 1173 } | 1202 } |
| 1174 | 1203 |
| 1175 | 1204 |
| 1176 void ClassFinalizer::FinalizeMalformedType(const Class& cls, | 1205 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, |
| 1206 const Class& cls, | |
| 1177 const Type& type, | 1207 const Type& type, |
| 1178 FinalizationKind finalization, | 1208 FinalizationKind finalization, |
| 1179 const char* format, ...) { | 1209 const char* format, ...) { |
| 1180 va_list args; | 1210 va_list args; |
| 1181 va_start(args, format); | 1211 va_start(args, format); |
| 1182 LanguageError& error = LanguageError::Handle(); | 1212 LanguageError& error = LanguageError::Handle(); |
| 1183 if ((finalization == kFinalizeWellFormed) || FLAG_enable_type_checks) { | 1213 if ((finalization == kFinalizeWellFormed) || FLAG_enable_type_checks) { |
| 1184 const Script& script = Script::Handle(cls.script()); | 1214 const Script& script = Script::Handle(cls.script()); |
| 1185 error ^= | 1215 if (prev_error.IsNull()) { |
| 1186 Parser::FormatError(script, type.token_index(), "Error", format, args); | 1216 error ^= Parser::FormatError( |
| 1217 script, type.token_index(), "Error", format, args); | |
| 1218 } else { | |
| 1219 error ^= Parser::FormatErrorWithAppend( | |
| 1220 prev_error, script, type.token_index(), "Error", format, args); | |
| 1221 } | |
| 1187 if (finalization == kFinalizeWellFormed) { | 1222 if (finalization == kFinalizeWellFormed) { |
| 1188 ReportError(error); | 1223 ReportError(error); |
| 1189 } | 1224 } |
| 1190 } | 1225 } |
| 1191 // Replace malformed type with Dynamic type. | 1226 // Replace malformed type with Dynamic type. |
| 1192 type.set_type_class(Class::Handle(Object::dynamic_class())); | 1227 type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 1193 type.set_arguments(AbstractTypeArguments::Handle()); | 1228 type.set_arguments(AbstractTypeArguments::Handle()); |
| 1194 if (FLAG_enable_type_checks) { | 1229 if (FLAG_enable_type_checks) { |
| 1195 // In checked mode, mark type as malformed. | 1230 // In checked mode, mark type as malformed. |
| 1196 type.set_malformed_error(error); | 1231 type.set_malformed_error(error); |
| 1197 } | 1232 } |
| 1198 type.set_is_finalized(); | 1233 if (!type.IsFinalized()) { |
| 1199 type.Canonicalize(); | 1234 type.set_is_finalized(); |
| 1235 type.Canonicalize(); | |
| 1236 } else { | |
| 1237 // The only case where the malformed type was already finalized is when its | |
| 1238 // type arguments are not within bounds. In that case, we have a prev_error. | |
| 1239 ASSERT(!prev_error.IsNull()); | |
| 1240 } | |
| 1200 } | 1241 } |
| 1201 | 1242 |
| 1202 | 1243 |
| 1203 void ClassFinalizer::ReportError(const Error& error) { | 1244 void ClassFinalizer::ReportError(const Error& error) { |
| 1204 Isolate::Current()->long_jump_base()->Jump(1, error); | 1245 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1205 UNREACHABLE(); | 1246 UNREACHABLE(); |
| 1206 } | 1247 } |
| 1207 | 1248 |
| 1208 | 1249 |
| 1209 void ClassFinalizer::ReportError(const Script& script, | 1250 void ClassFinalizer::ReportError(const Script& script, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1220 void ClassFinalizer::ReportError(const char* format, ...) { | 1261 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1221 va_list args; | 1262 va_list args; |
| 1222 va_start(args, format); | 1263 va_start(args, format); |
| 1223 const Error& error = Error::Handle( | 1264 const Error& error = Error::Handle( |
| 1224 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1265 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1225 va_end(args); | 1266 va_end(args); |
| 1226 ReportError(error); | 1267 ReportError(error); |
| 1227 } | 1268 } |
| 1228 | 1269 |
| 1229 } // namespace dart | 1270 } // namespace dart |
| OLD | NEW |