summaryrefslogtreecommitdiff
path: root/vm/native/java_lang_reflect_Method.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm/native/java_lang_reflect_Method.c')
-rw-r--r--vm/native/java_lang_reflect_Method.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/vm/native/java_lang_reflect_Method.c b/vm/native/java_lang_reflect_Method.c
new file mode 100644
index 0000000..f73c8d0
--- /dev/null
+++ b/vm/native/java_lang_reflect_Method.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * java.lang.reflect.Method
+ */
+#include "Dalvik.h"
+#include "native/InternalNativePriv.h"
+
+
+/*
+ * private int getMethodModifiers(Class decl_class, int slot)
+ *
+ * (Not sure why the access flags weren't stored in the class along with
+ * everything else. Not sure why this isn't static.)
+ */
+static void Dalvik_java_lang_reflect_Method_getMethodModifiers(const u4* args,
+ JValue* pResult)
+{
+ // ignore thisPtr in args[0]
+ ClassObject* declaringClass = (ClassObject*) args[1];
+ int slot = args[2];
+ Method* meth;
+
+ meth = dvmSlotToMethod(declaringClass, slot);
+ RETURN_INT(dvmFixMethodFlags(meth->accessFlags));
+}
+
+/*
+ * private Object invokeNative(Object obj, Object[] args, Class declaringClass,
+ * Class[] parameterTypes, Class returnType, int slot, boolean noAccessCheck)
+ *
+ * Invoke a static or virtual method via reflection.
+ */
+static void Dalvik_java_lang_reflect_Method_invokeNative(const u4* args,
+ JValue* pResult)
+{
+ // ignore thisPtr in args[0]
+ Object* methObj = (Object*) args[1]; // null for static methods
+ ArrayObject* argList = (ArrayObject*) args[2];
+ ClassObject* declaringClass = (ClassObject*) args[3];
+ ArrayObject* params = (ArrayObject*) args[4];
+ ClassObject* returnType = (ClassObject*) args[5];
+ int slot = args[6];
+ bool noAccessCheck = (args[7] != 0);
+ const Method* meth;
+ Object* result;
+
+ /*
+ * "If the underlying method is static, the class that declared the
+ * method is initialized if it has not already been initialized."
+ */
+ meth = dvmSlotToMethod(declaringClass, slot);
+ assert(meth != NULL);
+
+ if (dvmIsStaticMethod(meth)) {
+ if (!dvmIsClassInitialized(declaringClass)) {
+ if (!dvmInitClass(declaringClass))
+ goto init_failed;
+ }
+ } else {
+ /* looks like interfaces need this too? */
+ if (dvmIsInterfaceClass(declaringClass) &&
+ !dvmIsClassInitialized(declaringClass))
+ {
+ if (!dvmInitClass(declaringClass))
+ goto init_failed;
+ }
+
+ /* make sure the object is an instance of the expected class */
+ if (!dvmVerifyObjectInClass(methObj, declaringClass)) {
+ assert(dvmCheckException(dvmThreadSelf()));
+ RETURN_VOID();
+ }
+
+ /* do the virtual table lookup for the method */
+ meth = dvmGetVirtualizedMethod(methObj->clazz, meth);
+ if (meth == NULL) {
+ assert(dvmCheckException(dvmThreadSelf()));
+ RETURN_VOID();
+ }
+ }
+
+ /*
+ * If the method has a return value, "result" will be an object or
+ * a boxed primitive.
+ */
+ result = dvmInvokeMethod(methObj, meth, argList, params, returnType,
+ noAccessCheck);
+
+ RETURN_PTR(result);
+
+init_failed:
+ /*
+ * If initialization failed, an exception will be raised.
+ */
+ LOGD("Method.invoke() on bad class %s failed\n",
+ declaringClass->descriptor);
+ assert(dvmCheckException(dvmThreadSelf()));
+ RETURN_VOID();
+}
+
+/*
+ * public Annotation[] getDeclaredAnnotations(Class declaringClass, int slot)
+ *
+ * Return the annotations declared for this method.
+ */
+static void Dalvik_java_lang_reflect_Method_getDeclaredAnnotations(
+ const u4* args, JValue* pResult)
+{
+ // ignore thisPtr in args[0]
+ ClassObject* declaringClass = (ClassObject*) args[1];
+ int slot = args[2];
+ Method* meth;
+
+ meth = dvmSlotToMethod(declaringClass, slot);
+ assert(meth != NULL);
+
+ ArrayObject* annos = dvmGetMethodAnnotations(meth);
+ dvmReleaseTrackedAlloc((Object*)annos, NULL);
+ RETURN_PTR(annos);
+}
+
+/*
+ * public Annotation[] getParameterAnnotations(Class declaringClass, int slot)
+ *
+ * Return the annotations declared for this method's parameters.
+ */
+static void Dalvik_java_lang_reflect_Method_getParameterAnnotations(
+ const u4* args, JValue* pResult)
+{
+ // ignore thisPtr in args[0]
+ ClassObject* declaringClass = (ClassObject*) args[1];
+ int slot = args[2];
+ Method* meth;
+
+ meth = dvmSlotToMethod(declaringClass, slot);
+ assert(meth != NULL);
+
+ ArrayObject* annos = dvmGetParameterAnnotations(meth);
+ dvmReleaseTrackedAlloc((Object*)annos, NULL);
+ RETURN_PTR(annos);
+}
+
+/*
+ * private Object getDefaultValue(Class declaringClass, int slot)
+ *
+ * Return the default value for the annotation member represented by
+ * this Method instance. Returns NULL if none is defined.
+ */
+static void Dalvik_java_lang_reflect_Method_getDefaultValue(const u4* args,
+ JValue* pResult)
+{
+ // ignore thisPtr in args[0]
+ ClassObject* declaringClass = (ClassObject*) args[1];
+ int slot = args[2];
+ Method* meth;
+
+ /* make sure this is an annotation class member */
+ if (!dvmIsAnnotationClass(declaringClass))
+ RETURN_PTR(NULL);
+
+ meth = dvmSlotToMethod(declaringClass, slot);
+ assert(meth != NULL);
+
+ Object* def = dvmGetAnnotationDefaultValue(meth);
+ dvmReleaseTrackedAlloc(def, NULL);
+ RETURN_PTR(def);
+}
+
+/*
+ * private Object[] getSignatureAnnotation()
+ *
+ * Returns the signature annotation.
+ */
+static void Dalvik_java_lang_reflect_Method_getSignatureAnnotation(
+ const u4* args, JValue* pResult)
+{
+ // ignore thisPtr in args[0]
+ ClassObject* declaringClass = (ClassObject*) args[1];
+ int slot = args[2];
+ Method* meth;
+
+ meth = dvmSlotToMethod(declaringClass, slot);
+ assert(meth != NULL);
+
+ ArrayObject* arr = dvmGetMethodSignatureAnnotation(meth);
+ dvmReleaseTrackedAlloc((Object*) arr, NULL);
+ RETURN_PTR(arr);
+}
+
+const DalvikNativeMethod dvm_java_lang_reflect_Method[] = {
+ { "getMethodModifiers", "(Ljava/lang/Class;I)I",
+ Dalvik_java_lang_reflect_Method_getMethodModifiers },
+ { "invokeNative", "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;IZ)Ljava/lang/Object;",
+ Dalvik_java_lang_reflect_Method_invokeNative },
+ { "getDeclaredAnnotations", "(Ljava/lang/Class;I)[Ljava/lang/annotation/Annotation;",
+ Dalvik_java_lang_reflect_Method_getDeclaredAnnotations },
+ { "getParameterAnnotations", "(Ljava/lang/Class;I)[[Ljava/lang/annotation/Annotation;",
+ Dalvik_java_lang_reflect_Method_getParameterAnnotations },
+ { "getDefaultValue", "(Ljava/lang/Class;I)Ljava/lang/Object;",
+ Dalvik_java_lang_reflect_Method_getDefaultValue },
+ { "getSignatureAnnotation", "(Ljava/lang/Class;I)[Ljava/lang/Object;",
+ Dalvik_java_lang_reflect_Method_getSignatureAnnotation },
+ { NULL, NULL, NULL },
+};