OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
6 | 6 |
7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 Function& target_target = Function::Handle(target.RedirectionTarget()); | 433 Function& target_target = Function::Handle(target.RedirectionTarget()); |
434 if (target_target.IsNull()) { | 434 if (target_target.IsNull()) { |
435 ASSERT(target_type.IsMalformed()); | 435 ASSERT(target_type.IsMalformed()); |
436 } else { | 436 } else { |
437 // If the target type refers to type parameters, substitute them with the | 437 // If the target type refers to type parameters, substitute them with the |
438 // type arguments of the redirection type. | 438 // type arguments of the redirection type. |
439 if (!target_type.IsInstantiated()) { | 439 if (!target_type.IsInstantiated()) { |
440 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); | 440 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
441 Error& bound_error = Error::Handle(); | 441 Error& bound_error = Error::Handle(); |
442 target_type ^= target_type.InstantiateFrom( | 442 target_type ^= target_type.InstantiateFrom( |
443 type_args, &bound_error, NULL, Heap::kOld); | 443 type_args, &bound_error, NULL, NULL, Heap::kOld); |
444 if (bound_error.IsNull()) { | 444 if (bound_error.IsNull()) { |
445 target_type ^= FinalizeType(cls, target_type, kCanonicalize); | 445 target_type ^= FinalizeType(cls, target_type, kCanonicalize); |
446 } else { | 446 } else { |
447 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); | 447 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); |
448 const Script& script = Script::Handle(target_class.script()); | 448 const Script& script = Script::Handle(target_class.script()); |
449 FinalizeMalformedType(bound_error, script, target_type, | 449 FinalizeMalformedType(bound_error, script, target_type, |
450 "cannot resolve redirecting factory"); | 450 "cannot resolve redirecting factory"); |
451 target_target = Function::null(); | 451 target_target = Function::null(); |
452 } | 452 } |
453 } | 453 } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 if ((num_type_params == 0) || | 617 if ((num_type_params == 0) || |
618 arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) { | 618 arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) { |
619 return; | 619 return; |
620 } | 620 } |
621 // The type parameters are not instantiated. Verify that there is no other | 621 // The type parameters are not instantiated. Verify that there is no other |
622 // type pending finalization with the same type class, but different | 622 // type pending finalization with the same type class, but different |
623 // uninstantiated type parameters. | 623 // uninstantiated type parameters. |
624 TypeArguments& pending_arguments = TypeArguments::Handle(zone); | 624 TypeArguments& pending_arguments = TypeArguments::Handle(zone); |
625 const intptr_t num_pending_types = pending_types->length(); | 625 const intptr_t num_pending_types = pending_types->length(); |
626 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { | 626 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { |
627 const Type& pending_type = Type::Cast(pending_types->At(i)); | 627 const AbstractType& pending_type = pending_types->At(i); |
628 if (FLAG_trace_type_finalization) { | 628 if (FLAG_trace_type_finalization) { |
629 THR_Print(" Comparing with pending type '%s': %s\n", | 629 THR_Print(" Comparing with pending type '%s': %s\n", |
630 String::Handle(pending_type.Name()).ToCString(), | 630 String::Handle(pending_type.Name()).ToCString(), |
631 pending_type.ToCString()); | 631 pending_type.ToCString()); |
632 } | 632 } |
633 if ((pending_type.raw() != type.raw()) && | 633 if ((pending_type.raw() != type.raw()) && |
| 634 pending_type.IsType() && |
634 (pending_type.type_class() == type_cls.raw())) { | 635 (pending_type.type_class() == type_cls.raw())) { |
635 pending_arguments = pending_type.arguments(); | 636 pending_arguments = pending_type.arguments(); |
636 if (!pending_arguments.IsSubvectorEquivalent(arguments, | 637 if (!pending_arguments.IsSubvectorEquivalent(arguments, |
637 first_type_param, | 638 first_type_param, |
638 num_type_params) && | 639 num_type_params) && |
639 !pending_arguments.IsSubvectorInstantiated(first_type_param, | 640 !pending_arguments.IsSubvectorInstantiated(first_type_param, |
640 num_type_params)) { | 641 num_type_params)) { |
641 // Reject the non-contractive recursive type. | 642 // Reject the non-contractive recursive type. |
642 const String& type_name = String::Handle(zone, type.Name()); | 643 const String& type_name = String::Handle(zone, type.Name()); |
643 ReportError(cls, type.token_pos(), | 644 ReportError(cls, type.token_pos(), |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 ASSERT(!type_arg.IsBeingFinalized()); | 735 ASSERT(!type_arg.IsBeingFinalized()); |
735 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); | 736 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); |
736 if (type_arg.IsMalformed()) { | 737 if (type_arg.IsMalformed()) { |
737 // Malformed type arguments are mapped to dynamic. | 738 // Malformed type arguments are mapped to dynamic. |
738 type_arg = Type::DynamicType(); | 739 type_arg = Type::DynamicType(); |
739 } | 740 } |
740 full_arguments.SetTypeAt(offset + i, type_arg); | 741 full_arguments.SetTypeAt(offset + i, type_arg); |
741 } | 742 } |
742 } | 743 } |
743 if (offset > 0) { | 744 if (offset > 0) { |
744 TrailPtr trail = new Trail(Z, 4); | 745 TrailPtr instantiation_trail = new Trail(Z, 4); |
745 Error& bound_error = Error::Handle(); | 746 Error& bound_error = Error::Handle(Z); |
746 FinalizeTypeArguments(type_class, full_arguments, offset, | 747 FinalizeTypeArguments(type_class, full_arguments, offset, |
747 &bound_error, pending_types, trail); | 748 &bound_error, pending_types, instantiation_trail); |
748 } | 749 } |
749 if (full_arguments.IsRaw(0, num_type_arguments)) { | 750 if (full_arguments.IsRaw(0, num_type_arguments)) { |
750 // The parameterized_type is raw. Set its argument vector to null, which | 751 // The parameterized_type is raw. Set its argument vector to null, which |
751 // is more efficient in type tests. | 752 // is more efficient in type tests. |
752 full_arguments = TypeArguments::null(); | 753 full_arguments = TypeArguments::null(); |
753 } | 754 } |
754 type.set_arguments(full_arguments); | 755 type.set_arguments(full_arguments); |
755 } else { | 756 } else { |
756 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 757 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
757 } | 758 } |
758 } | 759 } |
759 | 760 |
760 // Self referencing types may get finalized indirectly. | 761 // Self referencing types may get finalized indirectly. |
761 if (!type.IsFinalized()) { | 762 if (!type.IsFinalized()) { |
762 ASSERT(full_arguments.IsNull() || | 763 ASSERT(full_arguments.IsNull() || |
763 !full_arguments.IsRaw(0, num_type_arguments)); | 764 !full_arguments.IsRaw(0, num_type_arguments)); |
| 765 if (FLAG_trace_type_finalization) { |
| 766 THR_Print("Marking type '%s' as finalized for class '%s'\n", |
| 767 String::Handle(Z, type.Name()).ToCString(), |
| 768 String::Handle(Z, cls.Name()).ToCString()); |
| 769 } |
764 // Mark the type as finalized. | 770 // Mark the type as finalized. |
765 type.SetIsFinalized(); | 771 type.SetIsFinalized(); |
766 // Do not yet remove the type from the pending_types array. | 772 // Do not yet remove the type from the pending_types array. |
767 } | 773 } |
768 return full_arguments.IsNull() ? 0 : full_arguments.Length(); | 774 return full_arguments.IsNull() ? 0 : full_arguments.Length(); |
769 } | 775 } |
770 | 776 |
771 | 777 |
772 // Finalize the type argument vector 'arguments' of the type defined by the | 778 // Finalize the type argument vector 'arguments' of the type defined by the |
773 // class 'cls' parameterized with the type arguments 'cls_args'. | 779 // class 'cls' parameterized with the type arguments 'cls_args'. |
(...skipping 27 matching lines...) Expand all Loading... |
801 // several type argument vectors may be mutually recursive and finalized at the | 807 // several type argument vectors may be mutually recursive and finalized at the |
802 // same time. Canonicalization happens when pending types are processed. | 808 // same time. Canonicalization happens when pending types are processed. |
803 // The trail is required to correctly instantiate a recursive type argument | 809 // The trail is required to correctly instantiate a recursive type argument |
804 // of the super type. | 810 // of the super type. |
805 void ClassFinalizer::FinalizeTypeArguments( | 811 void ClassFinalizer::FinalizeTypeArguments( |
806 const Class& cls, | 812 const Class& cls, |
807 const TypeArguments& arguments, | 813 const TypeArguments& arguments, |
808 intptr_t num_uninitialized_arguments, | 814 intptr_t num_uninitialized_arguments, |
809 Error* bound_error, | 815 Error* bound_error, |
810 PendingTypes* pending_types, | 816 PendingTypes* pending_types, |
811 TrailPtr trail) { | 817 TrailPtr instantiation_trail) { |
812 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 818 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
813 if (!cls.is_type_finalized()) { | 819 if (!cls.is_type_finalized()) { |
814 FinalizeTypeParameters(cls, pending_types); | 820 FinalizeTypeParameters(cls, pending_types); |
815 ResolveUpperBounds(cls); | 821 ResolveUpperBounds(cls); |
816 } | 822 } |
817 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 823 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
818 if (!super_type.IsNull()) { | 824 if (!super_type.IsNull()) { |
819 const Class& super_class = Class::Handle(super_type.type_class()); | 825 const Class& super_class = Class::Handle(super_type.type_class()); |
820 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 826 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
821 const intptr_t num_super_type_args = super_class.NumTypeArguments(); | 827 const intptr_t num_super_type_args = super_class.NumTypeArguments(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 AbstractType& ref_type = AbstractType::Handle( | 867 AbstractType& ref_type = AbstractType::Handle( |
862 TypeRef::Cast(super_type_arg).type()); | 868 TypeRef::Cast(super_type_arg).type()); |
863 THR_Print("Instantiating TypeRef '%s': '%s'\n" | 869 THR_Print("Instantiating TypeRef '%s': '%s'\n" |
864 " instantiator: '%s'\n", | 870 " instantiator: '%s'\n", |
865 String::Handle(super_type_arg.Name()).ToCString(), | 871 String::Handle(super_type_arg.Name()).ToCString(), |
866 ref_type.ToCString(), | 872 ref_type.ToCString(), |
867 arguments.ToCString()); | 873 arguments.ToCString()); |
868 } | 874 } |
869 Error& error = Error::Handle(); | 875 Error& error = Error::Handle(); |
870 super_type_arg = super_type_arg.InstantiateFrom( | 876 super_type_arg = super_type_arg.InstantiateFrom( |
871 arguments, &error, trail, Heap::kOld); | 877 arguments, &error, instantiation_trail, NULL, Heap::kOld); |
872 if (!error.IsNull()) { | 878 if (!error.IsNull()) { |
873 // InstantiateFrom does not report an error if the type is still | 879 // InstantiateFrom does not report an error if the type is still |
874 // uninstantiated. Instead, it will return a new BoundedType so | 880 // uninstantiated. Instead, it will return a new BoundedType so |
875 // that the check is postponed to run time. | 881 // that the check is postponed to run time. |
876 ASSERT(super_type_arg.IsInstantiated()); | 882 ASSERT(super_type_arg.IsInstantiated()); |
877 // Keep only the first bound error. | 883 // Keep only the first bound error. |
878 if (bound_error->IsNull()) { | 884 if (bound_error->IsNull()) { |
879 *bound_error = error.raw(); | 885 *bound_error = error.raw(); |
880 } | 886 } |
881 } | 887 } |
882 if (!super_type_arg.IsFinalized() && | 888 if (!super_type_arg.IsFinalized() && |
883 !super_type_arg.IsBeingFinalized()) { | 889 !super_type_arg.IsBeingFinalized()) { |
884 // The super_type_arg was instantiated from a type being finalized. | 890 // The super_type_arg was instantiated from a type being finalized. |
885 // We need to finish finalizing its type arguments. | 891 // We need to finish finalizing its type arguments. |
886 if (super_type_arg.IsTypeRef()) { | 892 if (super_type_arg.IsTypeRef()) { |
887 super_type_arg = TypeRef::Cast(super_type_arg).type(); | 893 super_type_arg = TypeRef::Cast(super_type_arg).type(); |
888 } | 894 } |
889 Type::Cast(super_type_arg).SetIsBeingFinalized(); | 895 Type::Cast(super_type_arg).SetIsBeingFinalized(); |
890 pending_types->Add(super_type_arg); | 896 pending_types->Add(super_type_arg); |
891 const Class& cls = Class::Handle(super_type_arg.type_class()); | 897 const Class& cls = Class::Handle(super_type_arg.type_class()); |
892 FinalizeTypeArguments( | 898 FinalizeTypeArguments( |
893 cls, | 899 cls, |
894 TypeArguments::Handle(super_type_arg.arguments()), | 900 TypeArguments::Handle(super_type_arg.arguments()), |
895 cls.NumTypeArguments() - cls.NumTypeParameters(), | 901 cls.NumTypeArguments() - cls.NumTypeParameters(), |
896 bound_error, | 902 bound_error, |
897 pending_types, | 903 pending_types, |
898 trail); | 904 instantiation_trail); |
899 Type::Cast(super_type_arg).SetIsFinalized(); | 905 Type::Cast(super_type_arg).SetIsFinalized(); |
900 } | 906 } |
901 } | 907 } |
902 } | 908 } |
903 arguments.SetTypeAt(i, super_type_arg); | 909 arguments.SetTypeAt(i, super_type_arg); |
904 } | 910 } |
905 FinalizeTypeArguments(super_class, arguments, super_offset, | 911 FinalizeTypeArguments(super_class, arguments, super_offset, |
906 bound_error, pending_types, trail); | 912 bound_error, pending_types, instantiation_trail); |
907 } | 913 } |
908 } | 914 } |
909 | 915 |
910 | 916 |
911 // Check the type argument vector 'arguments' against the corresponding bounds | 917 // Check the type argument vector 'arguments' against the corresponding bounds |
912 // of the type parameters of class 'cls' and, recursively, of its superclasses. | 918 // of the type parameters of class 'cls' and, recursively, of its superclasses. |
913 // Replace a type argument that cannot be checked at compile time by a | 919 // Replace a type argument that cannot be checked at compile time by a |
914 // BoundedType, thereby postponing the bound check to run time. | 920 // BoundedType, thereby postponing the bound check to run time. |
915 // Return a bound error if a type argument is not within bound at compile time. | 921 // Return a bound error if a type argument is not within bound at compile time. |
916 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, | 922 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, |
917 const TypeArguments& arguments, | 923 const TypeArguments& arguments, |
918 Error* bound_error) { | 924 Error* bound_error) { |
919 if (!cls.is_type_finalized()) { | 925 if (!cls.is_type_finalized()) { |
920 FinalizeTypeParameters(cls); | 926 FinalizeTypeParameters(cls); |
921 FinalizeUpperBounds(cls); | 927 FinalizeUpperBounds(cls, kFinalize); // No canonicalization yet. |
922 } | 928 } |
923 // Note that when finalizing a type, we need to verify the bounds in both | 929 // Note that when finalizing a type, we need to verify the bounds in both |
924 // production mode and checked mode, because the finalized type may be written | 930 // production mode and checked mode, because the finalized type may be written |
925 // to a snapshot. It would be wrong to ignore bounds when generating the | 931 // to a snapshot. It would be wrong to ignore bounds when generating the |
926 // snapshot in production mode and then use the unchecked type in checked mode | 932 // snapshot in production mode and then use the unchecked type in checked mode |
927 // after reading it from the snapshot. | 933 // after reading it from the snapshot. |
928 // However, we do not immediately report a bound error, which would be wrong | 934 // However, we do not immediately report a bound error, which would be wrong |
929 // in production mode, but simply postpone the bound checking to runtime. | 935 // in production mode, but simply postpone the bound checking to runtime. |
930 const intptr_t num_type_params = cls.NumTypeParameters(); | 936 const intptr_t num_type_params = cls.NumTypeParameters(); |
931 const intptr_t offset = cls.NumTypeArguments() - num_type_params; | 937 const intptr_t offset = cls.NumTypeArguments() - num_type_params; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 declared_bound = FinalizeType(cls, declared_bound, kCanonicalize); | 969 declared_bound = FinalizeType(cls, declared_bound, kCanonicalize); |
964 type_param.set_bound(declared_bound); | 970 type_param.set_bound(declared_bound); |
965 } | 971 } |
966 ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized()); | 972 ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized()); |
967 Error& error = Error::Handle(); | 973 Error& error = Error::Handle(); |
968 // Note that the bound may be malformed, in which case the bound check | 974 // Note that the bound may be malformed, in which case the bound check |
969 // will return an error and the bound check will be postponed to run time. | 975 // will return an error and the bound check will be postponed to run time. |
970 if (declared_bound.IsInstantiated()) { | 976 if (declared_bound.IsInstantiated()) { |
971 instantiated_bound = declared_bound.raw(); | 977 instantiated_bound = declared_bound.raw(); |
972 } else { | 978 } else { |
973 instantiated_bound = | 979 instantiated_bound = declared_bound.InstantiateFrom( |
974 declared_bound.InstantiateFrom(arguments, &error, NULL, Heap::kOld); | 980 arguments, &error, NULL, NULL, Heap::kOld); |
975 } | 981 } |
976 if (!instantiated_bound.IsFinalized()) { | 982 if (!instantiated_bound.IsFinalized()) { |
977 // The bound refers to type parameters, creating a cycle; postpone | 983 // The bound refers to type parameters, creating a cycle; postpone |
978 // bound check to run time, when the bound will be finalized. | 984 // bound check to run time, when the bound will be finalized. |
979 // The bound may not necessarily be 'IsBeingFinalized' yet, as is the | 985 // The bound may not necessarily be 'IsBeingFinalized' yet, as is the |
980 // case with a pair of type parameters of the same class referring to | 986 // case with a pair of type parameters of the same class referring to |
981 // each other via their bounds. | 987 // each other via their bounds. |
982 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 988 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
983 arguments.SetTypeAt(offset + i, type_arg); | 989 arguments.SetTypeAt(offset + i, type_arg); |
984 continue; | 990 continue; |
985 } | 991 } |
986 // Shortcut the special case where we check a type parameter against its | 992 // Shortcut the special case where we check a type parameter against its |
987 // declared upper bound. | 993 // declared upper bound. |
988 if (error.IsNull() && | 994 if (error.IsNull() && |
989 !(type_arg.Equals(type_param) && | 995 !(type_arg.Equals(type_param) && |
990 instantiated_bound.Equals(declared_bound))) { | 996 instantiated_bound.Equals(declared_bound))) { |
991 // If type_arg is a type parameter, its declared bound may not be | 997 // If type_arg is a type parameter, its declared bound may not be |
992 // resolved yet. | 998 // resolved yet. |
993 if (type_arg.IsTypeParameter()) { | 999 if (type_arg.IsTypeParameter()) { |
994 const Class& type_arg_cls = Class::Handle( | 1000 const Class& type_arg_cls = Class::Handle( |
995 TypeParameter::Cast(type_arg).parameterized_class()); | 1001 TypeParameter::Cast(type_arg).parameterized_class()); |
996 AbstractType& bound = AbstractType::Handle( | 1002 AbstractType& bound = AbstractType::Handle( |
997 TypeParameter::Cast(type_arg).bound()); | 1003 TypeParameter::Cast(type_arg).bound()); |
998 bound = ResolveType(type_arg_cls, bound); | 1004 bound = ResolveType(type_arg_cls, bound); |
999 TypeParameter::Cast(type_arg).set_bound(bound); | 1005 TypeParameter::Cast(type_arg).set_bound(bound); |
1000 } | 1006 } |
1001 // This may be called only if type needs to be finalized, therefore | 1007 // This may be called only if type needs to be finalized, therefore |
1002 // seems OK to allocate finalized types in old space. | 1008 // seems OK to allocate finalized types in old space. |
1003 if (!type_param.CheckBound(type_arg, instantiated_bound, | 1009 if (!type_param.CheckBound(type_arg, instantiated_bound, |
1004 &error, Heap::kOld) && error.IsNull()) { | 1010 &error, NULL, Heap::kOld) && |
| 1011 error.IsNull()) { |
1005 // The bound cannot be checked at compile time; postpone to run time. | 1012 // The bound cannot be checked at compile time; postpone to run time. |
1006 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 1013 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
1007 arguments.SetTypeAt(offset + i, type_arg); | 1014 arguments.SetTypeAt(offset + i, type_arg); |
1008 } | 1015 } |
1009 } | 1016 } |
1010 if (!error.IsNull() && bound_error->IsNull()) { | 1017 if (!error.IsNull() && bound_error->IsNull()) { |
1011 *bound_error = error.raw(); | 1018 *bound_error = error.raw(); |
1012 } | 1019 } |
1013 } | 1020 } |
1014 } | 1021 } |
1015 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 1022 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
1016 if (!super_type.IsNull()) { | 1023 if (!super_type.IsNull()) { |
1017 const Class& super_class = Class::Handle(super_type.type_class()); | 1024 const Class& super_class = Class::Handle(super_type.type_class()); |
1018 CheckTypeArgumentBounds(super_class, arguments, bound_error); | 1025 CheckTypeArgumentBounds(super_class, arguments, bound_error); |
1019 } | 1026 } |
1020 } | 1027 } |
1021 | 1028 |
1022 | 1029 |
1023 void ClassFinalizer::CheckTypeBounds(const Class& cls, | 1030 void ClassFinalizer::CheckTypeBounds(const Class& cls, |
1024 const AbstractType& type) { | 1031 const AbstractType& type) { |
| 1032 Zone* Z = Thread::Current()->zone(); |
1025 ASSERT(type.IsType() || type.IsFunctionType()); | 1033 ASSERT(type.IsType() || type.IsFunctionType()); |
1026 ASSERT(type.IsFinalized()); | 1034 ASSERT(type.IsFinalized()); |
1027 TypeArguments& arguments = TypeArguments::Handle(type.arguments()); | 1035 ASSERT(!type.IsCanonical()); |
| 1036 TypeArguments& arguments = TypeArguments::Handle(Z, type.arguments()); |
1028 if (arguments.IsNull()) { | 1037 if (arguments.IsNull()) { |
1029 return; | 1038 return; |
1030 } | 1039 } |
1031 const Class& type_class = Class::Handle(type.type_class()); | 1040 if (FLAG_trace_type_finalization) { |
1032 Error& bound_error = Error::Handle(); | 1041 THR_Print("Checking bounds of type '%s' for class '%s'\n", |
| 1042 String::Handle(Z, type.Name()).ToCString(), |
| 1043 String::Handle(Z, cls.Name()).ToCString()); |
| 1044 } |
| 1045 const Class& type_class = Class::Handle(Z, type.type_class()); |
| 1046 Error& bound_error = Error::Handle(Z); |
1033 CheckTypeArgumentBounds(type_class, arguments, &bound_error); | 1047 CheckTypeArgumentBounds(type_class, arguments, &bound_error); |
1034 type.set_arguments(arguments); | 1048 // CheckTypeArgumentBounds may have indirectly canonicalized this type. |
1035 // If a bound error occurred, mark the type as malbounded. | 1049 if (!type.IsCanonical()) { |
1036 // The bound error will be ignored in production mode. | 1050 type.set_arguments(arguments); |
1037 if (!bound_error.IsNull()) { | 1051 // If a bound error occurred, mark the type as malbounded. |
1038 // No compile-time error during finalization. | 1052 // The bound error will be ignored in production mode. |
1039 const String& type_name = String::Handle(type.UserVisibleName()); | 1053 if (!bound_error.IsNull()) { |
1040 FinalizeMalboundedType(bound_error, | 1054 // No compile-time error during finalization. |
1041 Script::Handle(cls.script()), | 1055 const String& type_name = String::Handle(Z, type.UserVisibleName()); |
1042 type, | 1056 FinalizeMalboundedType(bound_error, |
1043 "type '%s' has an out of bound type argument", | 1057 Script::Handle(Z, cls.script()), |
1044 type_name.ToCString()); | 1058 type, |
1045 if (FLAG_trace_type_finalization) { | 1059 "type '%s' has an out of bound type argument", |
1046 THR_Print("Marking type '%s' as malbounded: %s\n", | 1060 type_name.ToCString()); |
1047 String::Handle(type.Name()).ToCString(), | 1061 if (FLAG_trace_type_finalization) { |
1048 bound_error.ToCString()); | 1062 THR_Print("Marking type '%s' as malbounded: %s\n", |
| 1063 String::Handle(Z, type.Name()).ToCString(), |
| 1064 bound_error.ToCString()); |
| 1065 } |
1049 } | 1066 } |
1050 } | 1067 } |
| 1068 if (FLAG_trace_type_finalization) { |
| 1069 THR_Print("Done checking bounds of type '%s': %s\n", |
| 1070 String::Handle(Z, type.Name()).ToCString(), |
| 1071 type.ToCString()); |
| 1072 } |
1051 } | 1073 } |
1052 | 1074 |
1053 | 1075 |
1054 RawAbstractType* ClassFinalizer::FinalizeType( | 1076 RawAbstractType* ClassFinalizer::FinalizeType( |
1055 const Class& cls, | 1077 const Class& cls, |
1056 const AbstractType& type, | 1078 const AbstractType& type, |
1057 FinalizationKind finalization, | 1079 FinalizationKind finalization, |
1058 PendingTypes* pending_types) { | 1080 PendingTypes* pending_types) { |
1059 // Only the 'root' type of the graph can be canonicalized, after all depending | 1081 // Only the 'root' type of the graph can be canonicalized, after all depending |
1060 // types have been bound checked. | 1082 // types have been bound checked. |
1061 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); | 1083 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); |
1062 if (type.IsFinalized()) { | 1084 if (type.IsFinalized()) { |
1063 // Ensure type is canonical if canonicalization is requested, unless type is | 1085 // Ensure type is canonical if canonicalization is requested, unless type is |
1064 // malformed. | 1086 // malformed. |
1065 if ((finalization >= kCanonicalize) && !type.IsMalformed()) { | 1087 if ((finalization >= kCanonicalize) && |
| 1088 !type.IsMalformed() && |
| 1089 !type.IsCanonical() && |
| 1090 (type.IsType() || type.IsFunctionType())) { |
| 1091 CheckTypeBounds(cls, type); |
1066 return type.Canonicalize(); | 1092 return type.Canonicalize(); |
1067 } | 1093 } |
1068 return type.raw(); | 1094 return type.raw(); |
1069 } | 1095 } |
1070 ASSERT(finalization >= kFinalize); | 1096 ASSERT(finalization >= kFinalize); |
1071 | 1097 |
1072 if (type.IsTypeRef()) { | 1098 if (type.IsTypeRef()) { |
1073 // The referenced type will be finalized later by the code that set the | 1099 // The referenced type will be finalized later by the code that set the |
1074 // is_being_finalized mark bit. | 1100 // is_being_finalized mark bit. |
1075 return type.raw(); | 1101 return type.raw(); |
1076 } | 1102 } |
1077 | 1103 |
1078 // Recursive types must be processed in FinalizeTypeArguments() and cannot be | 1104 // Recursive types must be processed in FinalizeTypeArguments() and cannot be |
1079 // encountered here. | 1105 // encountered here. |
1080 ASSERT(!type.IsBeingFinalized()); | 1106 ASSERT(!type.IsBeingFinalized()); |
1081 | 1107 |
1082 Zone* Z = Thread::Current()->zone(); | 1108 Zone* Z = Thread::Current()->zone(); |
1083 const AbstractType& resolved_type = | 1109 const AbstractType& resolved_type = |
1084 AbstractType::Handle(Z, ResolveType(cls, type)); | 1110 AbstractType::Handle(Z, ResolveType(cls, type)); |
1085 // A malformed type gets mapped to a finalized type. | 1111 // A malformed type gets mapped to a finalized type. |
1086 if (resolved_type.IsMalformed()) { | 1112 if (resolved_type.IsMalformed()) { |
1087 ASSERT(resolved_type.IsFinalized()); | 1113 ASSERT(resolved_type.IsFinalized()); |
1088 return resolved_type.raw(); | 1114 return resolved_type.raw(); |
1089 } | 1115 } |
1090 | 1116 |
1091 if (FLAG_trace_type_finalization) { | 1117 if (FLAG_trace_type_finalization) { |
1092 THR_Print("Finalizing type '%s' for class '%s'\n", | 1118 THR_Print("Finalizing type '%s' for class '%s'\n", |
1093 String::Handle(Z, resolved_type.Name()).ToCString(), | 1119 String::Handle(Z, resolved_type.Name()).ToCString(), |
1094 cls.ToCString()); | 1120 String::Handle(Z, cls.Name()).ToCString()); |
1095 } | 1121 } |
1096 | 1122 |
1097 if (resolved_type.IsTypeParameter()) { | 1123 if (resolved_type.IsTypeParameter()) { |
1098 const TypeParameter& type_parameter = TypeParameter::Cast(resolved_type); | 1124 const TypeParameter& type_parameter = TypeParameter::Cast(resolved_type); |
1099 const Class& parameterized_class = | 1125 const Class& parameterized_class = |
1100 Class::Handle(Z, type_parameter.parameterized_class()); | 1126 Class::Handle(Z, type_parameter.parameterized_class()); |
1101 ASSERT(!parameterized_class.IsNull()); | 1127 ASSERT(!parameterized_class.IsNull()); |
1102 // The index must reflect the position of this type parameter in the type | 1128 // The index must reflect the position of this type parameter in the type |
1103 // arguments vector of its parameterized class. The offset to add is the | 1129 // arguments vector of its parameterized class. The offset to add is the |
1104 // number of type arguments in the super type, which is equal to the | 1130 // number of type arguments in the super type, which is equal to the |
(...skipping 30 matching lines...) Expand all Loading... |
1135 pending_types = new PendingTypes(Z, 4); | 1161 pending_types = new PendingTypes(Z, 4); |
1136 } | 1162 } |
1137 | 1163 |
1138 const intptr_t num_expanded_type_arguments = | 1164 const intptr_t num_expanded_type_arguments = |
1139 ExpandAndFinalizeTypeArguments(cls, resolved_type, pending_types); | 1165 ExpandAndFinalizeTypeArguments(cls, resolved_type, pending_types); |
1140 | 1166 |
1141 // If we are done finalizing a graph of mutually recursive types, check their | 1167 // If we are done finalizing a graph of mutually recursive types, check their |
1142 // bounds. | 1168 // bounds. |
1143 if (is_root_type) { | 1169 if (is_root_type) { |
1144 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { | 1170 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { |
1145 CheckTypeBounds(cls, pending_types->At(i)); | 1171 const AbstractType& type = pending_types->At(i); |
1146 if (FLAG_trace_type_finalization && resolved_type.IsRecursive()) { | 1172 if (!type.IsMalformed() && !type.IsCanonical()) { |
1147 THR_Print("Done finalizing recursive type '%s': %s\n", | 1173 CheckTypeBounds(cls, type); |
1148 String::Handle(Z, resolved_type.Name()).ToCString(), | |
1149 resolved_type.ToCString()); | |
1150 } | 1174 } |
1151 } | 1175 } |
1152 } | 1176 } |
1153 | 1177 |
1154 // If the type is a FunctionType, we also need to finalize the types in its | 1178 // If the type is a FunctionType, we also need to finalize the types in its |
1155 // signature, i.e. finalize the result type and parameter types of the | 1179 // signature, i.e. finalize the result type and parameter types of the |
1156 // signature function of this function type. | 1180 // signature function of this function type. |
1157 // We do this after marking this type as finalized in order to allow a | 1181 // We do this after marking this type as finalized in order to allow a |
1158 // function type to refer to itself via its parameter types and result type. | 1182 // function type to refer to itself via its parameter types and result type. |
1159 // Note that we do not instantiate these types according to the type | 1183 // Note that we do not instantiate these types according to the type |
(...skipping 11 matching lines...) Expand all Loading... |
1171 } | 1195 } |
1172 | 1196 |
1173 if (FLAG_trace_type_finalization) { | 1197 if (FLAG_trace_type_finalization) { |
1174 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1198 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
1175 String::Handle(Z, resolved_type.Name()).ToCString(), | 1199 String::Handle(Z, resolved_type.Name()).ToCString(), |
1176 num_expanded_type_arguments, | 1200 num_expanded_type_arguments, |
1177 resolved_type.ToCString()); | 1201 resolved_type.ToCString()); |
1178 } | 1202 } |
1179 | 1203 |
1180 if (finalization >= kCanonicalize) { | 1204 if (finalization >= kCanonicalize) { |
1181 if (FLAG_trace_type_finalization && resolved_type.IsRecursive()) { | 1205 if (FLAG_trace_type_finalization) { |
1182 AbstractType& recursive_type = | 1206 THR_Print("Canonicalizing type '%s'\n", |
| 1207 String::Handle(Z, resolved_type.Name()).ToCString()); |
| 1208 AbstractType& canonical_type = |
1183 AbstractType::Handle(Z, resolved_type.Canonicalize()); | 1209 AbstractType::Handle(Z, resolved_type.Canonicalize()); |
1184 THR_Print("Done canonicalizing recursive type '%s': %s\n", | 1210 THR_Print("Done canonicalizing type '%s'\n", |
1185 String::Handle(Z, recursive_type.Name()).ToCString(), | 1211 String::Handle(Z, canonical_type.Name()).ToCString()); |
1186 recursive_type.ToCString()); | 1212 return canonical_type.raw(); |
1187 return recursive_type.raw(); | |
1188 } | 1213 } |
1189 return resolved_type.Canonicalize(); | 1214 return resolved_type.Canonicalize(); |
1190 } else { | 1215 } else { |
1191 return resolved_type.raw(); | 1216 return resolved_type.raw(); |
1192 } | 1217 } |
1193 } | 1218 } |
1194 | 1219 |
1195 | 1220 |
1196 void ClassFinalizer::ResolveSignature(const Class& cls, | 1221 void ClassFinalizer::ResolveSignature(const Class& cls, |
1197 const Function& function) { | 1222 const Function& function) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 for (intptr_t i = 0; i < num_type_params; i++) { | 1326 for (intptr_t i = 0; i < num_type_params; i++) { |
1302 type_param ^= type_params.TypeAt(i); | 1327 type_param ^= type_params.TypeAt(i); |
1303 bound = type_param.bound(); | 1328 bound = type_param.bound(); |
1304 bound = ResolveType(cls, bound); | 1329 bound = ResolveType(cls, bound); |
1305 type_param.set_bound(bound); | 1330 type_param.set_bound(bound); |
1306 } | 1331 } |
1307 } | 1332 } |
1308 | 1333 |
1309 | 1334 |
1310 // Finalize the upper bounds of the type parameters of class cls. | 1335 // Finalize the upper bounds of the type parameters of class cls. |
1311 void ClassFinalizer::FinalizeUpperBounds(const Class& cls) { | 1336 void ClassFinalizer::FinalizeUpperBounds(const Class& cls, |
| 1337 FinalizationKind finalization) { |
1312 const intptr_t num_type_params = cls.NumTypeParameters(); | 1338 const intptr_t num_type_params = cls.NumTypeParameters(); |
1313 TypeParameter& type_param = TypeParameter::Handle(); | 1339 TypeParameter& type_param = TypeParameter::Handle(); |
1314 AbstractType& bound = AbstractType::Handle(); | 1340 AbstractType& bound = AbstractType::Handle(); |
1315 const TypeArguments& type_params = | 1341 const TypeArguments& type_params = |
1316 TypeArguments::Handle(cls.type_parameters()); | 1342 TypeArguments::Handle(cls.type_parameters()); |
1317 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1343 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
1318 (type_params.Length() == num_type_params)); | 1344 (type_params.Length() == num_type_params)); |
1319 for (intptr_t i = 0; i < num_type_params; i++) { | 1345 for (intptr_t i = 0; i < num_type_params; i++) { |
1320 type_param ^= type_params.TypeAt(i); | 1346 type_param ^= type_params.TypeAt(i); |
1321 bound = type_param.bound(); | 1347 bound = type_param.bound(); |
1322 // Bound may be finalized, but not canonical yet. | 1348 // Bound may be finalized, but not canonical yet. |
1323 if (bound.IsCanonical() || bound.IsBeingFinalized()) { | 1349 if (bound.IsCanonical() || bound.IsBeingFinalized()) { |
1324 // A bound involved in F-bounded quantification may form a cycle. | 1350 // A bound involved in F-bounded quantification may form a cycle. |
1325 continue; | 1351 continue; |
1326 } | 1352 } |
1327 bound = FinalizeType(cls, bound, kCanonicalize); | 1353 bound = FinalizeType(cls, bound, finalization); |
1328 type_param.set_bound(bound); | 1354 type_param.set_bound(bound); |
1329 } | 1355 } |
1330 } | 1356 } |
1331 | 1357 |
1332 | 1358 |
1333 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 1359 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
1334 // Note that getters and setters are explicitly listed as such in the list of | 1360 // Note that getters and setters are explicitly listed as such in the list of |
1335 // functions of a class, so we do not need to consider fields as implicitly | 1361 // functions of a class, so we do not need to consider fields as implicitly |
1336 // generating getters and setters. | 1362 // generating getters and setters. |
1337 // Most overriding conflicts are only static warnings, i.e. they are not | 1363 // Most overriding conflicts are only static warnings, i.e. they are not |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1759 param_bound = param.bound(); | 1785 param_bound = param.bound(); |
1760 if (!param_bound.IsInstantiated()) { | 1786 if (!param_bound.IsInstantiated()) { |
1761 // Make sure the bound is finalized before instantiating it. | 1787 // Make sure the bound is finalized before instantiating it. |
1762 if (!param_bound.IsFinalized() && | 1788 if (!param_bound.IsFinalized() && |
1763 !param_bound.IsBeingFinalized()) { | 1789 !param_bound.IsBeingFinalized()) { |
1764 param_bound = | 1790 param_bound = |
1765 FinalizeType(mixin_app_class, param_bound, kCanonicalize); | 1791 FinalizeType(mixin_app_class, param_bound, kCanonicalize); |
1766 param.set_bound(param_bound); // In case part of recursive type. | 1792 param.set_bound(param_bound); // In case part of recursive type. |
1767 } | 1793 } |
1768 param_bound = param_bound.InstantiateFrom( | 1794 param_bound = param_bound.InstantiateFrom( |
1769 instantiator, &bound_error, NULL, Heap::kOld); | 1795 instantiator, &bound_error, NULL, NULL, Heap::kOld); |
1770 // The instantiator contains only TypeParameter objects and no | 1796 // The instantiator contains only TypeParameter objects and no |
1771 // BoundedType objects, so no bound error may occur. | 1797 // BoundedType objects, so no bound error may occur. |
1772 ASSERT(!param_bound.IsBoundedType()); | 1798 ASSERT(!param_bound.IsBoundedType()); |
1773 ASSERT(bound_error.IsNull()); | 1799 ASSERT(bound_error.IsNull()); |
1774 ASSERT(!param_bound.IsInstantiated()); | 1800 ASSERT(!param_bound.IsInstantiated()); |
1775 param.set_bound(param_bound); | 1801 param.set_bound(param_bound); |
1776 } | 1802 } |
1777 } | 1803 } |
1778 } | 1804 } |
1779 | 1805 |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 mixin_class_super_type_args.Length() - num_aliased_mixin_type_params; | 2019 mixin_class_super_type_args.Length() - num_aliased_mixin_type_params; |
1994 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 2020 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
1995 type = mixin_class_super_type_args.TypeAt(offset + i); | 2021 type = mixin_class_super_type_args.TypeAt(offset + i); |
1996 if (!type.IsInstantiated()) { | 2022 if (!type.IsInstantiated()) { |
1997 // In the presence of bounds, the bounded type and the upper bound must | 2023 // In the presence of bounds, the bounded type and the upper bound must |
1998 // be instantiated separately. Instantiating a BoundedType would wrap | 2024 // be instantiated separately. Instantiating a BoundedType would wrap |
1999 // the BoundedType in another BoundedType. | 2025 // the BoundedType in another BoundedType. |
2000 if (type.IsBoundedType()) { | 2026 if (type.IsBoundedType()) { |
2001 bounded_type = BoundedType::Cast(type).type(); | 2027 bounded_type = BoundedType::Cast(type).type(); |
2002 bounded_type = bounded_type.InstantiateFrom( | 2028 bounded_type = bounded_type.InstantiateFrom( |
2003 instantiator, &bound_error, NULL, Heap::kOld); | 2029 instantiator, &bound_error, NULL, NULL, Heap::kOld); |
2004 // The instantiator contains only TypeParameter objects and no | 2030 // The instantiator contains only TypeParameter objects and no |
2005 // BoundedType objects, so no bound error may occur. | 2031 // BoundedType objects, so no bound error may occur. |
2006 ASSERT(bound_error.IsNull()); | 2032 ASSERT(bound_error.IsNull()); |
2007 upper_bound = BoundedType::Cast(type).bound(); | 2033 upper_bound = BoundedType::Cast(type).bound(); |
2008 upper_bound = upper_bound.InstantiateFrom( | 2034 upper_bound = upper_bound.InstantiateFrom( |
2009 instantiator, &bound_error, NULL, Heap::kOld); | 2035 instantiator, &bound_error, NULL, NULL, Heap::kOld); |
2010 ASSERT(bound_error.IsNull()); | 2036 ASSERT(bound_error.IsNull()); |
2011 type_parameter = BoundedType::Cast(type).type_parameter(); | 2037 type_parameter = BoundedType::Cast(type).type_parameter(); |
2012 // The type parameter that declared the bound does not change. | 2038 // The type parameter that declared the bound does not change. |
2013 type = BoundedType::New(bounded_type, upper_bound, type_parameter); | 2039 type = BoundedType::New(bounded_type, upper_bound, type_parameter); |
2014 } else { | 2040 } else { |
2015 type = type.InstantiateFrom( | 2041 type = type.InstantiateFrom( |
2016 instantiator, &bound_error, NULL, Heap::kOld); | 2042 instantiator, &bound_error, NULL, NULL, Heap::kOld); |
2017 ASSERT(bound_error.IsNull()); | 2043 ASSERT(bound_error.IsNull()); |
2018 } | 2044 } |
2019 } | 2045 } |
2020 new_mixin_type_args.SetTypeAt(i, type); | 2046 new_mixin_type_args.SetTypeAt(i, type); |
2021 } | 2047 } |
2022 } | 2048 } |
2023 TypeArguments& new_super_type_args = TypeArguments::Handle(zone); | 2049 TypeArguments& new_super_type_args = TypeArguments::Handle(zone); |
2024 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { | 2050 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { |
2025 new_super_type_args = TypeArguments::New(num_super_type_params + | 2051 new_super_type_args = TypeArguments::New(num_super_type_params + |
2026 num_aliased_mixin_type_params); | 2052 num_aliased_mixin_type_params); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2305 } | 2331 } |
2306 // Finalize type parameters before finalizing the super type. | 2332 // Finalize type parameters before finalizing the super type. |
2307 FinalizeTypeParameters(cls); // May change super type. | 2333 FinalizeTypeParameters(cls); // May change super type. |
2308 super_class = cls.SuperClass(); | 2334 super_class = cls.SuperClass(); |
2309 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); | 2335 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); |
2310 // Only resolving rather than finalizing the upper bounds here would result in | 2336 // Only resolving rather than finalizing the upper bounds here would result in |
2311 // instantiated type parameters of the super type to temporarily have | 2337 // instantiated type parameters of the super type to temporarily have |
2312 // unfinalized bounds. It is more efficient to finalize them early. | 2338 // unfinalized bounds. It is more efficient to finalize them early. |
2313 // Finalize bounds even if running in production mode, so that a snapshot | 2339 // Finalize bounds even if running in production mode, so that a snapshot |
2314 // contains them. | 2340 // contains them. |
2315 FinalizeUpperBounds(cls); | 2341 FinalizeUpperBounds(cls, kCanonicalizeWellFormed); |
2316 // Finalize super type. | 2342 // Finalize super type. |
2317 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 2343 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
2318 if (!super_type.IsNull()) { | 2344 if (!super_type.IsNull()) { |
2319 // In case of a bound error in the super type in production mode, the | 2345 // In case of a bound error in the super type in production mode, the |
2320 // finalized super type will have a BoundedType as type argument for the | 2346 // finalized super type will have a BoundedType as type argument for the |
2321 // out of bound type argument. | 2347 // out of bound type argument. |
2322 // It should not be a problem if the class is written to a snapshot and | 2348 // It should not be a problem if the class is written to a snapshot and |
2323 // later executed in checked mode. Note that the finalized type argument | 2349 // later executed in checked mode. Note that the finalized type argument |
2324 // vector of any type of the base class will contain a BoundedType for the | 2350 // vector of any type of the base class will contain a BoundedType for the |
2325 // out of bound type argument. | 2351 // out of bound type argument. |
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3293 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3319 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3294 field ^= fields_array.At(0); | 3320 field ^= fields_array.At(0); |
3295 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3321 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3296 name ^= field.name(); | 3322 name ^= field.name(); |
3297 expected_name ^= String::New("_data"); | 3323 expected_name ^= String::New("_data"); |
3298 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3324 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3299 #endif | 3325 #endif |
3300 } | 3326 } |
3301 | 3327 |
3302 } // namespace dart | 3328 } // namespace dart |
OLD | NEW |