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 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |