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

Side by Side Diff: runtime/lib/mirrors.cc

Issue 1167583002: Canonicalize mixin type during class finalization. Add asserts that most types are canonical. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: spelling Created 5 years, 6 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
« no previous file with comments | « no previous file | runtime/vm/class_finalizer.cc » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 "lib/mirrors.h" 5 #include "lib/mirrors.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bootstrap_natives.h" 8 #include "vm/bootstrap_natives.h"
9 #include "vm/class_finalizer.h" 9 #include "vm/class_finalizer.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/exceptions.h" 12 #include "vm/exceptions.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/parser.h" 14 #include "vm/parser.h"
15 #include "vm/port.h" 15 #include "vm/port.h"
16 #include "vm/resolver.h" 16 #include "vm/resolver.h"
17 #include "vm/symbols.h" 17 #include "vm/symbols.h"
18 18
19 namespace dart { 19 namespace dart {
20 20
21 #define PROPOGATE_IF_MALFOMRED(type) \ 21 #define PROPAGATE_IF_MALFORMED(type) \
22 if (type.IsMalformed()) { \ 22 if (type.IsMalformed()) { \
23 Exceptions::PropagateError(Error::Handle(type.error())); \ 23 Exceptions::PropagateError(Error::Handle(type.error())); \
24 } \ 24 } \
25 25
26 static RawInstance* CreateMirror(const String& mirror_class_name, 26 static RawInstance* CreateMirror(const String& mirror_class_name,
27 const Array& constructor_arguments) { 27 const Array& constructor_arguments) {
28 const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary()); 28 const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary());
29 const String& constructor_name = Symbols::Dot(); 29 const String& constructor_name = Symbols::Dot();
30 30
31 const Object& result = Object::Handle( 31 const Object& result = Object::Handle(
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 const TypeArguments& args = TypeArguments::Handle(cls.type_parameters()); 203 const TypeArguments& args = TypeArguments::Handle(cls.type_parameters());
204 if (args.IsNull()) { 204 if (args.IsNull()) {
205 return Object::empty_array().raw(); 205 return Object::empty_array().raw();
206 } 206 }
207 const Array& result = Array::Handle(Array::New(args.Length() * 2)); 207 const Array& result = Array::Handle(Array::New(args.Length() * 2));
208 TypeParameter& type = TypeParameter::Handle(); 208 TypeParameter& type = TypeParameter::Handle();
209 String& name = String::Handle(); 209 String& name = String::Handle();
210 for (intptr_t i = 0; i < args.Length(); i++) { 210 for (intptr_t i = 0; i < args.Length(); i++) {
211 type ^= args.TypeAt(i); 211 type ^= args.TypeAt(i);
212 ASSERT(type.IsTypeParameter()); 212 ASSERT(type.IsTypeParameter());
213 PROPOGATE_IF_MALFOMRED(type); 213 PROPAGATE_IF_MALFORMED(type);
214 ASSERT(type.IsFinalized()); 214 ASSERT(type.IsFinalized());
215 name ^= type.name(); 215 name ^= type.name();
216 result.SetAt(2 * i, name); 216 result.SetAt(2 * i, name);
217 result.SetAt(2 * i + 1, type); 217 result.SetAt(2 * i + 1, type);
218 } 218 }
219 return result.raw(); 219 return result.raw();
220 } 220 }
221 221
222 222
223 static RawInstance* CreateTypedefMirror(const Class& cls, 223 static RawInstance* CreateTypedefMirror(const Class& cls,
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 509
510 510
511 static RawInstance* CreateTypeMirror(const AbstractType& type) { 511 static RawInstance* CreateTypeMirror(const AbstractType& type) {
512 if (type.IsTypeRef()) { 512 if (type.IsTypeRef()) {
513 AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type()); 513 AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
514 ASSERT(!ref_type.IsTypeRef()); 514 ASSERT(!ref_type.IsTypeRef());
515 ASSERT(ref_type.IsCanonical()); 515 ASSERT(ref_type.IsCanonical());
516 return CreateTypeMirror(ref_type); 516 return CreateTypeMirror(ref_type);
517 } 517 }
518 ASSERT(type.IsFinalized()); 518 ASSERT(type.IsFinalized());
519 PROPOGATE_IF_MALFOMRED(type); 519 PROPAGATE_IF_MALFORMED(type);
520 ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType());
520 521
521 if (type.HasResolvedTypeClass()) { 522 if (type.HasResolvedTypeClass()) {
522 const Class& cls = Class::Handle(type.type_class()); 523 const Class& cls = Class::Handle(type.type_class());
523 // Handle void and dynamic types. 524 // Handle void and dynamic types.
524 if (cls.IsVoidClass()) { 525 if (cls.IsVoidClass()) {
525 Array& args = Array::Handle(Array::New(1)); 526 Array& args = Array::Handle(Array::New(1));
526 args.SetAt(0, Symbols::Void()); 527 args.SetAt(0, Symbols::Void());
527 return CreateMirror(Symbols::_SpecialTypeMirror(), args); 528 return CreateMirror(Symbols::_SpecialTypeMirror(), args);
528 } else if (cls.IsDynamicClass()) { 529 } else if (cls.IsDynamicClass()) {
529 Array& args = Array::Handle(Array::New(1)); 530 Array& args = Array::Handle(Array::New(1));
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 // Fall through case: Indicate that we didn't find any function or field using 756 // Fall through case: Indicate that we didn't find any function or field using
756 // a special null instance. This is different from a field being null. Callers 757 // a special null instance. This is different from a field being null. Callers
757 // make sure that this null does not leak into Dartland. 758 // make sure that this null does not leak into Dartland.
758 return Object::sentinel().raw(); 759 return Object::sentinel().raw();
759 } 760 }
760 761
761 762
762 static RawAbstractType* InstantiateType(const AbstractType& type, 763 static RawAbstractType* InstantiateType(const AbstractType& type,
763 const AbstractType& instantiator) { 764 const AbstractType& instantiator) {
764 ASSERT(type.IsFinalized()); 765 ASSERT(type.IsFinalized());
765 PROPOGATE_IF_MALFOMRED(type); 766 PROPAGATE_IF_MALFORMED(type);
767 ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType());
766 768
767 if (type.IsInstantiated() || instantiator.IsNull()) { 769 if (type.IsInstantiated() || instantiator.IsNull()) {
768 return type.Canonicalize(); 770 return type.Canonicalize();
769 } 771 }
770 772
771 ASSERT(!instantiator.IsNull()); 773 ASSERT(!instantiator.IsNull());
772 ASSERT(instantiator.IsFinalized()); 774 ASSERT(instantiator.IsFinalized());
773 PROPOGATE_IF_MALFOMRED(instantiator); 775 PROPAGATE_IF_MALFORMED(instantiator);
774 776
775 const TypeArguments& type_args = 777 const TypeArguments& type_args =
776 TypeArguments::Handle(instantiator.arguments()); 778 TypeArguments::Handle(instantiator.arguments());
777 Error& bound_error = Error::Handle(); 779 Error& bound_error = Error::Handle();
778 AbstractType& result = 780 AbstractType& result =
779 AbstractType::Handle(type.InstantiateFrom(type_args, &bound_error)); 781 AbstractType::Handle(type.InstantiateFrom(type_args, &bound_error));
780 if (!bound_error.IsNull()) { 782 if (!bound_error.IsNull()) {
781 Exceptions::PropagateError(bound_error); 783 Exceptions::PropagateError(bound_error);
782 UNREACHABLE(); 784 UNREACHABLE();
783 } 785 }
(...skipping 25 matching lines...) Expand all
809 811
810 DEFINE_NATIVE_ENTRY(MirrorSystem_isolate, 0) { 812 DEFINE_NATIVE_ENTRY(MirrorSystem_isolate, 0) {
811 VerifyMethodKindShifts(); 813 VerifyMethodKindShifts();
812 814
813 return CreateIsolateMirror(); 815 return CreateIsolateMirror();
814 } 816 }
815 817
816 818
817 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) { 819 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) {
818 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 820 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
819 PROPOGATE_IF_MALFOMRED(type); 821 PROPAGATE_IF_MALFORMED(type);
820 ASSERT(type.IsFinalized()); 822 ASSERT(type.IsFinalized());
821 ASSERT(type.HasResolvedTypeClass()); 823 ASSERT(type.HasResolvedTypeClass());
822 const Class& cls = Class::Handle(type.type_class()); 824 const Class& cls = Class::Handle(type.type_class());
823 ASSERT(!cls.IsNull()); 825 ASSERT(!cls.IsNull());
824 if (cls.IsDynamicClass() || 826 if (cls.IsDynamicClass() ||
825 cls.IsVoidClass() || 827 cls.IsVoidClass() ||
826 (cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass())) { 828 (cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass())) {
827 Exceptions::ThrowArgumentError(type); 829 Exceptions::ThrowArgumentError(type);
828 UNREACHABLE(); 830 UNREACHABLE();
829 } 831 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 936 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
935 const Class& klass = Class::Handle(ref.GetClassReferent()); 937 const Class& klass = Class::Handle(ref.GetClassReferent());
936 const Library& library = Library::Handle(klass.library()); 938 const Library& library = Library::Handle(klass.library());
937 ASSERT(!library.IsNull()); 939 ASSERT(!library.IsNull());
938 return library.url(); 940 return library.url();
939 } 941 }
940 942
941 943
942 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { 944 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) {
943 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 945 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
944 PROPOGATE_IF_MALFOMRED(type); 946 PROPAGATE_IF_MALFORMED(type);
945 ASSERT(type.IsFinalized()); 947 ASSERT(type.IsFinalized());
946 if (!type.HasResolvedTypeClass()) { 948 if (!type.HasResolvedTypeClass()) {
947 Exceptions::ThrowArgumentError(type); 949 Exceptions::ThrowArgumentError(type);
948 UNREACHABLE(); 950 UNREACHABLE();
949 } 951 }
950 const Class& cls = Class::Handle(type.type_class()); 952 const Class& cls = Class::Handle(type.type_class());
951 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); 953 const AbstractType& super_type = AbstractType::Handle(cls.super_type());
952 ASSERT(super_type.IsNull() || super_type.IsFinalized()); 954 ASSERT(super_type.IsNull() || super_type.IsFinalized());
953 return super_type.raw(); 955 return super_type.raw();
954 } 956 }
955 957
956 958
957 DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) { 959 DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) {
958 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 960 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
959 PROPOGATE_IF_MALFOMRED(type); 961 PROPAGATE_IF_MALFORMED(type);
960 ASSERT(type.IsFinalized()); 962 ASSERT(type.IsFinalized());
961 if (!type.HasResolvedTypeClass()) { 963 if (!type.HasResolvedTypeClass()) {
962 Exceptions::ThrowArgumentError(type); 964 Exceptions::ThrowArgumentError(type);
963 UNREACHABLE(); 965 UNREACHABLE();
964 } 966 }
965 const Class& cls = Class::Handle(type.type_class()); 967 const Class& cls = Class::Handle(type.type_class());
966 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); 968 const AbstractType& super_type = AbstractType::Handle(cls.super_type());
967 return InstantiateType(super_type, type); 969 return InstantiateType(super_type, type);
968 } 970 }
969 971
970 972
971 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) { 973 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) {
972 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 974 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
973 PROPOGATE_IF_MALFOMRED(type); 975 PROPAGATE_IF_MALFORMED(type);
974 ASSERT(type.IsFinalized()); 976 ASSERT(type.IsFinalized());
975 if (!type.HasResolvedTypeClass()) { 977 if (!type.HasResolvedTypeClass()) {
976 Exceptions::ThrowArgumentError(type); 978 Exceptions::ThrowArgumentError(type);
977 UNREACHABLE(); 979 UNREACHABLE();
978 } 980 }
979 const Class& cls = Class::Handle(type.type_class()); 981 const Class& cls = Class::Handle(type.type_class());
980 const Error& error = Error::Handle(cls.EnsureIsFinalized(isolate)); 982 const Error& error = Error::Handle(cls.EnsureIsFinalized(isolate));
981 if (!error.IsNull()) { 983 if (!error.IsNull()) {
982 Exceptions::PropagateError(error); 984 Exceptions::PropagateError(error);
983 } 985 }
984 986
985 return cls.interfaces(); 987 return cls.interfaces();
986 } 988 }
987 989
988 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) { 990 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) {
989 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 991 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
990 PROPOGATE_IF_MALFOMRED(type); 992 PROPAGATE_IF_MALFORMED(type);
991 ASSERT(type.IsFinalized()); 993 ASSERT(type.IsFinalized());
992 if (!type.HasResolvedTypeClass()) { 994 if (!type.HasResolvedTypeClass()) {
993 Exceptions::ThrowArgumentError(type); 995 Exceptions::ThrowArgumentError(type);
994 UNREACHABLE(); 996 UNREACHABLE();
995 } 997 }
996 const Class& cls = Class::Handle(type.type_class()); 998 const Class& cls = Class::Handle(type.type_class());
997 const Error& error = Error::Handle(cls.EnsureIsFinalized(isolate)); 999 const Error& error = Error::Handle(cls.EnsureIsFinalized(isolate));
998 if (!error.IsNull()) { 1000 if (!error.IsNull()) {
999 Exceptions::PropagateError(error); 1001 Exceptions::PropagateError(error);
1000 } 1002 }
1001 1003
1002 Array& interfaces = Array::Handle(cls.interfaces()); 1004 Array& interfaces = Array::Handle(cls.interfaces());
1003 Array& interfaces_inst = Array::Handle(Array::New(interfaces.Length())); 1005 Array& interfaces_inst = Array::Handle(Array::New(interfaces.Length()));
1004 AbstractType& interface = AbstractType::Handle(); 1006 AbstractType& interface = AbstractType::Handle();
1005 1007
1006 for (int i = 0; i < interfaces.Length(); i++) { 1008 for (int i = 0; i < interfaces.Length(); i++) {
1007 interface ^= interfaces.At(i); 1009 interface ^= interfaces.At(i);
1008 interface = InstantiateType(interface, type); 1010 interface = InstantiateType(interface, type);
1009 interfaces_inst.SetAt(i, interface); 1011 interfaces_inst.SetAt(i, interface);
1010 } 1012 }
1011 1013
1012 return interfaces_inst.raw(); 1014 return interfaces_inst.raw();
1013 } 1015 }
1014 1016
1015 1017
1016 DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 1) { 1018 DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 1) {
1017 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 1019 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
1018 PROPOGATE_IF_MALFOMRED(type); 1020 PROPAGATE_IF_MALFORMED(type);
1019 ASSERT(type.IsFinalized()); 1021 ASSERT(type.IsFinalized());
1020 if (!type.HasResolvedTypeClass()) { 1022 if (!type.HasResolvedTypeClass()) {
1021 Exceptions::ThrowArgumentError(type); 1023 Exceptions::ThrowArgumentError(type);
1022 UNREACHABLE(); 1024 UNREACHABLE();
1023 } 1025 }
1024 const Class& cls = Class::Handle(type.type_class()); 1026 const Class& cls = Class::Handle(type.type_class());
1025 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); 1027 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin());
1026 ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized()); 1028 ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized());
1027 return mixin_type.raw(); 1029 return mixin_type.raw();
1028 } 1030 }
1029 1031
1030 1032
1031 DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) { 1033 DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) {
1032 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 1034 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
1033 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, 1035 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType,
1034 instantiator, 1036 instantiator,
1035 arguments->NativeArgAt(1)); 1037 arguments->NativeArgAt(1));
1036 PROPOGATE_IF_MALFOMRED(type); 1038 PROPAGATE_IF_MALFORMED(type);
1037 ASSERT(type.IsFinalized()); 1039 ASSERT(type.IsFinalized());
1038 if (!type.HasResolvedTypeClass()) { 1040 if (!type.HasResolvedTypeClass()) {
1039 Exceptions::ThrowArgumentError(type); 1041 Exceptions::ThrowArgumentError(type);
1040 UNREACHABLE(); 1042 UNREACHABLE();
1041 } 1043 }
1042 const Class& cls = Class::Handle(type.type_class()); 1044 const Class& cls = Class::Handle(type.type_class());
1043 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); 1045 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin());
1044 if (mixin_type.IsNull()) { 1046 if (mixin_type.IsNull()) {
1045 return mixin_type.raw(); 1047 return mixin_type.raw();
1046 } 1048 }
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 } 2073 }
2072 2074
2073 DEFINE_NATIVE_ENTRY(TypeMirror_moreSpecificTest, 2) { 2075 DEFINE_NATIVE_ENTRY(TypeMirror_moreSpecificTest, 2) {
2074 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0)); 2076 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0));
2075 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1)); 2077 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1));
2076 return Bool::Get(a.IsMoreSpecificThan(b, NULL)).raw(); 2078 return Bool::Get(a.IsMoreSpecificThan(b, NULL)).raw();
2077 } 2079 }
2078 2080
2079 2081
2080 } // namespace dart 2082 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/class_finalizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698