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

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: rebase, mark failure on dart2js 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 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 720
721 721
722 DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) { 722 DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) {
723 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); 723 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
724 return param.bound(); 724 return param.bound();
725 } 725 }
726 726
727 727
728 // Invoke the function, or noSuchMethod if it is null. Propagate any unhandled 728 // Invoke the function, or noSuchMethod if it is null. Propagate any unhandled
729 // exceptions. Wrap and propagate any compilation errors. 729 // exceptions. Wrap and propagate any compilation errors.
730 static RawObject* ReflectivelyInvokeDynamicFunction(const Instance& receiver, 730 static RawObject* ReflectivelyInvokeDynamicFunction(
731 const Function& function, 731 const Instance& receiver,
732 const String& target_name, 732 const Function& function,
733 const Array& arguments) { 733 const String& target_name,
734 const Array& args,
735 const Array& args_descriptor) {
734 // Note "arguments" is already the internal arguments with the receiver as 736 // Note "arguments" is already the internal arguments with the receiver as
regis 2013/08/29 23:31:32 You mean "args" instead of "arguments".
735 // the first element. 737 // the first element.
736 Object& result = Object::Handle(); 738 Object& result = Object::Handle();
737 if (function.IsNull() || !function.is_visible()) { 739 if (function.IsNull() ||
738 const Array& arguments_descriptor = 740 !function.is_visible() ||
739 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); 741 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL)) {
740 result = DartEntry::InvokeNoSuchMethod(receiver, 742 result = DartEntry::InvokeNoSuchMethod(receiver,
741 target_name, 743 target_name,
742 arguments, 744 args,
743 arguments_descriptor); 745 args_descriptor);
744 } else { 746 } else {
745 result = DartEntry::InvokeFunction(function, arguments); 747 result = DartEntry::InvokeFunction(function,
748 args,
749 args_descriptor);
746 } 750 }
747 751
748 if (result.IsError()) { 752 if (result.IsError()) {
749 ThrowInvokeError(Error::Cast(result)); 753 ThrowInvokeError(Error::Cast(result));
750 UNREACHABLE(); 754 UNREACHABLE();
751 } 755 }
752 return result.raw(); 756 return result.raw();
753 } 757 }
754 758
755 759 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) {
756 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 4) {
757 // Argument 0 is the mirror, which is unused by the native. It exists 760 // Argument 0 is the mirror, which is unused by the native. It exists
758 // because this native is an instance method in order to be polymorphic 761 // because this native is an instance method in order to be polymorphic
759 // with its cousins. 762 // with its cousins.
760 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); 763 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1));
761 GET_NON_NULL_NATIVE_ARGUMENT( 764 GET_NON_NULL_NATIVE_ARGUMENT(
762 String, function_name, arguments->NativeArgAt(2)); 765 String, function_name, arguments->NativeArgAt(2));
763 GET_NON_NULL_NATIVE_ARGUMENT( 766 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3));
764 Array, positional_args, arguments->NativeArgAt(3)); 767 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
765 768
766 intptr_t number_of_arguments = positional_args.Length(); 769 const Array& args_descriptor =
767 770 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names));
768 const Array& args =
769 Array::Handle(Array::New(number_of_arguments + 1)); // Plus receiver.
770 Object& arg = Object::Handle();
771 args.SetAt(0, reflectee);
772 for (int i = 0; i < number_of_arguments; i++) {
773 arg = positional_args.At(i);
774 args.SetAt(i + 1, arg); // Plus receiver.
775 }
776
777 ArgumentsDescriptor args_desc(
778 Array::Handle(ArgumentsDescriptor::New(args.Length())));
779 771
780 Class& klass = Class::Handle(reflectee.clazz()); 772 Class& klass = Class::Handle(reflectee.clazz());
781 Function& function = Function::Handle(); 773 Function& function = Function::Handle();
782 while (!klass.IsNull()) { 774 while (!klass.IsNull()) {
783 function = klass.LookupDynamicFunctionAllowPrivate(function_name); 775 function = klass.LookupDynamicFunctionAllowPrivate(function_name);
784 if (!function.IsNull()) { 776 if (!function.IsNull()) {
785 break; 777 break;
786 } 778 }
787 klass = klass.SuperClass(); 779 klass = klass.SuperClass();
788 } 780 }
789 781
790 if (!function.IsNull() &&
791 !function.AreValidArguments(args_desc, NULL)) {
792 function = Function::null();
793 }
794
795 return ReflectivelyInvokeDynamicFunction(reflectee, 782 return ReflectivelyInvokeDynamicFunction(reflectee,
796 function, 783 function,
797 function_name, 784 function_name,
798 args); 785 args,
786 args_descriptor);
799 } 787 }
800 788
801 789
802 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) { 790 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) {
803 // Argument 0 is the mirror, which is unused by the native. It exists 791 // Argument 0 is the mirror, which is unused by the native. It exists
804 // because this native is an instance method in order to be polymorphic 792 // because this native is an instance method in order to be polymorphic
805 // with its cousins. 793 // with its cousins.
806 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); 794 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1));
807 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); 795 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2));
808 796
809 // Every instance field has a getter Function. Try to find the 797 // Every instance field has a getter Function. Try to find the
810 // getter in any superclass and use that function to access the 798 // getter in any superclass and use that function to access the
811 // field. 799 // field.
812 // NB: We do not use Resolver::ResolveDynamic because we want to find private 800 // NB: We do not use Resolver::ResolveDynamic because we want to find private
813 // members. 801 // members.
814 Class& klass = Class::Handle(reflectee.clazz()); 802 Class& klass = Class::Handle(reflectee.clazz());
815 String& internal_getter_name = String::Handle(Field::GetterName(getter_name)); 803 String& internal_getter_name = String::Handle(Field::GetterName(getter_name));
816 Function& getter = Function::Handle(); 804 Function& getter = Function::Handle();
817 while (!klass.IsNull()) { 805 while (!klass.IsNull()) {
818 getter = klass.LookupDynamicFunctionAllowPrivate(internal_getter_name); 806 getter = klass.LookupDynamicFunctionAllowPrivate(internal_getter_name);
819 if (!getter.IsNull()) { 807 if (!getter.IsNull()) {
820 break; 808 break;
821 } 809 }
822 klass = klass.SuperClass(); 810 klass = klass.SuperClass();
823 } 811 }
824 812
825 const int kNumArgs = 1; 813 const int kNumArgs = 1;
826 const Array& args = Array::Handle(Array::New(kNumArgs)); 814 const Array& args = Array::Handle(Array::New(kNumArgs));
827 args.SetAt(0, reflectee); 815 args.SetAt(0, reflectee);
816 const Array& args_descriptor =
817 Array::Handle(ArgumentsDescriptor::New(args.Length()));
828 818
829 return ReflectivelyInvokeDynamicFunction(reflectee, 819 return ReflectivelyInvokeDynamicFunction(reflectee,
830 getter, 820 getter,
831 internal_getter_name, 821 internal_getter_name,
832 args); 822 args,
823 args_descriptor);
833 } 824 }
834 825
835 826
836 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { 827 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) {
837 // Argument 0 is the mirror, which is unused by the native. It exists 828 // Argument 0 is the mirror, which is unused by the native. It exists
838 // because this native is an instance method in order to be polymorphic 829 // because this native is an instance method in order to be polymorphic
839 // with its cousins. 830 // with its cousins.
840 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); 831 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1));
841 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); 832 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2));
842 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); 833 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3));
(...skipping 20 matching lines...) Expand all
863 break; 854 break;
864 } 855 }
865 klass = klass.SuperClass(); 856 klass = klass.SuperClass();
866 } 857 }
867 858
868 // Invoke the setter and return the result. 859 // Invoke the setter and return the result.
869 const int kNumArgs = 2; 860 const int kNumArgs = 2;
870 const Array& args = Array::Handle(Array::New(kNumArgs)); 861 const Array& args = Array::Handle(Array::New(kNumArgs));
871 args.SetAt(0, reflectee); 862 args.SetAt(0, reflectee);
872 args.SetAt(1, value); 863 args.SetAt(1, value);
864 const Array& args_descriptor =
865 Array::Handle(ArgumentsDescriptor::New(args.Length()));
873 866
874 return ReflectivelyInvokeDynamicFunction(reflectee, 867 return ReflectivelyInvokeDynamicFunction(reflectee,
875 setter, 868 setter,
876 internal_setter_name, 869 internal_setter_name,
877 args); 870 args,
871 args_descriptor);
878 } 872 }
879 873
880 874
881 DEFINE_NATIVE_ENTRY(ClosureMirror_apply, 2) { 875 // If we get to a place where closures have a call method, we can just use
876 // InstanceMirror_invoke.
regis 2013/08/29 23:31:32 This kind of comment should be preceded by a TODO,
877 DEFINE_NATIVE_ENTRY(ClosureMirror_apply, 3) {
882 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); 878 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
883 ASSERT(!closure.IsNull() && closure.IsCallable(NULL, NULL)); 879 ASSERT(!closure.IsNull() && closure.IsCallable(NULL, NULL));
880 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(1));
881 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(2));
884 882
885 const Array& positional_args = 883 const Array& args_descriptor =
886 Array::CheckedHandle(arguments->NativeArgAt(1)); 884 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names));
887 intptr_t number_of_arguments = positional_args.Length();
888 885
889 // Set up arguments to include the closure as the first argument. 886 const Object& result =
890 const Array& args = Array::Handle(Array::New(number_of_arguments + 1)); 887 Object::Handle(DartEntry::InvokeClosure(args, args_descriptor));
891 Object& obj = Object::Handle(); 888 if (result.IsError()) {
892 args.SetAt(0, closure); 889 ThrowInvokeError(Error::Cast(result));
893 for (int i = 0; i < number_of_arguments; i++) {
894 obj = positional_args.At(i);
895 args.SetAt(i + 1, obj);
896 }
897
898 obj = DartEntry::InvokeClosure(args);
899 if (obj.IsError()) {
900 ThrowInvokeError(Error::Cast(obj));
901 UNREACHABLE(); 890 UNREACHABLE();
902 } 891 }
903 return obj.raw(); 892 return result.raw();
904 } 893 }
905 894
906 895
907 DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) { 896 DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) {
908 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); 897 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
909 ASSERT(!closure.IsNull()); 898 ASSERT(!closure.IsNull());
910 899
911 Function& function = Function::Handle(); 900 Function& function = Function::Handle();
912 bool callable = closure.IsCallable(&function, NULL); 901 bool callable = closure.IsCallable(&function, NULL);
913 ASSERT(callable); 902 ASSERT(callable);
914 903
915 return CreateMethodMirror(function, Instance::null_instance()); 904 return CreateMethodMirror(function, Instance::null_instance());
916 } 905 }
917 906
918 907
919 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) { 908 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 5) {
920 // Argument 0 is the mirror, which is unused by the native. It exists 909 // Argument 0 is the mirror, which is unused by the native. It exists
921 // because this native is an instance method in order to be polymorphic 910 // because this native is an instance method in order to be polymorphic
922 // with its cousins. 911 // with its cousins.
923 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); 912 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
924 const Class& klass = Class::Handle(ref.GetClassReferent()); 913 const Class& klass = Class::Handle(ref.GetClassReferent());
925 GET_NON_NULL_NATIVE_ARGUMENT( 914 GET_NON_NULL_NATIVE_ARGUMENT(
926 String, function_name, arguments->NativeArgAt(2)); 915 String, function_name, arguments->NativeArgAt(2));
927 GET_NON_NULL_NATIVE_ARGUMENT( 916 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3));
928 Array, positional_args, arguments->NativeArgAt(3)); 917 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
929 918
930 intptr_t number_of_arguments = positional_args.Length(); 919 const Array& args_descriptor =
920 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names));
931 921
932 const Function& function = Function::Handle( 922 const Function& function = Function::Handle(
933 klass.LookupStaticFunctionAllowPrivate(function_name)); 923 klass.LookupStaticFunctionAllowPrivate(function_name));
934 924
935 if (function.IsNull() || 925 if (function.IsNull() ||
936 !function.AreValidArgumentCounts(number_of_arguments, 926 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL) ||
937 /* named_args */ 0,
938 NULL) ||
939 !function.is_visible()) { 927 !function.is_visible()) {
940 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), 928 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
941 function_name, 929 function_name,
942 function, 930 function,
943 InvocationMirror::kStatic, 931 InvocationMirror::kStatic,
944 InvocationMirror::kMethod); 932 InvocationMirror::kMethod);
945 UNREACHABLE(); 933 UNREACHABLE();
946 } 934 }
947 935
948 Object& result = Object::Handle(DartEntry::InvokeFunction(function, 936 Object& result = Object::Handle(
949 positional_args)); 937 DartEntry::InvokeFunction(function, args, args_descriptor));
950 if (result.IsError()) { 938 if (result.IsError()) {
951 ThrowInvokeError(Error::Cast(result)); 939 ThrowInvokeError(Error::Cast(result));
952 UNREACHABLE(); 940 UNREACHABLE();
953 } 941 }
954 return result.raw(); 942 return result.raw();
955 } 943 }
956 944
957 945
958 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { 946 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) {
959 // Argument 0 is the mirror, which is unused by the native. It exists 947 // 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
1040 setter_name.ToCString())); 1028 setter_name.ToCString()));
1041 ThrowMirroredCompilationError(message); 1029 ThrowMirroredCompilationError(message);
1042 UNREACHABLE(); 1030 UNREACHABLE();
1043 } 1031 }
1044 1032
1045 field.set_value(value); 1033 field.set_value(value);
1046 return value.raw(); 1034 return value.raw();
1047 } 1035 }
1048 1036
1049 1037
1050 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 3) { 1038 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) {
1051 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 1039 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1052 const Class& klass = Class::Handle(ref.GetClassReferent()); 1040 const Class& klass = Class::Handle(ref.GetClassReferent());
1053 GET_NON_NULL_NATIVE_ARGUMENT( 1041 GET_NON_NULL_NATIVE_ARGUMENT(
1054 String, constructor_name, arguments->NativeArgAt(1)); 1042 String, constructor_name, arguments->NativeArgAt(1));
1055 GET_NON_NULL_NATIVE_ARGUMENT( 1043 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(2));
1056 Array, positional_args, arguments->NativeArgAt(2)); 1044 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(3));
1057
1058 intptr_t number_of_arguments = positional_args.Length();
1059 1045
1060 // By convention, the static function implementing a named constructor 'C' 1046 // By convention, the static function implementing a named constructor 'C'
1061 // for class 'A' is labeled 'A.C', and the static function implementing the 1047 // for class 'A' is labeled 'A.C', and the static function implementing the
1062 // unnamed constructor for class 'A' is labeled 'A.'. 1048 // unnamed constructor for class 'A' is labeled 'A.'.
1063 // This convention prevents users from explicitly calling constructors. 1049 // This convention prevents users from explicitly calling constructors.
1064 const String& klass_name = String::Handle(klass.Name()); 1050 const String& klass_name = String::Handle(klass.Name());
1065 String& internal_constructor_name = 1051 String& internal_constructor_name =
1066 String::Handle(String::Concat(klass_name, Symbols::Dot())); 1052 String::Handle(String::Concat(klass_name, Symbols::Dot()));
1067 if (!constructor_name.IsNull()) { 1053 if (!constructor_name.IsNull()) {
1068 internal_constructor_name = 1054 internal_constructor_name =
1069 String::Concat(internal_constructor_name, constructor_name); 1055 String::Concat(internal_constructor_name, constructor_name);
1070 } 1056 }
1071 1057
1072 Function& constructor = Function::Handle( 1058 Function& lookup_constructor = Function::Handle(
1073 klass.LookupFunctionAllowPrivate(internal_constructor_name)); 1059 klass.LookupFunctionAllowPrivate(internal_constructor_name));
1074 1060
1075 if (constructor.IsNull() || 1061 if (lookup_constructor.IsNull() ||
1076 (!constructor.IsConstructor() && !constructor.IsFactory()) || 1062 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) ||
1077 !constructor.AreValidArgumentCounts(number_of_arguments + 1063 !lookup_constructor.is_visible()) {
1078 constructor.NumImplicitParameters(),
1079 /* named args */ 0,
1080 NULL) ||
1081 !constructor.is_visible()) {
1082 // Pretend we didn't find the constructor at all when the arity is wrong 1064 // Pretend we didn't find the constructor at all when the arity is wrong
1083 // so as to produce the same NoSuchMethodError as the non-reflective case. 1065 // so as to produce the same NoSuchMethodError as the non-reflective case.
1084 constructor = Function::null(); 1066 lookup_constructor = Function::null();
1085 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), 1067 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
1086 internal_constructor_name, 1068 internal_constructor_name,
1087 constructor, 1069 lookup_constructor,
1088 InvocationMirror::kConstructor, 1070 InvocationMirror::kConstructor,
1089 InvocationMirror::kMethod); 1071 InvocationMirror::kMethod);
1090 UNREACHABLE(); 1072 UNREACHABLE();
1091 } 1073 }
1092 1074
1093 const Object& result = 1075 Class& redirected_klass = Class::Handle(klass.raw());
1094 Object::Handle(DartEntry::InvokeConstructor(klass, 1076 Function& redirected_constructor = Function::Handle(lookup_constructor.raw());
1095 constructor, 1077 if (lookup_constructor.IsRedirectingFactory()) {
1096 positional_args)); 1078 ClassFinalizer::ResolveRedirectingFactory(klass, lookup_constructor);
1097 if (result.IsError()) { 1079 Type& type = Type::Handle(lookup_constructor.RedirectionType());
1098 ThrowInvokeError(Error::Cast(result)); 1080 redirected_constructor = lookup_constructor.RedirectionTarget();
1081 ASSERT(!redirected_constructor.IsNull());
1082 redirected_klass = type.type_class();
1083 }
1084
1085 const intptr_t num_explicit_args = explicit_args.Length();
1086 const intptr_t num_implicit_args =
1087 redirected_constructor.IsConstructor() ? 2 : 1;
1088 const Array& args =
1089 Array::Handle(Array::New(num_implicit_args + num_explicit_args));
1090
1091 // Copy over the explicit arguments.
1092 Object& explicit_argument = Object::Handle();
1093 for (int i = 0; i < num_explicit_args; i++) {
1094 explicit_argument = explicit_args.At(i);
1095 args.SetAt(i + num_implicit_args, explicit_argument);
1096 }
1097
1098 const Array& args_descriptor =
1099 Array::Handle(ArgumentsDescriptor::New(args.Length(),
1100 arg_names));
1101
1102 if (!redirected_constructor.AreValidArguments(
1103 ArgumentsDescriptor(args_descriptor), NULL) ||
1104 !redirected_constructor.is_visible()) {
1105 // Pretend we didn't find the constructor at all when the arity is wrong
1106 // so as to produce the same NoSuchMethodError as the non-reflective case.
1107 redirected_constructor = Function::null();
1108 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
1109 internal_constructor_name,
1110 redirected_constructor,
1111 InvocationMirror::kConstructor,
1112 InvocationMirror::kMethod);
1099 UNREACHABLE(); 1113 UNREACHABLE();
1100 } 1114 }
1115
1116 Instance& new_object = Instance::Handle();
1117 if (redirected_constructor.IsConstructor()) {
1118 // Constructors get the uninitialized object and a constructor phase. Note
1119 // we have delayed allocation until after the function type and argument
1120 // matching checks.
1121 new_object = Instance::New(redirected_klass);
1122 args.SetAt(0, new_object);
1123 args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
1124 } else {
1125 // Factories get type arguments. Should we allow the user to specify type
1126 // arguments?
regis 2013/08/29 23:31:32 This should be a TODO too, but not TODO(iposva) fo
1127 args.SetAt(0, TypeArguments::Handle());
regis 2013/08/29 23:31:32 I think we preallocate such a null handle in objec
1128 }
1129
1130 // Invoke the constructor and return the new object.
1131 const Object& result =
1132 Object::Handle(DartEntry::InvokeFunction(redirected_constructor,
1133 args,
1134 args_descriptor));
1135 if (result.IsError()) {
1136 return result.raw();
1137 }
1138
1101 // Factories may return null. 1139 // Factories may return null.
1102 ASSERT(result.IsInstance() || result.IsNull()); 1140 ASSERT(result.IsInstance() || result.IsNull());
1103 return result.raw(); 1141
1142 if (redirected_constructor.IsConstructor()) {
1143 return new_object.raw();
1144 } else {
1145 return result.raw();
1146 }
1104 } 1147 }
1105 1148
1106 1149
1107 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) { 1150 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) {
1108 // Argument 0 is the mirror, which is unused by the native. It exists 1151 // Argument 0 is the mirror, which is unused by the native. It exists
1109 // because this native is an instance method in order to be polymorphic 1152 // because this native is an instance method in order to be polymorphic
1110 // with its cousins. 1153 // with its cousins.
1111 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); 1154 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1112 const Library& library = Library::Handle(ref.GetLibraryReferent()); 1155 const Library& library = Library::Handle(ref.GetLibraryReferent());
1113 GET_NON_NULL_NATIVE_ARGUMENT( 1156 GET_NON_NULL_NATIVE_ARGUMENT(
1114 String, function_name, arguments->NativeArgAt(2)); 1157 String, function_name, arguments->NativeArgAt(2));
1115 GET_NON_NULL_NATIVE_ARGUMENT( 1158 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3));
1116 Array, positional_args, arguments->NativeArgAt(3)); 1159 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
1117 1160
1118 intptr_t number_of_arguments = positional_args.Length(); 1161 const Array& args_descriptor =
1162 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names));
1119 1163
1120 String& ambiguity_error_msg = String::Handle(isolate); 1164 String& ambiguity_error_msg = String::Handle(isolate);
1121 const Function& function = Function::Handle( 1165 const Function& function = Function::Handle(
1122 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); 1166 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg));
1123 1167
1124 if (function.IsNull() && !ambiguity_error_msg.IsNull()) { 1168 if (function.IsNull() && !ambiguity_error_msg.IsNull()) {
1125 ThrowMirroredCompilationError(ambiguity_error_msg); 1169 ThrowMirroredCompilationError(ambiguity_error_msg);
1126 UNREACHABLE(); 1170 UNREACHABLE();
1127 } 1171 }
1128 1172
1129 if (function.IsNull() || 1173 if (function.IsNull() ||
1130 !function.AreValidArgumentCounts(number_of_arguments, 1174 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL) ||
1131 0, 1175 !function.is_visible()) {
1132 NULL) ||
1133 !function.is_visible()) {
1134 ThrowNoSuchMethod(Instance::null_instance(), 1176 ThrowNoSuchMethod(Instance::null_instance(),
1135 function_name, 1177 function_name,
1136 function, 1178 function,
1137 InvocationMirror::kTopLevel, 1179 InvocationMirror::kTopLevel,
1138 InvocationMirror::kMethod); 1180 InvocationMirror::kMethod);
1139 UNREACHABLE(); 1181 UNREACHABLE();
1140 } 1182 }
1141 1183
1142 const Object& result = Object::Handle( 1184 const Object& result = Object::Handle(
1143 DartEntry::InvokeFunction(function, positional_args)); 1185 DartEntry::InvokeFunction(function, args, args_descriptor));
1144 if (result.IsError()) { 1186 if (result.IsError()) {
1145 ThrowInvokeError(Error::Cast(result)); 1187 ThrowInvokeError(Error::Cast(result));
1146 UNREACHABLE(); 1188 UNREACHABLE();
1147 } 1189 }
1148 return result.raw(); 1190 return result.raw();
1149 } 1191 }
1150 1192
1151 1193
1152 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) { 1194 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) {
1153 // Argument 0 is the mirror, which is unused by the native. It exists 1195 // Argument 0 is the mirror, which is unused by the native. It exists
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 } 1389 }
1348 1390
1349 1391
1350 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { 1392 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) {
1351 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 1393 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1352 const Field& field = Field::Handle(ref.GetFieldReferent()); 1394 const Field& field = Field::Handle(ref.GetFieldReferent());
1353 return field.type(); 1395 return field.type();
1354 } 1396 }
1355 1397
1356 } // namespace dart 1398 } // 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