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 */ 30static 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 */ 48static 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 106init_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 */ 121static 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 */ 142static 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 */ 164static 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 */ 189static 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 205const 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