| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
| 16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
| 17 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 17 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
| 18 DEFINE_FLAG(bool, verify_implements, false, | 18 DEFINE_FLAG(bool, verify_implements, false, |
| 19 "Verify that all classes implement their interface."); | 19 "Verify that all classes implement their interface."); |
| 20 DECLARE_FLAG(bool, enable_type_checks); | 20 DECLARE_FLAG(bool, enable_type_checks); |
| 21 DECLARE_FLAG(bool, silent_warnings); |
| 22 DECLARE_FLAG(bool, warning_as_error); |
| 21 | 23 |
| 22 void ClassFinalizer::AddPendingClasses( | 24 void ClassFinalizer::AddPendingClasses( |
| 23 const GrowableArray<const Class*>& classes) { | 25 const GrowableArray<const Class*>& classes) { |
| 24 if (!classes.is_empty()) { | 26 if (!classes.is_empty()) { |
| 25 ObjectStore* object_store = Isolate::Current()->object_store(); | 27 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 26 const Array& old_array = Array::Handle(object_store->pending_classes()); | 28 const Array& old_array = Array::Handle(object_store->pending_classes()); |
| 27 const intptr_t old_length = old_array.Length(); | 29 const intptr_t old_length = old_array.Length(); |
| 28 const int new_length = old_length + classes.length(); | 30 const int new_length = old_length + classes.length(); |
| 29 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); | 31 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); |
| 30 // Add new classes. | 32 // Add new classes. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 61 if (setjmp(*jump.Set()) == 0) { | 63 if (setjmp(*jump.Set()) == 0) { |
| 62 const Array& class_array = Array::Handle(object_store->pending_classes()); | 64 const Array& class_array = Array::Handle(object_store->pending_classes()); |
| 63 ASSERT(!class_array.IsNull()); | 65 ASSERT(!class_array.IsNull()); |
| 64 Class& cls = Class::Handle(); | 66 Class& cls = Class::Handle(); |
| 65 // First resolve all superclasses. | 67 // First resolve all superclasses. |
| 66 for (intptr_t i = 0; i < class_array.Length(); i++) { | 68 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 67 cls ^= class_array.At(i); | 69 cls ^= class_array.At(i); |
| 68 if (FLAG_trace_class_finalization) { | 70 if (FLAG_trace_class_finalization) { |
| 69 OS::Print("Resolving super and default: %s\n", cls.ToCString()); | 71 OS::Print("Resolving super and default: %s\n", cls.ToCString()); |
| 70 } | 72 } |
| 71 ResolveSuperClass(cls); | 73 ResolveSuperType(cls); |
| 72 if (cls.is_interface()) { | 74 if (cls.is_interface()) { |
| 73 ResolveDefaultClass(cls); | 75 ResolveFactoryClass(cls); |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 // Finalize all classes. | 78 // Finalize all classes. |
| 77 for (intptr_t i = 0; i < class_array.Length(); i++) { | 79 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 78 cls ^= class_array.At(i); | 80 cls ^= class_array.At(i); |
| 79 FinalizeClass(cls); | 81 FinalizeClass(cls); |
| 80 } | 82 } |
| 81 if (FLAG_print_classes) { | 83 if (FLAG_print_classes) { |
| 82 for (intptr_t i = 0; i < class_array.Length(); i++) { | 84 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 83 cls ^= class_array.At(i); | 85 cls ^= class_array.At(i); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 const Script& script = Script::Handle(cls.script()); | 271 const Script& script = Script::Handle(cls.script()); |
| 270 ReportError(script, unresolved_class.token_index(), | 272 ReportError(script, unresolved_class.token_index(), |
| 271 "cannot resolve class name '%s' from '%s'.\n", | 273 "cannot resolve class name '%s' from '%s'.\n", |
| 272 String::Handle(unresolved_class.Name()).ToCString(), | 274 String::Handle(unresolved_class.Name()).ToCString(), |
| 273 String::Handle(cls.Name()).ToCString()); | 275 String::Handle(cls.Name()).ToCString()); |
| 274 } | 276 } |
| 275 return resolved_class.raw(); | 277 return resolved_class.raw(); |
| 276 } | 278 } |
| 277 | 279 |
| 278 | 280 |
| 279 // Resolve unresolved superclasses (String -> Class). | 281 // Resolve unresolved supertype (String -> Class). |
| 280 void ClassFinalizer::ResolveSuperClass(const Class& cls) { | 282 void ClassFinalizer::ResolveSuperType(const Class& cls) { |
| 281 if (cls.is_finalized()) { | 283 if (cls.is_finalized()) { |
| 282 return; | 284 return; |
| 283 } | 285 } |
| 284 Type& super_type = Type::Handle(cls.super_type()); | 286 Type& super_type = Type::Handle(cls.super_type()); |
| 285 if (super_type.IsNull()) { | 287 if (super_type.IsNull()) { |
| 286 return; | 288 return; |
| 287 } | 289 } |
| 288 // Resolve failures lead to a longjmp. | 290 // Resolve failures lead to a longjmp. |
| 289 super_type = ResolveType(cls, super_type); | 291 super_type = ResolveType(cls, super_type); |
| 290 if (super_type.IsTypeParameter()) { | 292 if (super_type.IsTypeParameter()) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 (super_class.raw() == object_store->four_byte_string_class())) { | 337 (super_class.raw() == object_store->four_byte_string_class())) { |
| 336 ReportError("'%s' is not allowed to extend '%s'\n", | 338 ReportError("'%s' is not allowed to extend '%s'\n", |
| 337 String::Handle(cls.Name()).ToCString(), | 339 String::Handle(cls.Name()).ToCString(), |
| 338 String::Handle(super_class.Name()).ToCString()); | 340 String::Handle(super_class.Name()).ToCString()); |
| 339 } | 341 } |
| 340 } | 342 } |
| 341 return; | 343 return; |
| 342 } | 344 } |
| 343 | 345 |
| 344 | 346 |
| 345 void ClassFinalizer::ResolveDefaultClass(const Class& interface) { | 347 void ClassFinalizer::ResolveFactoryClass(const Class& interface) { |
| 346 ASSERT(interface.is_interface()); | 348 ASSERT(interface.is_interface()); |
| 347 if (interface.is_finalized()) { | 349 if (interface.is_finalized() || |
| 350 !interface.HasFactoryClass() || |
| 351 interface.HasResolvedFactoryClass()) { |
| 348 return; | 352 return; |
| 349 } | 353 } |
| 350 Type& factory_type = Type::Handle(interface.factory_type()); | 354 const UnresolvedClass& unresolved_factory_class = |
| 351 if (factory_type.IsNull()) { | 355 UnresolvedClass::Handle(interface.UnresolvedFactoryClass()); |
| 352 // No resolving needed. | 356 |
| 357 // Lookup the factory class. |
| 358 const Class& factory_class = |
| 359 Class::Handle(ResolveClass(interface, unresolved_factory_class)); |
| 360 ASSERT(!factory_class.IsNull()); |
| 361 if (factory_class.is_interface()) { |
| 362 const String& interface_name = String::Handle(interface.Name()); |
| 363 const String& factory_name = String::Handle(factory_class.Name()); |
| 364 ReportError("factory clause of interface '%s' names non-class '%s'.\n", |
| 365 interface_name.ToCString(), |
| 366 factory_name.ToCString()); |
| 367 } |
| 368 interface.set_factory_class(factory_class); |
| 369 // Check that the type parameter lists are identical. |
| 370 const Class& factory_signature_class = Class::Handle( |
| 371 unresolved_factory_class.factory_signature_class()); |
| 372 ASSERT(!factory_signature_class.IsNull()); |
| 373 ResolveAndFinalizeUpperBounds(factory_class); |
| 374 ResolveAndFinalizeUpperBounds(factory_signature_class); |
| 375 const intptr_t num_type_params = factory_signature_class.NumTypeParameters(); |
| 376 bool mismatch = factory_class.NumTypeParameters() != num_type_params; |
| 377 if (mismatch && (num_type_params == 0)) { |
| 378 // TODO(regis): For now, and until the core lib is fixed, we accept a |
| 379 // factory clause with a class missing its list of type parameters. |
| 380 // See bug 5408808. |
| 381 const String& interface_name = String::Handle(interface.Name()); |
| 382 const String& factory_name = String::Handle(factory_class.Name()); |
| 383 ReportWarning("Warning: class '%s' in factory clause of interface '%s' is " |
| 384 "missing its type parameter list.\n", |
| 385 factory_name.ToCString(), |
| 386 interface_name.ToCString()); |
| 353 return; | 387 return; |
| 354 } | 388 } |
| 355 // Resolve failures lead to a longjmp. | 389 String& expected_type_name = String::Handle(); |
| 356 factory_type = ResolveType(interface, factory_type); | 390 String& actual_type_name = String::Handle(); |
| 357 interface.set_factory_type(factory_type); | 391 Type& expected_type_extends = Type::Handle(); |
| 358 if (factory_type.IsInterfaceType()) { | 392 Type& actual_type_extends = Type::Handle(); |
| 393 const Array& expected_type_names = |
| 394 Array::Handle(factory_signature_class.type_parameters()); |
| 395 const Array& actual_type_names = |
| 396 Array::Handle(factory_class.type_parameters()); |
| 397 const TypeArray& expected_extends_array = |
| 398 TypeArray::Handle(factory_signature_class.type_parameter_extends()); |
| 399 const TypeArray& actual_extends_array = |
| 400 TypeArray::Handle(factory_class.type_parameter_extends()); |
| 401 for (intptr_t i = 0; !mismatch && (i < num_type_params); i++) { |
| 402 expected_type_name ^= expected_type_names.At(i); |
| 403 actual_type_name ^= actual_type_names.At(i); |
| 404 expected_type_extends = expected_extends_array.TypeAt(i); |
| 405 actual_type_extends = actual_extends_array.TypeAt(i); |
| 406 if (!expected_type_name.Equals(actual_type_name) || |
| 407 !expected_type_extends.Equals(actual_type_extends)) { |
| 408 mismatch = true; |
| 409 } |
| 410 } |
| 411 if (mismatch) { |
| 359 const String& interface_name = String::Handle(interface.Name()); | 412 const String& interface_name = String::Handle(interface.Name()); |
| 360 ReportError("default clause of interface '%s' does not name a class\n", | 413 const String& factory_name = String::Handle(factory_class.Name()); |
| 361 interface_name.ToCString()); | 414 ReportError("mismatch in number or names of type parameters between " |
| 415 "factory clause of interface '%s' and actual factory " |
| 416 "class '%s'.\n", |
| 417 interface_name.ToCString(), |
| 418 factory_name.ToCString()); |
| 362 } | 419 } |
| 363 } | 420 } |
| 364 | 421 |
| 365 | 422 |
| 423 // TODO(regis): Now that we do not resolve type parameters anymore, we could |
| 424 // make this function void and resolve the type in place. |
| 366 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) { | 425 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) { |
| 367 if (type.IsResolved()) { | 426 if (type.IsResolved()) { |
| 368 return type.raw(); | 427 return type.raw(); |
| 369 } | 428 } |
| 370 if (FLAG_trace_type_finalization) { | 429 if (FLAG_trace_type_finalization) { |
| 371 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 430 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 372 } | 431 } |
| 373 | 432 |
| 374 // Resolve the type class. | 433 // Resolve the type class. |
| 375 if (!type.HasResolvedTypeClass()) { | 434 if (!type.HasResolvedTypeClass()) { |
| 435 // Type parameters are always resolved in the parser in the correct |
| 436 // non-static scope or factory scope. That resolution scope is unknown here. |
| 437 // Being able to resolve a type parameter from class cls here would indicate |
| 438 // that the type parameter appeared in a static scope. Leaving the type as |
| 439 // unresolved is the correct thing to do. |
| 440 |
| 441 // Lookup the type class. |
| 376 const UnresolvedClass& unresolved_class = | 442 const UnresolvedClass& unresolved_class = |
| 377 UnresolvedClass::Handle(type.unresolved_class()); | 443 UnresolvedClass::Handle(type.unresolved_class()); |
| 378 const String& type_class_name = String::Handle(unresolved_class.ident()); | |
| 379 | |
| 380 // The type class name may be a type parameter of cls that was not resolved | |
| 381 // by the parser because it appeared as part of the declaration | |
| 382 // as T1 in B<T1, T2 extends A<T1>> or | |
| 383 // as T2 in B<T1 extends A<T2>, T2>>. | |
| 384 const TypeParameter& type_parameter = TypeParameter::Handle( | |
| 385 cls.LookupTypeParameter(type_class_name)); | |
| 386 if (!type_parameter.IsNull()) { | |
| 387 // No need to check for proper instance scoping, since another type | |
| 388 // parameter must be involved for the type to still be unresolved. | |
| 389 // The scope checking was performed for the other type parameter already. | |
| 390 | |
| 391 // A type parameter cannot be parameterized, so report an error if type | |
| 392 // arguments have previously been parsed. | |
| 393 if (type.arguments() != TypeArguments::null()) { | |
| 394 ReportError("type parameter '%s' cannot be parameterized", | |
| 395 type_class_name.ToCString()); | |
| 396 } | |
| 397 return type_parameter.raw(); | |
| 398 } | |
| 399 | |
| 400 // Lookup the type class. | |
| 401 const Class& type_class = | 444 const Class& type_class = |
| 402 Class::Handle(ResolveClass(cls, unresolved_class)); | 445 Class::Handle(ResolveClass(cls, unresolved_class)); |
| 403 | 446 |
| 404 // Replace unresolved class with resolved type class. | 447 // Replace unresolved class with resolved type class. |
| 405 ASSERT(type.IsParameterizedType()); | 448 ASSERT(type.IsParameterizedType()); |
| 406 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 449 ParameterizedType& parameterized_type = ParameterizedType::Handle(); |
| 407 parameterized_type ^= type.raw(); | 450 parameterized_type ^= type.raw(); |
| 408 parameterized_type.set_type_class(Object::Handle(type_class.raw())); | 451 parameterized_type.set_type_class(Object::Handle(type_class.raw())); |
| 409 } | 452 } |
| 410 | 453 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 type_extends = extends_array.TypeAt(i); | 525 type_extends = extends_array.TypeAt(i); |
| 483 if (!type_extends.IsDynamicType()) { | 526 if (!type_extends.IsDynamicType()) { |
| 484 type = arguments.TypeAt(offset + i); | 527 type = arguments.TypeAt(offset + i); |
| 485 if (type.IsInstantiated()) { | 528 if (type.IsInstantiated()) { |
| 486 if (!type_extends.IsInstantiated()) { | 529 if (!type_extends.IsInstantiated()) { |
| 487 type_extends = type_extends.InstantiateFrom(arguments, offset); | 530 type_extends = type_extends.InstantiateFrom(arguments, offset); |
| 488 } | 531 } |
| 489 // TODO(regis): Where do we check the constraints when the type is | 532 // TODO(regis): Where do we check the constraints when the type is |
| 490 // generic? | 533 // generic? |
| 491 if (!type.IsSubtypeOf(type_extends)) { | 534 if (!type.IsSubtypeOf(type_extends)) { |
| 492 const String& type_name = String::Handle(type.Name()); | 535 const String& type_argument_name = String::Handle(type.Name()); |
| 536 const String& class_name = String::Handle(cls.Name()); |
| 493 const String& extends_name = String::Handle(type_extends.Name()); | 537 const String& extends_name = String::Handle(type_extends.Name()); |
| 494 ReportError("type argument '%s' of class '%s' " | 538 ReportError("type argument '%s' of class '%s' " |
| 495 "does not extend type '%s'\n", | 539 "does not extend type '%s'\n", |
| 496 type_name.ToCString(), | 540 type_argument_name.ToCString(), |
| 541 class_name.ToCString(), |
| 497 extends_name.ToCString()); | 542 extends_name.ToCString()); |
| 498 } | 543 } |
| 499 } | 544 } |
| 500 } | 545 } |
| 501 } | 546 } |
| 502 Type& super_type = Type::Handle(cls.super_type()); | 547 Type& super_type = Type::Handle(cls.super_type()); |
| 503 if (!super_type.IsNull()) { | 548 if (!super_type.IsNull()) { |
| 504 ASSERT(super_type.IsFinalized()); | 549 ASSERT(super_type.IsFinalized()); |
| 505 const Class& super_class = Class::Handle(super_type.type_class()); | 550 const Class& super_class = Class::Handle(super_type.type_class()); |
| 506 VerifyUpperBounds(super_class, arguments); | 551 VerifyUpperBounds(super_class, arguments); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 } | 684 } |
| 640 UNREACHABLE(); | 685 UNREACHABLE(); |
| 641 return Type::null(); | 686 return Type::null(); |
| 642 } | 687 } |
| 643 | 688 |
| 644 | 689 |
| 645 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 690 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 646 const Function& function) { | 691 const Function& function) { |
| 647 // Resolve result type. | 692 // Resolve result type. |
| 648 Type& type = Type::Handle(function.result_type()); | 693 Type& type = Type::Handle(function.result_type()); |
| 649 type = ResolveType(cls, type); | 694 if (!type.IsResolved()) { |
| 650 function.set_result_type(type); | 695 if (function.IsFactory()) { |
| 696 // The signature class of the factory for a generic class holds the type |
| 697 // parameters and their upper bounds. Copy the signature class from the |
| 698 // result before it gets resolved. |
| 699 const UnresolvedClass& unresolved_type_class = |
| 700 UnresolvedClass::Handle(type.unresolved_class()); |
| 701 const Class& factory_signature_class = |
| 702 Class::Handle(unresolved_type_class.factory_signature_class()); |
| 703 ASSERT(!factory_signature_class.IsNull()); |
| 704 function.set_signature_class(factory_signature_class); |
| 705 type = ResolveType(cls, type); |
| 706 function.set_result_type(type); |
| 707 const Class& type_class = Class::Handle(type.type_class()); |
| 708 // Verify that the factory signature declares the same number of type |
| 709 // parameters as the return type class or interface. |
| 710 ResolveAndFinalizeUpperBounds(factory_signature_class); |
| 711 if (factory_signature_class.NumTypeParameters() != |
| 712 type_class.NumTypeParameters()) { |
| 713 const String& function_name = String::Handle(function.name()); |
| 714 if (factory_signature_class.NumTypeParameters() == 0) { |
| 715 // TODO(regis): For now, and until the core lib is fixed, we accept a |
| 716 // factory method with missing list of type parameters and use the |
| 717 // list of the enclosing class. |
| 718 // See bug 5408808. |
| 719 const Class& enclosing_class = Class::Handle(function.owner()); |
| 720 function.set_signature_class(enclosing_class); |
| 721 ReportWarning("Warning: factory method '%s' should declare a list of " |
| 722 "%d type parameter%s.\n", |
| 723 function_name.ToCString(), |
| 724 type_class.NumTypeParameters(), |
| 725 type_class.NumTypeParameters() > 1 ? "s" : ""); |
| 726 } else { |
| 727 ReportError("factory method '%s' must declare %d type parameter%s.\n", |
| 728 function_name.ToCString(), |
| 729 type_class.NumTypeParameters(), |
| 730 type_class.NumTypeParameters() > 1 ? "s" : ""); |
| 731 } |
| 732 } |
| 733 } else { |
| 734 type = ResolveType(cls, type); |
| 735 function.set_result_type(type); |
| 736 } |
| 737 } |
| 651 type = FinalizeType(type); | 738 type = FinalizeType(type); |
| 652 function.set_result_type(type); | 739 function.set_result_type(type); |
| 653 // Resolve formal parameter types. | 740 // Resolve formal parameter types. |
| 654 const intptr_t num_parameters = function.NumberOfParameters(); | 741 const intptr_t num_parameters = function.NumberOfParameters(); |
| 655 for (intptr_t i = 0; i < num_parameters; i++) { | 742 for (intptr_t i = 0; i < num_parameters; i++) { |
| 656 type = function.ParameterTypeAt(i); | 743 type = function.ParameterTypeAt(i); |
| 657 type = ResolveType(cls, type); | 744 type = ResolveType(cls, type); |
| 658 function.SetParameterTypeAt(i, type); | 745 function.SetParameterTypeAt(i, type); |
| 659 type = FinalizeType(type); | 746 type = FinalizeType(type); |
| 660 function.SetParameterTypeAt(i, type); | 747 function.SetParameterTypeAt(i, type); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 ResolveInterfaces(cls, &visited); | 960 ResolveInterfaces(cls, &visited); |
| 874 Type& super_type = Type::Handle(cls.super_type()); | 961 Type& super_type = Type::Handle(cls.super_type()); |
| 875 if (!super_type.IsNull()) { | 962 if (!super_type.IsNull()) { |
| 876 const Class& super_class = Class::Handle(super_type.type_class()); | 963 const Class& super_class = Class::Handle(super_type.type_class()); |
| 877 // Finalize super class and super type. | 964 // Finalize super class and super type. |
| 878 FinalizeClass(super_class); | 965 FinalizeClass(super_class); |
| 879 super_type = FinalizeType(super_type); | 966 super_type = FinalizeType(super_type); |
| 880 cls.set_super_type(super_type); | 967 cls.set_super_type(super_type); |
| 881 } | 968 } |
| 882 if (cls.is_interface()) { | 969 if (cls.is_interface()) { |
| 883 Type& factory_type = Type::Handle(cls.factory_type()); | 970 if (cls.HasFactoryClass()) { |
| 884 if (!factory_type.IsNull()) { | 971 const Class& factory_class = Class::Handle(cls.FactoryClass()); |
| 885 const Class& factory_class = Class::Handle(factory_type.type_class()); | 972 // Finalize factory class. |
| 886 // Finalize factory class and factory type. | |
| 887 if (!factory_class.is_finalized()) { | 973 if (!factory_class.is_finalized()) { |
| 888 FinalizeClass(factory_class); | 974 FinalizeClass(factory_class); |
| 889 // Finalizing the factory class may indirectly finalize this interface. | 975 // Finalizing the factory class may indirectly finalize this interface. |
| 890 if (cls.is_finalized()) { | 976 if (cls.is_finalized()) { |
| 891 return; | 977 return; |
| 892 } | 978 } |
| 893 } | 979 } |
| 894 factory_type = FinalizeType(factory_type); | |
| 895 cls.set_factory_type(factory_type); | |
| 896 } | 980 } |
| 897 } | 981 } |
| 898 // Finalize interface types (but not necessarily interface classes). | 982 // Finalize interface types (but not necessarily interface classes). |
| 899 Array& interface_types = Array::Handle(cls.interfaces()); | 983 Array& interface_types = Array::Handle(cls.interfaces()); |
| 900 Type& interface_type = Type::Handle(); | 984 Type& interface_type = Type::Handle(); |
| 901 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 985 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
| 902 interface_type ^= interface_types.At(i); | 986 interface_type ^= interface_types.At(i); |
| 903 interface_type = FinalizeType(interface_type); | 987 interface_type = FinalizeType(interface_type); |
| 904 interface_types.SetAt(i, interface_type); | 988 interface_types.SetAt(i, interface_type); |
| 905 } | 989 } |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1153 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); | 1237 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); |
| 1154 ASSERT(msg_buffer != NULL); | 1238 ASSERT(msg_buffer != NULL); |
| 1155 va_list args; | 1239 va_list args; |
| 1156 va_start(args, format); | 1240 va_start(args, format); |
| 1157 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | 1241 OS::VSNPrint(msg_buffer, kBufferLength, format, args); |
| 1158 va_end(args); | 1242 va_end(args); |
| 1159 isolate->long_jump_base()->Jump(1, msg_buffer); | 1243 isolate->long_jump_base()->Jump(1, msg_buffer); |
| 1160 UNREACHABLE(); | 1244 UNREACHABLE(); |
| 1161 } | 1245 } |
| 1162 | 1246 |
| 1247 void ClassFinalizer::ReportWarning(const char* format, ...) { |
| 1248 if (FLAG_silent_warnings) return; |
| 1249 static const int kBufferLength = 1024; |
| 1250 Isolate* isolate = Isolate::Current(); |
| 1251 ASSERT(isolate != NULL); |
| 1252 Zone* zone = isolate->current_zone(); |
| 1253 ASSERT(zone != NULL); |
| 1254 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); |
| 1255 ASSERT(msg_buffer != NULL); |
| 1256 va_list args; |
| 1257 va_start(args, format); |
| 1258 OS::VSNPrint(msg_buffer, kBufferLength, format, args); |
| 1259 va_end(args); |
| 1260 if (FLAG_warning_as_error) { |
| 1261 isolate->long_jump_base()->Jump(1, msg_buffer); |
| 1262 UNREACHABLE(); |
| 1263 } else { |
| 1264 OS::Print(msg_buffer); |
| 1265 } |
| 1266 } |
| 1267 |
| 1163 } // namespace dart | 1268 } // namespace dart |
| OLD | NEW |