Пример #1
0
static void callVoidMethod(Env* env, CallInfo* callInfo) {
    void (*f)(CallInfo*) = _call0;
    rvmPushGatewayFrame(env);
    TrycatchContext tc = {0};
    tc.sel = CATCH_ALL_SEL;
    if (!rvmTrycatchEnter(env, &tc)) {
        f(callInfo);
    }
    rvmTrycatchLeave(env);
    rvmPopGatewayFrame(env);
}
Пример #2
0
void _bcHookInstrumented(DebugEnv* debugEnv, jint lineNumber, jint lineNumberOffset, jbyte* bptable, void* pc) {
    Env* env = (Env*) debugEnv;
    // Temporarily clear any exception that has been thrown. Could be the case if we are called from a catch block.
    Object* throwable = rvmExceptionClear(env);
    // We cannot use ENTER/LEAVEV as it will raise any exception thrown in here. We just want the code to 
    // proceed normally after we return.
    rvmPushGatewayFrame(env);
    rvmHookInstrumented(debugEnv, lineNumber, lineNumberOffset, bptable, pc);
    rvmPopGatewayFrame(env);
    // Restore the exception if one had been thrown when this function was called.
    env->throwable = throwable;
}
Пример #3
0
static jdouble callDoubleMethod(Env* env, CallInfo* callInfo) {
    jdouble result = 0;
    jdouble (*f)(CallInfo*) = (jdouble (*)(CallInfo*)) _call0;
    rvmPushGatewayFrame(env);
    TrycatchContext tc = {0};
    tc.sel = CATCH_ALL_SEL;
    if (!rvmTrycatchEnter(env, &tc)) {
        result = f(callInfo);
    }
    rvmTrycatchLeave(env);
    rvmPopGatewayFrame(env);
    return result;
}
Пример #4
0
static jboolean callBooleanMethod(Env* env, CallInfo* callInfo) {
    jboolean result = FALSE;
    jboolean (*f)(CallInfo*) = (jboolean (*)(CallInfo*)) _call0;
    rvmPushGatewayFrame(env);
    TrycatchContext tc = {0};
    tc.sel = CATCH_ALL_SEL;
    if (!rvmTrycatchEnter(env, &tc)) {
        result = f(callInfo);
    }
    rvmTrycatchLeave(env);
    rvmPopGatewayFrame(env);
    return result;
}
Пример #5
0
static Object* callObjectMethod(Env* env, CallInfo* callInfo) {
    Object* result = NULL;
    Object* (*f)(CallInfo*) = (Object* (*)(CallInfo*)) _call0;
    rvmPushGatewayFrame(env);
    TrycatchContext tc = {0};
    tc.sel = CATCH_ALL_SEL;
    if (!rvmTrycatchEnter(env, &tc)) {
        result = f(callInfo);
    }
    rvmTrycatchLeave(env);
    rvmPopGatewayFrame(env);
    return result;
}
Пример #6
0
void _bcPopCallbackFrame(Env* env) {
    rvmPopGatewayFrame(env);
}
Пример #7
0
void _bcPopNativeFrame(Env* env) {
    rvmPopGatewayFrame(env);
}
Пример #8
0
void _rvmProxyHandler(CallInfo* callInfo) {
    Env* env = (Env*) proxy0NextPtr(callInfo);
    Object* receiver = (Object*) proxy0NextPtr(callInfo);
    Class* proxyClass = receiver->clazz;
    ProxyClassData* proxyClassData = (ProxyClassData*) proxyClass->data;

    LookupKey key;
    memset(&key, 0, sizeof(LookupKey));
    key.name = (char*) env->reserved0;
    key.desc = (char*) env->reserved1;
    LookupEntry* entry;
    HASH_FIND(hh, proxyClassData->lookupsHash, &key, sizeof(LookupKey), entry);
    if (!entry) {
        rvmThrowNoSuchMethodError(env, "Failed to determine which method was called on proxy class");
        goto error;
    }

    ProxyMethod* method = entry->method;

    rvmPushGatewayFrameProxy(env, method);

    jint argsCount = rvmGetParameterCount((Method*) method);
    jvalue *jvalueArgs = NULL;
    if (argsCount > 0) {
        jvalueArgs = (jvalue*) rvmAllocateMemory(env, sizeof(jvalue) * argsCount);
        if (!jvalueArgs) goto errorPop;

        const char* desc = method->method.desc;
        const char* c;
        jint i = 0;
        while ((c = rvmGetNextParameterType(&desc))) {
            switch (c[0]) {
            case 'B':
                jvalueArgs[i++].b = (jbyte) proxy0NextInt(callInfo);
                break;
            case 'Z':
                jvalueArgs[i++].z = (jboolean) proxy0NextInt(callInfo);
                break;
            case 'S':
                jvalueArgs[i++].s = (jshort) proxy0NextInt(callInfo);
                break;
            case 'C':
                jvalueArgs[i++].c = (jchar) proxy0NextInt(callInfo);
                break;
            case 'I':
                jvalueArgs[i++].i = proxy0NextInt(callInfo);
                break;
            case 'J':
                jvalueArgs[i++].j = proxy0NextLong(callInfo);
                break;
            case 'F':
                jvalueArgs[i++].f = proxy0NextFloat(callInfo);
                break;
            case 'D':
                jvalueArgs[i++].d = proxy0NextDouble(callInfo);
                break;
            case '[':
            case 'L':
                jvalueArgs[i++].l = (jobject) proxy0NextPtr(callInfo);
                break;
            }
        }
    }

    jvalue returnValue;
    proxyClassData->handler(env, receiver, method, jvalueArgs, &returnValue);

    rvmPopGatewayFrame(env);

    if (rvmExceptionCheck(env)) goto error;

    proxy0ReturnInt(callInfo, 0);
    switch (rvmGetReturnType(method->method.desc)[0]) {
    case 'B':
        proxy0ReturnInt(callInfo, (jint) returnValue.b);
        break;
    case 'Z':
        proxy0ReturnInt(callInfo, (jint) returnValue.z);
        break;
    case 'S':
        proxy0ReturnInt(callInfo, (jint) returnValue.s);
        break;
    case 'C':
        proxy0ReturnInt(callInfo, (jint) returnValue.c);
        break;
    case 'I':
        proxy0ReturnInt(callInfo, returnValue.i);
        break;
    case 'J':
        proxy0ReturnLong(callInfo, returnValue.j);
        break;
    case 'F':
        proxy0ReturnFloat(callInfo, returnValue.f);
        break;
    case 'D':
        proxy0ReturnDouble(callInfo, returnValue.d);
        break;
    case '[':
    case 'L':
        proxy0ReturnPtr(callInfo, returnValue.l);
        break;
    }

    return;

errorPop:
    rvmPopGatewayFrame(env);
error:
    rvmRaiseException(env, rvmExceptionOccurred(env));
}
Пример #9
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();
}