int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg rint; char *s; args[0] = &ffi_type_pointer; values[0] = (void*) &s; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_sint, args) == FFI_OK); s = "a"; ffi_call(&cif, FFI_FN(my_strlen), &rint, values); CHECK(rint == 1); s = "1234567"; ffi_call(&cif, FFI_FN(my_strlen), &rint, values); CHECK(rint == 7); s = "1234567890123456789012345"; ffi_call(&cif, FFI_FN(my_strlen), &rint, values); CHECK(rint == 25); exit (0); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg rint; char *s; float v2; args[0] = &ffi_type_pointer; args[1] = &ffi_type_float; values[0] = (void*) &s; values[1] = (void*) &v2; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ffi_type_sint, args) == FFI_OK); s = "a"; v2 = 0.0; ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 1); s = "1234567"; v2 = -1.0; ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 6); s = "1234567890123456789012345"; v2 = 1.0; ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 26); exit(0); }
int main() { ffi_cif cif; ffi_type *args[1]; void *values[1]; char *s; int rc; void *cfunc = puts; /* Initialize the argument info vectors */ args[0] = &ffi_type_pointer; values[0] = &s; /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args) == FFI_OK) { s = "Hello World!"; ffi_call(&cif, cfunc, &rc, values); /* rc now holds the result of the call to puts */ /* values holds a pointer to the function's arg, so to call puts() again all we need to do is change the value of s */ s = "This is cool!"; ffi_call(&cif, cfunc, &rc, values); } return 0; }
int main(int argc, char *argv[]) { ffi_cif cif; ffi_type *args[1]; void *values[1]; args[0] = &ffi_type_complex_float; if(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_float, args) == FFI_OK) { float answer; float complex input; input = 1.0 + 2.0 * I; values[0] = &input; ffi_call(&cif, (void*) my_float_real, &answer, values); /* printf("answer = %g\n", answer); */ if(answer != 1.0) return 2; ffi_call(&cif, (void*) my_float_imag, &answer, values); /* printf("answer = %g\n", answer); */ if(answer != 2.0) return 2; } else { return 2; } args[0] = &ffi_type_complex_double; if(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_double, args) == FFI_OK) { double answer; double complex input; input = 1.0 + 2.0 * I; values[0] = &input; ffi_call(&cif, (void*) my_double_real, &answer, values); /* printf("answer = %g\n", answer); */ if(answer != 1.0) return 2; ffi_call(&cif, (void*) my_double_imag, &answer, values); /* printf("answer = %g\n", answer); */ if(answer != 2.0) return 2; } else { return 2; } return 0; }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; double rd; float f; double d; long double ld; args[0] = &ffi_type_float; values[0] = &f; args[1] = &ffi_type_double; values[1] = &d; args[2] = &ffi_type_longdouble; values[2] = &ld; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_double, args) == FFI_OK); f = 3.14159; d = (double)1.0/(double)3.0; ld = 2.71828182846L; floating_1 (f, d, ld); ffi_call(&cif, FFI_FN(floating_1), &rd, values); CHECK(fabs(rd - floating_1(f, d, ld)) < DBL_EPSILON); args[0] = &ffi_type_longdouble; values[0] = &ld; args[1] = &ffi_type_double; values[1] = &d; args[2] = &ffi_type_float; values[2] = &f; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_double, args) == FFI_OK); floating_2 (ld, d, f); ffi_call(&cif, FFI_FN(floating_2), &rd, values); CHECK(fabs(rd - floating_2(ld, d, f)) < DBL_EPSILON); exit (0); }
mp_obj_t ffifunc_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_obj_ffifunc_t *self = self_in; assert(n_kw == 0); assert(n_args == self->cif.nargs); ffi_arg values[n_args]; void *valueptrs[n_args]; int i; for (i = 0; i < n_args; i++) { mp_obj_t a = args[i]; if (a == mp_const_none) { values[i] = 0; } else if (MP_OBJ_IS_INT(a)) { values[i] = mp_obj_int_get(a); } else if (MP_OBJ_IS_STR(a)) { const char *s = mp_obj_str_get_str(a); values[i] = (ffi_arg)s; } else if (((mp_obj_base_t*)a)->type->buffer_p.get_buffer != NULL) { mp_obj_base_t *o = (mp_obj_base_t*)a; mp_buffer_info_t bufinfo; int ret = o->type->buffer_p.get_buffer(o, &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ? if (ret != 0 || bufinfo.buf == NULL) { goto error; } values[i] = (ffi_arg)bufinfo.buf; } else if (MP_OBJ_IS_TYPE(a, &fficallback_type)) { mp_obj_fficallback_t *p = a; values[i] = (ffi_arg)p->func; } else { goto error; } valueptrs[i] = &values[i]; } // If ffi_arg is not big enough to hold a double, then we must pass along a // pointer to a memory location of the correct size. // TODO check if this needs to be done for other types which don't fit into // ffi_arg. if (sizeof(ffi_arg) == 4 && self->rettype == 'd') { double retval; ffi_call(&self->cif, self->func, &retval, valueptrs); return mp_obj_new_float(retval); } else { ffi_arg retval; ffi_call(&self->cif, self->func, &retval, valueptrs); return return_ffi_value(retval, self->rettype); } error: nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Don't know how to pass object to native function")); }
static void call_final(mrb_state *mrb, void (*fn)(void), void *ctx, unsigned char *md) { ffi_cif cif; ffi_type *args[2]; void *values[2]; int rc; void *c; unsigned char *m; args[0] = &ffi_type_pointer; args[1] = &ffi_type_pointer; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_uint, args) != FFI_OK) { mrb_raise(mrb, E_RUNTIME_ERROR, "cannot execute function"); } c = ctx; m = md; values[0] = &m; values[1] = &c; ffi_call(&cif, fn, &rc, values); }
int main(void) { ffi_cif cif; ffi_type *args[4] = { &ffi_type_sint, &ffi_type_double, &ffi_type_sint, &ffi_type_double }; double fa[2] = {1,2}; int ia[2] = {1,2}; void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]}; float f, ff; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, &ffi_type_float, args) == FFI_OK); ff = align_arguments(ia[0], fa[0], ia[1], fa[1]);; ffi_call(&cif, FFI_FN(align_arguments), &f, values); if (f == ff) printf("align arguments tests ok!\n"); else CHECK(0); exit(0); }
int main(int argc, char* argv[]) { void* this_application= dlopen(NULL, // this would normally be a filename RTLD_LAZY); if (! this_application ) { printf("Some dlopen error: %s\n", dlerror()); } dlerror(); void* my_greet_voidptr= dlsym(this_application, "greet"); char* error= dlerror(); if (error != NULL) { printf("Some dlsym error: %s\n", error); } void (*my_greet_funptr)(); *(void**)(&my_greet_funptr)= my_greet_voidptr; ffi_cif the_cif; ffi_status status= ffi_prep_cif(&the_cif, FFI_DEFAULT_ABI, 0, // zero arguments &ffi_type_void, // returning void NULL // an array of zero argument types ); if (status != FFI_OK) { printf("Some error.\n"); } ffi_call(&the_cif, my_greet_voidptr, // my_greet_funptr, NULL, // discard any return value NULL // an array of zero arguments ); return 0; }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; float fl1, fl2, fl4, rfl; unsigned int in3; args[0] = &ffi_type_float; args[1] = &ffi_type_float; args[2] = &ffi_type_uint; args[3] = &ffi_type_float; values[0] = &fl1; values[1] = &fl2; values[2] = &in3; values[3] = &fl4; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &ffi_type_float, args) == FFI_OK); fl1 = 127.0; fl2 = 128.0; in3 = 255; fl4 = 512.7; ffi_call(&cif, FFI_FN(return_fl), &rfl, values); printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, in3, fl4)); CHECK(rfl == fl1 + fl2 + in3 + fl4); exit(0); }
void wl_closure_invoke(struct wl_closure *closure, uint32_t flags, struct wl_object *target, uint32_t opcode, void *data) { int count; ffi_cif cif; ffi_type *ffi_types[WL_CLOSURE_MAX_ARGS + 2]; void * ffi_args[WL_CLOSURE_MAX_ARGS + 2]; void (* const *implementation)(void); count = arg_count_for_signature(closure->message->signature); ffi_types[0] = &ffi_type_pointer; ffi_args[0] = &data; ffi_types[1] = &ffi_type_pointer; ffi_args[1] = ⌖ convert_arguments_to_ffi(closure->message->signature, flags, closure->args, count, ffi_types + 2, ffi_args + 2); ffi_prep_cif(&cif, FFI_DEFAULT_ABI, count + 2, &ffi_type_void, ffi_types); implementation = target->implementation; if (!implementation[opcode]) { wl_abort("listener function for opcode %u of %s is NULL\n", opcode, target->interface->name); } ffi_call(&cif, implementation[opcode], NULL, ffi_args); }
void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *raw) { void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); ffi_java_raw_to_ptrarray (cif, raw, avalue); ffi_call (cif, fn, rvalue, avalue); ffi_java_rvalue_to_raw (cif, rvalue); }
mp_obj_t ffifunc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_obj_ffifunc_t *self = self_in; assert(n_kw == 0); assert(n_args == self->cif.nargs); ffi_arg values[n_args]; void *valueptrs[n_args]; int i; for (i = 0; i < n_args; i++) { mp_obj_t a = args[i]; if (a == mp_const_none) { values[i] = 0; } else if (MP_OBJ_IS_INT(a)) { values[i] = mp_obj_int_get(a); } else if (MP_OBJ_IS_STR(a) || MP_OBJ_IS_TYPE(a, &mp_type_bytes)) { const char *s = mp_obj_str_get_str(a); values[i] = (ffi_arg)s; } else if (MP_OBJ_IS_TYPE(a, &fficallback_type)) { mp_obj_fficallback_t *p = a; values[i] = (ffi_arg)p->func; } else { assert(0); } valueptrs[i] = &values[i]; } ffi_arg retval; ffi_call(&self->cif, self->func, &retval, valueptrs); return return_ffi_value(retval, self->rettype); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; long long rlonglong; long long ll1; unsigned ll0, ll2; args[0] = &ffi_type_sint; args[1] = &ffi_type_sint64; args[2] = &ffi_type_sint; values[0] = &ll0; values[1] = &ll1; values[2] = &ll2; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_sint64, args) == FFI_OK); ll0 = 11111111; ll1 = 11111111111000LL; ll2 = 11111111; ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); printf("res: %" PRIdLL ", %" PRIdLL "\n", rlonglong, ll0 + ll1 + ll2); /* { dg-output "res: 11111133333222, 11111133333222" } */ exit(0); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg res; unsigned long ul1, ul2; args[0] = &ffi_type_ulong; args[1] = &ffi_type_ulong; values[0] = &ul1; values[1] = &ul2; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_ulong, args) == FFI_OK); ul1 = 1073741823L; ul2 = 1073741824L; ffi_call(&cif, FFI_FN(return_ul), &res, values); printf("res: %lu, %lu\n", (unsigned long)res, ul1 + ul2); /* { dg-output "res: 2147483647, 2147483647" } */ exit(0); }
void *api_call_method(int numargs, void *obj, void *initptr, va_list vl) { ffi_cif cif; ffi_type *args[numargs + 1]; void *values[numargs + 1]; void **val_heap = (void**)GC_malloc((numargs + 1) * sizeof(void*)); /*new void*[numargs + 1];*/ void *rv; args[0] = &ffi_type_pointer; values[0] = &val_heap[0]; for (int i = 0; i < numargs; i++) { args[i + 1] = &ffi_type_pointer; values[i + 1] = (void*)&val_heap[i + 1]; } int rc = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, numargs + 1, &ffi_type_pointer, args); assert(rc == FFI_OK); val_heap[0] = (void*)obj; for (int i = 0; i < numargs; i++) { val_heap[i + 1] = va_arg(vl, void*); } ffi_call(&cif, (void(*)())initptr, &rv, values); va_end(vl); GC_free(val_heap); /*delete[] val_heap;*/ return rv; }
int main (void) { ffi_cif cif; ffi_type *args[13]; void *values[13]; float fa[13]; float f, ff; int i; for (i = 0; i < 13; i++) { args[i] = &ffi_type_float; values[i] = &fa[i]; fa[i] = (float) i; } /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, &ffi_type_float, args) == FFI_OK); ffi_call(&cif, FFI_FN(many), &f, values); ff = many(fa[0], fa[1], fa[2], fa[3], fa[4], fa[5], fa[6], fa[7], fa[8], fa[9], fa[10],fa[11],fa[12]); if (fabs(f - ff) < FLT_EPSILON) exit(0); else abort(); }
static void invokeArray(JNIEnv* env, jlong ctxAddress, jbyteArray paramBuffer, void* returnBuffer) { Function* ctx = (Function *) j2p(ctxAddress); union { double d; long long ll; jbyte tmp[PARAM_SIZE]; } tmpStackBuffer[MAX_STACK_ARGS]; jbyte *tmpBuffer = (jbyte *) &tmpStackBuffer[0]; void* ffiStackArgs[MAX_STACK_ARGS]; void** ffiArgs = ffiStackArgs; if (ctx->cif.nargs > 0) { unsigned int i; if (ctx->cif.nargs > MAX_STACK_ARGS) { tmpBuffer = alloca_aligned(ctx->cif.nargs * PARAM_SIZE, MIN_ALIGN); ffiArgs = alloca_aligned(ctx->cif.nargs * sizeof(void *), MIN_ALIGN); } (*env)->GetByteArrayRegion(env, paramBuffer, 0, ctx->cif.nargs * PARAM_SIZE, tmpBuffer); for (i = 0; i < ctx->cif.nargs; ++i) { if (ctx->cif.arg_types[i]->type == FFI_TYPE_STRUCT) { ffiArgs[i] = *(void **) &tmpBuffer[i * PARAM_SIZE]; } else { ffiArgs[i] = &tmpBuffer[i * PARAM_SIZE]; } } } ffi_call(&ctx->cif, FFI_FN(ctx->function), returnBuffer, ffiArgs); set_last_error(errno); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg rint; short us; short us2; unsigned long ul = 0; args[0] = &ffi_type_ushort; args[1] = &ffi_type_ushort; values[0] = &us; values[1] = &us2; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_uint, args) == FFI_OK); for (us = 55; us < 30000; us+=1034) { for (us2 = 100; us2 < 30000; us2+=1945) { ffi_call(&cif, FFI_FN(promotion), &rint, values); CHECK((unsigned int)rint == (us << 16 | us2)); } } printf("%lu promotion2 tests run\n", ul); exit(0); }
static void call_hmac_final(mrb_state *mrb, void (*fn)(void), void *ctx, unsigned char *s, size_t *len) { ffi_cif cif; ffi_type *args[3]; void *values[3]; int rc; void *c; unsigned char *d; size_t *l; args[0] = &ffi_type_pointer; args[1] = &ffi_type_pointer; args[2] = &ffi_type_pointer; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_uint, args) != FFI_OK) { mrb_raise(mrb, E_RUNTIME_ERROR, "cannot execute function"); } c = ctx; d = s; l = len; values[0] = &c; values[1] = &d; values[2] = &l; ffi_call(&cif, fn, &rc, values); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg rint; signed char sc; unsigned long ul; args[0] = &ffi_type_schar; values[0] = ≻ /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_schar, args) == FFI_OK); for (sc = (signed char) -127; sc < (signed char) 127; sc++) { ul++; ffi_call(&cif, FFI_FN(return_sc), &rint, values); CHECK(rint == (ffi_arg) sc); } exit(0); }
int main(int argc, char *argv[]) { // dlfcn stuff void *handle; void *puts_addr; // ffi stuff ffi_cif cif; ffi_type *args[1]; void *values[1]; char *s; int rc; // get 'puts' address from global symbol space handle = dlopen(0, RTLD_LAZY); puts_addr = dlsym(handle, "puts"); // initialize the argument info vectors args[0] = &ffi_type_pointer; values[0] = &s; // Initialize the cif if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args) == FFI_OK) { s = "Hello from dlfcn / ffi"; ffi_call(&cif, puts_addr, &rc, values); } return 0; }
int main (void) { ffi_type *ffitypes[NARGS]; int i; ffi_cif cif; ffi_arg result = 0; u8 args[NARGS]; void *argptrs[NARGS]; for (i = 0; i < NARGS; ++i) ffitypes[i] = &ffi_type_uchar; CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, NARGS, &ffi_type_uint8, ffitypes) == FFI_OK); for (i = 0; i < NARGS; ++i) { args[i] = i; argptrs[i] = &args[i]; } ffi_call (&cif, FFI_FN (bar), &result, argptrs); CHECK (result == 21); return 0; }
int32_t __tgt_rtl_run_target_team_region(int32_t device_id, void *tgt_entry_ptr, void **tgt_args, int32_t arg_num, int32_t team_num, int32_t thread_limit, uint64_t loop_tripcount /*not used*/) { // ignore team num and thread limit. // Use libffi to launch execution. ffi_cif cif; // All args are references. std::vector<ffi_type *> args_types(arg_num, &ffi_type_pointer); std::vector<void *> args(arg_num); for (int32_t i = 0; i < arg_num; ++i) args[i] = &tgt_args[i]; ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, arg_num, &ffi_type_void, &args_types[0]); assert(status == FFI_OK && "Unable to prepare target launch!"); if (status != FFI_OK) return OFFLOAD_FAIL; DP("Running entry point at " DPxMOD "...\n", DPxPTR(tgt_entry_ptr)); ffi_call(&cif, FFI_FN(tgt_entry_ptr), NULL, &args[0]); return OFFLOAD_SUCCESS; }
variant external_call(int id,variant a1,variant a2, variant a3, variant a4, variant a5, variant a6, variant a7, variant a8, variant a9,variant a10,variant a11,variant a12,variant a13,variant a14,variant a15,variant a16) { map<int,external*>::iterator it; if ((it=externals.find(id)) == externals.end()) { show_error("Unknown external function called", 0); return 0; } external* a=it->second; ambiguous array[a->argc]; void *arg_values[a->argc]; variant args[] = { a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16 }; for (int i=0;i<a->argc;i++) { if (a->arg_type[i]==&ffi_type_double) array[i].d=(double)args[i]; else array[i].s=((string)args[i]).c_str(); arg_values[i]=&array[i]; } ambiguous result; ffi_call(&(a->cif), a->functionptr, &result, arg_values); if (a->restype==ty_string) return result.s; return result.d; }
/* * Class: com_kenai_jffi_Foreign * Method: invokeArrayReturnStruct * Signature: (J[B[B)V */ JNIEXPORT void JNICALL Java_com_kenai_jffi_Foreign_invokeArrayReturnStruct(JNIEnv* env, jclass self, jlong ctxAddress, jbyteArray paramBuffer, jbyteArray returnBuffer, jint offset) { Function* ctx = (Function *) j2p(ctxAddress); jbyte* retval = alloca(ctx->cif.rtype->size); jbyte* tmpBuffer; void** ffiArgs; int i; // // Due to the undocumented and somewhat strange struct-return handling when // using ffi_raw_call(), we convert from raw to ptr array, then call via normal // ffi_call // ffiArgs = alloca(ctx->cif.nargs * sizeof(void *)); #ifdef USE_RAW tmpBuffer = alloca(ctx->rawParameterSize); (*env)->GetByteArrayRegion(env, paramBuffer, 0, ctx->rawParameterSize, tmpBuffer); for (i = 0; i < (int) ctx->cif.nargs; ++i) { ffiArgs[i] = (tmpBuffer + ctx->rawParamOffsets[i]); } #else tmpBuffer = alloca(ctx->cif.nargs * PARAM_SIZE); (*env)->GetByteArrayRegion(env, paramBuffer, 0, ctx->cif.nargs * PARAM_SIZE, tmpBuffer); for (i = 0; i < (int) ctx->cif.nargs; ++i) { ffiArgs[i] = &tmpBuffer[i * PARAM_SIZE]; } #endif ffi_call(&ctx->cif, FFI_FN(ctx->function), retval, ffiArgs); SAVE_ERRNO(ctx); (*env)->SetByteArrayRegion(env, returnBuffer, offset, ctx->cif.rtype->size, retval); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg res; unsigned long l1, l2; args[0] = &ffi_type_slong; args[1] = &ffi_type_slong; values[0] = &l1; values[1] = &l2; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_slong, args) == FFI_OK); l1 = 1073741823L; l2 = 1073741824L; ffi_call(&cif, FFI_FN(return_sl), &res, values); printf("res: %ld, %ld\n", (long)res, l1 - l2); /* { dg-output "res: -1, -1" } */ exit(0); }
static void invokeArray(JNIEnv* env, jlong ctxAddress, jbyteArray paramBuffer, void* returnBuffer) { Function* ctx = (Function *) j2p(ctxAddress); void** ffiArgs = { NULL }; jbyte *tmpBuffer = NULL; if (ctx->cif.nargs > 0) { unsigned int i; tmpBuffer = alloca(ctx->cif.nargs * PARAM_SIZE); ffiArgs = alloca(ctx->cif.nargs * sizeof(void *)); (*env)->GetByteArrayRegion(env, paramBuffer, 0, ctx->cif.nargs * PARAM_SIZE, tmpBuffer); for (i = 0; i < ctx->cif.nargs; ++i) { if (unlikely(ctx->cif.arg_types[i]->type == FFI_TYPE_STRUCT)) { ffiArgs[i] = *(void **) &tmpBuffer[i * PARAM_SIZE]; } else { ffiArgs[i] = &tmpBuffer[i * PARAM_SIZE]; } } } ffi_call(&ctx->cif, FFI_FN(ctx->function), returnBuffer, ffiArgs); SAVE_ERRNO(ctx); }
static DNode * callmacro(int arg_count, void *units, void *mac, DNode **dnodes, MContext *mc) { ffi_type *args[arg_count]; void *vals[arg_count]; args[0] = &ffi_type_pointer; vals[0] = (void*) &mc; for (int i = 1; i < arg_count; i++) { args[i] = &ffi_type_pointer; vals[i] = (void *) &(dnodes[i - 1]); } ffi_cif cif; ffi_status res = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, arg_count, &ffi_type_pointer, args); _unused(res); assert((res == FFI_OK) && "prep_cif failed, cannot run macro"); DNode *ret_node = NULL; ffi_call(&cif, (void (*)()) mac, (void *) &ret_node, vals); return ret_node; }
cl_object si::call-cfun(cl_narg narg, ...) { #line 940 // ------------------------------2 #line 940 const cl_env_ptr the_env = ecl_process_env(); #line 940 cl_object cc_type; #line 940 va_list ARGS; va_start(ARGS, narg); cl_object fun = va_arg(ARGS,cl_object); cl_object return_type = va_arg(ARGS,cl_object); cl_object arg_types = va_arg(ARGS,cl_object); cl_object args = va_arg(ARGS,cl_object); #line 940 // ------------------------------3 void *cfun = ecl_foreign_data_pointer_safe(fun); cl_object object; volatile cl_index sp; ffi_cif cif; #line 946 // ------------------------------4 #line 946 #line 946 if (ecl_unlikely(narg < 4|| narg > 5)) FEwrong_num_arguments(ecl_make_fixnum(1589)); #line 946 if (narg > 4) { #line 946 cc_type = va_arg(ARGS,cl_object); #line 946 } else { #line 946 cc_type = ECL_SYM(":DEFAULT",1215); #line 946 } #line 946 // ------------------------------5 { sp = ECL_STACK_INDEX(the_env); prepare_cif(the_env, &cif, return_type, arg_types, args, cc_type, NULL); ffi_call(&cif, cfun, the_env->ffi_values, (void **)the_env->ffi_values_ptrs); object = ecl_foreign_data_ref_elt(the_env->ffi_values, ecl_foreign_type_code(return_type)); ECL_STACK_SET_INDEX(the_env, sp); { #line 953 #line 953 cl_object __value0 = object; #line 953 the_env->nvalues = 1; #line 953 return __value0; #line 953 } } }