Example #1
0
jdouble rvmCallDoubleInstanceMethodA(Env* env, Object* obj, Method* method, jvalue* args) {
    CallInfo* callInfo = INIT_CALL_INFO(env, obj, method, TRUE, args);
    if (!callInfo) return 0.0;
    if (obj && CLASS_IS_PROXY(obj->clazz)) {
        env->reserved0 = (void*) method->name;
        env->reserved1 = (void*) method->desc;
    }
    return callDoubleMethod(env, callInfo);
}
Example #2
0
jchar rvmCallNonvirtualCharInstanceMethodA(Env* env, Object* obj, Method* method, jvalue* args) {
    CallInfo* callInfo = INIT_CALL_INFO(env, obj, method, FALSE, args);
    if (!callInfo) return 0;
    if (obj && CLASS_IS_PROXY(obj->clazz)) {
        env->reserved0 = (void*) method->name;
        env->reserved1 = (void*) method->desc;
    }
    return callCharMethod(env, callInfo);
}
Example #3
0
void rvmInitialize(Env* env, Class* clazz) {
    obtainClassLock();
    // TODO: Throw java.lang.NoClassDefFoundError if state == CLASS_ERROR?
    if (CLASS_IS_STATE_ERROR(clazz)) {
        // TODO: Add the class' binary name in the message
        rvmThrowNew(env, java_lang_NoClassDefFoundError, "Could not initialize class ??");
        releaseClassLock();
        return;
    }
    if (!CLASS_IS_STATE_INITIALIZED(clazz) && !CLASS_IS_STATE_INITIALIZING(clazz)) {
        jint oldState = clazz->flags & CLASS_STATE_MASK;
        clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | CLASS_STATE_INITIALIZING;
        if (clazz->superclass) {
            rvmInitialize(env, clazz->superclass);
            if (rvmExceptionOccurred(env)) {
                clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | oldState;
                releaseClassLock();
                return;
            }
        }

        TRACEF("Initializing class %s", clazz->name);
        void* initializer = clazz->initializer;
        if (!initializer) {
            if (!CLASS_IS_ARRAY(clazz) && !CLASS_IS_PROXY(clazz) && !CLASS_IS_PRIMITIVE(clazz)) {
                env->vm->options->classInitialized(env, clazz);
            }
            clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | CLASS_STATE_INITIALIZED;
            releaseClassLock();
            return;
        }

        CallInfo* callInfo = call0AllocateCallInfo(env, initializer, 1, 0, 0, 0, 0);
        call0AddPtr(callInfo, env);
        void (*f)(CallInfo*) = (void (*)(CallInfo*)) _call0;
        rvmPushGatewayFrame(env);
        TrycatchContext tc = {0};
        tc.sel = CATCH_ALL_SEL;
        if (!rvmTrycatchEnter(env, &tc)) {
            f(callInfo);
        }
        rvmTrycatchLeave(env);
        rvmPopGatewayFrame(env);

        Object* exception = rvmExceptionClear(env);
        if (exception) {
            clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | CLASS_STATE_ERROR;
            if (!rvmIsInstanceOf(env, exception, java_lang_Error)) {
                // If exception isn't an instance of java.lang.Error 
                // we must wrap it in a java.lang.ExceptionInInitializerError
                Method* constructor = rvmGetInstanceMethod(env, java_lang_ExceptionInInitializerError, "<init>", "(Ljava/lang/Throwable;)V");
                if (!constructor) return;
                Object* wrappedException = rvmNewObject(env, java_lang_ExceptionInInitializerError, constructor, exception);
                if (!wrappedException) return;
                exception = wrappedException;
            }
            rvmThrow(env, exception);
            releaseClassLock();
            return;
        }
        if (!CLASS_IS_ARRAY(clazz) && !CLASS_IS_PROXY(clazz) && !CLASS_IS_PRIMITIVE(clazz)) {
            env->vm->options->classInitialized(env, clazz);
        }
        clazz->flags = (clazz->flags & (~CLASS_STATE_MASK)) | CLASS_STATE_INITIALIZED;
    }
    releaseClassLock();
}