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

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

Powered by Google App Engine
This is Rietveld 408576698