Exemplo n.º 1
0
void
jffi_save_errno_ctx(CallContext* ctx)
{
#ifdef _WIN32
    if (unlikely(ctx->error_fn != NULL)) {
	last_error = (*ctx->error_fn)();
    } else {
	last_error = GetLastError();
    }
#else
    if (unlikely(ctx->error_fn != NULL)) {
	thread_data_get()->error = (*ctx->error_fn)();
    } else {
	thread_data_get()->error = errno;
    }
#endif
}
Exemplo n.º 2
0
void
jffi_save_errno(void)
{
#ifdef _WIN32
    last_error = GetLastError();
    // printf("JFFI Saving ERRNO: %d on thread %d\n", last_error, (int)GetCurrentThreadId());
#else
    thread_data_get()->error = errno;
#endif
}
Exemplo n.º 3
0
/*
 * Class:     com_kenai_jffi_Foreign
 * Method:    getLastError
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_getLastError(JNIEnv* env, jobject self)
{
#ifdef _WIN32
    // printf("Getting ERRNO: %d on thread %d\n", last_error, (int)GetCurrentThreadId());
    return last_error;
#else
    return thread_data_get()->error;
#endif
}
Exemplo n.º 4
0
static void
closure_begin(Closure* closure, JNIEnv** penv, bool* detach)
{
    JavaVM* jvm = closure->magazine->jvm;

    *detach = (*jvm)->GetEnv(jvm, (void **)penv, JNI_VERSION_1_4) != JNI_OK
        && (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)penv, NULL) == JNI_OK;

#ifndef _WIN32
    if (*detach && thread_data_get()->attach_count++ >= THREAD_ATTACH_THRESHOLD) {
        thread_data_get()->attached_vm = jvm;
        *detach = false;
    }
#endif
    
    if ((**penv)->ExceptionCheck(*penv)) {
        (**penv)->ExceptionClear(*penv);
    }
}
Exemplo n.º 5
0
static ssize_t try_handler(machine_t *machine, request_t *request){ // {{{
	ssize_t               ret;
	data_t                freeme;
	request_t            *try_request;
	try_userdata         *userdata          = (try_userdata *)machine->userdata;
	try_threaddata       *threaddata        = thread_data_get(&userdata->thread_data);
	
	threaddata->machine  = machine;
	threaddata->request  = request;
	threaddata->ret      = 0;
	
	data_set_void(&freeme);
	
	if(userdata->request == 0){
		try_request = request;
	}else{
		if( (ret = get_hash(hash_data_find(request, userdata->request), &freeme, &try_request)) < 0)
			return ret;
	}
	
	request_t r_next[] = {
		{ userdata->return_to, DATA_MACHINET(userdata->try_end) },
		hash_inline(try_request),
		hash_end
	};
	
	fastcall_query r_query = { { 3, ACTION_QUERY }, r_next };
	if( (ret = data_query(&userdata->machine, &r_query)) < 0){
		if(userdata->request == 0){
			request_t r_pass[] = {
				{ HK(ret), DATA_PTR_SIZET(&ret) },
				hash_inline(request),
				hash_end
			};
			threaddata->ret = machine_pass(machine, r_pass);
		}else{
			request_t r_pass[] = {
				{ HK(ret), DATA_PTR_SIZET(&ret) },
				hash_inline(try_request),
				hash_end
			};
			
			request_t r_next[] = {
				{ HK(ret),               DATA_PTR_SIZET(&ret)   },
				{ userdata->request_out, DATA_PTR_HASHT(r_pass) },
				hash_inline(request),
				hash_end
			};
			threaddata->ret = machine_pass(machine, r_next);
		}
	}
	
	data_free(&freeme);
	return threaddata->ret;
} // }}}
Exemplo n.º 6
0
/*
 * Class:     com_kenai_jffi_Foreign
 * Method:    setLastError
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_setLastError(JNIEnv* env, jobject self, jint value)
{
#ifdef _WIN32
    // printf("Setting ERRNO: %d on thread %d\n", value, (int)GetCurrentThreadId());
    SetLastError(value);
    last_error = value;
#else
    thread_data_get()->error = errno = value;
#endif
}
Exemplo n.º 7
0
void
rbffi_save_errno(void)
{
    int error = 0;

#ifdef _WIN32
    error = GetLastError();
#else
    error = errno;
#endif

    thread_data_get()->td_errno = error;
}
Exemplo n.º 8
0
static ssize_t try_end_handler(machine_t *machine, request_t *request){ // {{{
	try_userdata         *userdata          = (try_userdata *)machine->userdata;
	try_threaddata       *threaddata        = thread_data_get(&userdata->thread_data);
	
	if(userdata->request == 0){
		threaddata->ret = machine_pass(threaddata->machine, request);
	}else{
		request_t r_next[] = {
			{ userdata->request_out, DATA_PTR_HASHT(request) },
			hash_inline(threaddata->request),
			hash_end
		};
		threaddata->ret = machine_pass(threaddata->machine, r_next);
	}
	return 0;
} // }}}
Exemplo n.º 9
0
static void
closure_end(Closure* closure, JNIEnv* env, bool detach)
{
    JavaVM* jvm = closure->magazine->jvm;
    bool clearException = detach;

#ifndef _WIN32
    if (thread_data_get()->attached_vm != NULL) {
        clearException = true;
    }
#endif

    if (env != NULL && clearException) {
        if ((*env)->ExceptionCheck(env)) {
            (*env)->ExceptionClear(env);
        }
    }

    if (detach) {
        (*jvm)->DetachCurrentThread(jvm);
    }
}
Exemplo n.º 10
0
/*
 * call-seq: error
 * @return [Numeric]
 * Get +errno+ value.
 */
