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 (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); }
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]; if (ctx->cif.nargs > 0) { if (ctx->cif.bytes > (int) sizeof(tmpStackBuffer)) { tmpBuffer = alloca_aligned(ctx->cif.bytes, MIN_ALIGN); } // calculate room needed for return address for struct returns int adj = ctx->cif.rtype->type == FFI_TYPE_STRUCT ? sizeof(void *) : 0; (*env)->GetByteArrayRegion(env, paramBuffer, 0, ctx->rawParameterSize, tmpBuffer + adj); } // For struct return values, we need to push a return value address on the parameter stack if (ctx->cif.rtype->type == FFI_TYPE_STRUCT) { *(void **) tmpBuffer = returnBuffer; } ffi_raw_call(&ctx->cif, FFI_FN(ctx->function), returnBuffer, (ffi_raw *) tmpBuffer); set_last_error(errno); }
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]; 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); }
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); }
/* * 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 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); }
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); }
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); }
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(); }
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); }
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 mrb_value mrb_digest_hmac_hexdigest(mrb_state *mrb, mrb_value self) { mrb_digest *digest; void *ctx_tmp; unsigned char md[MRB_DIGEST_AVAILABLE_SIZ]; size_t md_len; char hex[MRB_HEXDIGEST_AVAILABLE_SIZ]; digest = mrb_get_datatype(mrb, self, &mrb_hmac_type); if (digest == NULL) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } ctx_tmp = malloc(digest->ctx_size); if (ctx_tmp == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "cannot allocate memory"); } memcpy(ctx_tmp, digest->ctx, digest->ctx_size); md_len = 0L; call_hmac_final(mrb, FFI_FN(digest->func_final), ctx_tmp, md, &md_len); free(ctx_tmp); return mrb_str_new(mrb, (const char *)digest2hex(hex, md, md_len), md_len * 2); }
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; }
static mrb_value mrb_digest_digest_bang(mrb_state *mrb, mrb_value self) { mrb_digest *digest; unsigned char md[MRB_DIGEST_AVAILABLE_SIZ]; digest = mrb_get_datatype(mrb, self, &mrb_digest_type); if (digest == NULL) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } call_final(mrb, FFI_FN(digest->func_final), digest->ctx, md); call_init(mrb, FFI_FN(digest->func_init), digest->ctx); return mrb_str_new(mrb, (char *)md, digest->digest_size); }
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_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; }
int main (void) { ffi_cif cif; #ifndef USING_MMAP static ffi_closure cl; #endif ffi_closure *pcl; void* args_dbl[5]; ffi_type* cls_struct_fields[5]; ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; #ifdef USING_MMAP pcl = allocate_mmap (sizeof(ffi_closure)); #else pcl = &cl; #endif cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 }; struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 }; struct cls_struct_7byte res_dbl; cls_struct_fields[0] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[3] = &ffi_type_ushort; cls_struct_fields[4] = NULL; dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[1] = &cls_struct_type; dbl_arg_types[2] = NULL; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, dbl_arg_types) == FFI_OK); args_dbl[0] = &g_dbl; args_dbl[1] = &f_dbl; args_dbl[2] = NULL; ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl); /* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); /* { dg-output "\nres: 139 248 10 509" } */ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_7byte_gn, NULL) == FFI_OK); res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(pcl))(g_dbl, f_dbl); /* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d); /* { dg-output "\nres: 139 248 10 509" } */ exit(0); }
static VALUE call_blocking_function(void* data) { BlockingCall* b = (BlockingCall *) data; ffi_call(&b->info->ffi_cif, FFI_FN(b->function), b->retval, b->ffiValues); return Qnil; }
int main (void) { ffi_cif cif; #ifndef USING_MMAP static ffi_closure cl; #endif ffi_closure *pcl; void* args_dbl[5]; ffi_type* cls_struct_fields[4]; ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; #ifdef USING_MMAP pcl = allocate_mmap (sizeof(ffi_closure)); #else pcl = &cl; #endif cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; struct cls_struct_align g_dbl = { 12, (void *)4951, 127 }; struct cls_struct_align f_dbl = { 1, (void *)9320, 13 }; struct cls_struct_align res_dbl; cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_pointer; cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[3] = NULL; dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[1] = &cls_struct_type; dbl_arg_types[2] = NULL; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, dbl_arg_types) == FFI_OK); args_dbl[0] = &g_dbl; args_dbl[1] = &f_dbl; args_dbl[2] = NULL; ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ printf("res: %d %d %d\n", res_dbl.a, (size_t)res_dbl.b, res_dbl.c); /* { dg-output "\nres: 13 14271 140" } */ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK); res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl); /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ printf("res: %d %d %d\n", res_dbl.a, (size_t)res_dbl.b, res_dbl.c); /* { dg-output "\nres: 13 14271 140" } */ exit(0); }
int main (void) { ffi_cif cif; #ifndef USING_MMAP static ffi_closure cl; #endif ffi_closure *pcl; void* args_dbl[3]; ffi_type* cls_struct_fields[4]; ffi_type cls_struct_type; ffi_type* dbl_arg_types[3]; #ifdef USING_MMAP pcl = allocate_mmap (sizeof(ffi_closure)); #else pcl = &cl; #endif cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 }; struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 }; struct cls_struct_20byte res_dbl; cls_struct_fields[0] = &ffi_type_uint32; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_double; cls_struct_fields[3] = NULL; dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[1] = &cls_struct_type; dbl_arg_types[2] = NULL; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, dbl_arg_types) == FFI_OK); args_dbl[0] = &g_dbl; args_dbl[1] = &f_dbl; args_dbl[2] = NULL; ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl); /* { dg-output "1 2 3 4 5 7: 5 7 10" } */ printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c); /* { dg-output "\nres: 5 7 10" } */ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_20byte_gn, NULL) == FFI_OK); res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(pcl))(g_dbl, f_dbl); /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */ printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c); /* { dg-output "\nres: 5 7 10" } */ exit(0); }
int main (void) { ffi_cif cif; #ifndef USING_MMAP static ffi_closure cl; #endif ffi_closure *pcl; void* args_dbl[5]; ffi_type* cls_struct_fields[4]; ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; #ifdef USING_MMAP pcl = allocate_mmap (sizeof(ffi_closure)); #else pcl = &cl; #endif cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; struct cls_struct_3byte_1 g_dbl = { 15, 125 }; struct cls_struct_3byte_1 f_dbl = { 9, 19 }; struct cls_struct_3byte_1 res_dbl; cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = NULL; dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[1] = &cls_struct_type; dbl_arg_types[2] = NULL; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, dbl_arg_types) == FFI_OK); args_dbl[0] = &g_dbl; args_dbl[1] = &f_dbl; args_dbl[2] = NULL; ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl); /* { dg-output "15 125 9 19: 24 144" } */ printf("res: %d %d\n", res_dbl.a, res_dbl.b); /* { dg-output "\nres: 24 144" } */ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3byte_gn1, NULL) == FFI_OK); res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(pcl))(g_dbl, f_dbl); /* { dg-output "\n15 125 9 19: 24 144" } */ printf("res: %d %d\n", res_dbl.a, res_dbl.b); /* { dg-output "\nres: 24 144" } */ exit(0); }
static VALUE call_blocking_function(void* data) { BlockingCall* b = (BlockingCall *) data; b->frame->has_gvl = false; ffi_call(&b->info->ffi_cif, FFI_FN(b->function), b->retval, b->ffiValues); b->frame->has_gvl = true; return Qnil; }
int main (void) { ffi_cif cif; static ffi_closure cl; ffi_closure *pcl = &cl; void* args_dbl[5]; ffi_type* cls_struct_fields[5]; ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 }; struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 }; struct cls_struct_4_1byte res_dbl; cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[3] = &ffi_type_uchar; cls_struct_fields[4] = NULL; dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[1] = &cls_struct_type; dbl_arg_types[2] = NULL; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, dbl_arg_types) == FFI_OK); args_dbl[0] = &g_dbl; args_dbl[1] = &f_dbl; args_dbl[2] = NULL; ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl); /* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */ CHECK( res_dbl.a == (g_dbl.a + f_dbl.a)); CHECK( res_dbl.b == (g_dbl.b + f_dbl.b)); CHECK( res_dbl.c == (g_dbl.c + f_dbl.c)); CHECK( res_dbl.d == (g_dbl.d + f_dbl.d)); CHECK(ffi_prep_closure(pcl, &cif, cls_struct_4_1byte_gn, NULL) == FFI_OK); res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(pcl))(g_dbl, f_dbl); /* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */ CHECK( res_dbl.a == (g_dbl.a + f_dbl.a)); CHECK( res_dbl.b == (g_dbl.b + f_dbl.b)); CHECK( res_dbl.c == (g_dbl.c + f_dbl.c)); CHECK( res_dbl.d == (g_dbl.d + f_dbl.d)); exit(0); }
int main (void) { ffi_cif cif; #ifndef USING_MMAP static ffi_closure cl; #endif ffi_closure *pcl; void * args_dbl[5]; ffi_type * cl_arg_types[5]; ffi_arg res_call; signed char a, c; signed short b, d, res_closure; #ifdef USING_MMAP pcl = allocate_mmap (sizeof(ffi_closure)); #else pcl = &cl; #endif a = 1; b = 32765; c = 127; d = -128; args_dbl[0] = &a; args_dbl[1] = &b; args_dbl[2] = &c; args_dbl[3] = &d; args_dbl[4] = NULL; cl_arg_types[0] = &ffi_type_schar; cl_arg_types[1] = &ffi_type_sshort; cl_arg_types[2] = &ffi_type_schar; cl_arg_types[3] = &ffi_type_sshort; cl_arg_types[4] = NULL; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &ffi_type_sshort, cl_arg_types) == FFI_OK); ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); /* { dg-output "1 32765 127 -128: 32765" } */ printf("res: %d\n", res_call); /* { dg-output "\nres: 32765" } */ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); res_closure = (*((test_type)pcl))(1, 32765, 127, -128); /* { dg-output "\n1 32765 127 -128: 32765" } */ printf("res: %d\n", res_closure); /* { dg-output "\nres: 32765" } */ exit(0); }
int main(void) { ffi_type* my_ffi_struct_fields[4]; ffi_type my_ffi_struct_type; ffi_cif cif; static ffi_closure cl; ffi_closure *pcl = &cl; void* args[4]; ffi_type* arg_types[3]; struct my_ffi_struct g = { 1.0, 2.0, 3.0 }; struct my_ffi_struct f = { 1.0, 2.0, 3.0 }; struct my_ffi_struct res; my_ffi_struct_type.size = 0; my_ffi_struct_type.alignment = 0; my_ffi_struct_type.type = FFI_TYPE_STRUCT; my_ffi_struct_type.elements = my_ffi_struct_fields; my_ffi_struct_fields[0] = &ffi_type_double; my_ffi_struct_fields[1] = &ffi_type_double; my_ffi_struct_fields[2] = &ffi_type_double; my_ffi_struct_fields[3] = NULL; arg_types[0] = &my_ffi_struct_type; arg_types[1] = &my_ffi_struct_type; arg_types[2] = NULL; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type, arg_types) == FFI_OK); args[0] = &g; args[1] = &f; args[2] = NULL; ffi_call(&cif, FFI_FN(callee), &res, args); /* { dg-output "1 2 3 1 2 3: 2 4 6" } */ CHECK(res.a == 2.0); CHECK(res.b == 4.0); CHECK(res.c == 6.0); CHECK(ffi_prep_closure(pcl, &cif, stub, NULL) == FFI_OK); res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(pcl))(g, f); /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */ CHECK(res.a == 2.0); CHECK(res.b == 4.0); CHECK(res.c == 6.0); exit(0);; }
VALUE rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo) { void* retval; void** ffiValues; FFIStorage* params; ffiValues = ALLOCA_N(void *, fnInfo->parameterCount); params = ALLOCA_N(FFIStorage, fnInfo->parameterCount); retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG)); rbffi_SetupCallParams(argc, argv, fnInfo->parameterCount, fnInfo->nativeParameterTypes, params, ffiValues, fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums); #if defined(HAVE_NATIVETHREAD) && defined(HAVE_RB_THREAD_BLOCKING_REGION) if (unlikely(fnInfo->blocking)) { BlockingCall bc; bc.info = fnInfo; bc.function = function; bc.ffiValues = ffiValues; bc.retval = retval; rb_thread_blocking_region(call_blocking_function, &bc, (void *) -1, NULL); } else { ffi_call(&fnInfo->ffi_cif, FFI_FN(function), retval, ffiValues); } #else ffi_call(&fnInfo->ffi_cif, FFI_FN(function), retval, ffiValues); #endif if (!fnInfo->ignoreErrno) { rbffi_save_errno(); } return rbffi_NativeValue_ToRuby(fnInfo->returnType, fnInfo->rbReturnType, retval, fnInfo->rbEnums); }
static mrb_value mrb_hmac_init(mrb_state *mrb, mrb_value self) { unsigned char *s; mrb_int len; mrb_value digester; mrb_value r; void *evp_func; mrb_digest *digest; void *hmac_init_ex; void *evp_md; mrb_digest_conf *c; digest = init(mrb, self); mrb_get_args(mrb, "so", &s, &len, &digester); r = mrb_funcall(mrb, digester, "to_s", 0); evp_func = get_evp_md_func(mrb, digest, RSTRING_PTR(r)); c = get_digest_conf(RSTRING_PTR(r)); if (c == NULL) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } digest->block_size = c->block_size; digest->digest_size = c->digest_size; evp_md = call_digester(mrb, FFI_FN(evp_func)); hmac_init_ex = get_hmac_init_ex_func(mrb, digest); call_hmac_init_ex(mrb, FFI_FN(hmac_init_ex), digest->ctx, s, len, evp_md, NULL); digest->handle = dlopen("libcrypto.so", RTLD_LAZY); DATA_PTR(self) = digest; DATA_TYPE(self) = &mrb_hmac_type; return self; }