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