static VALUE function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc) { Function* fn = NULL; Data_Get_Struct(self, Function, fn); fn->rbFunctionInfo = rbFunctionInfo; Data_Get_Struct(fn->rbFunctionInfo, FunctionType, fn->info); if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) { Pointer* orig; Data_Get_Struct(rbProc, Pointer, orig); fn->base.memory = orig->memory; fn->base.rbParent = rbProc; } else if (rb_obj_is_kind_of(rbProc, rb_cProc) || rb_respond_to(rbProc, id_call)) { if (fn->info->closurePool == NULL) { fn->info->closurePool = rbffi_ClosurePool_New(sizeof(ffi_closure), callback_prep, fn->info); if (fn->info->closurePool == NULL) { rb_raise(rb_eNoMemError, "failed to create closure pool"); } } #if defined(DEFER_ASYNC_CALLBACK) if (async_cb_thread == Qnil) { #if !defined(HAVE_RB_THREAD_BLOCKING_REGION) pipe(async_cb_pipe); fcntl(async_cb_pipe[0], F_SETFL, fcntl(async_cb_pipe[0], F_GETFL) | O_NONBLOCK); fcntl(async_cb_pipe[1], F_SETFL, fcntl(async_cb_pipe[1], F_GETFL) | O_NONBLOCK); #endif async_cb_thread = rb_thread_create(async_cb_event, NULL); } #endif fn->closure = rbffi_Closure_Alloc(fn->info->closurePool); fn->closure->info = fn; fn->base.memory.address = fn->closure->code; fn->base.memory.size = sizeof(*fn->closure); fn->autorelease = true; } else { rb_raise(rb_eTypeError, "wrong argument type %s, expected pointer or proc", rb_obj_classname(rbProc)); } fn->rbProc = rbProc; return self; }
void rbffi_MethodHandle_Init(VALUE module) { defaultClosurePool = rbffi_ClosurePool_New(trampoline_size(), prep_trampoline, NULL); #if defined(CUSTOM_TRAMPOLINE) if (trampoline_offsets(&trampoline_ctx_offset, &trampoline_func_offset) != 0) { rb_raise(rb_eFatal, "Could not locate offsets in trampoline code"); } #else ffi_status ffiStatus = ffi_prep_cif(&mh_cif, FFI_DEFAULT_ABI, 3, &ffi_type_ulong, methodHandleParamTypes); if (ffiStatus != FFI_OK) { rb_raise(rb_eFatal, "ffi_prep_cif failed. status=%#x", ffiStatus); } #endif }
static VALUE function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc) { Function* fn = NULL; Data_Get_Struct(self, Function, fn); fn->rbFunctionInfo = rbFunctionInfo; Data_Get_Struct(fn->rbFunctionInfo, FunctionType, fn->info); if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) { AbstractMemory* memory; Data_Get_Struct(rbProc, AbstractMemory, memory); fn->memory = *memory; } else if (rb_obj_is_kind_of(rbProc, rb_cProc) || rb_respond_to(rbProc, id_call)) { if (fn->info->closurePool == NULL) { fn->info->closurePool = rbffi_ClosurePool_New(sizeof(ffi_closure), callback_prep, fn->info); if (fn->info->closurePool == NULL) { rb_raise(rb_eNoMemError, "failed to create closure pool"); } } fn->closure = rbffi_Closure_Alloc(fn->info->closurePool); fn->closure->info = fn; fn->memory.address = fn->closure->code; fn->memory.size = sizeof(*fn->closure); fn->autorelease = true; } else { rb_raise(rb_eTypeError, "wrong argument type. Expected pointer or proc"); } fn->rbProc = rbProc; return self; }