Пример #1
0
Object* Java_java_lang_reflect_Array_createMultiArray(Env* env, Class* cls, Class* componentType, IntArray* dimensions) {
    const char* componentTypeDesc = rvmGetClassDescriptor(env, componentType);
    char* desc = rvmAllocateMemoryAtomic(env, strlen(componentTypeDesc) + dimensions->length + 1);
    memset(desc, '[', dimensions->length);
    strcat(desc, componentTypeDesc);

    Class* clazz = rvmFindClassByDescriptor(env, desc, componentType->classLoader);
    return (Object*) rvmNewMultiArray(env, dimensions->length, dimensions->values, clazz);
}
Пример #2
0
static Class* findType(Env* env, const char* classDesc, Object* loader) {
    Class* c = rvmFindClassByDescriptor(env, classDesc, loader);
    if (!c) {
        if (rvmExceptionOccurred(env)->clazz == java_lang_ClassNotFoundException) {
            rvmExceptionClear(env);
            char* className = rvmCopyMemoryAtomicZ(env, classDesc);
            className[strlen(className)] = 0;
            rvmThrowNew(env, java_lang_TypeNotPresentException, rvmFromBinaryClassName(env, &className[1]));
        }
    }
    return c;
}
Пример #3
0
ObjectArray* Java_java_lang_reflect_Method_getParameterTypes(Env* env, Class* clazz, jlong methodPtr) {
    Method* method = (Method*) LONG_TO_PTR(methodPtr);

    jint argsCount = rvmGetParameterCount(method);

    Class* array_java_lang_Class = rvmFindClassUsingLoader(env, "[Ljava/lang/Class;", NULL);
    if (!array_java_lang_Class) return NULL;
    ObjectArray* paramTypes = rvmNewObjectArray(env, argsCount, NULL, array_java_lang_Class, NULL);
    if (!paramTypes) return NULL;

    const char* desc = method->desc;
    const char* s;
    jint i = 0;
    while ((s = rvmGetNextParameterType(&desc))) {
        char* paramTypeName = rvmAllocateMemoryAtomic(env, desc - s + 1);
        if (!paramTypeName) return NULL;
        strncpy(paramTypeName, s, desc - s);
        Class* paramType = rvmFindClassByDescriptor(env, paramTypeName, method->clazz->classLoader);
        if (!paramType) return NULL;
        paramTypes->values[i++] = (Object*) paramType;
    }

    return paramTypes;
}
Пример #4
0
static jboolean getAnnotationValue(Env* env, void** attributes, Class* expectedAnnotationClass, Object* classLoader,
        jvalue* result, jboolean ignoreClassNotFound) {

    char* annotationTypeName = getString(attributes);
    if (expectedAnnotationClass && strncmp(&annotationTypeName[1], expectedAnnotationClass->name, strlen(expectedAnnotationClass->name))) {
        return throwFormatError(env, rvmFromBinaryClassName(env, expectedAnnotationClass->name));
    }

    Class* annotationClass = expectedAnnotationClass;
    if (!annotationClass) {
        annotationClass = rvmFindClassByDescriptor(env, annotationTypeName, classLoader);
        if (!annotationClass) {
            if (ignoreClassNotFound && rvmExceptionOccurred(env)->clazz == java_lang_ClassNotFoundException) {
                rvmExceptionClear(env);
                jint length = getInt(attributes);
                for (jint i = 0; i < length; i++) {
                    getString(attributes);
                    skipElementValue(attributes);
                }
            }
            return FALSE;
        }
    }

    // Find the annotation impl class
    Class* annotationImplClass = findAnnotationImplClass(env, annotationClass, classLoader);
    if (rvmExceptionCheck(env)) return FALSE;

    jint length = getInt(attributes);
    if (length == 0) {
        // No member values specified. Use a singleton instance.
        Method* factoryMethod = rvmGetClassMethod(env, annotationImplClass, "$createSingleton", "()Ljava/lang/Object;");
        if (rvmExceptionCheck(env)) return FALSE;
        Object* annotationObject = rvmCallObjectClassMethod(env, annotationImplClass, factoryMethod);
        if (rvmExceptionCheck(env)) return FALSE;
        result->l = (jobject) annotationObject;
        return TRUE;
    }

    // Call the annotation impl $create() method
    Method* factoryMethod = rvmGetClassMethod(env, annotationImplClass, "$create", "()Ljava/lang/Object;");
    if (rvmExceptionCheck(env)) return FALSE;
    Object* annotationObject = rvmCallObjectClassMethod(env, annotationImplClass, factoryMethod);
    if (rvmExceptionCheck(env)) return FALSE;

    jint i = 0;
    for (i = 0; i < length; i++) {
        char* name = getString(attributes);
        Method* method = getAnnotationValueMethod(env, annotationClass, name);
        if (rvmExceptionCheck(env)) return FALSE;
        if (!method) {
            skipElementValue(attributes);
        } else {
            const char* memberDesc = rvmGetReturnType(method->desc);
            Class* type = findType(env, memberDesc, method->clazz->classLoader);
            Object* value = NULL;
            if (!type) {
                value = rvmExceptionClear(env);
            } else {
                jvalue v = {0};
                if (!parseElementValue(env, attributes, type, classLoader, &v)) {
                    value = rvmExceptionClear(env);
                } else {
                    value = rvmBox(env, type, &v);
                }
            }

            InstanceField* field = getAnnotationMemberField(env, annotationImplClass, method->name);
            if (!field) return FALSE;

            rvmSetObjectInstanceFieldValue(env, annotationObject, field, value);
            if (rvmExceptionCheck(env)) return FALSE;
        }
    }

    result->l = (jobject) annotationObject;
    return TRUE;
}
Пример #5
0
Object* Java_java_lang_reflect_Method_internalInvoke(Env* env, Class* clazz, jlong methodPtr, ObjectArray* parameterTypes, Object* receiver, ObjectArray* args) {
    Method* method = (Method*) LONG_TO_PTR(methodPtr);

    /*
     * The Java code has already checked that the method is accessible
     * to the the caller, that the receiver isn't null (for non static methods),
     * that the receiver is an instance of the declaring class (for non static methods)
     * and that the number of arguments are correct. The args array is never null.
     */

    jvalue* jvalueArgs = validateAndUnwrapArgs(env, parameterTypes, args);
    if (!jvalueArgs) return NULL;

    const char* retDesc = rvmGetReturnType(method->desc);

    jvalue jvalueRet[1];
    if (METHOD_IS_STATIC(method)) {
        switch (retDesc[0]) {
        case 'V':
            rvmCallVoidClassMethodA(env, method->clazz, method, jvalueArgs);
            jvalueRet->l = NULL;
            break;
        case 'Z':
            jvalueRet->z = rvmCallBooleanClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        case 'B':
            jvalueRet->b = rvmCallByteClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        case 'S':
            jvalueRet->s = rvmCallShortClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        case 'C':
            jvalueRet->c = rvmCallCharClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        case 'I':
            jvalueRet->i = rvmCallIntClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        case 'J':
            jvalueRet->j = rvmCallLongClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        case 'F':
            jvalueRet->f = rvmCallFloatClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        case 'D':
            jvalueRet->d = rvmCallDoubleClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        default:
            jvalueRet->l = (jobject) rvmCallObjectClassMethodA(env, method->clazz, method, jvalueArgs);
            break;
        }
    } else {
        switch (retDesc[0]) {
        case 'V':
            rvmCallVoidInstanceMethodA(env, receiver, method, jvalueArgs);
            jvalueRet->l = NULL;
            break;
        case 'Z':
            jvalueRet->z = rvmCallBooleanInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        case 'B':
            jvalueRet->b = rvmCallByteInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        case 'S':
            jvalueRet->s = rvmCallShortInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        case 'C':
            jvalueRet->c = rvmCallCharInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        case 'I':
            jvalueRet->i = rvmCallIntInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        case 'J':
            jvalueRet->j = rvmCallLongInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        case 'F':
            jvalueRet->f = rvmCallFloatInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        case 'D':
            jvalueRet->d = rvmCallDoubleInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        default:
            jvalueRet->l = (jobject) rvmCallObjectInstanceMethodA(env, receiver, method, jvalueArgs);
            break;
        }
    }

    if (rvmExceptionCheck(env)) {
        throwInvocationTargetException(env, rvmExceptionOccurred(env));
        return NULL;
    }

    if (retDesc[0] != 'L' && retDesc[0] != '[') {
        // Return type is primitive. Box it.
        Class* retType = rvmFindClassByDescriptor(env, retDesc, NULL);
        return rvmBox(env, retType, jvalueRet);
    } else {
        return (Object*) jvalueRet->l;
    }
}
Пример #6
0
Class* Java_java_lang_reflect_Method_getReturnType(Env* env, Class* clazz, jlong methodPtr) {
    Method* method = (Method*) LONG_TO_PTR(methodPtr);
    return rvmFindClassByDescriptor(env, rvmGetReturnType(method->desc), method->clazz->classLoader);
}