| /* |
| * 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.Class |
| */ |
| #include "Dalvik.h" |
| #include "native/InternalNativePriv.h" |
| |
| |
| /* |
| * native public boolean desiredAssertionStatus() |
| * |
| * Determine the class-init-time assertion status of a class. This is |
| * called from <clinit> in javac-generated classes that use the Java |
| * programming language "assert" keyword. |
| */ |
| static void Dalvik_java_lang_Class_desiredAssertionStatus(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* thisPtr = (ClassObject*) args[0]; |
| char* className = dvmDescriptorToName(thisPtr->descriptor); |
| int i; |
| bool enable = false; |
| |
| /* |
| * Run through the list of arguments specified on the command line. The |
| * last matching argument takes precedence. |
| */ |
| for (i = 0; i < gDvm.assertionCtrlCount; i++) { |
| const AssertionControl* pCtrl = &gDvm.assertionCtrl[i]; |
| |
| if (pCtrl->isPackage) { |
| /* |
| * Given "dalvik/system/Debug" or "MyStuff", compute the |
| * length of the package portion of the class name string. |
| * |
| * Unlike most package operations, we allow matching on |
| * "sub-packages", so "dalvik..." will match "dalvik.Foo" |
| * and "dalvik.system.Foo". |
| * |
| * The pkgOrClass string looks like "dalvik/system/", i.e. it still |
| * has the terminating slash, so we can be sure we're comparing |
| * against full package component names. |
| */ |
| const char* lastSlash; |
| int pkgLen; |
| |
| lastSlash = strrchr(className, '/'); |
| if (lastSlash == NULL) { |
| pkgLen = 0; |
| } else { |
| pkgLen = lastSlash - className +1; |
| } |
| |
| if (pCtrl->pkgOrClassLen > pkgLen || |
| memcmp(pCtrl->pkgOrClass, className, pCtrl->pkgOrClassLen) != 0) |
| { |
| LOGV("ASRT: pkg no match: '%s'(%d) vs '%s'\n", |
| className, pkgLen, pCtrl->pkgOrClass); |
| } else { |
| LOGV("ASRT: pkg match: '%s'(%d) vs '%s' --> %d\n", |
| className, pkgLen, pCtrl->pkgOrClass, pCtrl->enable); |
| enable = pCtrl->enable; |
| } |
| } else { |
| /* |
| * "pkgOrClass" holds a fully-qualified class name, converted from |
| * dot-form to slash-form. An empty string means all classes. |
| */ |
| if (pCtrl->pkgOrClass == NULL) { |
| /* -esa/-dsa; see if class is a "system" class */ |
| if (strncmp(className, "java/", 5) != 0) { |
| LOGV("ASRT: sys no match: '%s'\n", className); |
| } else { |
| LOGV("ASRT: sys match: '%s' --> %d\n", |
| className, pCtrl->enable); |
| enable = pCtrl->enable; |
| } |
| } else if (*pCtrl->pkgOrClass == '\0') { |
| LOGV("ASRT: class all: '%s' --> %d\n", |
| className, pCtrl->enable); |
| enable = pCtrl->enable; |
| } else { |
| if (strcmp(pCtrl->pkgOrClass, className) != 0) { |
| LOGV("ASRT: cls no match: '%s' vs '%s'\n", |
| className, pCtrl->pkgOrClass); |
| } else { |
| LOGV("ASRT: cls match: '%s' vs '%s' --> %d\n", |
| className, pCtrl->pkgOrClass, pCtrl->enable); |
| enable = pCtrl->enable; |
| } |
| } |
| } |
| } |
| |
| free(className); |
| RETURN_INT(enable); |
| } |
| |
| /* |
| * static public Class<?> classForName(String name, boolean initialize, |
| * ClassLoader loader) |
| * |
| * Return the Class object associated with the class or interface with |
| * the specified name. |
| * |
| * "name" is in "binary name" format, e.g. "dalvik.system.Debug$1". |
| */ |
| static void Dalvik_java_lang_Class_classForName(const u4* args, JValue* pResult) |
| { |
| StringObject* nameObj = (StringObject*) args[0]; |
| bool initialize = (args[1] != 0); |
| Object* loader = (Object*) args[2]; |
| |
| RETURN_PTR(dvmFindClassByName(nameObj, loader, initialize)); |
| } |
| |
| /* |
| * static private ClassLoader getClassLoader(Class clazz) |
| * |
| * Return the class' defining class loader. |
| */ |
| static void Dalvik_java_lang_Class_getClassLoader(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| |
| RETURN_PTR(clazz->classLoader); |
| } |
| |
| /* |
| * public Class<?> getComponentType() |
| * |
| * If this is an array type, return the class of the elements; otherwise |
| * return NULL. |
| */ |
| static void Dalvik_java_lang_Class_getComponentType(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* thisPtr = (ClassObject*) args[0]; |
| |
| if (!dvmIsArrayClass(thisPtr)) |
| RETURN_PTR(NULL); |
| |
| /* |
| * We can't just return thisPtr->elementClass, because that gives |
| * us the base type (e.g. X[][][] returns X). If this is a multi- |
| * dimensional array, we have to do the lookup by name. |
| */ |
| if (thisPtr->descriptor[1] == '[') |
| RETURN_PTR(dvmFindArrayClass(&thisPtr->descriptor[1], |
| thisPtr->classLoader)); |
| else |
| RETURN_PTR(thisPtr->elementClass); |
| } |
| |
| /* |
| * private static Class<?>[] getDeclaredClasses(Class<?> clazz, |
| * boolean publicOnly) |
| * |
| * Return an array with the classes that are declared by the specified class. |
| * If "publicOnly" is set, we strip out any classes that don't have "public" |
| * access. |
| */ |
| static void Dalvik_java_lang_Class_getDeclaredClasses(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| bool publicOnly = (args[1] != 0); |
| ArrayObject* classes; |
| |
| classes = dvmGetDeclaredClasses(clazz); |
| if (classes == NULL) { |
| if (!dvmCheckException(dvmThreadSelf())) { |
| /* empty list, so create a zero-length array */ |
| classes = dvmAllocArrayByClass(gDvm.classJavaLangClassArray, |
| 0, ALLOC_DEFAULT); |
| } |
| } else if (publicOnly) { |
| u4 count, newIdx, publicCount = 0; |
| ClassObject** pSource = (ClassObject**)(void*)classes->contents; |
| u4 length = classes->length; |
| |
| /* count up public classes */ |
| for (count = 0; count < length; count++) { |
| if (dvmIsPublicClass(pSource[count])) |
| publicCount++; |
| } |
| |
| /* create a new array to hold them */ |
| ArrayObject* newClasses; |
| newClasses = dvmAllocArrayByClass(gDvm.classJavaLangClassArray, |
| publicCount, ALLOC_DEFAULT); |
| |
| /* copy them over */ |
| for (count = newIdx = 0; count < length; count++) { |
| if (dvmIsPublicClass(pSource[count])) { |
| dvmSetObjectArrayElement(newClasses, newIdx, |
| (Object *)pSource[count]); |
| newIdx++; |
| } |
| } |
| assert(newIdx == publicCount); |
| dvmReleaseTrackedAlloc((Object*) classes, NULL); |
| classes = newClasses; |
| } |
| |
| dvmReleaseTrackedAlloc((Object*) classes, NULL); |
| RETURN_PTR(classes); |
| } |
| |
| /* |
| * static Constructor[] getDeclaredConstructors(Class clazz, boolean publicOnly) |
| * throws SecurityException |
| */ |
| static void Dalvik_java_lang_Class_getDeclaredConstructors(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| bool publicOnly = (args[1] != 0); |
| ArrayObject* constructors; |
| |
| constructors = dvmGetDeclaredConstructors(clazz, publicOnly); |
| dvmReleaseTrackedAlloc((Object*) constructors, NULL); |
| |
| RETURN_PTR(constructors); |
| } |
| |
| /* |
| * static Field[] getDeclaredFields(Class klass, boolean publicOnly) |
| */ |
| static void Dalvik_java_lang_Class_getDeclaredFields(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| bool publicOnly = (args[1] != 0); |
| ArrayObject* fields; |
| |
| fields = dvmGetDeclaredFields(clazz, publicOnly); |
| dvmReleaseTrackedAlloc((Object*) fields, NULL); |
| |
| RETURN_PTR(fields); |
| } |
| |
| /* |
| * static Field getDeclaredField(Class klass, String name) |
| */ |
| static void Dalvik_java_lang_Class_getDeclaredField(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| StringObject* nameObj = (StringObject*) args[1]; |
| Object* fieldObj = dvmGetDeclaredField(clazz, nameObj); |
| dvmReleaseTrackedAlloc((Object*) fieldObj, NULL); |
| RETURN_PTR(fieldObj); |
| } |
| |
| /* |
| * static Method[] getDeclaredMethods(Class clazz, boolean publicOnly) |
| * throws SecurityException |
| */ |
| static void Dalvik_java_lang_Class_getDeclaredMethods(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| bool publicOnly = (args[1] != 0); |
| ArrayObject* methods; |
| |
| methods = dvmGetDeclaredMethods(clazz, publicOnly); |
| dvmReleaseTrackedAlloc((Object*) methods, NULL); |
| |
| RETURN_PTR(methods); |
| } |
| |
| /* |
| * static native Member getDeclaredConstructorOrMethod( |
| * Class clazz, String name, Class[] args); |
| */ |
| static void Dalvik_java_lang_Class_getDeclaredConstructorOrMethod( |
| const u4* args, JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| StringObject* nameObj = (StringObject*) args[1]; |
| ArrayObject* methodArgs = (ArrayObject*) args[2]; |
| |
| Object* methodObj; |
| |
| methodObj = dvmGetDeclaredConstructorOrMethod(clazz, nameObj, methodArgs); |
| dvmReleaseTrackedAlloc(methodObj, NULL); |
| |
| RETURN_PTR(methodObj); |
| } |
| |
| /* |
| * Class[] getInterfaces() |
| */ |
| static void Dalvik_java_lang_Class_getInterfaces(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| ArrayObject* interfaces; |
| |
| interfaces = dvmGetInterfaces(clazz); |
| dvmReleaseTrackedAlloc((Object*) interfaces, NULL); |
| |
| RETURN_PTR(interfaces); |
| } |
| |
| /* |
| * private static int getModifiers(Class klass, boolean |
| * ignoreInnerClassesAttrib) |
| * |
| * Return the class' modifier flags. If "ignoreInnerClassesAttrib" is false, |
| * and this is an inner class, we return the access flags from the inner class |
| * attribute. |
| */ |
| static void Dalvik_java_lang_Class_getModifiers(const u4* args, JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| bool ignoreInner = args[1]; |
| u4 accessFlags; |
| |
| accessFlags = clazz->accessFlags & JAVA_FLAGS_MASK; |
| |
| if (!ignoreInner) { |
| /* see if we have an InnerClass annotation with flags in it */ |
| StringObject* className = NULL; |
| int innerFlags; |
| |
| if (dvmGetInnerClass(clazz, &className, &innerFlags)) |
| accessFlags = innerFlags & JAVA_FLAGS_MASK; |
| |
| dvmReleaseTrackedAlloc((Object*) className, NULL); |
| } |
| |
| RETURN_INT(accessFlags); |
| } |
| |
| /* |
| * private native String getNameNative() |
| * |
| * Return the class' name. The exact format is bizarre, but it's the specified |
| * behavior: keywords for primitive types, regular "[I" form for primitive |
| * arrays (so "int" but "[I"), and arrays of reference types written |
| * between "L" and ";" but with dots rather than slashes (so "java.lang.String" |
| * but "[Ljava.lang.String;"). Madness. |
| */ |
| static void Dalvik_java_lang_Class_getNameNative(const u4* args, JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| const char* descriptor = clazz->descriptor; |
| StringObject* nameObj; |
| |
| if ((descriptor[0] != 'L') && (descriptor[0] != '[')) { |
| /* |
| * The descriptor indicates that this is the class for |
| * a primitive type; special-case the return value. |
| */ |
| const char* name; |
| switch (descriptor[0]) { |
| case 'Z': name = "boolean"; break; |
| case 'B': name = "byte"; break; |
| case 'C': name = "char"; break; |
| case 'S': name = "short"; break; |
| case 'I': name = "int"; break; |
| case 'J': name = "long"; break; |
| case 'F': name = "float"; break; |
| case 'D': name = "double"; break; |
| case 'V': name = "void"; break; |
| default: { |
| LOGE("Unknown primitive type '%c'\n", descriptor[0]); |
| assert(false); |
| RETURN_PTR(NULL); |
| } |
| } |
| |
| nameObj = dvmCreateStringFromCstr(name); |
| } else { |
| /* |
| * Convert the UTF-8 name to a java.lang.String. The |
| * name must use '.' to separate package components. |
| * |
| * TODO: this could be more efficient. Consider a custom |
| * conversion function here that walks the string once and |
| * avoids the allocation for the common case (name less than, |
| * say, 128 bytes). |
| */ |
| char* dotName = dvmDescriptorToDot(clazz->descriptor); |
| nameObj = dvmCreateStringFromCstr(dotName); |
| free(dotName); |
| } |
| |
| dvmReleaseTrackedAlloc((Object*) nameObj, NULL); |
| RETURN_PTR(nameObj); |
| } |
| |
| /* |
| * Return the superclass for instances of this class. |
| * |
| * If the class represents a java/lang/Object, an interface, a primitive |
| * type, or void (which *is* a primitive type??), return NULL. |
| * |
| * For an array, return the java/lang/Object ClassObject. |
| */ |
| static void Dalvik_java_lang_Class_getSuperclass(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| |
| if (dvmIsPrimitiveClass(clazz) || dvmIsInterfaceClass(clazz)) |
| RETURN_PTR(NULL); |
| else |
| RETURN_PTR(clazz->super); |
| } |
| |
| /* |
| * public boolean isAssignableFrom(Class<?> cls) |
| * |
| * Determine if this class is either the same as, or is a superclass or |
| * superinterface of, the class specified in the "cls" parameter. |
| */ |
| static void Dalvik_java_lang_Class_isAssignableFrom(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* thisPtr = (ClassObject*) args[0]; |
| ClassObject* testClass = (ClassObject*) args[1]; |
| |
| if (testClass == NULL) { |
| dvmThrowNullPointerException(NULL); |
| RETURN_INT(false); |
| } |
| RETURN_INT(dvmInstanceof(testClass, thisPtr)); |
| } |
| |
| /* |
| * public boolean isInstance(Object o) |
| * |
| * Dynamic equivalent of Java programming language "instanceof". |
| */ |
| static void Dalvik_java_lang_Class_isInstance(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* thisPtr = (ClassObject*) args[0]; |
| Object* testObj = (Object*) args[1]; |
| |
| if (testObj == NULL) |
| RETURN_INT(false); |
| RETURN_INT(dvmInstanceof(testObj->clazz, thisPtr)); |
| } |
| |
| /* |
| * public boolean isInterface() |
| */ |
| static void Dalvik_java_lang_Class_isInterface(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* thisPtr = (ClassObject*) args[0]; |
| |
| RETURN_INT(dvmIsInterfaceClass(thisPtr)); |
| } |
| |
| /* |
| * public boolean isPrimitive() |
| */ |
| static void Dalvik_java_lang_Class_isPrimitive(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* thisPtr = (ClassObject*) args[0]; |
| |
| RETURN_INT(dvmIsPrimitiveClass(thisPtr)); |
| } |
| |
| /* |
| * public T newInstance() throws InstantiationException, IllegalAccessException |
| * |
| * Create a new instance of this class. |
| */ |
| static void Dalvik_java_lang_Class_newInstance(const u4* args, JValue* pResult) |
| { |
| Thread* self = dvmThreadSelf(); |
| ClassObject* clazz = (ClassObject*) args[0]; |
| Method* init; |
| Object* newObj; |
| |
| /* can't instantiate these */ |
| if (dvmIsPrimitiveClass(clazz) || dvmIsInterfaceClass(clazz) |
| || dvmIsArrayClass(clazz) || dvmIsAbstractClass(clazz)) |
| { |
| LOGD("newInstance failed: p%d i%d [%d a%d\n", |
| dvmIsPrimitiveClass(clazz), dvmIsInterfaceClass(clazz), |
| dvmIsArrayClass(clazz), dvmIsAbstractClass(clazz)); |
| dvmThrowInstantiationException(clazz, NULL); |
| RETURN_VOID(); |
| } |
| |
| /* initialize the class if it hasn't been already */ |
| if (!dvmIsClassInitialized(clazz)) { |
| if (!dvmInitClass(clazz)) { |
| LOGW("Class init failed in newInstance call (%s)\n", |
| clazz->descriptor); |
| assert(dvmCheckException(self)); |
| RETURN_VOID(); |
| } |
| } |
| |
| /* find the "nullary" constructor */ |
| init = dvmFindDirectMethodByDescriptor(clazz, "<init>", "()V"); |
| if (init == NULL) { |
| /* common cause: secret "this" arg on non-static inner class ctor */ |
| LOGD("newInstance failed: no <init>()\n"); |
| dvmThrowInstantiationException(clazz, "no empty constructor"); |
| RETURN_VOID(); |
| } |
| |
| /* |
| * Verify access from the call site. |
| * |
| * First, make sure the method invoking Class.newInstance() has permission |
| * to access the class. |
| * |
| * Second, make sure it has permission to invoke the constructor. The |
| * constructor must be public or, if the caller is in the same package, |
| * have package scope. |
| */ |
| ClassObject* callerClass = dvmGetCaller2Class(self->interpSave.curFrame); |
| |
| if (!dvmCheckClassAccess(callerClass, clazz)) { |
| LOGD("newInstance failed: %s not accessible to %s\n", |
| clazz->descriptor, callerClass->descriptor); |
| dvmThrowIllegalAccessException("access to class not allowed"); |
| RETURN_VOID(); |
| } |
| if (!dvmCheckMethodAccess(callerClass, init)) { |
| LOGD("newInstance failed: %s.<init>() not accessible to %s\n", |
| clazz->descriptor, callerClass->descriptor); |
| dvmThrowIllegalAccessException("access to constructor not allowed"); |
| RETURN_VOID(); |
| } |
| |
| newObj = dvmAllocObject(clazz, ALLOC_DEFAULT); |
| JValue unused; |
| |
| /* invoke constructor; unlike reflection calls, we don't wrap exceptions */ |
| dvmCallMethod(self, init, newObj, &unused); |
| dvmReleaseTrackedAlloc(newObj, NULL); |
| |
| RETURN_PTR(newObj); |
| } |
| |
| /* |
| * private Object[] getSignatureAnnotation() |
| * |
| * Returns the signature annotation array. |
| */ |
| static void Dalvik_java_lang_Class_getSignatureAnnotation(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| ArrayObject* arr = dvmGetClassSignatureAnnotation(clazz); |
| |
| dvmReleaseTrackedAlloc((Object*) arr, NULL); |
| RETURN_PTR(arr); |
| } |
| |
| /* |
| * public Class getDeclaringClass() |
| * |
| * Get the class that encloses this class (if any). |
| */ |
| static void Dalvik_java_lang_Class_getDeclaringClass(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| |
| ClassObject* enclosing = dvmGetDeclaringClass(clazz); |
| dvmReleaseTrackedAlloc((Object*) enclosing, NULL); |
| RETURN_PTR(enclosing); |
| } |
| |
| /* |
| * public Class getEnclosingClass() |
| * |
| * Get the class that encloses this class (if any). |
| */ |
| static void Dalvik_java_lang_Class_getEnclosingClass(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| |
| ClassObject* enclosing = dvmGetEnclosingClass(clazz); |
| dvmReleaseTrackedAlloc((Object*) enclosing, NULL); |
| RETURN_PTR(enclosing); |
| } |
| |
| /* |
| * public Constructor getEnclosingConstructor() |
| * |
| * Get the constructor that encloses this class (if any). |
| */ |
| static void Dalvik_java_lang_Class_getEnclosingConstructor(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| |
| Object* enclosing = dvmGetEnclosingMethod(clazz); |
| if (enclosing != NULL) { |
| dvmReleaseTrackedAlloc(enclosing, NULL); |
| if (enclosing->clazz == gDvm.classJavaLangReflectConstructor) { |
| RETURN_PTR(enclosing); |
| } |
| assert(enclosing->clazz == gDvm.classJavaLangReflectMethod); |
| } |
| RETURN_PTR(NULL); |
| } |
| |
| /* |
| * public Method getEnclosingMethod() |
| * |
| * Get the method that encloses this class (if any). |
| */ |
| static void Dalvik_java_lang_Class_getEnclosingMethod(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| |
| Object* enclosing = dvmGetEnclosingMethod(clazz); |
| if (enclosing != NULL) { |
| dvmReleaseTrackedAlloc(enclosing, NULL); |
| if (enclosing->clazz == gDvm.classJavaLangReflectMethod) { |
| RETURN_PTR(enclosing); |
| } |
| assert(enclosing->clazz == gDvm.classJavaLangReflectConstructor); |
| } |
| RETURN_PTR(NULL); |
| } |
| |
| #if 0 |
| static void Dalvik_java_lang_Class_getGenericInterfaces(const u4* args, |
| JValue* pResult) |
| { |
| dvmThrowUnsupportedOperationException("native method not implemented"); |
| |
| RETURN_PTR(NULL); |
| } |
| |
| static void Dalvik_java_lang_Class_getGenericSuperclass(const u4* args, |
| JValue* pResult) |
| { |
| dvmThrowUnsupportedOperationException("native method not implemented"); |
| |
| RETURN_PTR(NULL); |
| } |
| |
| static void Dalvik_java_lang_Class_getTypeParameters(const u4* args, |
| JValue* pResult) |
| { |
| dvmThrowUnsupportedOperationException("native method not implemented"); |
| |
| RETURN_PTR(NULL); |
| } |
| #endif |
| |
| /* |
| * public boolean isAnonymousClass() |
| * |
| * Returns true if this is an "anonymous" class. |
| */ |
| static void Dalvik_java_lang_Class_isAnonymousClass(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| StringObject* className = NULL; |
| int accessFlags; |
| |
| /* |
| * If this has an InnerClass annotation, pull it out. Lack of the |
| * annotation, or an annotation with a NULL class name, indicates |
| * that this is an anonymous inner class. |
| */ |
| if (!dvmGetInnerClass(clazz, &className, &accessFlags)) |
| RETURN_BOOLEAN(false); |
| |
| dvmReleaseTrackedAlloc((Object*) className, NULL); |
| RETURN_BOOLEAN(className == NULL); |
| } |
| |
| /* |
| * private Annotation[] getDeclaredAnnotations() |
| * |
| * Return the annotations declared on this class. |
| */ |
| static void Dalvik_java_lang_Class_getDeclaredAnnotations(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| |
| ArrayObject* annos = dvmGetClassAnnotations(clazz); |
| dvmReleaseTrackedAlloc((Object*) annos, NULL); |
| RETURN_PTR(annos); |
| } |
| |
| /* |
| * private Annotation getDeclaredAnnotation(Class annotationClass) |
| */ |
| static void Dalvik_java_lang_Class_getDeclaredAnnotation(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| ClassObject* annotationClazz = (ClassObject*) args[1]; |
| |
| RETURN_PTR(dvmGetClassAnnotation(clazz, annotationClazz)); |
| } |
| |
| /* |
| * private boolean isDeclaredAnnotationPresent(Class annotationClass); |
| */ |
| static void Dalvik_java_lang_Class_isDeclaredAnnotationPresent(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| ClassObject* annotationClazz = (ClassObject*) args[1]; |
| |
| RETURN_BOOLEAN(dvmIsClassAnnotationPresent(clazz, annotationClazz)); |
| } |
| |
| /* |
| * public String getInnerClassName() |
| * |
| * Returns the simple name of a member class or local class, or null otherwise. |
| */ |
| static void Dalvik_java_lang_Class_getInnerClassName(const u4* args, |
| JValue* pResult) |
| { |
| ClassObject* clazz = (ClassObject*) args[0]; |
| StringObject* nameObj; |
| int flags; |
| |
| if (dvmGetInnerClass(clazz, &nameObj, &flags)) { |
| dvmReleaseTrackedAlloc((Object*) nameObj, NULL); |
| RETURN_PTR(nameObj); |
| } else { |
| RETURN_PTR(NULL); |
| } |
| } |
| |
| const DalvikNativeMethod dvm_java_lang_Class[] = { |
| { "desiredAssertionStatus", "()Z", |
| Dalvik_java_lang_Class_desiredAssertionStatus }, |
| { "classForName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;", |
| Dalvik_java_lang_Class_classForName }, |
| { "getClassLoader", "(Ljava/lang/Class;)Ljava/lang/ClassLoader;", |
| Dalvik_java_lang_Class_getClassLoader }, |
| { "getComponentType", "()Ljava/lang/Class;", |
| Dalvik_java_lang_Class_getComponentType }, |
| { "getSignatureAnnotation", "()[Ljava/lang/Object;", |
| Dalvik_java_lang_Class_getSignatureAnnotation }, |
| { "getDeclaredClasses", "(Ljava/lang/Class;Z)[Ljava/lang/Class;", |
| Dalvik_java_lang_Class_getDeclaredClasses }, |
| { "getDeclaredConstructors", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;", |
| Dalvik_java_lang_Class_getDeclaredConstructors }, |
| { "getDeclaredFields", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;", |
| Dalvik_java_lang_Class_getDeclaredFields }, |
| { "getDeclaredMethods", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;", |
| Dalvik_java_lang_Class_getDeclaredMethods }, |
| { "getDeclaredField", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Field;", |
| Dalvik_java_lang_Class_getDeclaredField }, |
| { "getDeclaredConstructorOrMethod", "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;", |
| Dalvik_java_lang_Class_getDeclaredConstructorOrMethod }, |
| { "getInterfaces", "()[Ljava/lang/Class;", |
| Dalvik_java_lang_Class_getInterfaces }, |
| { "getModifiers", "(Ljava/lang/Class;Z)I", |
| Dalvik_java_lang_Class_getModifiers }, |
| { "getNameNative", "()Ljava/lang/String;", |
| Dalvik_java_lang_Class_getNameNative }, |
| { "getSuperclass", "()Ljava/lang/Class;", |
| Dalvik_java_lang_Class_getSuperclass }, |
| { "isAssignableFrom", "(Ljava/lang/Class;)Z", |
| Dalvik_java_lang_Class_isAssignableFrom }, |
| { "isInstance", "(Ljava/lang/Object;)Z", |
| Dalvik_java_lang_Class_isInstance }, |
| { "isInterface", "()Z", |
| Dalvik_java_lang_Class_isInterface }, |
| { "isPrimitive", "()Z", |
| Dalvik_java_lang_Class_isPrimitive }, |
| { "newInstanceImpl", "()Ljava/lang/Object;", |
| Dalvik_java_lang_Class_newInstance }, |
| { "getDeclaringClass", "()Ljava/lang/Class;", |
| Dalvik_java_lang_Class_getDeclaringClass }, |
| { "getEnclosingClass", "()Ljava/lang/Class;", |
| Dalvik_java_lang_Class_getEnclosingClass }, |
| { "getEnclosingConstructor", "()Ljava/lang/reflect/Constructor;", |
| Dalvik_java_lang_Class_getEnclosingConstructor }, |
| { "getEnclosingMethod", "()Ljava/lang/reflect/Method;", |
| Dalvik_java_lang_Class_getEnclosingMethod }, |
| #if 0 |
| { "getGenericInterfaces", "()[Ljava/lang/reflect/Type;", |
| Dalvik_java_lang_Class_getGenericInterfaces }, |
| { "getGenericSuperclass", "()Ljava/lang/reflect/Type;", |
| Dalvik_java_lang_Class_getGenericSuperclass }, |
| { "getTypeParameters", "()Ljava/lang/reflect/TypeVariable;", |
| Dalvik_java_lang_Class_getTypeParameters }, |
| #endif |
| { "isAnonymousClass", "()Z", |
| Dalvik_java_lang_Class_isAnonymousClass }, |
| { "getDeclaredAnnotations", "()[Ljava/lang/annotation/Annotation;", |
| Dalvik_java_lang_Class_getDeclaredAnnotations }, |
| { "getDeclaredAnnotation", "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;", |
| Dalvik_java_lang_Class_getDeclaredAnnotation }, |
| { "isDeclaredAnnotationPresent", "(Ljava/lang/Class;)Z", |
| Dalvik_java_lang_Class_isDeclaredAnnotationPresent }, |
| { "getInnerClassName", "()Ljava/lang/String;", |
| Dalvik_java_lang_Class_getInnerClassName }, |
| { NULL, NULL, NULL }, |
| }; |