| 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 |