OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |