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/invocation_mirror.h" | 5 #include "lib/invocation_mirror.h" |
6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 const Function& function = | 767 const Function& function = |
768 Function::Handle(isolate, cls.LookupDynamicFunction(Symbols::hashCode())); | 768 Function::Handle(isolate, cls.LookupDynamicFunction(Symbols::hashCode())); |
769 const Array& args = Array::Handle(isolate, Array::New(1)); | 769 const Array& args = Array::Handle(isolate, Array::New(1)); |
770 args.SetAt(0, reflectee); | 770 args.SetAt(0, reflectee); |
771 return DartEntry::InvokeFunction(function, args); | 771 return DartEntry::InvokeFunction(function, args); |
772 } | 772 } |
773 | 773 |
774 | 774 |
775 // Invoke the function, or noSuchMethod if it is null. Propagate any unhandled | 775 // Invoke the function, or noSuchMethod if it is null. Propagate any unhandled |
776 // exceptions. Wrap and propagate any compilation errors. | 776 // exceptions. Wrap and propagate any compilation errors. |
777 static RawObject* ReflectivelyInvokeDynamicFunction(const Instance& receiver, | 777 static RawObject* ReflectivelyInvokeDynamicFunction( |
778 const Function& function, | 778 const Instance& receiver, |
779 const String& target_name, | 779 const Function& function, |
780 const Array& arguments) { | 780 const String& target_name, |
781 // Note "arguments" is already the internal arguments with the receiver as | 781 const Array& args, |
782 // the first element. | 782 const Array& args_descriptor) { |
| 783 // Note "args" is already the internal arguments with the receiver as the |
| 784 // first element. |
783 Object& result = Object::Handle(); | 785 Object& result = Object::Handle(); |
784 if (function.IsNull() || !function.is_visible()) { | 786 if (function.IsNull() || |
785 const Array& arguments_descriptor = | 787 !function.is_visible() || |
786 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); | 788 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL)) { |
787 result = DartEntry::InvokeNoSuchMethod(receiver, | 789 result = DartEntry::InvokeNoSuchMethod(receiver, |
788 target_name, | 790 target_name, |
789 arguments, | 791 args, |
790 arguments_descriptor); | 792 args_descriptor); |
791 } else { | 793 } else { |
792 result = DartEntry::InvokeFunction(function, arguments); | 794 result = DartEntry::InvokeFunction(function, |
| 795 args, |
| 796 args_descriptor); |
793 } | 797 } |
794 | 798 |
795 if (result.IsError()) { | 799 if (result.IsError()) { |
796 ThrowInvokeError(Error::Cast(result)); | 800 ThrowInvokeError(Error::Cast(result)); |
797 UNREACHABLE(); | 801 UNREACHABLE(); |
798 } | 802 } |
799 return result.raw(); | 803 return result.raw(); |
800 } | 804 } |
801 | 805 |
802 | 806 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) { |
803 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 4) { | |
804 // Argument 0 is the mirror, which is unused by the native. It exists | 807 // Argument 0 is the mirror, which is unused by the native. It exists |
805 // because this native is an instance method in order to be polymorphic | 808 // because this native is an instance method in order to be polymorphic |
806 // with its cousins. | 809 // with its cousins. |
807 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); | 810 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); |
808 GET_NON_NULL_NATIVE_ARGUMENT( | 811 GET_NON_NULL_NATIVE_ARGUMENT( |
809 String, function_name, arguments->NativeArgAt(2)); | 812 String, function_name, arguments->NativeArgAt(2)); |
810 GET_NON_NULL_NATIVE_ARGUMENT( | 813 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); |
811 Array, positional_args, arguments->NativeArgAt(3)); | 814 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
812 | 815 |
813 intptr_t number_of_arguments = positional_args.Length(); | 816 const Array& args_descriptor = |
814 | 817 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
815 const Array& args = | |
816 Array::Handle(Array::New(number_of_arguments + 1)); // Plus receiver. | |
817 Object& arg = Object::Handle(); | |
818 args.SetAt(0, reflectee); | |
819 for (int i = 0; i < number_of_arguments; i++) { | |
820 arg = positional_args.At(i); | |
821 args.SetAt(i + 1, arg); // Plus receiver. | |
822 } | |
823 | |
824 ArgumentsDescriptor args_desc( | |
825 Array::Handle(ArgumentsDescriptor::New(args.Length()))); | |
826 | 818 |
827 Class& klass = Class::Handle(reflectee.clazz()); | 819 Class& klass = Class::Handle(reflectee.clazz()); |
828 Function& function = Function::Handle(); | 820 Function& function = Function::Handle(); |
829 while (!klass.IsNull()) { | 821 while (!klass.IsNull()) { |
830 function = klass.LookupDynamicFunctionAllowPrivate(function_name); | 822 function = klass.LookupDynamicFunctionAllowPrivate(function_name); |
831 if (!function.IsNull()) { | 823 if (!function.IsNull()) { |
832 break; | 824 break; |
833 } | 825 } |
834 klass = klass.SuperClass(); | 826 klass = klass.SuperClass(); |
835 } | 827 } |
836 | 828 |
837 if (!function.IsNull() && | |
838 !function.AreValidArguments(args_desc, NULL)) { | |
839 function = Function::null(); | |
840 } | |
841 | |
842 return ReflectivelyInvokeDynamicFunction(reflectee, | 829 return ReflectivelyInvokeDynamicFunction(reflectee, |
843 function, | 830 function, |
844 function_name, | 831 function_name, |
845 args); | 832 args, |
| 833 args_descriptor); |
846 } | 834 } |
847 | 835 |
848 | 836 |
849 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) { | 837 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) { |
850 // Argument 0 is the mirror, which is unused by the native. It exists | 838 // Argument 0 is the mirror, which is unused by the native. It exists |
851 // because this native is an instance method in order to be polymorphic | 839 // because this native is an instance method in order to be polymorphic |
852 // with its cousins. | 840 // with its cousins. |
853 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); | 841 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); |
854 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); | 842 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); |
855 | 843 |
856 // Every instance field has a getter Function. Try to find the | 844 // Every instance field has a getter Function. Try to find the |
857 // getter in any superclass and use that function to access the | 845 // getter in any superclass and use that function to access the |
858 // field. | 846 // field. |
859 // NB: We do not use Resolver::ResolveDynamic because we want to find private | 847 // NB: We do not use Resolver::ResolveDynamic because we want to find private |
860 // members. | 848 // members. |
861 Class& klass = Class::Handle(reflectee.clazz()); | 849 Class& klass = Class::Handle(reflectee.clazz()); |
862 String& internal_getter_name = String::Handle(Field::GetterName(getter_name)); | 850 String& internal_getter_name = String::Handle(Field::GetterName(getter_name)); |
863 Function& getter = Function::Handle(); | 851 Function& getter = Function::Handle(); |
864 while (!klass.IsNull()) { | 852 while (!klass.IsNull()) { |
865 getter = klass.LookupDynamicFunctionAllowPrivate(internal_getter_name); | 853 getter = klass.LookupDynamicFunctionAllowPrivate(internal_getter_name); |
866 if (!getter.IsNull()) { | 854 if (!getter.IsNull()) { |
867 break; | 855 break; |
868 } | 856 } |
869 klass = klass.SuperClass(); | 857 klass = klass.SuperClass(); |
870 } | 858 } |
871 | 859 |
872 const int kNumArgs = 1; | 860 const int kNumArgs = 1; |
873 const Array& args = Array::Handle(Array::New(kNumArgs)); | 861 const Array& args = Array::Handle(Array::New(kNumArgs)); |
874 args.SetAt(0, reflectee); | 862 args.SetAt(0, reflectee); |
| 863 const Array& args_descriptor = |
| 864 Array::Handle(ArgumentsDescriptor::New(args.Length())); |
875 | 865 |
876 return ReflectivelyInvokeDynamicFunction(reflectee, | 866 return ReflectivelyInvokeDynamicFunction(reflectee, |
877 getter, | 867 getter, |
878 internal_getter_name, | 868 internal_getter_name, |
879 args); | 869 args, |
| 870 args_descriptor); |
880 } | 871 } |
881 | 872 |
882 | 873 |
883 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { | 874 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { |
884 // Argument 0 is the mirror, which is unused by the native. It exists | 875 // Argument 0 is the mirror, which is unused by the native. It exists |
885 // because this native is an instance method in order to be polymorphic | 876 // because this native is an instance method in order to be polymorphic |
886 // with its cousins. | 877 // with its cousins. |
887 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); | 878 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); |
888 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); | 879 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); |
889 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); | 880 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); |
(...skipping 20 matching lines...) Expand all Loading... |
910 break; | 901 break; |
911 } | 902 } |
912 klass = klass.SuperClass(); | 903 klass = klass.SuperClass(); |
913 } | 904 } |
914 | 905 |
915 // Invoke the setter and return the result. | 906 // Invoke the setter and return the result. |
916 const int kNumArgs = 2; | 907 const int kNumArgs = 2; |
917 const Array& args = Array::Handle(Array::New(kNumArgs)); | 908 const Array& args = Array::Handle(Array::New(kNumArgs)); |
918 args.SetAt(0, reflectee); | 909 args.SetAt(0, reflectee); |
919 args.SetAt(1, value); | 910 args.SetAt(1, value); |
| 911 const Array& args_descriptor = |
| 912 Array::Handle(ArgumentsDescriptor::New(args.Length())); |
920 | 913 |
921 return ReflectivelyInvokeDynamicFunction(reflectee, | 914 return ReflectivelyInvokeDynamicFunction(reflectee, |
922 setter, | 915 setter, |
923 internal_setter_name, | 916 internal_setter_name, |
924 args); | 917 args, |
| 918 args_descriptor); |
925 } | 919 } |
926 | 920 |
927 | 921 |
928 DEFINE_NATIVE_ENTRY(ClosureMirror_apply, 2) { | 922 DEFINE_NATIVE_ENTRY(ClosureMirror_apply, 3) { |
929 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); | 923 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); |
930 ASSERT(!closure.IsNull() && closure.IsCallable(NULL, NULL)); | 924 ASSERT(!closure.IsNull() && closure.IsCallable(NULL, NULL)); |
| 925 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(1)); |
| 926 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(2)); |
931 | 927 |
932 const Array& positional_args = | 928 const Array& args_descriptor = |
933 Array::CheckedHandle(arguments->NativeArgAt(1)); | 929 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
934 intptr_t number_of_arguments = positional_args.Length(); | |
935 | 930 |
936 // Set up arguments to include the closure as the first argument. | 931 const Object& result = |
937 const Array& args = Array::Handle(Array::New(number_of_arguments + 1)); | 932 Object::Handle(DartEntry::InvokeClosure(args, args_descriptor)); |
938 Object& obj = Object::Handle(); | 933 if (result.IsError()) { |
939 args.SetAt(0, closure); | 934 ThrowInvokeError(Error::Cast(result)); |
940 for (int i = 0; i < number_of_arguments; i++) { | |
941 obj = positional_args.At(i); | |
942 args.SetAt(i + 1, obj); | |
943 } | |
944 | |
945 obj = DartEntry::InvokeClosure(args); | |
946 if (obj.IsError()) { | |
947 ThrowInvokeError(Error::Cast(obj)); | |
948 UNREACHABLE(); | 935 UNREACHABLE(); |
949 } | 936 } |
950 return obj.raw(); | 937 return result.raw(); |
951 } | 938 } |
952 | 939 |
953 | 940 |
954 DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) { | 941 DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) { |
955 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); | 942 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); |
956 ASSERT(!closure.IsNull()); | 943 ASSERT(!closure.IsNull()); |
957 | 944 |
958 Function& function = Function::Handle(); | 945 Function& function = Function::Handle(); |
959 bool callable = closure.IsCallable(&function, NULL); | 946 bool callable = closure.IsCallable(&function, NULL); |
960 ASSERT(callable); | 947 ASSERT(callable); |
961 | 948 |
962 return CreateMethodMirror(function, Instance::null_instance()); | 949 return CreateMethodMirror(function, Instance::null_instance()); |
963 } | 950 } |
964 | 951 |
965 | 952 |
966 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) { | 953 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 5) { |
967 // Argument 0 is the mirror, which is unused by the native. It exists | 954 // Argument 0 is the mirror, which is unused by the native. It exists |
968 // because this native is an instance method in order to be polymorphic | 955 // because this native is an instance method in order to be polymorphic |
969 // with its cousins. | 956 // with its cousins. |
970 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 957 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
971 const Class& klass = Class::Handle(ref.GetClassReferent()); | 958 const Class& klass = Class::Handle(ref.GetClassReferent()); |
972 GET_NON_NULL_NATIVE_ARGUMENT( | 959 GET_NON_NULL_NATIVE_ARGUMENT( |
973 String, function_name, arguments->NativeArgAt(2)); | 960 String, function_name, arguments->NativeArgAt(2)); |
974 GET_NON_NULL_NATIVE_ARGUMENT( | 961 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); |
975 Array, positional_args, arguments->NativeArgAt(3)); | 962 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
976 | 963 |
977 intptr_t number_of_arguments = positional_args.Length(); | 964 const Array& args_descriptor = |
| 965 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
978 | 966 |
979 const Function& function = Function::Handle( | 967 const Function& function = Function::Handle( |
980 klass.LookupStaticFunctionAllowPrivate(function_name)); | 968 klass.LookupStaticFunctionAllowPrivate(function_name)); |
981 | 969 |
982 if (function.IsNull() || | 970 if (function.IsNull() || |
983 !function.AreValidArgumentCounts(number_of_arguments, | 971 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL) || |
984 /* named_args */ 0, | |
985 NULL) || | |
986 !function.is_visible()) { | 972 !function.is_visible()) { |
987 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 973 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), |
988 function_name, | 974 function_name, |
989 function, | 975 function, |
990 InvocationMirror::kStatic, | 976 InvocationMirror::kStatic, |
991 InvocationMirror::kMethod); | 977 InvocationMirror::kMethod); |
992 UNREACHABLE(); | 978 UNREACHABLE(); |
993 } | 979 } |
994 | 980 |
995 Object& result = Object::Handle(DartEntry::InvokeFunction(function, | 981 Object& result = Object::Handle( |
996 positional_args)); | 982 DartEntry::InvokeFunction(function, args, args_descriptor)); |
997 if (result.IsError()) { | 983 if (result.IsError()) { |
998 ThrowInvokeError(Error::Cast(result)); | 984 ThrowInvokeError(Error::Cast(result)); |
999 UNREACHABLE(); | 985 UNREACHABLE(); |
1000 } | 986 } |
1001 return result.raw(); | 987 return result.raw(); |
1002 } | 988 } |
1003 | 989 |
1004 | 990 |
1005 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { | 991 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { |
1006 // Argument 0 is the mirror, which is unused by the native. It exists | 992 // Argument 0 is the mirror, which is unused by the native. It exists |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 setter_name.ToCString())); | 1073 setter_name.ToCString())); |
1088 ThrowMirroredCompilationError(message); | 1074 ThrowMirroredCompilationError(message); |
1089 UNREACHABLE(); | 1075 UNREACHABLE(); |
1090 } | 1076 } |
1091 | 1077 |
1092 field.set_value(value); | 1078 field.set_value(value); |
1093 return value.raw(); | 1079 return value.raw(); |
1094 } | 1080 } |
1095 | 1081 |
1096 | 1082 |
1097 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 3) { | 1083 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) { |
1098 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1084 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
1099 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1085 const Class& klass = Class::Handle(ref.GetClassReferent()); |
1100 GET_NON_NULL_NATIVE_ARGUMENT( | 1086 GET_NON_NULL_NATIVE_ARGUMENT( |
1101 String, constructor_name, arguments->NativeArgAt(1)); | 1087 String, constructor_name, arguments->NativeArgAt(1)); |
1102 GET_NON_NULL_NATIVE_ARGUMENT( | 1088 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(2)); |
1103 Array, positional_args, arguments->NativeArgAt(2)); | 1089 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(3)); |
1104 | |
1105 intptr_t number_of_arguments = positional_args.Length(); | |
1106 | 1090 |
1107 // By convention, the static function implementing a named constructor 'C' | 1091 // By convention, the static function implementing a named constructor 'C' |
1108 // for class 'A' is labeled 'A.C', and the static function implementing the | 1092 // for class 'A' is labeled 'A.C', and the static function implementing the |
1109 // unnamed constructor for class 'A' is labeled 'A.'. | 1093 // unnamed constructor for class 'A' is labeled 'A.'. |
1110 // This convention prevents users from explicitly calling constructors. | 1094 // This convention prevents users from explicitly calling constructors. |
1111 const String& klass_name = String::Handle(klass.Name()); | 1095 const String& klass_name = String::Handle(klass.Name()); |
1112 String& internal_constructor_name = | 1096 String& internal_constructor_name = |
1113 String::Handle(String::Concat(klass_name, Symbols::Dot())); | 1097 String::Handle(String::Concat(klass_name, Symbols::Dot())); |
1114 if (!constructor_name.IsNull()) { | 1098 if (!constructor_name.IsNull()) { |
1115 internal_constructor_name = | 1099 internal_constructor_name = |
1116 String::Concat(internal_constructor_name, constructor_name); | 1100 String::Concat(internal_constructor_name, constructor_name); |
1117 } | 1101 } |
1118 | 1102 |
1119 Function& constructor = Function::Handle( | 1103 Function& lookup_constructor = Function::Handle( |
1120 klass.LookupFunctionAllowPrivate(internal_constructor_name)); | 1104 klass.LookupFunctionAllowPrivate(internal_constructor_name)); |
1121 | 1105 |
1122 if (constructor.IsNull() || | 1106 if (lookup_constructor.IsNull() || |
1123 (!constructor.IsConstructor() && !constructor.IsFactory()) || | 1107 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) || |
1124 !constructor.AreValidArgumentCounts(number_of_arguments + | 1108 !lookup_constructor.is_visible()) { |
1125 constructor.NumImplicitParameters(), | |
1126 /* named args */ 0, | |
1127 NULL) || | |
1128 !constructor.is_visible()) { | |
1129 // Pretend we didn't find the constructor at all when the arity is wrong | 1109 // Pretend we didn't find the constructor at all when the arity is wrong |
1130 // so as to produce the same NoSuchMethodError as the non-reflective case. | 1110 // so as to produce the same NoSuchMethodError as the non-reflective case. |
1131 constructor = Function::null(); | 1111 lookup_constructor = Function::null(); |
1132 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 1112 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), |
1133 internal_constructor_name, | 1113 internal_constructor_name, |
1134 constructor, | 1114 lookup_constructor, |
1135 InvocationMirror::kConstructor, | 1115 InvocationMirror::kConstructor, |
1136 InvocationMirror::kMethod); | 1116 InvocationMirror::kMethod); |
1137 UNREACHABLE(); | 1117 UNREACHABLE(); |
1138 } | 1118 } |
1139 | 1119 |
1140 const Object& result = | 1120 Class& redirected_klass = Class::Handle(klass.raw()); |
1141 Object::Handle(DartEntry::InvokeConstructor(klass, | 1121 Function& redirected_constructor = Function::Handle(lookup_constructor.raw()); |
1142 constructor, | 1122 if (lookup_constructor.IsRedirectingFactory()) { |
1143 positional_args)); | 1123 ClassFinalizer::ResolveRedirectingFactory(klass, lookup_constructor); |
1144 if (result.IsError()) { | 1124 Type& type = Type::Handle(lookup_constructor.RedirectionType()); |
1145 ThrowInvokeError(Error::Cast(result)); | 1125 redirected_constructor = lookup_constructor.RedirectionTarget(); |
| 1126 ASSERT(!redirected_constructor.IsNull()); |
| 1127 redirected_klass = type.type_class(); |
| 1128 } |
| 1129 |
| 1130 const intptr_t num_explicit_args = explicit_args.Length(); |
| 1131 const intptr_t num_implicit_args = |
| 1132 redirected_constructor.IsConstructor() ? 2 : 1; |
| 1133 const Array& args = |
| 1134 Array::Handle(Array::New(num_implicit_args + num_explicit_args)); |
| 1135 |
| 1136 // Copy over the explicit arguments. |
| 1137 Object& explicit_argument = Object::Handle(); |
| 1138 for (int i = 0; i < num_explicit_args; i++) { |
| 1139 explicit_argument = explicit_args.At(i); |
| 1140 args.SetAt(i + num_implicit_args, explicit_argument); |
| 1141 } |
| 1142 |
| 1143 const Array& args_descriptor = |
| 1144 Array::Handle(ArgumentsDescriptor::New(args.Length(), |
| 1145 arg_names)); |
| 1146 |
| 1147 if (!redirected_constructor.AreValidArguments( |
| 1148 ArgumentsDescriptor(args_descriptor), NULL) || |
| 1149 !redirected_constructor.is_visible()) { |
| 1150 // Pretend we didn't find the constructor at all when the arity is wrong |
| 1151 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1152 redirected_constructor = Function::null(); |
| 1153 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), |
| 1154 internal_constructor_name, |
| 1155 redirected_constructor, |
| 1156 InvocationMirror::kConstructor, |
| 1157 InvocationMirror::kMethod); |
1146 UNREACHABLE(); | 1158 UNREACHABLE(); |
1147 } | 1159 } |
| 1160 |
| 1161 Instance& new_object = Instance::Handle(); |
| 1162 if (redirected_constructor.IsConstructor()) { |
| 1163 // Constructors get the uninitialized object and a constructor phase. Note |
| 1164 // we have delayed allocation until after the function type and argument |
| 1165 // matching checks. |
| 1166 new_object = Instance::New(redirected_klass); |
| 1167 args.SetAt(0, new_object); |
| 1168 args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
| 1169 } else { |
| 1170 // Factories get type arguments. |
| 1171 // TODO(12921): Should we allow the user to specify type arguments? Use type |
| 1172 // arguments from the mirror? |
| 1173 args.SetAt(0, Object::null_abstract_type_arguments()); |
| 1174 } |
| 1175 |
| 1176 // Invoke the constructor and return the new object. |
| 1177 const Object& result = |
| 1178 Object::Handle(DartEntry::InvokeFunction(redirected_constructor, |
| 1179 args, |
| 1180 args_descriptor)); |
| 1181 if (result.IsError()) { |
| 1182 return result.raw(); |
| 1183 } |
| 1184 |
1148 // Factories may return null. | 1185 // Factories may return null. |
1149 ASSERT(result.IsInstance() || result.IsNull()); | 1186 ASSERT(result.IsInstance() || result.IsNull()); |
1150 return result.raw(); | 1187 |
| 1188 if (redirected_constructor.IsConstructor()) { |
| 1189 return new_object.raw(); |
| 1190 } else { |
| 1191 return result.raw(); |
| 1192 } |
1151 } | 1193 } |
1152 | 1194 |
1153 | 1195 |
1154 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) { | 1196 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) { |
1155 // Argument 0 is the mirror, which is unused by the native. It exists | 1197 // Argument 0 is the mirror, which is unused by the native. It exists |
1156 // because this native is an instance method in order to be polymorphic | 1198 // because this native is an instance method in order to be polymorphic |
1157 // with its cousins. | 1199 // with its cousins. |
1158 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1200 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
1159 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1201 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
1160 GET_NON_NULL_NATIVE_ARGUMENT( | 1202 GET_NON_NULL_NATIVE_ARGUMENT( |
1161 String, function_name, arguments->NativeArgAt(2)); | 1203 String, function_name, arguments->NativeArgAt(2)); |
1162 GET_NON_NULL_NATIVE_ARGUMENT( | 1204 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); |
1163 Array, positional_args, arguments->NativeArgAt(3)); | 1205 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
1164 | 1206 |
1165 intptr_t number_of_arguments = positional_args.Length(); | 1207 const Array& args_descriptor = |
| 1208 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
1166 | 1209 |
1167 String& ambiguity_error_msg = String::Handle(isolate); | 1210 String& ambiguity_error_msg = String::Handle(isolate); |
1168 const Function& function = Function::Handle( | 1211 const Function& function = Function::Handle( |
1169 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); | 1212 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); |
1170 | 1213 |
1171 if (function.IsNull() && !ambiguity_error_msg.IsNull()) { | 1214 if (function.IsNull() && !ambiguity_error_msg.IsNull()) { |
1172 ThrowMirroredCompilationError(ambiguity_error_msg); | 1215 ThrowMirroredCompilationError(ambiguity_error_msg); |
1173 UNREACHABLE(); | 1216 UNREACHABLE(); |
1174 } | 1217 } |
1175 | 1218 |
1176 if (function.IsNull() || | 1219 if (function.IsNull() || |
1177 !function.AreValidArgumentCounts(number_of_arguments, | 1220 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL) || |
1178 0, | 1221 !function.is_visible()) { |
1179 NULL) || | |
1180 !function.is_visible()) { | |
1181 ThrowNoSuchMethod(Instance::null_instance(), | 1222 ThrowNoSuchMethod(Instance::null_instance(), |
1182 function_name, | 1223 function_name, |
1183 function, | 1224 function, |
1184 InvocationMirror::kTopLevel, | 1225 InvocationMirror::kTopLevel, |
1185 InvocationMirror::kMethod); | 1226 InvocationMirror::kMethod); |
1186 UNREACHABLE(); | 1227 UNREACHABLE(); |
1187 } | 1228 } |
1188 | 1229 |
1189 const Object& result = Object::Handle( | 1230 const Object& result = Object::Handle( |
1190 DartEntry::InvokeFunction(function, positional_args)); | 1231 DartEntry::InvokeFunction(function, args, args_descriptor)); |
1191 if (result.IsError()) { | 1232 if (result.IsError()) { |
1192 ThrowInvokeError(Error::Cast(result)); | 1233 ThrowInvokeError(Error::Cast(result)); |
1193 UNREACHABLE(); | 1234 UNREACHABLE(); |
1194 } | 1235 } |
1195 return result.raw(); | 1236 return result.raw(); |
1196 } | 1237 } |
1197 | 1238 |
1198 | 1239 |
1199 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) { | 1240 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) { |
1200 // Argument 0 is the mirror, which is unused by the native. It exists | 1241 // Argument 0 is the mirror, which is unused by the native. It exists |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 } | 1439 } |
1399 | 1440 |
1400 | 1441 |
1401 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1442 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
1402 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1443 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
1403 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1444 const Field& field = Field::Handle(ref.GetFieldReferent()); |
1404 return field.type(); | 1445 return field.type(); |
1405 } | 1446 } |
1406 | 1447 |
1407 } // namespace dart | 1448 } // namespace dart |
OLD | NEW |