| 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 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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( | 777 static RawObject* ReflectivelyInvokeDynamicFunction( |
| 778 const Instance& receiver, | 778 const Instance& receiver, |
| 779 const Function& function, | 779 const Function& function, |
| 780 const String& target_name, | 780 const String& target_name, |
| 781 const Array& args, | 781 const Array& args, |
| 782 const Array& args_descriptor) { | 782 const Array& args_descriptor_array) { |
| 783 // Note "args" is already the internal arguments with the receiver as the | 783 // Note "args" is already the internal arguments with the receiver as the |
| 784 // first element. | 784 // first element. |
| 785 Object& result = Object::Handle(); | 785 Object& result = Object::Handle(); |
| 786 |
| 787 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 786 if (function.IsNull() || | 788 if (function.IsNull() || |
| 787 !function.is_visible() || | 789 !function.is_visible() || |
| 788 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL)) { | 790 !function.AreValidArguments(args_descriptor, NULL)) { |
| 789 result = DartEntry::InvokeNoSuchMethod(receiver, | 791 result = DartEntry::InvokeNoSuchMethod(receiver, |
| 790 target_name, | 792 target_name, |
| 791 args, | 793 args, |
| 792 args_descriptor); | 794 args_descriptor_array); |
| 793 } else { | 795 } else { |
| 794 result = DartEntry::InvokeFunction(function, | 796 result = DartEntry::InvokeFunction(function, |
| 795 args, | 797 args, |
| 796 args_descriptor); | 798 args_descriptor_array); |
| 797 } | 799 } |
| 798 | 800 |
| 799 if (result.IsError()) { | 801 if (result.IsError()) { |
| 800 ThrowInvokeError(Error::Cast(result)); | 802 ThrowInvokeError(Error::Cast(result)); |
| 801 UNREACHABLE(); | 803 UNREACHABLE(); |
| 802 } | 804 } |
| 803 return result.raw(); | 805 return result.raw(); |
| 804 } | 806 } |
| 805 | 807 |
| 806 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) { | 808 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 // Argument 0 is the mirror, which is unused by the native. It exists | 956 // Argument 0 is the mirror, which is unused by the native. It exists |
| 955 // because this native is an instance method in order to be polymorphic | 957 // because this native is an instance method in order to be polymorphic |
| 956 // with its cousins. | 958 // with its cousins. |
| 957 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 959 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 958 const Class& klass = Class::Handle(ref.GetClassReferent()); | 960 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 959 GET_NON_NULL_NATIVE_ARGUMENT( | 961 GET_NON_NULL_NATIVE_ARGUMENT( |
| 960 String, function_name, arguments->NativeArgAt(2)); | 962 String, function_name, arguments->NativeArgAt(2)); |
| 961 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); | 963 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); |
| 962 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); | 964 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
| 963 | 965 |
| 964 const Array& args_descriptor = | 966 const Array& args_descriptor_array = |
| 965 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); | 967 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
| 966 | 968 |
| 967 const Function& function = Function::Handle( | 969 const Function& function = Function::Handle( |
| 968 klass.LookupStaticFunctionAllowPrivate(function_name)); | 970 klass.LookupStaticFunctionAllowPrivate(function_name)); |
| 969 | 971 |
| 972 |
| 973 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 970 if (function.IsNull() || | 974 if (function.IsNull() || |
| 971 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL) || | 975 !function.AreValidArguments(args_descriptor, NULL) || |
| 972 !function.is_visible()) { | 976 !function.is_visible()) { |
| 973 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 977 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), |
| 974 function_name, | 978 function_name, |
| 975 function, | 979 function, |
| 976 InvocationMirror::kStatic, | 980 InvocationMirror::kStatic, |
| 977 InvocationMirror::kMethod); | 981 InvocationMirror::kMethod); |
| 978 UNREACHABLE(); | 982 UNREACHABLE(); |
| 979 } | 983 } |
| 980 | 984 |
| 981 Object& result = Object::Handle( | 985 Object& result = Object::Handle( |
| 982 DartEntry::InvokeFunction(function, args, args_descriptor)); | 986 DartEntry::InvokeFunction(function, args, args_descriptor_array)); |
| 983 if (result.IsError()) { | 987 if (result.IsError()) { |
| 984 ThrowInvokeError(Error::Cast(result)); | 988 ThrowInvokeError(Error::Cast(result)); |
| 985 UNREACHABLE(); | 989 UNREACHABLE(); |
| 986 } | 990 } |
| 987 return result.raw(); | 991 return result.raw(); |
| 988 } | 992 } |
| 989 | 993 |
| 990 | 994 |
| 991 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { | 995 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { |
| 992 // Argument 0 is the mirror, which is unused by the native. It exists | 996 // Argument 0 is the mirror, which is unused by the native. It exists |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 const Array& args = | 1137 const Array& args = |
| 1134 Array::Handle(Array::New(num_implicit_args + num_explicit_args)); | 1138 Array::Handle(Array::New(num_implicit_args + num_explicit_args)); |
| 1135 | 1139 |
| 1136 // Copy over the explicit arguments. | 1140 // Copy over the explicit arguments. |
| 1137 Object& explicit_argument = Object::Handle(); | 1141 Object& explicit_argument = Object::Handle(); |
| 1138 for (int i = 0; i < num_explicit_args; i++) { | 1142 for (int i = 0; i < num_explicit_args; i++) { |
| 1139 explicit_argument = explicit_args.At(i); | 1143 explicit_argument = explicit_args.At(i); |
| 1140 args.SetAt(i + num_implicit_args, explicit_argument); | 1144 args.SetAt(i + num_implicit_args, explicit_argument); |
| 1141 } | 1145 } |
| 1142 | 1146 |
| 1143 const Array& args_descriptor = | 1147 const Array& args_descriptor_array = |
| 1144 Array::Handle(ArgumentsDescriptor::New(args.Length(), | 1148 Array::Handle(ArgumentsDescriptor::New(args.Length(), |
| 1145 arg_names)); | 1149 arg_names)); |
| 1146 | 1150 |
| 1147 if (!redirected_constructor.AreValidArguments( | 1151 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 1148 ArgumentsDescriptor(args_descriptor), NULL) || | 1152 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) || |
| 1149 !redirected_constructor.is_visible()) { | 1153 !redirected_constructor.is_visible()) { |
| 1150 // Pretend we didn't find the constructor at all when the arity is wrong | 1154 // 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. | 1155 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1152 redirected_constructor = Function::null(); | 1156 redirected_constructor = Function::null(); |
| 1153 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 1157 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), |
| 1154 internal_constructor_name, | 1158 internal_constructor_name, |
| 1155 redirected_constructor, | 1159 redirected_constructor, |
| 1156 InvocationMirror::kConstructor, | 1160 InvocationMirror::kConstructor, |
| 1157 InvocationMirror::kMethod); | 1161 InvocationMirror::kMethod); |
| 1158 UNREACHABLE(); | 1162 UNREACHABLE(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1170 // Factories get type arguments. | 1174 // Factories get type arguments. |
| 1171 // TODO(12921): Should we allow the user to specify type arguments? Use type | 1175 // TODO(12921): Should we allow the user to specify type arguments? Use type |
| 1172 // arguments from the mirror? | 1176 // arguments from the mirror? |
| 1173 args.SetAt(0, Object::null_abstract_type_arguments()); | 1177 args.SetAt(0, Object::null_abstract_type_arguments()); |
| 1174 } | 1178 } |
| 1175 | 1179 |
| 1176 // Invoke the constructor and return the new object. | 1180 // Invoke the constructor and return the new object. |
| 1177 const Object& result = | 1181 const Object& result = |
| 1178 Object::Handle(DartEntry::InvokeFunction(redirected_constructor, | 1182 Object::Handle(DartEntry::InvokeFunction(redirected_constructor, |
| 1179 args, | 1183 args, |
| 1180 args_descriptor)); | 1184 args_descriptor_array)); |
| 1181 if (result.IsError()) { | 1185 if (result.IsError()) { |
| 1182 return result.raw(); | 1186 return result.raw(); |
| 1183 } | 1187 } |
| 1184 | 1188 |
| 1185 // Factories may return null. | 1189 // Factories may return null. |
| 1186 ASSERT(result.IsInstance() || result.IsNull()); | 1190 ASSERT(result.IsInstance() || result.IsNull()); |
| 1187 | 1191 |
| 1188 if (redirected_constructor.IsConstructor()) { | 1192 if (redirected_constructor.IsConstructor()) { |
| 1189 return new_object.raw(); | 1193 return new_object.raw(); |
| 1190 } else { | 1194 } else { |
| 1191 return result.raw(); | 1195 return result.raw(); |
| 1192 } | 1196 } |
| 1193 } | 1197 } |
| 1194 | 1198 |
| 1195 | 1199 |
| 1196 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) { | 1200 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) { |
| 1197 // Argument 0 is the mirror, which is unused by the native. It exists | 1201 // Argument 0 is the mirror, which is unused by the native. It exists |
| 1198 // because this native is an instance method in order to be polymorphic | 1202 // because this native is an instance method in order to be polymorphic |
| 1199 // with its cousins. | 1203 // with its cousins. |
| 1200 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1204 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1201 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1205 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
| 1202 GET_NON_NULL_NATIVE_ARGUMENT( | 1206 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1203 String, function_name, arguments->NativeArgAt(2)); | 1207 String, function_name, arguments->NativeArgAt(2)); |
| 1204 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); | 1208 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); |
| 1205 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); | 1209 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
| 1206 | 1210 |
| 1207 const Array& args_descriptor = | 1211 const Array& args_descriptor_array = |
| 1208 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); | 1212 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
| 1209 | 1213 |
| 1210 String& ambiguity_error_msg = String::Handle(isolate); | 1214 String& ambiguity_error_msg = String::Handle(isolate); |
| 1211 const Function& function = Function::Handle( | 1215 const Function& function = Function::Handle( |
| 1212 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); | 1216 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); |
| 1213 | 1217 |
| 1214 if (function.IsNull() && !ambiguity_error_msg.IsNull()) { | 1218 if (function.IsNull() && !ambiguity_error_msg.IsNull()) { |
| 1215 ThrowMirroredCompilationError(ambiguity_error_msg); | 1219 ThrowMirroredCompilationError(ambiguity_error_msg); |
| 1216 UNREACHABLE(); | 1220 UNREACHABLE(); |
| 1217 } | 1221 } |
| 1218 | 1222 |
| 1223 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 1219 if (function.IsNull() || | 1224 if (function.IsNull() || |
| 1220 !function.AreValidArguments(ArgumentsDescriptor(args_descriptor), NULL) || | 1225 !function.AreValidArguments(args_descriptor, NULL) || |
| 1221 !function.is_visible()) { | 1226 !function.is_visible()) { |
| 1222 ThrowNoSuchMethod(Instance::null_instance(), | 1227 ThrowNoSuchMethod(Instance::null_instance(), |
| 1223 function_name, | 1228 function_name, |
| 1224 function, | 1229 function, |
| 1225 InvocationMirror::kTopLevel, | 1230 InvocationMirror::kTopLevel, |
| 1226 InvocationMirror::kMethod); | 1231 InvocationMirror::kMethod); |
| 1227 UNREACHABLE(); | 1232 UNREACHABLE(); |
| 1228 } | 1233 } |
| 1229 | 1234 |
| 1230 const Object& result = Object::Handle( | 1235 const Object& result = Object::Handle( |
| 1231 DartEntry::InvokeFunction(function, args, args_descriptor)); | 1236 DartEntry::InvokeFunction(function, args, args_descriptor_array)); |
| 1232 if (result.IsError()) { | 1237 if (result.IsError()) { |
| 1233 ThrowInvokeError(Error::Cast(result)); | 1238 ThrowInvokeError(Error::Cast(result)); |
| 1234 UNREACHABLE(); | 1239 UNREACHABLE(); |
| 1235 } | 1240 } |
| 1236 return result.raw(); | 1241 return result.raw(); |
| 1237 } | 1242 } |
| 1238 | 1243 |
| 1239 | 1244 |
| 1240 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) { | 1245 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) { |
| 1241 // Argument 0 is the mirror, which is unused by the native. It exists | 1246 // 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... |
| 1439 } | 1444 } |
| 1440 | 1445 |
| 1441 | 1446 |
| 1442 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1447 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
| 1443 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1448 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1444 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1449 const Field& field = Field::Handle(ref.GetFieldReferent()); |
| 1445 return field.type(); | 1450 return field.type(); |
| 1446 } | 1451 } |
| 1447 | 1452 |
| 1448 } // namespace dart | 1453 } // namespace dart |
| OLD | NEW |