| 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" |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 ReportError("type argument '%s' does not extend type '%s'\n", | 444 ReportError("type argument '%s' does not extend type '%s'\n", |
| 445 type_name.ToCString(), | 445 type_name.ToCString(), |
| 446 extends_name.ToCString()); | 446 extends_name.ToCString()); |
| 447 } | 447 } |
| 448 } | 448 } |
| 449 } | 449 } |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 Type& super_type = Type::Handle(cls.super_type()); | 452 Type& super_type = Type::Handle(cls.super_type()); |
| 453 if (!super_type.IsNull()) { | 453 if (!super_type.IsNull()) { |
| 454 FinalizeType(super_type); | 454 super_type = FinalizeType(super_type); |
| 455 super_type = super_type.Canonicalize(); | |
| 456 cls.set_super_type(super_type); | 455 cls.set_super_type(super_type); |
| 457 const Class& super_class = Class::Handle(super_type.type_class()); | 456 const Class& super_class = Class::Handle(super_type.type_class()); |
| 458 const TypeArguments& super_type_args = | 457 const TypeArguments& super_type_args = |
| 459 TypeArguments::Handle(super_type.arguments()); | 458 TypeArguments::Handle(super_type.arguments()); |
| 460 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 459 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 461 const intptr_t offset = super_class.NumTypeArguments(); | 460 const intptr_t offset = super_class.NumTypeArguments(); |
| 462 const intptr_t super_offset = offset - num_super_type_params; | 461 const intptr_t super_offset = offset - num_super_type_params; |
| 463 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); | 462 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); |
| 464 Type& super_type_arg = Type::Handle(); | 463 Type& super_type_arg = Type::Handle(); |
| 465 for (intptr_t i = 0; i < num_super_type_params; i++) { | 464 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 466 super_type_arg = super_type_args.TypeAt(super_offset + i); | 465 super_type_arg = super_type_args.TypeAt(super_offset + i); |
| 467 if (!super_type_arg.IsInstantiated()) { | 466 if (!super_type_arg.IsInstantiated()) { |
| 468 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); | 467 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); |
| 469 } | 468 } |
| 470 super_type_arg = super_type_arg.Canonicalize(); | 469 super_type_arg = super_type_arg.Canonicalize(); |
| 471 arguments.SetTypeAt(super_offset + i, super_type_arg); | 470 arguments.SetTypeAt(super_offset + i, super_type_arg); |
| 472 } | 471 } |
| 473 FinalizeTypeArguments(super_class, arguments); | 472 FinalizeTypeArguments(super_class, arguments); |
| 474 } | 473 } |
| 475 } | 474 } |
| 476 | 475 |
| 477 | 476 |
| 478 void ClassFinalizer::FinalizeType(const Type& type) { | 477 RawType* ClassFinalizer::FinalizeType(const Type& type) { |
| 479 ASSERT(type.IsResolved()); | 478 ASSERT(type.IsResolved()); |
| 480 if (type.IsFinalized()) { | 479 if (type.IsFinalized()) { |
| 481 return; | 480 return type.raw(); |
| 482 } | 481 } |
| 483 | 482 |
| 484 // At this point, we can only have a parameterized_type. | 483 // At this point, we can only have a parameterized_type. |
| 485 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 484 ParameterizedType& parameterized_type = ParameterizedType::Handle(); |
| 486 parameterized_type ^= type.raw(); | 485 parameterized_type ^= type.raw(); |
| 487 | 486 |
| 488 if (parameterized_type.IsBeingFinalized()) { | 487 if (parameterized_type.IsBeingFinalized()) { |
| 489 ReportError("type '%s' illegally refers to itself\n", | 488 ReportError("type '%s' illegally refers to itself\n", |
| 490 String::Handle(parameterized_type.Name()).ToCString()); | 489 String::Handle(parameterized_type.Name()).ToCString()); |
| 491 } | 490 } |
| 492 | 491 |
| 493 // Mark type as being finalized in order to detect illegal self reference. | 492 // Mark type as being finalized in order to detect illegal self reference. |
| 494 parameterized_type.set_is_being_finalized(); | 493 parameterized_type.set_is_being_finalized(); |
| 495 | 494 |
| 496 // Finalize the current type arguments of the type, which are still the | 495 // Finalize the current type arguments of the type, which are still the |
| 497 // parsed type arguments. | 496 // parsed type arguments. |
| 498 TypeArguments& arguments = | 497 TypeArguments& arguments = |
| 499 TypeArguments::Handle(parameterized_type.arguments()); | 498 TypeArguments::Handle(parameterized_type.arguments()); |
| 500 if (!arguments.IsNull()) { | 499 if (!arguments.IsNull()) { |
| 501 intptr_t num_arguments = arguments.Length(); | 500 intptr_t num_arguments = arguments.Length(); |
| 502 for (intptr_t i = 0; i < num_arguments; i++) { | 501 for (intptr_t i = 0; i < num_arguments; i++) { |
| 503 Type& type_argument = Type::Handle(arguments.TypeAt(i)); | 502 Type& type_argument = Type::Handle(arguments.TypeAt(i)); |
| 504 FinalizeType(type_argument); | 503 type_argument = FinalizeType(type_argument); |
| 505 type_argument = type_argument.Canonicalize(); | |
| 506 arguments.SetTypeAt(i, type_argument); | 504 arguments.SetTypeAt(i, type_argument); |
| 507 } | 505 } |
| 508 } | 506 } |
| 509 | 507 |
| 510 // The type class does not need to be finalized in order to finalize the type, | 508 // The type class does not need to be finalized in order to finalize the type, |
| 511 // however, it must at least be resolved. This was done as part of resolving | 509 // however, it must at least be resolved. This was done as part of resolving |
| 512 // the type itself. | 510 // the type itself. |
| 513 Class& type_class = Class::Handle(parameterized_type.type_class()); | 511 Class& type_class = Class::Handle(parameterized_type.type_class()); |
| 514 | 512 |
| 515 // The finalized type argument vector needs num_type_arguments types. | 513 // The finalized type argument vector needs num_type_arguments types. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 parameterized_type.set_arguments(full_arguments); | 546 parameterized_type.set_arguments(full_arguments); |
| 549 } | 547 } |
| 550 | 548 |
| 551 // If the type is a function type, finalize the result and parameter types. | 549 // If the type is a function type, finalize the result and parameter types. |
| 552 if (type_class.IsSignatureClass()) { | 550 if (type_class.IsSignatureClass()) { |
| 553 ResolveAndFinalizeSignature( | 551 ResolveAndFinalizeSignature( |
| 554 type_class, Function::Handle(type_class.signature_function())); | 552 type_class, Function::Handle(type_class.signature_function())); |
| 555 } | 553 } |
| 556 | 554 |
| 557 parameterized_type.set_is_finalized(); | 555 parameterized_type.set_is_finalized(); |
| 556 return parameterized_type.Canonicalize(); |
| 558 } | 557 } |
| 559 | 558 |
| 560 | 559 |
| 561 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, | 560 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, |
| 562 String* errmsg) { | 561 String* errmsg) { |
| 563 Isolate* isolate = Isolate::Current(); | 562 Isolate* isolate = Isolate::Current(); |
| 564 ASSERT(isolate != NULL); | 563 ASSERT(isolate != NULL); |
| 565 LongJump* base = isolate->long_jump_base(); | 564 LongJump* base = isolate->long_jump_base(); |
| 566 LongJump jump; | 565 LongJump jump; |
| 567 isolate->set_long_jump_base(&jump); | 566 isolate->set_long_jump_base(&jump); |
| 568 if (setjmp(*jump.Set()) == 0) { | 567 if (setjmp(*jump.Set()) == 0) { |
| 569 FinalizeType(type); | 568 const Type& canonical_type = Type::Handle(FinalizeType(type)); |
| 570 isolate->set_long_jump_base(base); | 569 isolate->set_long_jump_base(base); |
| 571 *errmsg = String::null(); | 570 *errmsg = String::null(); |
| 572 return type.Canonicalize(); | 571 return canonical_type.raw(); |
| 573 } else { | 572 } else { |
| 574 // Error occured: Get the error message. | 573 // Error occured: Get the error message. |
| 575 isolate->set_long_jump_base(base); | 574 isolate->set_long_jump_base(base); |
| 576 *errmsg = isolate->object_store()->sticky_error(); | 575 *errmsg = isolate->object_store()->sticky_error(); |
| 577 return type.raw(); | 576 return type.raw(); |
| 578 } | 577 } |
| 579 UNREACHABLE(); | 578 UNREACHABLE(); |
| 580 return Type::null(); | 579 return Type::null(); |
| 581 } | 580 } |
| 582 | 581 |
| 583 | 582 |
| 584 // Top level function signatures are canonicalized, added to the library class | 583 // Top level function signatures are canonicalized, added to the library class |
| 585 // dictionary, and finalized with other library classes and interfaces. | 584 // dictionary, and finalized with other library classes and interfaces. |
| 586 // Function signatures used as type of a local variable or of a local function | 585 // Function signatures used as type of a local variable or of a local function |
| 587 // are canonicalized and finalized upon creation, since all the types they | 586 // are canonicalized and finalized upon creation, since all the types they |
| 588 // reference are already resolved. | 587 // reference are already resolved. |
| 589 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 588 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 590 const Function& function) { | 589 const Function& function) { |
| 591 // Resolve result type. | 590 // Resolve result type. |
| 592 Type& type = Type::Handle(function.result_type()); | 591 Type& type = Type::Handle(function.result_type()); |
| 593 type = ResolveType(cls, type); | 592 type = ResolveType(cls, type); |
| 594 function.set_result_type(type); | 593 function.set_result_type(type); |
| 595 FinalizeType(type); | 594 type = FinalizeType(type); |
| 596 type = type.Canonicalize(); | |
| 597 function.set_result_type(type); | 595 function.set_result_type(type); |
| 598 // Resolve formal parameter types. | 596 // Resolve formal parameter types. |
| 599 const intptr_t num_parameters = function.NumberOfParameters(); | 597 const intptr_t num_parameters = function.NumberOfParameters(); |
| 600 for (intptr_t i = 0; i < num_parameters; i++) { | 598 for (intptr_t i = 0; i < num_parameters; i++) { |
| 601 type = function.ParameterTypeAt(i); | 599 type = function.ParameterTypeAt(i); |
| 602 type = ResolveType(cls, type); | 600 type = ResolveType(cls, type); |
| 603 function.SetParameterTypeAt(i, type); | 601 function.SetParameterTypeAt(i, type); |
| 604 FinalizeType(type); | 602 type = FinalizeType(type); |
| 605 type = type.Canonicalize(); | |
| 606 function.SetParameterTypeAt(i, type); | 603 function.SetParameterTypeAt(i, type); |
| 607 } | 604 } |
| 608 } | 605 } |
| 609 | 606 |
| 610 | 607 |
| 611 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, | 608 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, |
| 612 const String& name) { | 609 const String& name) { |
| 613 Class& super_class = Class::Handle(); | 610 Class& super_class = Class::Handle(); |
| 614 Function& function = Function::Handle(); | 611 Function& function = Function::Handle(); |
| 615 Field& field = Field::Handle(); | 612 Field& field = Field::Handle(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 Field& field = Field::Handle(); | 661 Field& field = Field::Handle(); |
| 665 Type& type = Type::Handle(); | 662 Type& type = Type::Handle(); |
| 666 String& name = String::Handle(); | 663 String& name = String::Handle(); |
| 667 Class& super_class = Class::Handle(); | 664 Class& super_class = Class::Handle(); |
| 668 intptr_t num_fields = array.Length(); | 665 intptr_t num_fields = array.Length(); |
| 669 for (intptr_t i = 0; i < num_fields; i++) { | 666 for (intptr_t i = 0; i < num_fields; i++) { |
| 670 field ^= array.At(i); | 667 field ^= array.At(i); |
| 671 type = field.type(); | 668 type = field.type(); |
| 672 type = ResolveType(cls, type); | 669 type = ResolveType(cls, type); |
| 673 field.set_type(type); | 670 field.set_type(type); |
| 674 FinalizeType(type); | 671 type = FinalizeType(type); |
| 675 type = type.Canonicalize(); | |
| 676 field.set_type(type); | 672 field.set_type(type); |
| 677 name = field.name(); | 673 name = field.name(); |
| 678 super_class = FindSuperOwnerOfInstanceMember(cls, name); | 674 super_class = FindSuperOwnerOfInstanceMember(cls, name); |
| 679 if (!super_class.IsNull()) { | 675 if (!super_class.IsNull()) { |
| 680 const String& class_name = String::Handle(cls.Name()); | 676 const String& class_name = String::Handle(cls.Name()); |
| 681 const String& super_class_name = String::Handle(super_class.Name()); | 677 const String& super_class_name = String::Handle(super_class.Name()); |
| 682 ReportError("field '%s' of class '%s' conflicts with instance " | 678 ReportError("field '%s' of class '%s' conflicts with instance " |
| 683 "member '%s' of super class '%s'.\n", | 679 "member '%s' of super class '%s'.\n", |
| 684 name.ToCString(), | 680 name.ToCString(), |
| 685 class_name.ToCString(), | 681 class_name.ToCString(), |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 "setter '%s' of super class '%s'.\n", | 772 "setter '%s' of super class '%s'.\n", |
| 777 function_name.ToCString(), | 773 function_name.ToCString(), |
| 778 class_name.ToCString(), | 774 class_name.ToCString(), |
| 779 function_name.ToCString(), | 775 function_name.ToCString(), |
| 780 super_class_name.ToCString()); | 776 super_class_name.ToCString()); |
| 781 } | 777 } |
| 782 } | 778 } |
| 783 } | 779 } |
| 784 // Resolve the signature type if this class is a signature class. | 780 // Resolve the signature type if this class is a signature class. |
| 785 if (cls.IsSignatureClass()) { | 781 if (cls.IsSignatureClass()) { |
| 786 const Type& signature_type = Type::Handle(cls.SignatureType()); | 782 Type& signature_type = Type::Handle(cls.SignatureType()); |
| 787 FinalizeType(signature_type); | 783 signature_type = FinalizeType(signature_type); |
| 788 // Signature types are canonicalized by default. | 784 // Signature types are canonicalized by default. |
| 785 ASSERT(signature_type.raw() == cls.SignatureType()); |
| 789 } | 786 } |
| 790 } | 787 } |
| 791 | 788 |
| 792 | 789 |
| 793 void ClassFinalizer::FinalizeClass(const Class& cls) { | 790 void ClassFinalizer::FinalizeClass(const Class& cls) { |
| 794 if (cls.is_finalized()) { | 791 if (cls.is_finalized()) { |
| 795 return; | 792 return; |
| 796 } | 793 } |
| 797 if (FLAG_trace_class_finalization) { | 794 if (FLAG_trace_class_finalization) { |
| 798 OS::Print("Finalize %s\n", cls.ToCString()); | 795 OS::Print("Finalize %s\n", cls.ToCString()); |
| 799 } | 796 } |
| 800 if (!IsSuperCycleFree(cls)) { | 797 if (!IsSuperCycleFree(cls)) { |
| 801 const String& name = String::Handle(cls.Name()); | 798 const String& name = String::Handle(cls.Name()); |
| 802 ReportError("class '%s' has a cycle in its superclass relationship.\n", | 799 ReportError("class '%s' has a cycle in its superclass relationship.\n", |
| 803 name.ToCString()); | 800 name.ToCString()); |
| 804 } | 801 } |
| 805 GrowableArray<const Class*> visited; | 802 GrowableArray<const Class*> visited; |
| 806 ResolveInterfaces(cls, &visited); | 803 ResolveInterfaces(cls, &visited); |
| 807 Type& super_type = Type::Handle(cls.super_type()); | 804 Type& super_type = Type::Handle(cls.super_type()); |
| 808 if (!super_type.IsNull()) { | 805 if (!super_type.IsNull()) { |
| 809 const Class& super_class = Class::Handle(super_type.type_class()); | 806 const Class& super_class = Class::Handle(super_type.type_class()); |
| 810 // Finalize super class and super type. | 807 // Finalize super class and super type. |
| 811 FinalizeClass(super_class); | 808 FinalizeClass(super_class); |
| 812 FinalizeType(super_type); | 809 super_type = FinalizeType(super_type); |
| 813 super_type = super_type.Canonicalize(); | |
| 814 cls.set_super_type(super_type); | 810 cls.set_super_type(super_type); |
| 815 } | 811 } |
| 816 if (cls.is_interface()) { | 812 if (cls.is_interface()) { |
| 817 Type& factory_type = Type::Handle(cls.factory_type()); | 813 Type& factory_type = Type::Handle(cls.factory_type()); |
| 818 if (!factory_type.IsNull()) { | 814 if (!factory_type.IsNull()) { |
| 819 const Class& factory_class = Class::Handle(factory_type.type_class()); | 815 const Class& factory_class = Class::Handle(factory_type.type_class()); |
| 820 // Finalize factory class and factory type. | 816 // Finalize factory class and factory type. |
| 821 if (!factory_class.is_finalized()) { | 817 if (!factory_class.is_finalized()) { |
| 822 FinalizeClass(factory_class); | 818 FinalizeClass(factory_class); |
| 823 // Finalizing the factory class may indirectly finalize this interface. | 819 // Finalizing the factory class may indirectly finalize this interface. |
| 824 if (cls.is_finalized()) { | 820 if (cls.is_finalized()) { |
| 825 return; | 821 return; |
| 826 } | 822 } |
| 827 } | 823 } |
| 828 FinalizeType(factory_type); | 824 factory_type = FinalizeType(factory_type); |
| 829 factory_type = factory_type.Canonicalize(); | |
| 830 cls.set_factory_type(factory_type); | 825 cls.set_factory_type(factory_type); |
| 831 } | 826 } |
| 832 } | 827 } |
| 833 // Finalize interface types (but not necessarily interface classes). | 828 // Finalize interface types (but not necessarily interface classes). |
| 834 Array& interface_types = Array::Handle(cls.interfaces()); | 829 Array& interface_types = Array::Handle(cls.interfaces()); |
| 835 Type& interface_type = Type::Handle(); | 830 Type& interface_type = Type::Handle(); |
| 836 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 831 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
| 837 interface_type ^= interface_types.At(i); | 832 interface_type ^= interface_types.At(i); |
| 838 FinalizeType(interface_type); | 833 interface_type = FinalizeType(interface_type); |
| 839 interface_type = interface_type.Canonicalize(); | |
| 840 interface_types.SetAt(i, interface_type); | 834 interface_types.SetAt(i, interface_type); |
| 841 } | 835 } |
| 842 // Mark as finalized before resolving member types in order to break cycles. | 836 // Mark as finalized before resolving member types in order to break cycles. |
| 843 cls.Finalize(); | 837 cls.Finalize(); |
| 844 ResolveAndFinalizeMemberTypes(cls); | 838 ResolveAndFinalizeMemberTypes(cls); |
| 845 // Run additional checks after all types are finalized. | 839 // Run additional checks after all types are finalized. |
| 846 if (cls.is_const()) { | 840 if (cls.is_const()) { |
| 847 CheckForLegalConstClass(cls); | 841 CheckForLegalConstClass(cls); |
| 848 } | 842 } |
| 849 } | 843 } |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 ASSERT(msg_buffer != NULL); | 1084 ASSERT(msg_buffer != NULL); |
| 1091 va_list args; | 1085 va_list args; |
| 1092 va_start(args, format); | 1086 va_start(args, format); |
| 1093 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | 1087 OS::VSNPrint(msg_buffer, kBufferLength, format, args); |
| 1094 va_end(args); | 1088 va_end(args); |
| 1095 isolate->long_jump_base()->Jump(1, msg_buffer); | 1089 isolate->long_jump_base()->Jump(1, msg_buffer); |
| 1096 UNREACHABLE(); | 1090 UNREACHABLE(); |
| 1097 } | 1091 } |
| 1098 | 1092 |
| 1099 } // namespace dart | 1093 } // namespace dart |
| OLD | NEW |