1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "java_lang_reflect_Executable.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
20*795d594fSAndroid Build Coastguard Worker #include "nativehelper/jni_macros.h"
21*795d594fSAndroid Build Coastguard Worker
22*795d594fSAndroid Build Coastguard Worker #include "art_method-alloc-inl.h"
23*795d594fSAndroid Build Coastguard Worker #include "class_root-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_annotations.h"
25*795d594fSAndroid Build Coastguard Worker #include "handle.h"
26*795d594fSAndroid Build Coastguard Worker #include "jni/jni_internal.h"
27*795d594fSAndroid Build Coastguard Worker #include "mirror/class-alloc-inl.h"
28*795d594fSAndroid Build Coastguard Worker #include "mirror/class-inl.h"
29*795d594fSAndroid Build Coastguard Worker #include "mirror/method.h"
30*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h"
31*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-alloc-inl.h"
32*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-inl.h"
33*795d594fSAndroid Build Coastguard Worker #include "native_util.h"
34*795d594fSAndroid Build Coastguard Worker #include "reflection.h"
35*795d594fSAndroid Build Coastguard Worker #include "scoped_fast_native_object_access-inl.h"
36*795d594fSAndroid Build Coastguard Worker #include "well_known_classes.h"
37*795d594fSAndroid Build Coastguard Worker
38*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
39*795d594fSAndroid Build Coastguard Worker
40*795d594fSAndroid Build Coastguard Worker using android::base::StringPrintf;
41*795d594fSAndroid Build Coastguard Worker
Executable_getDeclaredAnnotationsNative(JNIEnv * env,jobject javaMethod)42*795d594fSAndroid Build Coastguard Worker static jobjectArray Executable_getDeclaredAnnotationsNative(JNIEnv* env, jobject javaMethod) {
43*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
44*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
45*795d594fSAndroid Build Coastguard Worker if (method->GetDeclaringClass()->IsProxyClass()) {
46*795d594fSAndroid Build Coastguard Worker // Return an empty array instead of a null pointer.
47*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> annotation_array_class =
48*795d594fSAndroid Build Coastguard Worker WellKnownClasses::ToClass(WellKnownClasses::java_lang_annotation_Annotation__array);
49*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> empty_array =
50*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0);
51*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobjectArray>(empty_array);
52*795d594fSAndroid Build Coastguard Worker }
53*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForMethod(method));
54*795d594fSAndroid Build Coastguard Worker }
55*795d594fSAndroid Build Coastguard Worker
Executable_getAnnotationNative(JNIEnv * env,jobject javaMethod,jclass annotationType)56*795d594fSAndroid Build Coastguard Worker static jobject Executable_getAnnotationNative(JNIEnv* env,
57*795d594fSAndroid Build Coastguard Worker jobject javaMethod,
58*795d594fSAndroid Build Coastguard Worker jclass annotationType) {
59*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
60*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(soa.Self());
61*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
62*795d594fSAndroid Build Coastguard Worker if (method->IsProxyMethod()) {
63*795d594fSAndroid Build Coastguard Worker return nullptr;
64*795d594fSAndroid Build Coastguard Worker } else {
65*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
66*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobject>(annotations::GetAnnotationForMethod(method, klass));
67*795d594fSAndroid Build Coastguard Worker }
68*795d594fSAndroid Build Coastguard Worker }
69*795d594fSAndroid Build Coastguard Worker
Executable_getSignatureAnnotation(JNIEnv * env,jobject javaMethod)70*795d594fSAndroid Build Coastguard Worker static jobjectArray Executable_getSignatureAnnotation(JNIEnv* env, jobject javaMethod) {
71*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
72*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
73*795d594fSAndroid Build Coastguard Worker if (method->GetDeclaringClass()->IsProxyClass()) {
74*795d594fSAndroid Build Coastguard Worker return nullptr;
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobjectArray>(annotations::GetSignatureAnnotationForMethod(method));
77*795d594fSAndroid Build Coastguard Worker }
78*795d594fSAndroid Build Coastguard Worker
79*795d594fSAndroid Build Coastguard Worker
Executable_getParameterAnnotationsNative(JNIEnv * env,jobject javaMethod)80*795d594fSAndroid Build Coastguard Worker static jobjectArray Executable_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) {
81*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
82*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
83*795d594fSAndroid Build Coastguard Worker if (method->IsProxyMethod()) {
84*795d594fSAndroid Build Coastguard Worker return nullptr;
85*795d594fSAndroid Build Coastguard Worker }
86*795d594fSAndroid Build Coastguard Worker
87*795d594fSAndroid Build Coastguard Worker StackHandleScope<4> hs(soa.Self());
88*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Object>> annotations =
89*795d594fSAndroid Build Coastguard Worker hs.NewHandle(annotations::GetParameterAnnotations(method));
90*795d594fSAndroid Build Coastguard Worker if (annotations.IsNull()) {
91*795d594fSAndroid Build Coastguard Worker return nullptr;
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker
94*795d594fSAndroid Build Coastguard Worker // If the method is not a constructor, or has parameter annotations
95*795d594fSAndroid Build Coastguard Worker // for each parameter, then we can return those annotations
96*795d594fSAndroid Build Coastguard Worker // unmodified. Otherwise, we need to look at whether the
97*795d594fSAndroid Build Coastguard Worker // constructor has implicit parameters as these may need padding
98*795d594fSAndroid Build Coastguard Worker // with empty parameter annotations.
99*795d594fSAndroid Build Coastguard Worker if (!method->IsConstructor() ||
100*795d594fSAndroid Build Coastguard Worker annotations->GetLength() == static_cast<int>(method->GetNumberOfParameters())) {
101*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobjectArray>(annotations.Get());
102*795d594fSAndroid Build Coastguard Worker }
103*795d594fSAndroid Build Coastguard Worker
104*795d594fSAndroid Build Coastguard Worker // If declaring class is a local or an enum, do not pad parameter
105*795d594fSAndroid Build Coastguard Worker // annotations, as the implicit constructor parameters are an implementation
106*795d594fSAndroid Build Coastguard Worker // detail rather than required by JLS.
107*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> declaring_class = hs.NewHandle(method->GetDeclaringClass());
108*795d594fSAndroid Build Coastguard Worker if (annotations::GetEnclosingMethod(declaring_class) != nullptr ||
109*795d594fSAndroid Build Coastguard Worker declaring_class->IsEnum()) {
110*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobjectArray>(annotations.Get());
111*795d594fSAndroid Build Coastguard Worker }
112*795d594fSAndroid Build Coastguard Worker
113*795d594fSAndroid Build Coastguard Worker // Prepare to resize the annotations so there is 1:1 correspondence
114*795d594fSAndroid Build Coastguard Worker // with the constructor parameters.
115*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Object>> resized_annotations = hs.NewHandle(
116*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Object>::Alloc(
117*795d594fSAndroid Build Coastguard Worker soa.Self(),
118*795d594fSAndroid Build Coastguard Worker annotations->GetClass(),
119*795d594fSAndroid Build Coastguard Worker static_cast<int>(method->GetNumberOfParameters())));
120*795d594fSAndroid Build Coastguard Worker if (resized_annotations.IsNull()) {
121*795d594fSAndroid Build Coastguard Worker DCHECK(soa.Self()->IsExceptionPending());
122*795d594fSAndroid Build Coastguard Worker return nullptr;
123*795d594fSAndroid Build Coastguard Worker }
124*795d594fSAndroid Build Coastguard Worker
125*795d594fSAndroid Build Coastguard Worker static constexpr bool kTransactionActive = false;
126*795d594fSAndroid Build Coastguard Worker const int32_t offset = resized_annotations->GetLength() - annotations->GetLength();
127*795d594fSAndroid Build Coastguard Worker if (offset > 0) {
128*795d594fSAndroid Build Coastguard Worker // Workaround for dexers (d8/dx) that do not insert annotations
129*795d594fSAndroid Build Coastguard Worker // for implicit parameters (b/68033708).
130*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> annotation_array_class =
131*795d594fSAndroid Build Coastguard Worker WellKnownClasses::ToClass(WellKnownClasses::java_lang_annotation_Annotation__array);
132*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Object>> empty_annotations = hs.NewHandle(
133*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0));
134*795d594fSAndroid Build Coastguard Worker if (empty_annotations.IsNull()) {
135*795d594fSAndroid Build Coastguard Worker DCHECK(soa.Self()->IsExceptionPending());
136*795d594fSAndroid Build Coastguard Worker return nullptr;
137*795d594fSAndroid Build Coastguard Worker }
138*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < offset; ++i) {
139*795d594fSAndroid Build Coastguard Worker resized_annotations->SetWithoutChecks<kTransactionActive>(i, empty_annotations.Get());
140*795d594fSAndroid Build Coastguard Worker }
141*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < annotations->GetLength(); ++i) {
142*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> annotation = annotations->GetWithoutChecks(i);
143*795d594fSAndroid Build Coastguard Worker resized_annotations->SetWithoutChecks<kTransactionActive>(i + offset, annotation);
144*795d594fSAndroid Build Coastguard Worker }
145*795d594fSAndroid Build Coastguard Worker } else {
146*795d594fSAndroid Build Coastguard Worker // Workaround for Jack (defunct) erroneously inserting annotations
147*795d594fSAndroid Build Coastguard Worker // for local classes (b/68033708).
148*795d594fSAndroid Build Coastguard Worker DCHECK_LT(offset, 0);
149*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < resized_annotations->GetLength(); ++i) {
150*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> annotation = annotations->GetWithoutChecks(i - offset);
151*795d594fSAndroid Build Coastguard Worker resized_annotations->SetWithoutChecks<kTransactionActive>(i, annotation);
152*795d594fSAndroid Build Coastguard Worker }
153*795d594fSAndroid Build Coastguard Worker }
154*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobjectArray>(resized_annotations.Get());
155*795d594fSAndroid Build Coastguard Worker }
156*795d594fSAndroid Build Coastguard Worker
Executable_getParameters0(JNIEnv * env,jobject javaMethod)157*795d594fSAndroid Build Coastguard Worker static jobjectArray Executable_getParameters0(JNIEnv* env, jobject javaMethod) {
158*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
159*795d594fSAndroid Build Coastguard Worker Thread* self = soa.Self();
160*795d594fSAndroid Build Coastguard Worker StackHandleScope<6> hs(self);
161*795d594fSAndroid Build Coastguard Worker
162*795d594fSAndroid Build Coastguard Worker Handle<mirror::Method> executable = hs.NewHandle(soa.Decode<mirror::Method>(javaMethod));
163*795d594fSAndroid Build Coastguard Worker ArtMethod* art_method = executable.Get()->GetArtMethod();
164*795d594fSAndroid Build Coastguard Worker if (art_method->GetDeclaringClass()->IsProxyClass()) {
165*795d594fSAndroid Build Coastguard Worker return nullptr;
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker
168*795d594fSAndroid Build Coastguard Worker // Find the MethodParameters system annotation.
169*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::ObjectArray<mirror::String>> names =
170*795d594fSAndroid Build Coastguard Worker hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr);
171*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::IntArray> access_flags = hs.NewHandle<mirror::IntArray>(nullptr);
172*795d594fSAndroid Build Coastguard Worker if (!annotations::GetParametersMetadataForMethod(art_method, &names, &access_flags)) {
173*795d594fSAndroid Build Coastguard Worker return nullptr;
174*795d594fSAndroid Build Coastguard Worker }
175*795d594fSAndroid Build Coastguard Worker
176*795d594fSAndroid Build Coastguard Worker // Validate the MethodParameters system annotation data.
177*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(names == nullptr || access_flags == nullptr)) {
178*795d594fSAndroid Build Coastguard Worker ThrowIllegalArgumentException(
179*795d594fSAndroid Build Coastguard Worker StringPrintf("Missing parameter metadata for names or access flags for %s",
180*795d594fSAndroid Build Coastguard Worker art_method->PrettyMethod().c_str()).c_str());
181*795d594fSAndroid Build Coastguard Worker return nullptr;
182*795d594fSAndroid Build Coastguard Worker }
183*795d594fSAndroid Build Coastguard Worker
184*795d594fSAndroid Build Coastguard Worker // Check array sizes match each other
185*795d594fSAndroid Build Coastguard Worker int32_t names_count = names.Get()->GetLength();
186*795d594fSAndroid Build Coastguard Worker int32_t access_flags_count = access_flags.Get()->GetLength();
187*795d594fSAndroid Build Coastguard Worker if (names_count != access_flags_count) {
188*795d594fSAndroid Build Coastguard Worker ThrowIllegalArgumentException(
189*795d594fSAndroid Build Coastguard Worker StringPrintf(
190*795d594fSAndroid Build Coastguard Worker "Inconsistent parameter metadata for %s. names length: %d, access flags length: %d",
191*795d594fSAndroid Build Coastguard Worker art_method->PrettyMethod().c_str(),
192*795d594fSAndroid Build Coastguard Worker names_count,
193*795d594fSAndroid Build Coastguard Worker access_flags_count).c_str());
194*795d594fSAndroid Build Coastguard Worker return nullptr;
195*795d594fSAndroid Build Coastguard Worker }
196*795d594fSAndroid Build Coastguard Worker
197*795d594fSAndroid Build Coastguard Worker // Instantiate a Parameter[] to hold the result.
198*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> parameter_array_class =
199*795d594fSAndroid Build Coastguard Worker hs.NewHandle(
200*795d594fSAndroid Build Coastguard Worker WellKnownClasses::ToClass(WellKnownClasses::java_lang_reflect_Parameter__array));
201*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Object>> parameter_array = hs.NewHandle(
202*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Object>::Alloc(self, parameter_array_class.Get(), names_count));
203*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(parameter_array == nullptr)) {
204*795d594fSAndroid Build Coastguard Worker self->AssertPendingException();
205*795d594fSAndroid Build Coastguard Worker return nullptr;
206*795d594fSAndroid Build Coastguard Worker }
207*795d594fSAndroid Build Coastguard Worker
208*795d594fSAndroid Build Coastguard Worker ArtMethod* parameter_init = WellKnownClasses::java_lang_reflect_Parameter_init;
209*795d594fSAndroid Build Coastguard Worker
210*795d594fSAndroid Build Coastguard Worker // Mutable handles used in the loop below to ensure cleanup without scaling the number of
211*795d594fSAndroid Build Coastguard Worker // handles by the number of parameters.
212*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::String> name = hs.NewHandle<mirror::String>(nullptr);
213*795d594fSAndroid Build Coastguard Worker
214*795d594fSAndroid Build Coastguard Worker // Populate the Parameter[] to return.
215*795d594fSAndroid Build Coastguard Worker for (int32_t parameter_index = 0; parameter_index < names_count; parameter_index++) {
216*795d594fSAndroid Build Coastguard Worker name.Assign(names.Get()->Get(parameter_index));
217*795d594fSAndroid Build Coastguard Worker int32_t modifiers = access_flags.Get()->Get(parameter_index);
218*795d594fSAndroid Build Coastguard Worker
219*795d594fSAndroid Build Coastguard Worker // Create the Parameter to add to parameter_array.
220*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> parameter = parameter_init->NewObject<'L', 'I', 'L', 'I'>(
221*795d594fSAndroid Build Coastguard Worker self, name, modifiers, executable, parameter_index);
222*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(parameter == nullptr)) {
223*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
224*795d594fSAndroid Build Coastguard Worker return nullptr;
225*795d594fSAndroid Build Coastguard Worker }
226*795d594fSAndroid Build Coastguard Worker
227*795d594fSAndroid Build Coastguard Worker // We're initializing a newly allocated array object, so we do not need to record that under
228*795d594fSAndroid Build Coastguard Worker // a transaction. If the transaction is aborted, the whole object shall be unreachable.
229*795d594fSAndroid Build Coastguard Worker parameter_array->SetWithoutChecks</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
230*795d594fSAndroid Build Coastguard Worker parameter_index, parameter);
231*795d594fSAndroid Build Coastguard Worker }
232*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobjectArray>(parameter_array.Get());
233*795d594fSAndroid Build Coastguard Worker }
234*795d594fSAndroid Build Coastguard Worker
Executable_isAnnotationPresentNative(JNIEnv * env,jobject javaMethod,jclass annotationType)235*795d594fSAndroid Build Coastguard Worker static jboolean Executable_isAnnotationPresentNative(JNIEnv* env,
236*795d594fSAndroid Build Coastguard Worker jobject javaMethod,
237*795d594fSAndroid Build Coastguard Worker jclass annotationType) {
238*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
239*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
240*795d594fSAndroid Build Coastguard Worker if (method->GetDeclaringClass()->IsProxyClass()) {
241*795d594fSAndroid Build Coastguard Worker return false;
242*795d594fSAndroid Build Coastguard Worker }
243*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(soa.Self());
244*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
245*795d594fSAndroid Build Coastguard Worker return annotations::IsMethodAnnotationPresent(method, klass);
246*795d594fSAndroid Build Coastguard Worker }
247*795d594fSAndroid Build Coastguard Worker
Executable_compareMethodParametersInternal(JNIEnv * env,jobject thisMethod,jobject otherMethod)248*795d594fSAndroid Build Coastguard Worker static jint Executable_compareMethodParametersInternal(JNIEnv* env,
249*795d594fSAndroid Build Coastguard Worker jobject thisMethod,
250*795d594fSAndroid Build Coastguard Worker jobject otherMethod) {
251*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
252*795d594fSAndroid Build Coastguard Worker ArtMethod* this_method = ArtMethod::FromReflectedMethod(soa, thisMethod);
253*795d594fSAndroid Build Coastguard Worker ArtMethod* other_method = ArtMethod::FromReflectedMethod(soa, otherMethod);
254*795d594fSAndroid Build Coastguard Worker
255*795d594fSAndroid Build Coastguard Worker this_method = this_method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
256*795d594fSAndroid Build Coastguard Worker other_method = other_method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
257*795d594fSAndroid Build Coastguard Worker
258*795d594fSAndroid Build Coastguard Worker // Get dex files early. (`ArtMethod::GetParameterTypeList()` includes `GetDexFile()`,
259*795d594fSAndroid Build Coastguard Worker // so the compiler should deduplicate these subexpressions after inlining.)
260*795d594fSAndroid Build Coastguard Worker const DexFile* this_dex_file = this_method->GetDexFile();
261*795d594fSAndroid Build Coastguard Worker const DexFile* other_dex_file = other_method->GetDexFile();
262*795d594fSAndroid Build Coastguard Worker
263*795d594fSAndroid Build Coastguard Worker const dex::TypeList* this_list = this_method->GetParameterTypeList();
264*795d594fSAndroid Build Coastguard Worker const dex::TypeList* other_list = other_method->GetParameterTypeList();
265*795d594fSAndroid Build Coastguard Worker
266*795d594fSAndroid Build Coastguard Worker if (this_list == other_list) {
267*795d594fSAndroid Build Coastguard Worker return 0;
268*795d594fSAndroid Build Coastguard Worker }
269*795d594fSAndroid Build Coastguard Worker
270*795d594fSAndroid Build Coastguard Worker if (this_list == nullptr && other_list != nullptr) {
271*795d594fSAndroid Build Coastguard Worker return -1;
272*795d594fSAndroid Build Coastguard Worker }
273*795d594fSAndroid Build Coastguard Worker
274*795d594fSAndroid Build Coastguard Worker if (other_list == nullptr && this_list != nullptr) {
275*795d594fSAndroid Build Coastguard Worker return 1;
276*795d594fSAndroid Build Coastguard Worker }
277*795d594fSAndroid Build Coastguard Worker
278*795d594fSAndroid Build Coastguard Worker const int32_t this_size = this_list->Size();
279*795d594fSAndroid Build Coastguard Worker const int32_t other_size = other_list->Size();
280*795d594fSAndroid Build Coastguard Worker
281*795d594fSAndroid Build Coastguard Worker if (this_size != other_size) {
282*795d594fSAndroid Build Coastguard Worker return (this_size - other_size);
283*795d594fSAndroid Build Coastguard Worker }
284*795d594fSAndroid Build Coastguard Worker
285*795d594fSAndroid Build Coastguard Worker for (int32_t i = 0; i < this_size; ++i) {
286*795d594fSAndroid Build Coastguard Worker int cmp = DexFile::CompareDescriptors(
287*795d594fSAndroid Build Coastguard Worker this_dex_file->GetTypeDescriptorView(this_list->GetTypeItem(i).type_idx_),
288*795d594fSAndroid Build Coastguard Worker other_dex_file->GetTypeDescriptorView(other_list->GetTypeItem(i).type_idx_));
289*795d594fSAndroid Build Coastguard Worker if (cmp != 0) {
290*795d594fSAndroid Build Coastguard Worker return (cmp < 0) ? -1 : 1;
291*795d594fSAndroid Build Coastguard Worker }
292*795d594fSAndroid Build Coastguard Worker }
293*795d594fSAndroid Build Coastguard Worker
294*795d594fSAndroid Build Coastguard Worker return 0;
295*795d594fSAndroid Build Coastguard Worker }
296*795d594fSAndroid Build Coastguard Worker
Executable_getMethodNameInternal(JNIEnv * env,jobject javaMethod)297*795d594fSAndroid Build Coastguard Worker static jstring Executable_getMethodNameInternal(JNIEnv* env, jobject javaMethod) {
298*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
299*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
300*795d594fSAndroid Build Coastguard Worker method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
301*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jstring>(method->ResolveNameString());
302*795d594fSAndroid Build Coastguard Worker }
303*795d594fSAndroid Build Coastguard Worker
Executable_getMethodReturnTypeInternal(JNIEnv * env,jobject javaMethod)304*795d594fSAndroid Build Coastguard Worker static jclass Executable_getMethodReturnTypeInternal(JNIEnv* env, jobject javaMethod) {
305*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
306*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
307*795d594fSAndroid Build Coastguard Worker method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
308*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> return_type(method->ResolveReturnType());
309*795d594fSAndroid Build Coastguard Worker if (return_type.IsNull()) {
310*795d594fSAndroid Build Coastguard Worker CHECK(soa.Self()->IsExceptionPending());
311*795d594fSAndroid Build Coastguard Worker return nullptr;
312*795d594fSAndroid Build Coastguard Worker }
313*795d594fSAndroid Build Coastguard Worker
314*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jclass>(return_type);
315*795d594fSAndroid Build Coastguard Worker }
316*795d594fSAndroid Build Coastguard Worker
Executable_getParameterTypesInternal(JNIEnv * env,jobject javaMethod)317*795d594fSAndroid Build Coastguard Worker static jobjectArray Executable_getParameterTypesInternal(JNIEnv* env, jobject javaMethod) {
318*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
319*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
320*795d594fSAndroid Build Coastguard Worker method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
321*795d594fSAndroid Build Coastguard Worker
322*795d594fSAndroid Build Coastguard Worker const dex::TypeList* params = method->GetParameterTypeList();
323*795d594fSAndroid Build Coastguard Worker if (params == nullptr) {
324*795d594fSAndroid Build Coastguard Worker return nullptr;
325*795d594fSAndroid Build Coastguard Worker }
326*795d594fSAndroid Build Coastguard Worker
327*795d594fSAndroid Build Coastguard Worker const uint32_t num_params = params->Size();
328*795d594fSAndroid Build Coastguard Worker
329*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(soa.Self());
330*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> class_array_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>();
331*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Class>> ptypes = hs.NewHandle(
332*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, num_params));
333*795d594fSAndroid Build Coastguard Worker if (ptypes.IsNull()) {
334*795d594fSAndroid Build Coastguard Worker DCHECK(soa.Self()->IsExceptionPending());
335*795d594fSAndroid Build Coastguard Worker return nullptr;
336*795d594fSAndroid Build Coastguard Worker }
337*795d594fSAndroid Build Coastguard Worker
338*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::Class> param(hs.NewHandle<mirror::Class>(nullptr));
339*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < num_params; ++i) {
340*795d594fSAndroid Build Coastguard Worker const dex::TypeIndex type_idx = params->GetTypeItem(i).type_idx_;
341*795d594fSAndroid Build Coastguard Worker param.Assign(Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method));
342*795d594fSAndroid Build Coastguard Worker if (param.Get() == nullptr) {
343*795d594fSAndroid Build Coastguard Worker DCHECK(soa.Self()->IsExceptionPending());
344*795d594fSAndroid Build Coastguard Worker return nullptr;
345*795d594fSAndroid Build Coastguard Worker }
346*795d594fSAndroid Build Coastguard Worker ptypes->SetWithoutChecks<false>(i, param.Get());
347*795d594fSAndroid Build Coastguard Worker }
348*795d594fSAndroid Build Coastguard Worker
349*795d594fSAndroid Build Coastguard Worker return soa.AddLocalReference<jobjectArray>(ptypes.Get());
350*795d594fSAndroid Build Coastguard Worker }
351*795d594fSAndroid Build Coastguard Worker
Executable_getParameterCountInternal(JNIEnv * env,jobject javaMethod)352*795d594fSAndroid Build Coastguard Worker static jint Executable_getParameterCountInternal(JNIEnv* env, jobject javaMethod) {
353*795d594fSAndroid Build Coastguard Worker ScopedFastNativeObjectAccess soa(env);
354*795d594fSAndroid Build Coastguard Worker ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
355*795d594fSAndroid Build Coastguard Worker method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
356*795d594fSAndroid Build Coastguard Worker
357*795d594fSAndroid Build Coastguard Worker const dex::TypeList* params = method->GetParameterTypeList();
358*795d594fSAndroid Build Coastguard Worker return (params == nullptr) ? 0 : params->Size();
359*795d594fSAndroid Build Coastguard Worker }
360*795d594fSAndroid Build Coastguard Worker
361*795d594fSAndroid Build Coastguard Worker
362*795d594fSAndroid Build Coastguard Worker static JNINativeMethod gMethods[] = {
363*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, compareMethodParametersInternal,
364*795d594fSAndroid Build Coastguard Worker "(Ljava/lang/reflect/Method;)I"),
365*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getAnnotationNative,
366*795d594fSAndroid Build Coastguard Worker "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
367*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getDeclaredAnnotationsNative,
368*795d594fSAndroid Build Coastguard Worker "()[Ljava/lang/annotation/Annotation;"),
369*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getParameterAnnotationsNative,
370*795d594fSAndroid Build Coastguard Worker "()[[Ljava/lang/annotation/Annotation;"),
371*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getMethodNameInternal, "()Ljava/lang/String;"),
372*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getMethodReturnTypeInternal, "()Ljava/lang/Class;"),
373*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getParameterTypesInternal, "()[Ljava/lang/Class;"),
374*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getParameterCountInternal, "()I"),
375*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getParameters0, "()[Ljava/lang/reflect/Parameter;"),
376*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, getSignatureAnnotation, "()[Ljava/lang/String;"),
377*795d594fSAndroid Build Coastguard Worker FAST_NATIVE_METHOD(Executable, isAnnotationPresentNative, "(Ljava/lang/Class;)Z"),
378*795d594fSAndroid Build Coastguard Worker };
379*795d594fSAndroid Build Coastguard Worker
register_java_lang_reflect_Executable(JNIEnv * env)380*795d594fSAndroid Build Coastguard Worker void register_java_lang_reflect_Executable(JNIEnv* env) {
381*795d594fSAndroid Build Coastguard Worker REGISTER_NATIVE_METHODS("java/lang/reflect/Executable");
382*795d594fSAndroid Build Coastguard Worker }
383*795d594fSAndroid Build Coastguard Worker
384*795d594fSAndroid Build Coastguard Worker } // namespace art
385