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/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 const intptr_t num_arguments = arguments.Length(); | 484 const intptr_t num_arguments = arguments.Length(); |
485 AbstractType& type_argument = AbstractType::Handle(); | 485 AbstractType& type_argument = AbstractType::Handle(); |
486 for (intptr_t i = 0; i < num_arguments; i++) { | 486 for (intptr_t i = 0; i < num_arguments; i++) { |
487 type_argument = arguments.TypeAt(i); | 487 type_argument = arguments.TypeAt(i); |
488 ResolveType(cls, type_argument, finalization); | 488 ResolveType(cls, type_argument, finalization); |
489 } | 489 } |
490 } | 490 } |
491 } | 491 } |
492 | 492 |
493 | 493 |
494 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { | 494 void ClassFinalizer::FinalizeTypeParameters( |
| 495 const Class& cls, |
| 496 GrowableObjectArray* pending_types) { |
495 if (cls.IsMixinApplication()) { | 497 if (cls.IsMixinApplication()) { |
496 // Setup the type parameters of the mixin application and finalize the | 498 // Setup the type parameters of the mixin application and finalize the |
497 // mixin type. | 499 // mixin type. |
498 ApplyMixinType(cls); | 500 ApplyMixinType(cls, pending_types); |
499 } | 501 } |
500 // The type parameter bounds are not finalized here. | 502 // The type parameter bounds are not finalized here. |
501 const TypeArguments& type_parameters = | 503 const TypeArguments& type_parameters = |
502 TypeArguments::Handle(cls.type_parameters()); | 504 TypeArguments::Handle(cls.type_parameters()); |
503 if (!type_parameters.IsNull()) { | 505 if (!type_parameters.IsNull()) { |
504 TypeParameter& type_parameter = TypeParameter::Handle(); | 506 TypeParameter& type_parameter = TypeParameter::Handle(); |
505 const intptr_t num_types = type_parameters.Length(); | 507 const intptr_t num_types = type_parameters.Length(); |
506 for (intptr_t i = 0; i < num_types; i++) { | 508 for (intptr_t i = 0; i < num_types; i++) { |
507 type_parameter ^= type_parameters.TypeAt(i); | 509 type_parameter ^= type_parameters.TypeAt(i); |
508 type_parameter ^= FinalizeType(cls, | 510 type_parameter ^= FinalizeType( |
509 type_parameter, | 511 cls, type_parameter, kFinalize, pending_types); |
510 kCanonicalizeWellFormed); | |
511 type_parameters.SetTypeAt(i, type_parameter); | 512 type_parameters.SetTypeAt(i, type_parameter); |
512 } | 513 } |
513 } | 514 } |
514 } | 515 } |
515 | 516 |
516 | 517 |
517 // Finalize the type argument vector 'arguments' of the type defined by the | 518 // Finalize the type argument vector 'arguments' of the type defined by the |
518 // class 'cls' parameterized with the type arguments 'cls_args'. | 519 // class 'cls' parameterized with the type arguments 'cls_args'. |
519 // The vector 'cls_args' is already initialized as a subvector at the correct | 520 // The vector 'cls_args' is already initialized as a subvector at the correct |
520 // position in the passed in 'arguments' vector. | 521 // position in the passed in 'arguments' vector. |
(...skipping 13 matching lines...) Expand all Loading... |
534 // i.e. cls_args = [String, double], offset = 2, length = 2. | 535 // i.e. cls_args = [String, double], offset = 2, length = 2. |
535 // Output: arguments = [int, double, String, double] | 536 // Output: arguments = [int, double, String, double] |
536 // Example 2 (with overlap): | 537 // Example 2 (with overlap): |
537 // Declared: class C<K, V> extends B<K> { ... } | 538 // Declared: class C<K, V> extends B<K> { ... } |
538 // class B<T> extends A<int> { ... } | 539 // class B<T> extends A<int> { ... } |
539 // Input: C<String, double> expressed as | 540 // Input: C<String, double> expressed as |
540 // cls = C, arguments = [dynamic, String, double], | 541 // cls = C, arguments = [dynamic, String, double], |
541 // num_uninitialized_arguments = 1, | 542 // num_uninitialized_arguments = 1, |
542 // i.e. cls_args = [String, double], offset = 1, length = 2. | 543 // i.e. cls_args = [String, double], offset = 1, length = 2. |
543 // Output: arguments = [int, String, double] | 544 // Output: arguments = [int, String, double] |
| 545 // |
| 546 // It is too early to canonicalize the type arguments of the vector, because |
| 547 // several type argument vectors may be mutually recursive and finalized at the |
| 548 // same time. Canonicalization happens when pending types are processed. |
544 void ClassFinalizer::FinalizeTypeArguments( | 549 void ClassFinalizer::FinalizeTypeArguments( |
545 const Class& cls, | 550 const Class& cls, |
546 const AbstractTypeArguments& arguments, | 551 const AbstractTypeArguments& arguments, |
547 intptr_t num_uninitialized_arguments, | 552 intptr_t num_uninitialized_arguments, |
548 FinalizationKind finalization, | 553 Error* bound_error, |
549 Error* bound_error) { | 554 GrowableObjectArray* pending_types) { |
550 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 555 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
551 if (!cls.is_type_finalized()) { | 556 if (!cls.is_type_finalized()) { |
552 FinalizeTypeParameters(cls); | 557 FinalizeTypeParameters(cls, pending_types); |
553 ResolveUpperBounds(cls); | 558 ResolveUpperBounds(cls); |
554 } | 559 } |
555 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 560 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
556 if (!super_type.IsNull()) { | 561 if (!super_type.IsNull()) { |
557 const Class& super_class = Class::Handle(super_type.type_class()); | 562 const Class& super_class = Class::Handle(super_type.type_class()); |
558 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); | 563 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
559 if (super_type.IsBeingFinalized()) { | 564 const intptr_t num_super_type_args = super_class.NumTypeArguments(); |
560 // This type references itself via its type arguments. This is legal, but | 565 ASSERT(num_super_type_args == |
561 // we must avoid endless recursion. We therefore map the innermost | 566 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); |
562 // super type to dynamic. | 567 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { |
563 // Note that a direct self-reference via the super class chain is illegal | 568 super_type ^= FinalizeType( |
564 // and reported as an error earlier. | 569 cls, super_type, kFinalize, pending_types); |
565 // Such legal self-references occur with F-bounded quantification. | |
566 // Example 1: class Derived extends Base<Derived>. | |
567 // The type 'Derived' forms a cycle by pointing to itself via its | |
568 // flattened type argument vector: Derived[Derived[...]] | |
569 // We break the cycle as follows: Derived[Derived[dynamic]] | |
570 // Example 2: class Derived extends Base<Middle<Derived>> results in | |
571 // Derived[Middle[Derived[dynamic]]] | |
572 // Example 3: class Derived<T> extends Base<Derived<T>> results in | |
573 // Derived[Derived[dynamic], T]. | |
574 ASSERT(super_type_args.IsNull()); // Same as a vector of dynamic. | |
575 } else { | |
576 super_type ^= FinalizeType(cls, super_type, finalization); | |
577 cls.set_super_type(super_type); | 570 cls.set_super_type(super_type); |
578 super_type_args = super_type.arguments(); | |
579 } | 571 } |
580 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 572 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle( |
581 const intptr_t offset = super_class.NumTypeArguments(); | 573 super_type.arguments()); |
582 const intptr_t super_offset = offset - num_super_type_params; | 574 // Offset of super type's type parameters in cls' type argument vector. |
583 ASSERT(offset == (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); | 575 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
584 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 576 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
585 for (intptr_t i = 0; super_offset + i < num_uninitialized_arguments; i++) { | 577 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
586 if (!super_type_args.IsNull()) { | 578 if (!super_type_args.IsNull()) { |
587 super_type_arg = super_type_args.TypeAt(super_offset + i); | 579 super_type_arg = super_type_args.TypeAt(i); |
| 580 if (!super_type_arg.IsFinalized()) { |
| 581 super_type_arg ^= FinalizeType( |
| 582 cls, super_type_arg, kFinalize, pending_types); |
| 583 super_type_args.SetTypeAt(i, super_type_arg); |
| 584 } |
588 if (!super_type_arg.IsInstantiated()) { | 585 if (!super_type_arg.IsInstantiated()) { |
589 Error& error = Error::Handle(); | 586 Error& error = Error::Handle(); |
590 super_type_arg = super_type_arg.InstantiateFrom(arguments, &error); | 587 super_type_arg = super_type_arg.InstantiateFrom(arguments, &error); |
591 if (!error.IsNull()) { | 588 if (!error.IsNull()) { |
592 // InstantiateFrom does not report an error if the type is still | 589 // InstantiateFrom does not report an error if the type is still |
593 // uninstantiated. Instead, it will return a new BoundedType so that | 590 // uninstantiated. Instead, it will return a new BoundedType so that |
594 // the check is postponed to run time. | 591 // the check is postponed to run time. |
595 ASSERT(super_type_arg.IsInstantiated()); | 592 ASSERT(super_type_arg.IsInstantiated()); |
596 // Keep only the first bound error. | 593 // Keep only the first bound error. |
597 if (bound_error->IsNull()) { | 594 if (bound_error->IsNull()) { |
598 *bound_error = error.raw(); | 595 *bound_error = error.raw(); |
599 } | 596 } |
600 } | 597 } |
601 } | 598 } |
602 if (finalization >= kCanonicalize) { | |
603 super_type_arg = super_type_arg.Canonicalize(); | |
604 } | |
605 } | 599 } |
606 arguments.SetTypeAt(super_offset + i, super_type_arg); | 600 arguments.SetTypeAt(i, super_type_arg); |
607 } | 601 } |
608 FinalizeTypeArguments(super_class, arguments, super_offset, | 602 FinalizeTypeArguments(super_class, arguments, super_offset, |
609 finalization, bound_error); | 603 bound_error, pending_types); |
610 } | 604 } |
611 } | 605 } |
612 | 606 |
613 | 607 |
614 // Check the type argument vector 'arguments' against the corresponding bounds | 608 // Check the type argument vector 'arguments' against the corresponding bounds |
615 // of the type parameters of class 'cls' and, recursively, of its superclasses. | 609 // of the type parameters of class 'cls' and, recursively, of its superclasses. |
616 // Replace a type argument that cannot be checked at compile time by a | 610 // Replace a type argument that cannot be checked at compile time by a |
617 // BoundedType, thereby postponing the bound check to run time. | 611 // BoundedType, thereby postponing the bound check to run time. |
618 // Return a bound error if a type argument is not within bound at compile time. | 612 // Return a bound error if a type argument is not within bound at compile time. |
619 void ClassFinalizer::CheckTypeArgumentBounds( | 613 void ClassFinalizer::CheckTypeArgumentBounds( |
(...skipping 20 matching lines...) Expand all Loading... |
640 TypeArguments::Handle(cls.type_parameters()); | 634 TypeArguments::Handle(cls.type_parameters()); |
641 ASSERT((cls_type_params.IsNull() && (num_type_params == 0)) || | 635 ASSERT((cls_type_params.IsNull() && (num_type_params == 0)) || |
642 (cls_type_params.Length() == num_type_params)); | 636 (cls_type_params.Length() == num_type_params)); |
643 // In case of overlapping type argument vectors, the same type argument may | 637 // In case of overlapping type argument vectors, the same type argument may |
644 // get checked against different bounds. | 638 // get checked against different bounds. |
645 for (intptr_t i = 0; i < num_type_params; i++) { | 639 for (intptr_t i = 0; i < num_type_params; i++) { |
646 type_arg = arguments.TypeAt(offset + i); | 640 type_arg = arguments.TypeAt(offset + i); |
647 if (type_arg.IsDynamicType()) { | 641 if (type_arg.IsDynamicType()) { |
648 continue; | 642 continue; |
649 } | 643 } |
| 644 ASSERT(type_arg.IsFinalized()); |
650 cls_type_param = cls_type_params.TypeAt(i); | 645 cls_type_param = cls_type_params.TypeAt(i); |
651 const TypeParameter& type_param = TypeParameter::Cast(cls_type_param); | 646 const TypeParameter& type_param = TypeParameter::Cast(cls_type_param); |
652 ASSERT(type_param.IsFinalized()); | 647 ASSERT(type_param.IsFinalized()); |
653 declared_bound = type_param.bound(); | 648 declared_bound = type_param.bound(); |
654 if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { | 649 if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { |
655 if (!declared_bound.IsFinalized() && !declared_bound.IsBeingFinalized()) { | 650 if (!declared_bound.IsFinalized() && !declared_bound.IsBeingFinalized()) { |
656 declared_bound = FinalizeType(cls, declared_bound, kCanonicalize); | 651 declared_bound = FinalizeType(cls, declared_bound, kCanonicalize); |
657 type_param.set_bound(declared_bound); | 652 type_param.set_bound(declared_bound); |
658 } | 653 } |
659 ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized()); | 654 ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 } | 688 } |
694 } | 689 } |
695 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 690 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
696 if (!super_type.IsNull()) { | 691 if (!super_type.IsNull()) { |
697 const Class& super_class = Class::Handle(super_type.type_class()); | 692 const Class& super_class = Class::Handle(super_type.type_class()); |
698 CheckTypeArgumentBounds(super_class, arguments, bound_error); | 693 CheckTypeArgumentBounds(super_class, arguments, bound_error); |
699 } | 694 } |
700 } | 695 } |
701 | 696 |
702 | 697 |
703 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, | 698 void ClassFinalizer::CheckTypeBounds(const Class& cls, const Type& type) { |
704 const AbstractType& type, | 699 ASSERT(type.IsFinalized()); |
705 FinalizationKind finalization) { | 700 AbstractTypeArguments& arguments = |
| 701 AbstractTypeArguments::Handle(type.arguments()); |
| 702 if (arguments.IsNull()) { |
| 703 return; |
| 704 } |
| 705 Class& owner_class = Class::Handle(); |
| 706 Class& type_class = Class::Handle(type.type_class()); |
| 707 if (type_class.IsSignatureClass()) { |
| 708 const Function& signature_fun = |
| 709 Function::Handle(type_class.signature_function()); |
| 710 ASSERT(!signature_fun.is_static()); |
| 711 owner_class = signature_fun.Owner(); |
| 712 } else { |
| 713 owner_class = type_class.raw(); |
| 714 } |
| 715 Error& bound_error = Error::Handle(); |
| 716 CheckTypeArgumentBounds(owner_class, arguments, &bound_error); |
| 717 type.set_arguments(arguments); |
| 718 // If a bound error occurred, mark the type as malbounded. |
| 719 // The bound error will be ignored in production mode. |
| 720 if (!bound_error.IsNull()) { |
| 721 // No compile-time error during finalization. |
| 722 const String& type_name = String::Handle(type.UserVisibleName()); |
| 723 FinalizeMalboundedType(bound_error, |
| 724 Script::Handle(cls.script()), |
| 725 type, |
| 726 "type '%s' has an out of bound type argument", |
| 727 type_name.ToCString()); |
| 728 if (FLAG_trace_type_finalization) { |
| 729 OS::Print("Marking type '%s' as malbounded: %s\n", |
| 730 String::Handle(type.Name()).ToCString(), |
| 731 bound_error.ToCString()); |
| 732 } |
| 733 } |
| 734 } |
| 735 |
| 736 |
| 737 RawAbstractType* ClassFinalizer::FinalizeType( |
| 738 const Class& cls, |
| 739 const AbstractType& type, |
| 740 FinalizationKind finalization, |
| 741 GrowableObjectArray* pending_types) { |
| 742 // Only the 'root' type of the graph can be canonicalized, after all depending |
| 743 // types have been bound checked. |
| 744 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); |
706 if (type.IsFinalized()) { | 745 if (type.IsFinalized()) { |
707 // Ensure type is canonical if canonicalization is requested, unless type is | 746 // Ensure type is canonical if canonicalization is requested, unless type is |
708 // malformed. | 747 // malformed. |
709 if ((finalization >= kCanonicalize) && !type.IsMalformed()) { | 748 if ((finalization >= kCanonicalize) && !type.IsMalformed()) { |
710 return type.Canonicalize(); | 749 return type.Canonicalize(); |
711 } | 750 } |
712 return type.raw(); | 751 return type.raw(); |
713 } | 752 } |
714 ASSERT(type.IsResolved()); | 753 ASSERT(type.IsResolved()); |
715 ASSERT(finalization >= kFinalize); | 754 ASSERT(finalization >= kFinalize); |
716 | 755 |
| 756 if (type.IsTypeRef()) { |
| 757 // The referenced type will be finalized later by the code that set the |
| 758 // is_being_finalized mark bit. |
| 759 return type.raw(); |
| 760 } |
| 761 |
| 762 if (type.IsBeingFinalized()) { |
| 763 if (FLAG_trace_type_finalization) { |
| 764 OS::Print("Creating TypeRef '%s' for class '%s'\n", |
| 765 String::Handle(type.Name()).ToCString(), |
| 766 cls.ToCString()); |
| 767 } |
| 768 return TypeRef::New(type); |
| 769 } |
| 770 |
717 if (FLAG_trace_type_finalization) { | 771 if (FLAG_trace_type_finalization) { |
718 OS::Print("Finalizing type '%s' for class '%s'\n", | 772 OS::Print("Finalizing type '%s' for class '%s'\n", |
719 String::Handle(type.Name()).ToCString(), | 773 String::Handle(type.Name()).ToCString(), |
720 cls.ToCString()); | 774 cls.ToCString()); |
721 } | 775 } |
722 | 776 |
723 if (type.IsTypeParameter()) { | 777 if (type.IsTypeParameter()) { |
724 const TypeParameter& type_parameter = TypeParameter::Cast(type); | 778 const TypeParameter& type_parameter = TypeParameter::Cast(type); |
725 const Class& parameterized_class = | 779 const Class& parameterized_class = |
726 Class::Handle(type_parameter.parameterized_class()); | 780 Class::Handle(type_parameter.parameterized_class()); |
(...skipping 20 matching lines...) Expand all Loading... |
747 type_parameter.index()); | 801 type_parameter.index()); |
748 } | 802 } |
749 | 803 |
750 // We do not canonicalize type parameters. | 804 // We do not canonicalize type parameters. |
751 return type_parameter.raw(); | 805 return type_parameter.raw(); |
752 } | 806 } |
753 | 807 |
754 // At this point, we can only have a parameterized_type. | 808 // At this point, we can only have a parameterized_type. |
755 const Type& parameterized_type = Type::Cast(type); | 809 const Type& parameterized_type = Type::Cast(type); |
756 | 810 |
757 // Types illegally referring to themselves should have been detected earlier. | 811 // This type is the root type of the type graph if no pending types queue is |
758 ASSERT(!parameterized_type.IsBeingFinalized()); | 812 // allocated yet. |
759 | 813 const bool is_root_type = (pending_types == NULL); |
760 // Mark type as being finalized in order to detect illegal self reference. | 814 GrowableObjectArray& types = GrowableObjectArray::Handle(); |
761 parameterized_type.set_is_being_finalized(); | 815 if (is_root_type) { |
| 816 types = GrowableObjectArray::New(); |
| 817 pending_types = &types; |
| 818 } |
762 | 819 |
763 // The type class does not need to be finalized in order to finalize the type, | 820 // The type class does not need to be finalized in order to finalize the type, |
764 // however, it must at least be resolved (this was done as part of resolving | 821 // however, it must at least be resolved (this was done as part of resolving |
765 // the type itself, a precondition to calling FinalizeType). | 822 // the type itself, a precondition to calling FinalizeType). |
766 // Also, the interfaces of the type class must be resolved and the type | 823 // Also, the interfaces of the type class must be resolved and the type |
767 // parameters of the type class must be finalized. | 824 // parameters of the type class must be finalized. |
768 Class& type_class = Class::Handle(parameterized_type.type_class()); | 825 Class& type_class = Class::Handle(parameterized_type.type_class()); |
769 if (!type_class.is_type_finalized()) { | 826 if (!type_class.is_type_finalized()) { |
770 FinalizeTypeParameters(type_class); | 827 FinalizeTypeParameters(type_class, pending_types); |
771 ResolveUpperBounds(type_class); | 828 ResolveUpperBounds(type_class); |
772 } | 829 } |
773 | 830 |
774 // Finalize the current type arguments of the type, which are still the | |
775 // parsed type arguments. | |
776 AbstractTypeArguments& arguments = | |
777 AbstractTypeArguments::Handle(parameterized_type.arguments()); | |
778 if (!arguments.IsNull()) { | |
779 const intptr_t num_arguments = arguments.Length(); | |
780 AbstractType& type_argument = AbstractType::Handle(); | |
781 for (intptr_t i = 0; i < num_arguments; i++) { | |
782 type_argument = arguments.TypeAt(i); | |
783 type_argument = FinalizeType(cls, type_argument, finalization); | |
784 if (type_argument.IsMalformed()) { | |
785 // Malformed type arguments are mapped to dynamic. | |
786 type_argument = Type::DynamicType(); | |
787 } | |
788 arguments.SetTypeAt(i, type_argument); | |
789 } | |
790 } | |
791 | |
792 // The finalized type argument vector needs num_type_arguments types. | 831 // The finalized type argument vector needs num_type_arguments types. |
793 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 832 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
794 // The type class has num_type_parameters type parameters. | 833 // The type class has num_type_parameters type parameters. |
795 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 834 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
796 | 835 |
797 // Initialize the type argument vector. | 836 // Initialize the type argument vector. |
798 // Check the number of parsed type arguments, if any. | 837 // Check the number of parsed type arguments, if any. |
799 // Specifying no type arguments indicates a raw type, which is not an error. | 838 // Specifying no type arguments indicates a raw type, which is not an error. |
800 // However, type parameter bounds are checked below, even for a raw type. | 839 // However, type parameter bounds are checked below, even for a raw type. |
| 840 AbstractTypeArguments& arguments = |
| 841 AbstractTypeArguments::Handle(parameterized_type.arguments()); |
801 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 842 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
802 // Wrong number of type arguments. The type is mapped to the raw type. | 843 // Wrong number of type arguments. The type is mapped to the raw type. |
803 if (FLAG_error_on_bad_type) { | 844 if (FLAG_error_on_bad_type) { |
804 const Script& script = Script::Handle(cls.script()); | 845 const Script& script = Script::Handle(cls.script()); |
805 const String& type_class_name = String::Handle(type_class.Name()); | 846 const String& type_class_name = String::Handle(type_class.Name()); |
806 ReportError(Error::Handle(), // No previous error. | 847 ReportError(Error::Handle(), // No previous error. |
807 script, parameterized_type.token_pos(), | 848 script, parameterized_type.token_pos(), |
808 "wrong number of type arguments for class '%s'", | 849 "wrong number of type arguments for class '%s'", |
809 type_class_name.ToCString()); | 850 type_class_name.ToCString()); |
810 } | 851 } |
811 // Make the type raw and continue without reporting any error. | 852 // Make the type raw and continue without reporting any error. |
812 // A static warning should have been reported. | 853 // A static warning should have been reported. |
813 arguments = AbstractTypeArguments::null(); | 854 arguments = AbstractTypeArguments::null(); |
814 parameterized_type.set_arguments(arguments); | 855 parameterized_type.set_arguments(arguments); |
815 } | 856 } |
| 857 |
816 // The full type argument vector consists of the type arguments of the | 858 // The full type argument vector consists of the type arguments of the |
817 // super types of type_class, which are initialized from the parsed | 859 // super types of type_class, which are initialized from the parsed |
818 // type arguments, followed by the parsed type arguments. | 860 // type arguments, followed by the parsed type arguments. |
819 TypeArguments& full_arguments = TypeArguments::Handle(); | 861 TypeArguments& full_arguments = TypeArguments::Handle(); |
820 Error& bound_error = Error::Handle(); | 862 Error& bound_error = Error::Handle(); |
821 if (num_type_arguments > 0) { | 863 if (num_type_arguments > 0) { |
822 // If no type arguments were parsed and if the super types do not prepend | 864 // If no type arguments were parsed and if the super types do not prepend |
823 // type arguments to the vector, we can leave the vector as null. | 865 // type arguments to the vector, we can leave the vector as null. |
824 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 866 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
825 full_arguments = TypeArguments::New(num_type_arguments); | 867 full_arguments = TypeArguments::New(num_type_arguments); |
826 // Copy the parsed type arguments at the correct offset in the full type | 868 // Copy the parsed type arguments at the correct offset in the full type |
827 // argument vector. | 869 // argument vector. |
828 const intptr_t offset = num_type_arguments - num_type_parameters; | 870 const intptr_t offset = num_type_arguments - num_type_parameters; |
829 AbstractType& type_arg = AbstractType::Handle(Type::DynamicType()); | 871 AbstractType& type_arg = AbstractType::Handle(Type::DynamicType()); |
| 872 // TODO(regis): Leave the temporary type argument values as null. |
830 for (intptr_t i = 0; i < offset; i++) { | 873 for (intptr_t i = 0; i < offset; i++) { |
831 // Temporarily set the type arguments of the super classes to dynamic. | 874 // Temporarily set the type arguments of the super classes to dynamic. |
832 full_arguments.SetTypeAt(i, type_arg); | 875 full_arguments.SetTypeAt(i, type_arg); |
833 } | 876 } |
834 for (intptr_t i = 0; i < num_type_parameters; i++) { | 877 for (intptr_t i = 0; i < num_type_parameters; i++) { |
835 // If no type parameters were provided, a raw type is desired, so we | 878 // If no type parameters were provided, a raw type is desired, so we |
836 // create a vector of dynamic. | 879 // create a vector of dynamic. |
837 if (!arguments.IsNull()) { | 880 if (!arguments.IsNull()) { |
838 type_arg = arguments.TypeAt(i); | 881 type_arg = arguments.TypeAt(i); |
| 882 // The parsed type_arg may or may not be finalized. |
839 } | 883 } |
840 ASSERT(type_arg.IsFinalized()); // Index of type parameter is adjusted. | |
841 full_arguments.SetTypeAt(offset + i, type_arg); | 884 full_arguments.SetTypeAt(offset + i, type_arg); |
842 } | 885 } |
843 // Replace the compile-time argument vector (of length zero or | 886 // Replace the compile-time argument vector (of length zero or |
844 // num_type_parameters) of this type being finalized with the still | 887 // num_type_parameters) of this type being finalized with the still |
845 // unfinalized run-time argument vector (of length num_type_arguments). | 888 // unfinalized run-time argument vector (of length num_type_arguments). |
846 // This type being finalized may be recursively reached via bounds | 889 // This type being finalized may be recursively reached via bounds |
847 // checking, in which case type arguments of super classes will be seen | 890 // checking, in which case type arguments of super classes will be seen |
848 // as dynamic. | 891 // as dynamic. |
849 parameterized_type.set_arguments(full_arguments); | 892 parameterized_type.set_arguments(full_arguments); |
| 893 // Mark type as being finalized in order to detect self reference. |
| 894 parameterized_type.set_is_being_finalized(); |
| 895 // Finalize the current type arguments of the type, which are still the |
| 896 // parsed type arguments. |
| 897 if (!arguments.IsNull()) { |
| 898 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 899 type_arg = full_arguments.TypeAt(offset + i); |
| 900 ASSERT(!type_arg.IsBeingFinalized()); |
| 901 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); |
| 902 if (type_arg.IsMalformed()) { |
| 903 // Malformed type arguments are mapped to dynamic. |
| 904 type_arg = Type::DynamicType(); |
| 905 } |
| 906 full_arguments.SetTypeAt(offset + i, type_arg); |
| 907 } |
| 908 } |
850 // If the type class is a signature class, the full argument vector | 909 // If the type class is a signature class, the full argument vector |
851 // must include the argument vector of the super type. | 910 // must include the argument vector of the super type. |
852 // If the signature class is a function type alias, it is also the owner | 911 // If the signature class is a function type alias, it is also the owner |
853 // of its signature function and no super type is involved. | 912 // of its signature function and no super type is involved. |
854 // If the signature class is canonical (not an alias), the owner of its | 913 // If the signature class is canonical (not an alias), the owner of its |
855 // signature function may either be an alias or the enclosing class of a | 914 // signature function may either be an alias or the enclosing class of a |
856 // local function, in which case the super type of the enclosing class is | 915 // local function, in which case the super type of the enclosing class is |
857 // also considered when filling up the argument vector. | 916 // also considered when filling up the argument vector. |
| 917 Class& owner_class = Class::Handle(); |
858 if (type_class.IsSignatureClass()) { | 918 if (type_class.IsSignatureClass()) { |
859 const Function& signature_fun = | 919 const Function& signature_fun = |
860 Function::Handle(type_class.signature_function()); | 920 Function::Handle(type_class.signature_function()); |
861 ASSERT(!signature_fun.is_static()); | 921 ASSERT(!signature_fun.is_static()); |
862 const Class& sig_fun_owner = Class::Handle(signature_fun.Owner()); | 922 owner_class = signature_fun.Owner(); |
863 if (offset > 0) { | |
864 FinalizeTypeArguments(sig_fun_owner, full_arguments, offset, | |
865 finalization, &bound_error); | |
866 } | |
867 CheckTypeArgumentBounds(sig_fun_owner, full_arguments, &bound_error); | |
868 } else { | 923 } else { |
869 if (offset > 0) { | 924 owner_class = type_class.raw(); |
870 FinalizeTypeArguments(type_class, full_arguments, offset, | 925 } |
871 finalization, &bound_error); | 926 if (offset > 0) { |
872 } | 927 FinalizeTypeArguments(owner_class, full_arguments, offset, |
873 CheckTypeArgumentBounds(type_class, full_arguments, &bound_error); | 928 &bound_error, pending_types); |
874 } | 929 } |
875 if (full_arguments.IsRaw(0, num_type_arguments)) { | 930 if (full_arguments.IsRaw(0, num_type_arguments)) { |
876 // The parameterized_type is raw. Set its argument vector to null, which | 931 // The parameterized_type is raw. Set its argument vector to null, which |
877 // is more efficient in type tests. | 932 // is more efficient in type tests. |
878 full_arguments = TypeArguments::null(); | 933 full_arguments = TypeArguments::null(); |
879 } else if (finalization >= kCanonicalize) { | 934 } else { |
880 // FinalizeTypeArguments can modify 'full_arguments', | 935 // Postpone bound checking until after all types in the graph of |
881 // canonicalize afterwards. | 936 // mutually recursive types are finalized. |
882 full_arguments ^= full_arguments.Canonicalize(); | 937 pending_types->Add(parameterized_type); |
883 ASSERT(full_arguments.Length() == num_type_arguments); | |
884 } | 938 } |
885 parameterized_type.set_arguments(full_arguments); | 939 parameterized_type.set_arguments(full_arguments); |
886 } else { | 940 } else { |
887 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 941 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
888 } | 942 } |
889 } | 943 } |
890 | 944 |
891 // Self referencing types may get finalized indirectly. | 945 // Self referencing types may get finalized indirectly. |
892 if (!parameterized_type.IsFinalized()) { | 946 if (!parameterized_type.IsFinalized()) { |
| 947 ASSERT(full_arguments.IsNull() || |
| 948 !full_arguments.IsRaw(0, num_type_arguments)); |
893 // Mark the type as finalized. | 949 // Mark the type as finalized. |
894 parameterized_type.SetIsFinalized(); | 950 parameterized_type.SetIsFinalized(); |
895 } | 951 } |
896 | 952 |
| 953 // If we are done finalizing a graph of mutually recursive types, check their |
| 954 // bounds. |
| 955 if (is_root_type) { |
| 956 Type& type = Type::Handle(); |
| 957 for (intptr_t i = 0; i < types.Length(); i++) { |
| 958 type ^= types.At(i); |
| 959 CheckTypeBounds(cls, type); |
| 960 } |
| 961 } |
| 962 |
897 // If the type class is a signature class, we are currently finalizing a | 963 // If the type class is a signature class, we are currently finalizing a |
898 // signature type, i.e. finalizing the result type and parameter types of the | 964 // signature type, i.e. finalizing the result type and parameter types of the |
899 // signature function of this signature type. | 965 // signature function of this signature type. |
900 // We do this after marking this type as finalized in order to allow a | 966 // We do this after marking this type as finalized in order to allow a |
901 // function type to refer to itself via its parameter types and result type. | 967 // function type to refer to itself via its parameter types and result type. |
902 if (type_class.IsSignatureClass()) { | 968 if (type_class.IsSignatureClass()) { |
903 // The class may be created while parsing a function body, after all | 969 // The class may be created while parsing a function body, after all |
904 // pending classes have already been finalized. | 970 // pending classes have already been finalized. |
905 FinalizeTypesInClass(type_class); | 971 FinalizeTypesInClass(type_class); |
906 } | 972 } |
907 | 973 |
908 // If a bound error occurred, mark the type as malbounded. | |
909 // The bound error will be ignored in production mode. | |
910 if (!bound_error.IsNull()) { | |
911 // No compile-time error during finalization. | |
912 const String& parameterized_type_name = String::Handle( | |
913 parameterized_type.UserVisibleName()); | |
914 FinalizeMalboundedType(bound_error, | |
915 Script::Handle(cls.script()), | |
916 parameterized_type, | |
917 "type '%s' has an out of bound type argument", | |
918 parameterized_type_name.ToCString()); | |
919 | |
920 if (FLAG_trace_type_finalization) { | |
921 OS::Print("Done finalizing malbounded type '%s' with bound error: %s\n", | |
922 String::Handle(parameterized_type.Name()).ToCString(), | |
923 bound_error.ToCString()); | |
924 } | |
925 | |
926 return parameterized_type.raw();; | |
927 } | |
928 | |
929 if (FLAG_trace_type_finalization) { | 974 if (FLAG_trace_type_finalization) { |
930 OS::Print("Done finalizing type '%s' with %" Pd " type args\n", | 975 OS::Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
931 String::Handle(parameterized_type.Name()).ToCString(), | 976 String::Handle(parameterized_type.Name()).ToCString(), |
932 parameterized_type.arguments() == AbstractTypeArguments::null() ? | 977 parameterized_type.arguments() == AbstractTypeArguments::null() ? |
933 0 : num_type_arguments); | 978 0 : num_type_arguments, |
| 979 parameterized_type.ToCString()); |
934 } | 980 } |
935 | 981 |
936 if (finalization >= kCanonicalize) { | 982 if (finalization >= kCanonicalize) { |
937 return parameterized_type.Canonicalize(); | 983 return parameterized_type.Canonicalize(); |
938 } else { | 984 } else { |
939 return parameterized_type.raw(); | 985 return parameterized_type.raw(); |
940 } | 986 } |
941 } | 987 } |
942 | 988 |
943 | 989 |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1682 if (FLAG_trace_class_finalization) { | 1728 if (FLAG_trace_class_finalization) { |
1683 OS::Print("Inserting class %s to mixin application alias %s " | 1729 OS::Print("Inserting class %s to mixin application alias %s " |
1684 "with super type '%s'\n", | 1730 "with super type '%s'\n", |
1685 inserted_class.ToCString(), | 1731 inserted_class.ToCString(), |
1686 mixin_app_class.ToCString(), | 1732 mixin_app_class.ToCString(), |
1687 String::Handle(super_type.Name()).ToCString()); | 1733 String::Handle(super_type.Name()).ToCString()); |
1688 } | 1734 } |
1689 } | 1735 } |
1690 | 1736 |
1691 | 1737 |
1692 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) { | 1738 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, |
| 1739 GrowableObjectArray* pending_types) { |
1693 if (mixin_app_class.is_mixin_type_applied()) { | 1740 if (mixin_app_class.is_mixin_type_applied()) { |
1694 return; | 1741 return; |
1695 } | 1742 } |
1696 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1743 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
1697 ASSERT(!mixin_type.IsNull()); | 1744 ASSERT(!mixin_type.IsNull()); |
1698 ASSERT(mixin_type.HasResolvedTypeClass()); | 1745 ASSERT(mixin_type.HasResolvedTypeClass()); |
1699 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1746 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
1700 | 1747 |
1701 if (FLAG_trace_class_finalization) { | 1748 if (FLAG_trace_class_finalization) { |
1702 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n", | 1749 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n", |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1753 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); | 1800 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); |
1754 } | 1801 } |
1755 // Mark the application class as having been applied its mixin type in order | 1802 // Mark the application class as having been applied its mixin type in order |
1756 // to avoid cycles while finalizing its mixin type. | 1803 // to avoid cycles while finalizing its mixin type. |
1757 mixin_app_class.set_is_mixin_type_applied(); | 1804 mixin_app_class.set_is_mixin_type_applied(); |
1758 // Finalize the mixin type, which may have been changed in case | 1805 // Finalize the mixin type, which may have been changed in case |
1759 // mixin_app_class is an alias. | 1806 // mixin_app_class is an alias. |
1760 mixin_type = mixin_app_class.mixin(); | 1807 mixin_type = mixin_app_class.mixin(); |
1761 ASSERT(!mixin_type.IsBeingFinalized()); | 1808 ASSERT(!mixin_type.IsBeingFinalized()); |
1762 mixin_type ^= | 1809 mixin_type ^= |
1763 FinalizeType(mixin_app_class, mixin_type, kCanonicalizeWellFormed); | 1810 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types); |
1764 // TODO(14453): Check for a malbounded mixin_type. | 1811 // TODO(14453): Check for a malbounded mixin_type. |
1765 mixin_app_class.set_mixin(mixin_type); | 1812 mixin_app_class.set_mixin(mixin_type); |
1766 } | 1813 } |
1767 | 1814 |
1768 | 1815 |
1769 void ClassFinalizer::CreateForwardingConstructors( | 1816 void ClassFinalizer::CreateForwardingConstructors( |
1770 const Class& mixin_app, | 1817 const Class& mixin_app, |
1771 const GrowableObjectArray& cloned_funcs) { | 1818 const GrowableObjectArray& cloned_funcs) { |
1772 const String& mixin_name = String::Handle(mixin_app.Name()); | 1819 const String& mixin_name = String::Handle(mixin_app.Name()); |
1773 const Class& super_class = Class::Handle(mixin_app.SuperClass()); | 1820 const Class& super_class = Class::Handle(mixin_app.SuperClass()); |
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2758 expected_name ^= String::New("_offset"); | 2805 expected_name ^= String::New("_offset"); |
2759 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2806 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
2760 field ^= fields_array.At(2); | 2807 field ^= fields_array.At(2); |
2761 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2808 ASSERT(field.Offset() == TypedDataView::length_offset()); |
2762 name ^= field.name(); | 2809 name ^= field.name(); |
2763 ASSERT(name.Equals("length")); | 2810 ASSERT(name.Equals("length")); |
2764 #endif | 2811 #endif |
2765 } | 2812 } |
2766 | 2813 |
2767 } // namespace dart | 2814 } // namespace dart |
OLD | NEW |