static VALUE function_attach(VALUE self, VALUE module, VALUE name) { Function* fn; char var[1024]; Data_Get_Struct(self, Function, fn); if (fn->info->parameterCount == -1) { rb_raise(rb_eRuntimeError, "Cannot attach variadic functions"); } if (fn->methodHandle == NULL) { fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->memory.address); } // // Stash the Function in a module variable so it does not get garbage collected // snprintf(var, sizeof(var), "@@%s", StringValueCStr(name)); rb_cv_set(module, var, self); rb_define_module_function(module, StringValueCStr(name), rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1); rb_define_method(module, StringValueCStr(name), rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1); return self; }
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, FunctionInfo, fn->info); if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) { AbstractMemory* memory; Data_Get_Struct(rbProc, AbstractMemory, memory); fn->memory = *memory; fn->rbAddress = rbProc; } else if (rb_obj_is_kind_of(rbProc, rb_cProc)) { fn->rbAddress = rbffi_NativeCallback_NewInstance(fn->rbFunctionInfo, rbProc); NativeCallback* cb; Data_Get_Struct(fn->rbAddress, NativeCallback, cb); fn->memory.address = cb->code; fn->memory.size = LONG_MAX; fn->allocated = true; } else { rb_raise(rb_eTypeError, "wrong argument type. Expected pointer or proc"); } fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->memory.address); return self; }