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