static VALUE
get_last_error(VALUE self)
{
    return INT2NUM(thread_data_get()->td_errno);
}
Exemplo n.º 11
0
static void
closure_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
{
    Closure* closure = (Closure *) user_data;
    
    JNIEnv* env;
    int i;
    bool detach;
#if FAULT_PROTECT_ENABLED
    ThreadData* td = thread_data_get();
    FaultData* fdp;
#endif

    closure_begin(closure, &env, &detach);
#if FAULT_PROTECT_ENABLED
    fdp = td->fault_data;
    td->fault_data = NULL;
#endif

    if (closure->magazine->callWithPrimitiveParameters) {
        // allocate one more than the parameter count (for the struct return value)
        jvalue* jparams = alloca((cif->nargs + 1) * sizeof(jvalue));

        for (i = 0; i < (int) cif->nargs; i++) {
            jvalue* vp = &jparams[i];

            vp->j = 0LL; // zero out any bits not filled below
            switch (cif->arg_types[i]->type) {
                case FFI_TYPE_SINT8:
                case FFI_TYPE_UINT8:
                    vp->b = *(jbyte *) parameters[i];
                    break;

                case FFI_TYPE_SINT16:
                case FFI_TYPE_UINT16:
                    vp->s = *(jshort *) parameters[i];
                    break;

                case FFI_TYPE_SINT32:
                case FFI_TYPE_UINT32:
                case FFI_TYPE_INT:
                    vp->i = *(jint *) parameters[i];
                    break;

                case FFI_TYPE_SINT64:
                case FFI_TYPE_UINT64:
                    vp->j = *(jlong *) parameters[i];
                    break;

                case FFI_TYPE_FLOAT:
                    vp->i = *(jfloat *) parameters[i];
                    break;

                case FFI_TYPE_DOUBLE:
                    vp->i = *(jdouble *) parameters[i];
                    break;

                case FFI_TYPE_POINTER:
                    if (cif->arg_types[i]->size == 4) {
                        vp->i = (uintptr_t) *(void **) parameters[i];
                    } else {
                        vp->j = p2j(*(void **) parameters[i]);
                    }
                    break;

                case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
                case FFI_TYPE_LONGDOUBLE:
#endif
                    vp->j = p2j(parameters[i]);
                    break;

                default:
                    memset(vp, 0, sizeof(*vp));
                    break;

            }
        }

        switch (cif->rtype->type) {
            case FFI_TYPE_VOID:
                (*env)->CallVoidMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                *((ffi_sarg *) retval) = 0;
                break;

            case FFI_TYPE_SINT8:
                *((ffi_sarg *) retval) = (*env)->CallByteMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_SINT16:
                *((ffi_sarg *) retval) = (*env)->CallShortMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_SINT32:
            case FFI_TYPE_INT:
                *((ffi_sarg *) retval) = (*env)->CallIntMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_UINT8:
                *((ffi_arg *) retval) = (*env)->CallByteMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_UINT16:
                *((ffi_arg *) retval) = (*env)->CallShortMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_UINT32:
                *((ffi_arg *) retval) = (*env)->CallIntMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_SINT64:
                *((int64_t *) retval) = (*env)->CallLongMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_UINT64:
                *((uint64_t *) retval) = (*env)->CallLongMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_POINTER:
                if (cif->rtype->size == 4) {
                    *((ffi_arg *) retval) = (*env)->CallIntMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                } else {
                    *((ffi_arg *) retval) = (*env)->CallLongMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                }
                break;

            case FFI_TYPE_FLOAT:
                *((float *) retval) = (*env)->CallFloatMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_DOUBLE:
                *((double *) retval) = (*env)->CallDoubleMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
                case FFI_TYPE_LONGDOUBLE:
#endif
                // stuff the retval in as the last parameter passed to the java method
                jparams[cif->nargs].j = p2j(retval);
                (*env)->CallVoidMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
                break;

            default:
                memset(retval, 0, cif->rtype->size);
        }

    } else {
        jvalue jparams[2];
        jparams[0].j = p2j(retval);
        jparams[1].j = p2j(parameters);
        //
        // Do the actual invoke - the java code will unmarshal the arguments
        //
        (*env)->CallVoidMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
    }


    if ((*env)->ExceptionCheck(env)) {
        memset(retval, 0, cif->rtype->size);
    }

#if FAULT_PROTECT_ENABLED
    td->fault_data = fdp;
#endif
    closure_end(closure, env, detach);
}