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

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

Issue 211963003: Detect and reject illegal recursive types (non-contractive types). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 months 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 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 for (intptr_t i = 0; i < num_types; i++) { 505 for (intptr_t i = 0; i < num_types; i++) {
506 type_parameter ^= type_parameters.TypeAt(i); 506 type_parameter ^= type_parameters.TypeAt(i);
507 type_parameter ^= FinalizeType( 507 type_parameter ^= FinalizeType(
508 cls, type_parameter, kFinalize, pending_types); 508 cls, type_parameter, kFinalize, pending_types);
509 type_parameters.SetTypeAt(i, type_parameter); 509 type_parameters.SetTypeAt(i, type_parameter);
510 } 510 }
511 } 511 }
512 } 512 }
513 513
514 514
515 // This function reports a compilation error if the recursive 'type' being
516 // finalized is a non-contractive type. This can be detected by looking at the
srdjan 2014/03/26 18:02:12 non-contractive types is not a commonly known term
regis 2014/03/26 18:41:29 I expanded the comment and added a reference to th
517 // queue of types pending finalization that may be mutually recursive with the
518 // checked type.
519 void ClassFinalizer::CheckRecursiveType(const Class& cls,
520 const Type& type,
521 GrowableObjectArray* pending_types) {
522 Isolate* isolate = Isolate::Current();
523 if (FLAG_trace_type_finalization) {
524 OS::Print("Checking recursive type '%s' for class '%s'\n",
525 String::Handle(type.Name()).ToCString(),
526 cls.ToCString());
527 }
528 const Class& type_cls = Class::Handle(isolate, type.type_class());
529 const TypeArguments& arguments =
530 TypeArguments::Handle(isolate, type.arguments());
531 // A type can only be recursive via its type arguments.
532 ASSERT(!arguments.IsNull());
533 const intptr_t num_type_args = arguments.Length();
534 ASSERT(num_type_args > 0);
535 ASSERT(num_type_args == type_cls.NumTypeArguments());
536 const intptr_t num_type_params = type_cls.NumTypeParameters();
537 const intptr_t first_type_param = num_type_args - num_type_params;
538 // If the type parameters are instantiated (or null), no divergence can occur.
539 if ((num_type_params == 0) ||
540 arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) {
541 return;
542 }
543 // The type parameters are not instantiated. Verify that there is no other
544 // type pending finalization with the same type class, but different
545 // uninstantiated type parameters.
546 Type& pending_type = Type::Handle(isolate);
547 TypeArguments& pending_arguments = TypeArguments::Handle(isolate);
548 const intptr_t num_pending_types = pending_types->Length();
549 for (intptr_t i = num_pending_types - 1; i >= 0; i--) {
550 pending_type ^= pending_types->At(i);
551 if (FLAG_trace_type_finalization) {
552 OS::Print(" Comparing with pending type '%s'\n",
553 String::Handle(pending_type.Name()).ToCString());
554 }
555 if ((pending_type.raw() != type.raw()) &&
556 (pending_type.type_class() == type_cls.raw())) {
557 pending_arguments = pending_type.arguments();
558 if (!pending_arguments.IsSubvectorEquivalent(arguments,
559 first_type_param,
560 num_type_params) &&
561 !pending_arguments.IsSubvectorInstantiated(first_type_param,
562 num_type_params)) {
563 // Reject the non-contractive recursive type.
564 const Script& script = Script::Handle(isolate, cls.script());
565 const String& type_name = String::Handle(isolate, type.Name());
566 ReportError(Error::Handle(isolate), // No previous error.
567 script, type.token_pos(),
568 "illegal recursive type '%s'",
569 type_name.ToCString());
570 }
571 }
572 }
573 }
574
575
515 // Finalize the type argument vector 'arguments' of the type defined by the 576 // Finalize the type argument vector 'arguments' of the type defined by the
516 // class 'cls' parameterized with the type arguments 'cls_args'. 577 // class 'cls' parameterized with the type arguments 'cls_args'.
517 // The vector 'cls_args' is already initialized as a subvector at the correct 578 // The vector 'cls_args' is already initialized as a subvector at the correct
518 // position in the passed in 'arguments' vector. 579 // position in the passed in 'arguments' vector.
519 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at 580 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at
520 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' 581 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments'
521 // vector. 582 // vector.
522 // The type argument vector of cls may overlap the type argument vector of its 583 // The type argument vector of cls may overlap the type argument vector of its
523 // super class. In case of an overlap, the overlapped type arguments of the 584 // super class. In case of an overlap, the overlapped type arguments of the
524 // super class are already initialized. The still uninitialized ones have an 585 // super class are already initialized. The still uninitialized ones have an
(...skipping 10 matching lines...) Expand all
535 // Declared: class C<K, V> extends B<K> { ... } 596 // Declared: class C<K, V> extends B<K> { ... }
536 // class B<T> extends A<int> { ... } 597 // class B<T> extends A<int> { ... }
537 // Input: C<String, double> expressed as 598 // Input: C<String, double> expressed as
538 // cls = C, arguments = [dynamic, String, double], 599 // cls = C, arguments = [dynamic, String, double],
539 // num_uninitialized_arguments = 1, 600 // num_uninitialized_arguments = 1,
540 // i.e. cls_args = [String, double], offset = 1, length = 2. 601 // i.e. cls_args = [String, double], offset = 1, length = 2.
541 // Output: arguments = [int, String, double] 602 // Output: arguments = [int, String, double]
542 // 603 //
543 // It is too early to canonicalize the type arguments of the vector, because 604 // It is too early to canonicalize the type arguments of the vector, because
544 // several type argument vectors may be mutually recursive and finalized at the 605 // several type argument vectors may be mutually recursive and finalized at the
545 // same time. Canonicalization happens when pending types are processed. 606 // same time. Canonicalization happens when pending types are processed.
srdjan 2014/03/26 18:02:12 Maybe document 'trail' in comment.
regis 2014/03/26 18:41:29 Added comment about trail.
546 void ClassFinalizer::FinalizeTypeArguments( 607 void ClassFinalizer::FinalizeTypeArguments(
547 const Class& cls, 608 const Class& cls,
548 const TypeArguments& arguments, 609 const TypeArguments& arguments,
549 intptr_t num_uninitialized_arguments, 610 intptr_t num_uninitialized_arguments,
550 Error* bound_error, 611 Error* bound_error,
551 GrowableObjectArray* pending_types) { 612 GrowableObjectArray* pending_types,
613 GrowableObjectArray* trail) {
552 ASSERT(arguments.Length() >= cls.NumTypeArguments()); 614 ASSERT(arguments.Length() >= cls.NumTypeArguments());
553 if (!cls.is_type_finalized()) { 615 if (!cls.is_type_finalized()) {
554 FinalizeTypeParameters(cls, pending_types); 616 FinalizeTypeParameters(cls, pending_types);
555 ResolveUpperBounds(cls); 617 ResolveUpperBounds(cls);
556 } 618 }
557 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 619 AbstractType& super_type = AbstractType::Handle(cls.super_type());
558 if (!super_type.IsNull()) { 620 if (!super_type.IsNull()) {
559 const Class& super_class = Class::Handle(super_type.type_class()); 621 const Class& super_class = Class::Handle(super_type.type_class());
560 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 622 const intptr_t num_super_type_params = super_class.NumTypeParameters();
561 const intptr_t num_super_type_args = super_class.NumTypeArguments(); 623 const intptr_t num_super_type_args = super_class.NumTypeArguments();
562 ASSERT(num_super_type_args == 624 ASSERT(num_super_type_args ==
563 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); 625 (cls.NumTypeArguments() - cls.NumOwnTypeArguments()));
564 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { 626 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) {
565 super_type ^= FinalizeType( 627 super_type ^= FinalizeType(
566 cls, super_type, kFinalize, pending_types); 628 cls, super_type, kFinalize, pending_types);
567 cls.set_super_type(super_type); 629 cls.set_super_type(super_type);
568 } 630 }
569 TypeArguments& super_type_args = TypeArguments::Handle( 631 TypeArguments& super_type_args = TypeArguments::Handle(
570 super_type.arguments()); 632 super_type.arguments());
571 // Offset of super type's type parameters in cls' type argument vector. 633 // Offset of super type's type parameters in cls' type argument vector.
572 const intptr_t super_offset = num_super_type_args - num_super_type_params; 634 const intptr_t super_offset = num_super_type_args - num_super_type_params;
573 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); 635 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType());
574 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { 636 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) {
575 if (!super_type_args.IsNull()) { 637 if (!super_type_args.IsNull()) {
576 super_type_arg = super_type_args.TypeAt(i); 638 super_type_arg = super_type_args.TypeAt(i);
577 if (!super_type_arg.IsFinalized()) { 639 if (!super_type_arg.IsTypeRef()) {
578 super_type_arg ^= FinalizeType( 640 if (super_type_arg.IsBeingFinalized()) {
579 cls, super_type_arg, kFinalize, pending_types); 641 ASSERT(super_type_arg.IsType());
580 super_type_args.SetTypeAt(i, super_type_arg); 642 CheckRecursiveType(cls, Type::Cast(super_type_arg), pending_types);
643 if (FLAG_trace_type_finalization) {
644 OS::Print("Creating TypeRef '%s' for class '%s'\n",
645 String::Handle(super_type_arg.Name()).ToCString(),
646 cls.ToCString());
647 }
648 super_type_arg = TypeRef::New(super_type_arg);
649 super_type_args.SetTypeAt(i, super_type_arg);
650 } else {
651 if (!super_type_arg.IsFinalized()) {
652 super_type_arg ^= FinalizeType(
653 cls, super_type_arg, kFinalize, pending_types);
654 super_type_args.SetTypeAt(i, super_type_arg);
655 // Note that super_type_arg may still not be finalized here, in
656 // which case it is a TypeRef to a legal recursive type.
657 // Therefore, it does not need to be instantiated below.
658 // See tests/language/regress_16640_test.dart for an example.
659 }
660 }
581 } 661 }
582 if (!super_type_arg.IsBeingFinalized() && 662 if (!super_type_arg.IsBeingFinalized() &&
583 !super_type_arg.IsInstantiated()) { 663 !super_type_arg.IsInstantiated()) {
584 Error& error = Error::Handle(); 664 Error& error = Error::Handle();
585 super_type_arg = super_type_arg.InstantiateFrom(arguments, &error); 665 super_type_arg =
666 super_type_arg.InstantiateFrom(arguments, &error, trail);
586 if (!error.IsNull()) { 667 if (!error.IsNull()) {
587 // InstantiateFrom does not report an error if the type is still 668 // InstantiateFrom does not report an error if the type is still
588 // uninstantiated. Instead, it will return a new BoundedType so that 669 // uninstantiated. Instead, it will return a new BoundedType so
589 // the check is postponed to run time. 670 // that the check is postponed to run time.
590 ASSERT(super_type_arg.IsInstantiated()); 671 ASSERT(super_type_arg.IsInstantiated());
591 // Keep only the first bound error. 672 // Keep only the first bound error.
592 if (bound_error->IsNull()) { 673 if (bound_error->IsNull()) {
593 *bound_error = error.raw(); 674 *bound_error = error.raw();
594 } 675 }
595 } 676 }
596 } 677 }
597 } 678 }
598 arguments.SetTypeAt(i, super_type_arg); 679 arguments.SetTypeAt(i, super_type_arg);
599 } 680 }
600 FinalizeTypeArguments(super_class, arguments, super_offset, 681 FinalizeTypeArguments(super_class, arguments, super_offset,
601 bound_error, pending_types); 682 bound_error, pending_types, trail);
602 } 683 }
603 } 684 }
604 685
605 686
606 // Check the type argument vector 'arguments' against the corresponding bounds 687 // Check the type argument vector 'arguments' against the corresponding bounds
607 // of the type parameters of class 'cls' and, recursively, of its superclasses. 688 // of the type parameters of class 'cls' and, recursively, of its superclasses.
608 // Replace a type argument that cannot be checked at compile time by a 689 // Replace a type argument that cannot be checked at compile time by a
609 // BoundedType, thereby postponing the bound check to run time. 690 // BoundedType, thereby postponing the bound check to run time.
610 // Return a bound error if a type argument is not within bound at compile time. 691 // Return a bound error if a type argument is not within bound at compile time.
611 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, 692 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 return type.raw(); 837 return type.raw();
757 } 838 }
758 ASSERT(finalization >= kFinalize); 839 ASSERT(finalization >= kFinalize);
759 840
760 if (type.IsTypeRef()) { 841 if (type.IsTypeRef()) {
761 // The referenced type will be finalized later by the code that set the 842 // The referenced type will be finalized later by the code that set the
762 // is_being_finalized mark bit. 843 // is_being_finalized mark bit.
763 return type.raw(); 844 return type.raw();
764 } 845 }
765 846
766 if (type.IsBeingFinalized()) { 847 // Recursive types must be processed in FinalizeTypeArguments() and cannot be
767 if (FLAG_trace_type_finalization) { 848 // encountered here.
768 OS::Print("Creating TypeRef '%s' for class '%s'\n", 849 ASSERT(!type.IsBeingFinalized());
769 String::Handle(type.Name()).ToCString(), 850
770 cls.ToCString()); 851 // A malformed type gets mapped to a finalized type.
771 } 852 ResolveType(cls, type);
772 return TypeRef::New(type); 853 if (type.IsMalformed()) {
854 ASSERT(type.IsFinalized());
855 return type.raw();
773 } 856 }
774 857
775 ResolveType(cls, type); 858 Isolate* isolate = Isolate::Current();
776 if (FLAG_trace_type_finalization) { 859 if (FLAG_trace_type_finalization) {
777 OS::Print("Finalizing type '%s' for class '%s'\n", 860 OS::Print("Finalizing type '%s' for class '%s'\n",
778 String::Handle(type.Name()).ToCString(), 861 String::Handle(isolate, type.Name()).ToCString(),
779 cls.ToCString()); 862 cls.ToCString());
780 } 863 }
781 864
782 if (type.IsTypeParameter()) { 865 if (type.IsTypeParameter()) {
783 const TypeParameter& type_parameter = TypeParameter::Cast(type); 866 const TypeParameter& type_parameter = TypeParameter::Cast(type);
784 const Class& parameterized_class = 867 const Class& parameterized_class =
785 Class::Handle(type_parameter.parameterized_class()); 868 Class::Handle(isolate, type_parameter.parameterized_class());
786 ASSERT(!parameterized_class.IsNull()); 869 ASSERT(!parameterized_class.IsNull());
787 // The index must reflect the position of this type parameter in the type 870 // The index must reflect the position of this type parameter in the type
788 // arguments vector of its parameterized class. The offset to add is the 871 // arguments vector of its parameterized class. The offset to add is the
789 // number of type arguments in the super type, which is equal to the 872 // number of type arguments in the super type, which is equal to the
790 // difference in number of type arguments and type parameters of the 873 // difference in number of type arguments and type parameters of the
791 // parameterized class. 874 // parameterized class.
792 const intptr_t offset = parameterized_class.NumTypeArguments() - 875 const intptr_t offset = parameterized_class.NumTypeArguments() -
793 parameterized_class.NumTypeParameters(); 876 parameterized_class.NumTypeParameters();
794 // Calling NumTypeParameters() may finalize this type parameter if it 877 // Calling NumTypeParameters() may finalize this type parameter if it
795 // belongs to a mixin application class. 878 // belongs to a mixin application class.
796 if (!type_parameter.IsFinalized()) { 879 if (!type_parameter.IsFinalized()) {
797 type_parameter.set_index(type_parameter.index() + offset); 880 type_parameter.set_index(type_parameter.index() + offset);
798 type_parameter.set_is_finalized(); 881 type_parameter.set_is_finalized();
799 } else { 882 } else {
800 ASSERT(cls.IsMixinApplication()); 883 ASSERT(cls.IsMixinApplication());
801 } 884 }
802 885
803 if (FLAG_trace_type_finalization) { 886 if (FLAG_trace_type_finalization) {
804 OS::Print("Done finalizing type parameter '%s' with index %" Pd "\n", 887 OS::Print("Done finalizing type parameter '%s' with index %" Pd "\n",
805 String::Handle(type_parameter.name()).ToCString(), 888 String::Handle(isolate, type_parameter.name()).ToCString(),
806 type_parameter.index()); 889 type_parameter.index());
807 } 890 }
808 891
809 // We do not canonicalize type parameters. 892 // We do not canonicalize type parameters.
810 return type_parameter.raw(); 893 return type_parameter.raw();
811 } 894 }
812 895
813 // At this point, we can only have a parameterized_type. 896 // At this point, we can only have a parameterized_type.
814 const Type& parameterized_type = Type::Cast(type); 897 const Type& parameterized_type = Type::Cast(type);
815 898
816 Isolate* isolate = Isolate::Current();
817 // This type is the root type of the type graph if no pending types queue is 899 // This type is the root type of the type graph if no pending types queue is
818 // allocated yet. 900 // allocated yet.
819 const bool is_root_type = (pending_types == NULL); 901 const bool is_root_type = (pending_types == NULL);
820 GrowableObjectArray& types = GrowableObjectArray::Handle(isolate); 902 GrowableObjectArray& types = GrowableObjectArray::Handle(isolate);
821 if (is_root_type) { 903 if (is_root_type) {
822 types = GrowableObjectArray::New(); 904 types = GrowableObjectArray::New();
823 pending_types = &types; 905 pending_types = &types;
824 } 906 }
825 907
826 // The type class does not need to be finalized in order to finalize the type, 908 // The type class does not need to be finalized in order to finalize the type,
(...skipping 28 matching lines...) Expand all
855 script, parameterized_type.token_pos(), 937 script, parameterized_type.token_pos(),
856 "wrong number of type arguments for class '%s'", 938 "wrong number of type arguments for class '%s'",
857 type_class_name.ToCString()); 939 type_class_name.ToCString());
858 } 940 }
859 // Make the type raw and continue without reporting any error. 941 // Make the type raw and continue without reporting any error.
860 // A static warning should have been reported. 942 // A static warning should have been reported.
861 arguments = TypeArguments::null(); 943 arguments = TypeArguments::null();
862 parameterized_type.set_arguments(arguments); 944 parameterized_type.set_arguments(arguments);
863 } 945 }
864 946
947 // Mark the type as being finalized in order to detect self reference and
948 // postpone bound checking until after all types in the graph of
949 // mutually recursive types are finalized.
950 parameterized_type.set_is_being_finalized();
951 pending_types->Add(parameterized_type);
952
865 // The full type argument vector consists of the type arguments of the 953 // The full type argument vector consists of the type arguments of the
866 // super types of type_class, which are initialized from the parsed 954 // super types of type_class, which are initialized from the parsed
867 // type arguments, followed by the parsed type arguments. 955 // type arguments, followed by the parsed type arguments.
868 TypeArguments& full_arguments = TypeArguments::Handle(isolate); 956 TypeArguments& full_arguments = TypeArguments::Handle(isolate);
869 Error& bound_error = Error::Handle(isolate); 957 Error& bound_error = Error::Handle(isolate);
870 if (num_type_arguments > 0) { 958 if (num_type_arguments > 0) {
871 // If no type arguments were parsed and if the super types do not prepend 959 // If no type arguments were parsed and if the super types do not prepend
872 // type arguments to the vector, we can leave the vector as null. 960 // type arguments to the vector, we can leave the vector as null.
873 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { 961 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) {
874 full_arguments = TypeArguments::New(num_type_arguments); 962 full_arguments = TypeArguments::New(num_type_arguments);
(...skipping 12 matching lines...) Expand all
887 } 975 }
888 full_arguments.SetTypeAt(offset + i, type_arg); 976 full_arguments.SetTypeAt(offset + i, type_arg);
889 } 977 }
890 // Replace the compile-time argument vector (of length zero or 978 // Replace the compile-time argument vector (of length zero or
891 // num_type_parameters) of this type being finalized with the still 979 // num_type_parameters) of this type being finalized with the still
892 // unfinalized run-time argument vector (of length num_type_arguments). 980 // unfinalized run-time argument vector (of length num_type_arguments).
893 // This type being finalized may be recursively reached via bounds 981 // This type being finalized may be recursively reached via bounds
894 // checking, in which case type arguments of super classes will be seen 982 // checking, in which case type arguments of super classes will be seen
895 // as dynamic. 983 // as dynamic.
896 parameterized_type.set_arguments(full_arguments); 984 parameterized_type.set_arguments(full_arguments);
897 // Mark type as being finalized in order to detect self reference.
898 parameterized_type.set_is_being_finalized();
899 // Finalize the current type arguments of the type, which are still the 985 // Finalize the current type arguments of the type, which are still the
900 // parsed type arguments. 986 // parsed type arguments.
901 if (!arguments.IsNull()) { 987 if (!arguments.IsNull()) {
902 for (intptr_t i = 0; i < num_type_parameters; i++) { 988 for (intptr_t i = 0; i < num_type_parameters; i++) {
903 type_arg = full_arguments.TypeAt(offset + i); 989 type_arg = full_arguments.TypeAt(offset + i);
904 ASSERT(!type_arg.IsBeingFinalized()); 990 ASSERT(!type_arg.IsBeingFinalized());
905 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); 991 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types);
906 if (type_arg.IsMalformed()) { 992 if (type_arg.IsMalformed()) {
907 // Malformed type arguments are mapped to dynamic. 993 // Malformed type arguments are mapped to dynamic.
908 type_arg = Type::DynamicType(); 994 type_arg = Type::DynamicType();
(...skipping 12 matching lines...) Expand all
921 Class& owner_class = Class::Handle(isolate); 1007 Class& owner_class = Class::Handle(isolate);
922 if (type_class.IsSignatureClass()) { 1008 if (type_class.IsSignatureClass()) {
923 const Function& signature_fun = 1009 const Function& signature_fun =
924 Function::Handle(isolate, type_class.signature_function()); 1010 Function::Handle(isolate, type_class.signature_function());
925 ASSERT(!signature_fun.is_static()); 1011 ASSERT(!signature_fun.is_static());
926 owner_class = signature_fun.Owner(); 1012 owner_class = signature_fun.Owner();
927 } else { 1013 } else {
928 owner_class = type_class.raw(); 1014 owner_class = type_class.raw();
929 } 1015 }
930 if (offset > 0) { 1016 if (offset > 0) {
1017 GrowableObjectArray& trail =
1018 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
931 FinalizeTypeArguments(owner_class, full_arguments, offset, 1019 FinalizeTypeArguments(owner_class, full_arguments, offset,
932 &bound_error, pending_types); 1020 &bound_error, pending_types, &trail);
933 } 1021 }
934 if (full_arguments.IsRaw(0, num_type_arguments)) { 1022 if (full_arguments.IsRaw(0, num_type_arguments)) {
935 // The parameterized_type is raw. Set its argument vector to null, which 1023 // The parameterized_type is raw. Set its argument vector to null, which
936 // is more efficient in type tests. 1024 // is more efficient in type tests.
937 full_arguments = TypeArguments::null(); 1025 full_arguments = TypeArguments::null();
938 } else {
939 // Postpone bound checking until after all types in the graph of
940 // mutually recursive types are finalized.
941 pending_types->Add(parameterized_type);
942 } 1026 }
943 parameterized_type.set_arguments(full_arguments); 1027 parameterized_type.set_arguments(full_arguments);
944 } else { 1028 } else {
945 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. 1029 ASSERT(full_arguments.IsNull()); // Use null vector for raw type.
946 } 1030 }
947 } 1031 }
948 1032
949 // Self referencing types may get finalized indirectly. 1033 // Self referencing types may get finalized indirectly.
950 if (!parameterized_type.IsFinalized()) { 1034 if (!parameterized_type.IsFinalized()) {
951 ASSERT(full_arguments.IsNull() || 1035 ASSERT(full_arguments.IsNull() ||
952 !full_arguments.IsRaw(0, num_type_arguments)); 1036 !full_arguments.IsRaw(0, num_type_arguments));
953 // Mark the type as finalized. 1037 // Mark the type as finalized.
954 parameterized_type.SetIsFinalized(); 1038 parameterized_type.SetIsFinalized();
1039 // Do not yet remove the type from the pending_types array.
955 } 1040 }
956 1041
957 // If we are done finalizing a graph of mutually recursive types, check their 1042 // If we are done finalizing a graph of mutually recursive types, check their
958 // bounds. 1043 // bounds.
959 if (is_root_type) { 1044 if (is_root_type) {
960 Type& type = Type::Handle(isolate); 1045 Type& type = Type::Handle(isolate);
961 for (intptr_t i = 0; i < types.Length(); i++) { 1046 for (intptr_t i = 0; i < types.Length(); i++) {
962 type ^= types.At(i); 1047 type ^= types.At(i);
963 CheckTypeBounds(cls, type); 1048 CheckTypeBounds(cls, type);
964 } 1049 }
(...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 mixin_app_class.ToCString()); 2569 mixin_app_class.ToCString());
2485 } 2570 }
2486 } 2571 }
2487 // This mixin application class becomes the type class of the super type of 2572 // This mixin application class becomes the type class of the super type of
2488 // the next mixin application class. It is however too early to provide the 2573 // the next mixin application class. It is however too early to provide the
2489 // correct super type arguments. We use the raw type for now. 2574 // correct super type arguments. We use the raw type for now.
2490 mixin_super_type = Type::New(mixin_app_class, 2575 mixin_super_type = Type::New(mixin_app_class,
2491 Object::null_type_arguments(), 2576 Object::null_type_arguments(),
2492 mixin_type.token_pos()); 2577 mixin_type.token_pos());
2493 } 2578 }
2494 AbstractType& type_arg = AbstractType::Handle(); 2579 TypeArguments& mixin_app_args = TypeArguments::Handle();
2495 const TypeArguments& mixin_app_args = 2580 if (type_args.Length() > 0) {
2496 TypeArguments::Handle(TypeArguments::New(type_args.Length())); 2581 mixin_app_args = TypeArguments::New(type_args.Length());
2497 for (intptr_t i = 0; i < type_args.Length(); i++) { 2582 AbstractType& type_arg = AbstractType::Handle();
2498 type_arg ^= type_args.At(i); 2583 for (intptr_t i = 0; i < type_args.Length(); i++) {
2499 mixin_app_args.SetTypeAt(i, type_arg); 2584 type_arg ^= type_args.At(i);
2585 mixin_app_args.SetTypeAt(i, type_arg);
2586 }
2500 } 2587 }
2501 if (FLAG_trace_class_finalization) { 2588 if (FLAG_trace_class_finalization) {
2502 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", 2589 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n",
2503 mixin_app_args.ToCString()); 2590 mixin_app_args.ToCString());
2504 } 2591 }
2505 // The mixin application class at depth k is a subclass of mixin application 2592 // The mixin application class at depth k is a subclass of mixin application
2506 // class at depth k - 1. Build a new super type with the class at the highest 2593 // class at depth k - 1. Build a new super type with the class at the highest
2507 // depth (the last one processed by the loop above) as the type class and the 2594 // depth (the last one processed by the loop above) as the type class and the
2508 // collected type arguments from the super type and all mixin types. 2595 // collected type arguments from the super type and all mixin types.
2509 // This super type replaces the MixinAppType object in the class that extends 2596 // This super type replaces the MixinAppType object in the class that extends
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
2931 expected_name ^= String::New("_offset"); 3018 expected_name ^= String::New("_offset");
2932 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 3019 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2933 field ^= fields_array.At(2); 3020 field ^= fields_array.At(2);
2934 ASSERT(field.Offset() == TypedDataView::length_offset()); 3021 ASSERT(field.Offset() == TypedDataView::length_offset());
2935 name ^= field.name(); 3022 name ^= field.name();
2936 ASSERT(name.Equals("length")); 3023 ASSERT(name.Equals("length"));
2937 #endif 3024 #endif
2938 } 3025 }
2939 3026
2940 } // namespace dart 3027 } // 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