Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(671)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 103913005: Introduce class TypeRef in the VM to fully support recursive types. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698