• 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  * 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