Chromium Code Reviews| 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 |