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

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

Issue 23604003: Support named and optional positional arguments in reflective invocation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix wrong variable in async unwrap error message Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('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/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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698