1 /*
2 * Copyright (C) 2008 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
17 /*
18 * java.lang.reflect.Method
19 */
20 #include "Dalvik.h"
21 #include "native/InternalNativePriv.h"
22
23
24 /*
25 * private int getMethodModifiers(Class decl_class, int slot)
26 *
27 * (Not sure why the access flags weren't stored in the class along with
28 * everything else. Not sure why this isn't static.)
29 */
Dalvik_java_lang_reflect_Method_getMethodModifiers(const u4 * args,JValue * pResult)30 static void Dalvik_java_lang_reflect_Method_getMethodModifiers(const u4* args,
31 JValue* pResult)
32 {
33 // ignore thisPtr in args[0]
34 ClassObject* declaringClass = (ClassObject*) args[1];
35 int slot = args[2];
36 Method* meth;
37
38 meth = dvmSlotToMethod(declaringClass, slot);
39 RETURN_INT(dvmFixMethodFlags(meth->accessFlags));
40 }
41
42 /*
43 * private Object invokeNative(Object obj, Object[] args, Class declaringClass,
44 * Class[] parameterTypes, Class returnType, int slot, boolean noAccessCheck)
45 *
46 * Invoke a static or virtual method via reflection.
47 */
Dalvik_java_lang_reflect_Method_invokeNative(const u4 * args,JValue * pResult)48 static void Dalvik_java_lang_reflect_Method_invokeNative(const u4* args,
49 JValue* pResult)
50 {
51 // ignore thisPtr in args[0]
52 Object* methObj = (Object*) args[1]; // null for static methods
53 ArrayObject* argList = (ArrayObject*) args[2];
54 ClassObject* declaringClass = (ClassObject*) args[3];
55 ArrayObject* params = (ArrayObject*) args[4];
56 ClassObject* returnType = (ClassObject*) args[5];
57 int slot = args[6];
58 bool noAccessCheck = (args[7] != 0);
59 const Method* meth;
60 Object* result;
61
62 /*
63 * "If the underlying method is static, the class that declared the
64 * method is initialized if it has not already been initialized."
65 */
66 meth = dvmSlotToMethod(declaringClass, slot);
67 assert(meth != NULL);
68
69 if (dvmIsStaticMethod(meth)) {
70 if (!dvmIsClassInitialized(declaringClass)) {
71 if (!dvmInitClass(declaringClass))
72 goto init_failed;
73 }
74 } else {
75 /* looks like interfaces need this too? */
76 if (dvmIsInterfaceClass(declaringClass) &&
77 !dvmIsClassInitialized(declaringClass))
78 {
79 if (!dvmInitClass(declaringClass))
80 goto init_failed;
81 }
82
83 /* make sure the object is an instance of the expected class */
84 if (!dvmVerifyObjectInClass(methObj, declaringClass)) {
85 assert(dvmCheckException(dvmThreadSelf()));
86 RETURN_VOID();
87 }
88
89 /* do the virtual table lookup for the method */
90 meth = dvmGetVirtualizedMethod(methObj->clazz, meth);
91 if (meth == NULL) {
92 assert(dvmCheckException(dvmThreadSelf()));
93 RETURN_VOID();
94 }
95 }
96
97 /*
98 * If the method has a return value, "result" will be an object or
99 * a boxed primitive.
100 */
101 result = dvmInvokeMethod(methObj, meth, argList, params, returnType,
102 noAccessCheck);
103
104 RETURN_PTR(result);
105
106 init_failed:
107 /*
108 * If initialization failed, an exception will be raised.
109 */
110 LOGD("Method.invoke() on bad class %s failed\n",
111 declaringClass->descriptor);
112 assert(dvmCheckException(dvmThreadSelf()));
113 RETURN_VOID();
114 }
115
116 /*
117 * public Annotation[] getDeclaredAnnotations(Class declaringClass, int slot)
118 *
119 * Return the annotations declared for this method.
120 */
Dalvik_java_lang_reflect_Method_getDeclaredAnnotations(const u4 * args,JValue * pResult)121 static void Dalvik_java_lang_reflect_Method_getDeclaredAnnotations(
122 const u4* args, JValue* pResult)
123 {
124 // ignore thisPtr in args[0]
125 ClassObject* declaringClass = (ClassObject*) args[1];
126 int slot = args[2];
127 Method* meth;
128
129 meth = dvmSlotToMethod(declaringClass, slot);
130 assert(meth != NULL);
131
132 ArrayObject* annos = dvmGetMethodAnnotations(meth);
133 dvmReleaseTrackedAlloc((Object*)annos, NULL);
134 RETURN_PTR(annos);
135 }
136
137 /*
138 * public Annotation[] getParameterAnnotations(Class declaringClass, int slot)
139 *
140 * Return the annotations declared for this method's parameters.
141 */
Dalvik_java_lang_reflect_Method_getParameterAnnotations(const u4 * args,JValue * pResult)142 static void Dalvik_java_lang_reflect_Method_getParameterAnnotations(
143 const u4* args, JValue* pResult)
144 {
145 // ignore thisPtr in args[0]
146 ClassObject* declaringClass = (ClassObject*) args[1];
147 int slot = args[2];
148 Method* meth;
149
150 meth = dvmSlotToMethod(declaringClass, slot);
151 assert(meth != NULL);
152
153 ArrayObject* annos = dvmGetParameterAnnotations(meth);
154 dvmReleaseTrackedAlloc((Object*)annos, NULL);
155 RETURN_PTR(annos);
156 }
157
158 /*
159 * private Object getDefaultValue(Class declaringClass, int slot)
160 *
161 * Return the default value for the annotation member represented by
162 * this Method instance. Returns NULL if none is defined.
163 */
Dalvik_java_lang_reflect_Method_getDefaultValue(const u4 * args,JValue * pResult)164 static void Dalvik_java_lang_reflect_Method_getDefaultValue(const u4* args,
165 JValue* pResult)
166 {
167 // ignore thisPtr in args[0]
168 ClassObject* declaringClass = (ClassObject*) args[1];
169 int slot = args[2];
170 Method* meth;
171
172 /* make sure this is an annotation class member */
173 if (!dvmIsAnnotationClass(declaringClass))
174 RETURN_PTR(NULL);
175
176 meth = dvmSlotToMethod(declaringClass, slot);
177 assert(meth != NULL);
178
179 Object* def = dvmGetAnnotationDefaultValue(meth);
180 dvmReleaseTrackedAlloc(def, NULL);
181 RETURN_PTR(def);
182 }
183
184 /*
185 * private Object[] getSignatureAnnotation()
186 *
187 * Returns the signature annotation.
188 */
Dalvik_java_lang_reflect_Method_getSignatureAnnotation(const u4 * args,JValue * pResult)189 static void Dalvik_java_lang_reflect_Method_getSignatureAnnotation(
190 const u4* args, JValue* pResult)
191 {
192 // ignore thisPtr in args[0]
193 ClassObject* declaringClass = (ClassObject*) args[1];
194 int slot = args[2];
195 Method* meth;
196
197 meth = dvmSlotToMethod(declaringClass, slot);
198 assert(meth != NULL);
199
200 ArrayObject* arr = dvmGetMethodSignatureAnnotation(meth);
201 dvmReleaseTrackedAlloc((Object*) arr, NULL);
202 RETURN_PTR(arr);
203 }
204
205 const DalvikNativeMethod dvm_java_lang_reflect_Method[] = {
206 { "getMethodModifiers", "(Ljava/lang/Class;I)I",
207 Dalvik_java_lang_reflect_Method_getMethodModifiers },
208 { "invokeNative", "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;IZ)Ljava/lang/Object;",
209 Dalvik_java_lang_reflect_Method_invokeNative },
210 { "getDeclaredAnnotations", "(Ljava/lang/Class;I)[Ljava/lang/annotation/Annotation;",
211 Dalvik_java_lang_reflect_Method_getDeclaredAnnotations },
212 { "getParameterAnnotations", "(Ljava/lang/Class;I)[[Ljava/lang/annotation/Annotation;",
213 Dalvik_java_lang_reflect_Method_getParameterAnnotations },
214 { "getDefaultValue", "(Ljava/lang/Class;I)Ljava/lang/Object;",
215 Dalvik_java_lang_reflect_Method_getDefaultValue },
216 { "getSignatureAnnotation", "(Ljava/lang/Class;I)[Ljava/lang/Object;",
217 Dalvik_java_lang_reflect_Method_getSignatureAnnotation },
218 { NULL, NULL, NULL },
219 };
220
221