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