blob: 918730b980812a9d9b0458889cb1dcf190a4a92a [file] [log] [blame]
Jeff Hao1133db72016-04-04 19:50:14 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Neil Fuller0e844392016-09-08 13:43:31 +010017#include "java_lang_reflect_Executable.h"
Jeff Hao1133db72016-04-04 19:50:14 -070018
Andreas Gampe46ee31b2016-12-14 10:11:49 -080019#include "android-base/stringprintf.h"
Andreas Gampea14100c2017-04-24 15:09:56 -070020#include "nativehelper/jni_macros.h"
Andreas Gampe46ee31b2016-12-14 10:11:49 -080021
Jeff Hao1133db72016-04-04 19:50:14 -070022#include "art_method-inl.h"
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010023#include "class_root.h"
David Sehr9e734c72018-01-04 17:56:19 -080024#include "dex/dex_file_annotations.h"
Neil Fuller79a21e72016-09-09 14:24:51 +010025#include "handle.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010026#include "jni/jni_internal.h"
Jeff Hao1133db72016-04-04 19:50:14 -070027#include "mirror/class-inl.h"
Neil Fuller79a21e72016-09-09 14:24:51 +010028#include "mirror/method.h"
Jeff Hao1133db72016-04-04 19:50:14 -070029#include "mirror/object-inl.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -070030#include "mirror/object_array-alloc-inl.h"
Jeff Hao1133db72016-04-04 19:50:14 -070031#include "mirror/object_array-inl.h"
Andreas Gampe87583b32017-05-25 11:22:18 -070032#include "native_util.h"
Jeff Hao1133db72016-04-04 19:50:14 -070033#include "reflection.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070034#include "scoped_fast_native_object_access-inl.h"
Jeff Hao1133db72016-04-04 19:50:14 -070035#include "well_known_classes.h"
36
37namespace art {
38
Andreas Gampe46ee31b2016-12-14 10:11:49 -080039using android::base::StringPrintf;
40
Neil Fuller0e844392016-09-08 13:43:31 +010041static jobjectArray Executable_getDeclaredAnnotationsNative(JNIEnv* env, jobject javaMethod) {
Jeff Hao1133db72016-04-04 19:50:14 -070042 ScopedFastNativeObjectAccess soa(env);
43 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
44 if (method->GetDeclaringClass()->IsProxyClass()) {
45 // Return an empty array instead of a null pointer.
Mathieu Chartier0795f232016-09-27 18:43:30 -070046 ObjPtr<mirror::Class> annotation_array_class =
47 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array);
48 ObjPtr<mirror::ObjectArray<mirror::Object>> empty_array =
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070049 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0);
Jeff Hao1133db72016-04-04 19:50:14 -070050 return soa.AddLocalReference<jobjectArray>(empty_array);
51 }
David Sehr9323e6e2016-09-13 08:58:35 -070052 return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForMethod(method));
Jeff Hao1133db72016-04-04 19:50:14 -070053}
54
Neil Fuller0e844392016-09-08 13:43:31 +010055static jobject Executable_getAnnotationNative(JNIEnv* env,
Neil Fuller79a21e72016-09-09 14:24:51 +010056 jobject javaMethod,
57 jclass annotationType) {
Neil Fuller16b21cd2016-08-12 09:37:02 +010058 ScopedFastNativeObjectAccess soa(env);
59 StackHandleScope<1> hs(soa.Self());
60 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
61 if (method->IsProxyMethod()) {
62 return nullptr;
63 } else {
Mathieu Chartier0795f232016-09-27 18:43:30 -070064 Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
David Sehr9323e6e2016-09-13 08:58:35 -070065 return soa.AddLocalReference<jobject>(annotations::GetAnnotationForMethod(method, klass));
Neil Fuller16b21cd2016-08-12 09:37:02 +010066 }
67}
68
Neil Fuller0e844392016-09-08 13:43:31 +010069static jobjectArray Executable_getSignatureAnnotation(JNIEnv* env, jobject javaMethod) {
Jeff Hao1133db72016-04-04 19:50:14 -070070 ScopedFastNativeObjectAccess soa(env);
71 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
72 if (method->GetDeclaringClass()->IsProxyClass()) {
73 return nullptr;
74 }
David Sehr9323e6e2016-09-13 08:58:35 -070075 return soa.AddLocalReference<jobjectArray>(annotations::GetSignatureAnnotationForMethod(method));
Jeff Hao1133db72016-04-04 19:50:14 -070076}
77
78
Neil Fuller0e844392016-09-08 13:43:31 +010079static jobjectArray Executable_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) {
Neil Fuller16b21cd2016-08-12 09:37:02 +010080 ScopedFastNativeObjectAccess soa(env);
81 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
82 if (method->IsProxyMethod()) {
83 return nullptr;
Neil Fuller16b21cd2016-08-12 09:37:02 +010084 }
Orion Hodson58143d22018-02-20 08:44:20 +000085
86 StackHandleScope<4> hs(soa.Self());
87 Handle<mirror::ObjectArray<mirror::Object>> annotations =
88 hs.NewHandle(annotations::GetParameterAnnotations(method));
89 if (annotations.IsNull()) {
90 return nullptr;
91 }
92
93 // If the method is not a constructor, or has parameter annotations
94 // for each parameter, then we can return those annotations
95 // unmodified. Otherwise, we need to look at whether the
96 // constructor has implicit parameters as these may need padding
97 // with empty parameter annotations.
98 if (!method->IsConstructor() ||
99 annotations->GetLength() == static_cast<int>(method->GetNumberOfParameters())) {
100 return soa.AddLocalReference<jobjectArray>(annotations.Get());
101 }
102
103 // If declaring class is a local or an enum, do not pad parameter
104 // annotations, as the implicit constructor parameters are an implementation
105 // detail rather than required by JLS.
106 Handle<mirror::Class> declaring_class = hs.NewHandle(method->GetDeclaringClass());
107 if (annotations::GetEnclosingMethod(declaring_class) != nullptr ||
108 declaring_class->IsEnum()) {
109 return soa.AddLocalReference<jobjectArray>(annotations.Get());
110 }
111
112 // Prepare to resize the annotations so there is 1:1 correspondence
113 // with the constructor parameters.
114 Handle<mirror::ObjectArray<mirror::Object>> resized_annotations = hs.NewHandle(
115 mirror::ObjectArray<mirror::Object>::Alloc(
116 soa.Self(),
117 annotations->GetClass(),
118 static_cast<int>(method->GetNumberOfParameters())));
119 if (resized_annotations.IsNull()) {
120 DCHECK(soa.Self()->IsExceptionPending());
121 return nullptr;
122 }
123
124 static constexpr bool kTransactionActive = false;
125 const int32_t offset = resized_annotations->GetLength() - annotations->GetLength();
126 if (offset > 0) {
127 // Workaround for dexers (d8/dx) that do not insert annotations
128 // for implicit parameters (b/68033708).
129 ObjPtr<mirror::Class> annotation_array_class =
130 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array);
131 Handle<mirror::ObjectArray<mirror::Object>> empty_annotations = hs.NewHandle(
132 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0));
133 if (empty_annotations.IsNull()) {
134 DCHECK(soa.Self()->IsExceptionPending());
135 return nullptr;
136 }
137 for (int i = 0; i < offset; ++i) {
138 resized_annotations->SetWithoutChecks<kTransactionActive>(i, empty_annotations.Get());
139 }
140 for (int i = 0; i < annotations->GetLength(); ++i) {
141 ObjPtr<mirror::Object> annotation = annotations->GetWithoutChecks(i);
142 resized_annotations->SetWithoutChecks<kTransactionActive>(i + offset, annotation);
143 }
144 } else {
145 // Workaround for Jack (defunct) erroneously inserting annotations
146 // for local classes (b/68033708).
147 DCHECK_LT(offset, 0);
148 for (int i = 0; i < resized_annotations->GetLength(); ++i) {
149 ObjPtr<mirror::Object> annotation = annotations->GetWithoutChecks(i - offset);
150 resized_annotations->SetWithoutChecks<kTransactionActive>(i, annotation);
151 }
152 }
153 return soa.AddLocalReference<jobjectArray>(resized_annotations.Get());
Neil Fuller16b21cd2016-08-12 09:37:02 +0100154}
155
Neil Fuller79a21e72016-09-09 14:24:51 +0100156static jobjectArray Executable_getParameters0(JNIEnv* env, jobject javaMethod) {
157 ScopedFastNativeObjectAccess soa(env);
158 Thread* self = soa.Self();
159 StackHandleScope<8> hs(self);
160
Mathieu Chartier0795f232016-09-27 18:43:30 -0700161 Handle<mirror::Method> executable = hs.NewHandle(soa.Decode<mirror::Method>(javaMethod));
Neil Fuller79a21e72016-09-09 14:24:51 +0100162 ArtMethod* art_method = executable.Get()->GetArtMethod();
163 if (art_method->GetDeclaringClass()->IsProxyClass()) {
164 return nullptr;
165 }
166
167 // Find the MethodParameters system annotation.
168 MutableHandle<mirror::ObjectArray<mirror::String>> names =
169 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr);
170 MutableHandle<mirror::IntArray> access_flags = hs.NewHandle<mirror::IntArray>(nullptr);
171 if (!annotations::GetParametersMetadataForMethod(art_method, &names, &access_flags)) {
172 return nullptr;
173 }
174
175 // Validate the MethodParameters system annotation data.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800176 if (UNLIKELY(names == nullptr || access_flags == nullptr)) {
Neil Fuller79a21e72016-09-09 14:24:51 +0100177 ThrowIllegalArgumentException(
178 StringPrintf("Missing parameter metadata for names or access flags for %s",
David Sehr709b0702016-10-13 09:12:37 -0700179 art_method->PrettyMethod().c_str()).c_str());
Neil Fuller79a21e72016-09-09 14:24:51 +0100180 return nullptr;
181 }
182
183 // Check array sizes match each other
184 int32_t names_count = names.Get()->GetLength();
185 int32_t access_flags_count = access_flags.Get()->GetLength();
186 if (names_count != access_flags_count) {
187 ThrowIllegalArgumentException(
188 StringPrintf(
189 "Inconsistent parameter metadata for %s. names length: %d, access flags length: %d",
David Sehr709b0702016-10-13 09:12:37 -0700190 art_method->PrettyMethod().c_str(),
Neil Fuller79a21e72016-09-09 14:24:51 +0100191 names_count,
192 access_flags_count).c_str());
193 return nullptr;
194 }
195
196 // Instantiate a Parameter[] to hold the result.
197 Handle<mirror::Class> parameter_array_class =
198 hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700199 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Parameter__array));
Neil Fuller79a21e72016-09-09 14:24:51 +0100200 Handle<mirror::ObjectArray<mirror::Object>> parameter_array =
201 hs.NewHandle(
202 mirror::ObjectArray<mirror::Object>::Alloc(self,
203 parameter_array_class.Get(),
204 names_count));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800205 if (UNLIKELY(parameter_array == nullptr)) {
Neil Fuller79a21e72016-09-09 14:24:51 +0100206 self->AssertPendingException();
207 return nullptr;
208 }
209
210 Handle<mirror::Class> parameter_class =
Mathieu Chartier0795f232016-09-27 18:43:30 -0700211 hs.NewHandle(soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Parameter));
Neil Fuller79a21e72016-09-09 14:24:51 +0100212 ArtMethod* parameter_init =
Andreas Gampe13b27842016-11-07 16:48:23 -0800213 jni::DecodeArtMethod(WellKnownClasses::java_lang_reflect_Parameter_init);
Neil Fuller79a21e72016-09-09 14:24:51 +0100214
215 // Mutable handles used in the loop below to ensure cleanup without scaling the number of
216 // handles by the number of parameters.
217 MutableHandle<mirror::String> name = hs.NewHandle<mirror::String>(nullptr);
218 MutableHandle<mirror::Object> parameter = hs.NewHandle<mirror::Object>(nullptr);
219
220 // Populate the Parameter[] to return.
221 for (int32_t parameter_index = 0; parameter_index < names_count; parameter_index++) {
222 name.Assign(names.Get()->Get(parameter_index));
223 int32_t modifiers = access_flags.Get()->Get(parameter_index);
224
225 // Allocate / initialize the Parameter to add to parameter_array.
226 parameter.Assign(parameter_class->AllocObject(self));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800227 if (UNLIKELY(parameter == nullptr)) {
Neil Fuller79a21e72016-09-09 14:24:51 +0100228 self->AssertPendingOOMException();
229 return nullptr;
230 }
231
232 uint32_t args[5] = { PointerToLowMemUInt32(parameter.Get()),
233 PointerToLowMemUInt32(name.Get()),
234 static_cast<uint32_t>(modifiers),
235 PointerToLowMemUInt32(executable.Get()),
236 static_cast<uint32_t>(parameter_index)
237 };
238 JValue result;
239 static const char* method_signature = "VLILI"; // return + parameter types
240 parameter_init->Invoke(self, args, sizeof(args), &result, method_signature);
241 if (UNLIKELY(self->IsExceptionPending())) {
242 return nullptr;
243 }
244
245 // Store the Parameter in the Parameter[].
246 parameter_array.Get()->Set(parameter_index, parameter.Get());
247 if (UNLIKELY(self->IsExceptionPending())) {
248 return nullptr;
249 }
250 }
251 return soa.AddLocalReference<jobjectArray>(parameter_array.Get());
252}
253
Neil Fuller0e844392016-09-08 13:43:31 +0100254static jboolean Executable_isAnnotationPresentNative(JNIEnv* env,
Neil Fuller79a21e72016-09-09 14:24:51 +0100255 jobject javaMethod,
256 jclass annotationType) {
Jeff Hao1133db72016-04-04 19:50:14 -0700257 ScopedFastNativeObjectAccess soa(env);
258 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
259 if (method->GetDeclaringClass()->IsProxyClass()) {
260 return false;
261 }
262 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700263 Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
David Sehr9323e6e2016-09-13 08:58:35 -0700264 return annotations::IsMethodAnnotationPresent(method, klass);
Jeff Hao1133db72016-04-04 19:50:14 -0700265}
266
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000267static jint Executable_compareMethodParametersInternal(JNIEnv* env,
268 jobject thisMethod,
269 jobject otherMethod) {
270 ScopedFastNativeObjectAccess soa(env);
271 ArtMethod* this_method = ArtMethod::FromReflectedMethod(soa, thisMethod);
272 ArtMethod* other_method = ArtMethod::FromReflectedMethod(soa, otherMethod);
273
274 this_method = this_method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
275 other_method = other_method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
276
277 const DexFile::TypeList* this_list = this_method->GetParameterTypeList();
278 const DexFile::TypeList* other_list = other_method->GetParameterTypeList();
279
280 if (this_list == other_list) {
281 return 0;
282 }
283
284 if (this_list == nullptr && other_list != nullptr) {
285 return -1;
286 }
287
288 if (other_list == nullptr && this_list != nullptr) {
289 return 1;
290 }
291
292 const int32_t this_size = this_list->Size();
293 const int32_t other_size = other_list->Size();
294
295 if (this_size != other_size) {
296 return (this_size - other_size);
297 }
298
299 for (int32_t i = 0; i < this_size; ++i) {
300 const DexFile::TypeId& lhs = this_method->GetDexFile()->GetTypeId(
301 this_list->GetTypeItem(i).type_idx_);
302 const DexFile::TypeId& rhs = other_method->GetDexFile()->GetTypeId(
303 other_list->GetTypeItem(i).type_idx_);
304
305 uint32_t lhs_len, rhs_len;
306 const char* lhs_data = this_method->GetDexFile()->StringDataAndUtf16LengthByIdx(
307 lhs.descriptor_idx_, &lhs_len);
308 const char* rhs_data = other_method->GetDexFile()->StringDataAndUtf16LengthByIdx(
309 rhs.descriptor_idx_, &rhs_len);
310
311 int cmp = strcmp(lhs_data, rhs_data);
312 if (cmp != 0) {
313 return (cmp < 0) ? -1 : 1;
314 }
315 }
316
317 return 0;
318}
319
Igor Murashkin06537f72018-02-22 15:03:05 -0800320static jstring Executable_getMethodNameInternal(JNIEnv* env, jobject javaMethod) {
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000321 ScopedFastNativeObjectAccess soa(env);
322 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
323 method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
Vladimir Marko18090d12018-06-01 16:53:12 +0100324 return soa.AddLocalReference<jstring>(method->ResolveNameString());
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000325}
326
Igor Murashkin06537f72018-02-22 15:03:05 -0800327static jclass Executable_getMethodReturnTypeInternal(JNIEnv* env, jobject javaMethod) {
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000328 ScopedFastNativeObjectAccess soa(env);
329 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
330 method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
Vladimir Markob45528c2017-07-27 14:14:28 +0100331 ObjPtr<mirror::Class> return_type(method->ResolveReturnType());
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000332 if (return_type.IsNull()) {
333 CHECK(soa.Self()->IsExceptionPending());
334 return nullptr;
335 }
336
Igor Murashkin06537f72018-02-22 15:03:05 -0800337 return soa.AddLocalReference<jclass>(return_type);
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000338}
339
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000340static jobjectArray Executable_getParameterTypesInternal(JNIEnv* env, jobject javaMethod) {
341 ScopedFastNativeObjectAccess soa(env);
342 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
343 method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
344
345 const DexFile::TypeList* params = method->GetParameterTypeList();
346 if (params == nullptr) {
347 return nullptr;
348 }
349
350 const uint32_t num_params = params->Size();
351
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100352 StackHandleScope<2> hs(soa.Self());
353 ObjPtr<mirror::Class> class_array_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>();
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000354 Handle<mirror::ObjectArray<mirror::Class>> ptypes = hs.NewHandle(
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100355 mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, num_params));
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000356 if (ptypes.IsNull()) {
357 DCHECK(soa.Self()->IsExceptionPending());
358 return nullptr;
359 }
360
361 MutableHandle<mirror::Class> param(hs.NewHandle<mirror::Class>(nullptr));
362 for (uint32_t i = 0; i < num_params; ++i) {
363 const dex::TypeIndex type_idx = params->GetTypeItem(i).type_idx_;
364 param.Assign(Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method));
365 if (param.Get() == nullptr) {
366 DCHECK(soa.Self()->IsExceptionPending());
367 return nullptr;
368 }
369 ptypes->SetWithoutChecks<false>(i, param.Get());
370 }
371
372 return soa.AddLocalReference<jobjectArray>(ptypes.Get());
373}
374
375static jint Executable_getParameterCountInternal(JNIEnv* env, jobject javaMethod) {
376 ScopedFastNativeObjectAccess soa(env);
377 ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
378 method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
379
380 const DexFile::TypeList* params = method->GetParameterTypeList();
381 return (params == nullptr) ? 0 : params->Size();
382}
383
384
Jeff Hao1133db72016-04-04 19:50:14 -0700385static JNINativeMethod gMethods[] = {
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000386 FAST_NATIVE_METHOD(Executable, compareMethodParametersInternal,
387 "(Ljava/lang/reflect/Method;)I"),
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800388 FAST_NATIVE_METHOD(Executable, getAnnotationNative,
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000389 "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
390 FAST_NATIVE_METHOD(Executable, getDeclaredAnnotationsNative,
391 "()[Ljava/lang/annotation/Annotation;"),
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800392 FAST_NATIVE_METHOD(Executable, getParameterAnnotationsNative,
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000393 "()[[Ljava/lang/annotation/Annotation;"),
394 FAST_NATIVE_METHOD(Executable, getMethodNameInternal, "()Ljava/lang/String;"),
395 FAST_NATIVE_METHOD(Executable, getMethodReturnTypeInternal, "()Ljava/lang/Class;"),
396 FAST_NATIVE_METHOD(Executable, getParameterTypesInternal, "()[Ljava/lang/Class;"),
397 FAST_NATIVE_METHOD(Executable, getParameterCountInternal, "()I"),
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800398 FAST_NATIVE_METHOD(Executable, getParameters0, "()[Ljava/lang/reflect/Parameter;"),
399 FAST_NATIVE_METHOD(Executable, getSignatureAnnotation, "()[Ljava/lang/String;"),
400 FAST_NATIVE_METHOD(Executable, isAnnotationPresentNative, "(Ljava/lang/Class;)Z"),
Jeff Hao1133db72016-04-04 19:50:14 -0700401};
402
Neil Fuller0e844392016-09-08 13:43:31 +0100403void register_java_lang_reflect_Executable(JNIEnv* env) {
404 REGISTER_NATIVE_METHODS("java/lang/reflect/Executable");
Jeff Hao1133db72016-04-04 19:50:14 -0700405}
406
407} // namespace art