diff options
author | Jean Boussier <jean.boussier@gmail.com> | 2023-03-02 16:42:24 +0100 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2023-03-02 16:45:06 +0100 |
commit | ca2744aed44da7486b3839b879388af3f6307a88 (patch) | |
tree | c98b63bdeb16cbc6e443f384ffae3a1f1de95b8c /ext/ffi_c/Function.c | |
parent | 227d1ce472ec90144249f8cf85b52d85cbab925c (diff) | |
download | ffi-ca2744aed44da7486b3839b879388af3f6307a88.tar.gz |
Convert FFI::AbstractMemory and descendants to TypedData
Ref: https://github.com/ffi/ffi/pull/991
The old untyped DATA API is soft deprecated and
this new one open the door to write barriers, compaction, memsize etc.
Diffstat (limited to 'ext/ffi_c/Function.c')
-rw-r--r-- | ext/ffi_c/Function.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/ext/ffi_c/Function.c b/ext/ffi_c/Function.c index 1a57591..e395b95 100644 --- a/ext/ffi_c/Function.c +++ b/ext/ffi_c/Function.c @@ -75,8 +75,8 @@ typedef struct Function_ { VALUE rbFunctionInfo; } Function; -static void function_mark(Function *); -static void function_free(Function *); +static void function_mark(void *data); +static void function_free(void *data); static VALUE function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc); static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data); static bool callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize); @@ -95,6 +95,17 @@ static VALUE async_cb_call(void *); extern int ruby_thread_has_gvl_p(void); extern int ruby_native_thread_p(void); +static const rb_data_type_t function_data_type = { + .wrap_struct_name = "FFI::Function", + .function = { + .dmark = function_mark, + .dfree = function_free, + .dsize = NULL, + }, + .parent = &rbffi_pointer_data_type, + .flags = RUBY_TYPED_FREE_IMMEDIATELY +}; + VALUE rbffi_FunctionClass = Qnil; #if defined(DEFER_ASYNC_CALLBACK) @@ -139,7 +150,7 @@ function_allocate(VALUE klass) Function *fn; VALUE obj; - obj = Data_Make_Struct(klass, Function, function_mark, function_free, fn); + obj = TypedData_Make_Struct(klass, Function, &function_data_type, fn); fn->base.memory.flags = MEM_RD; fn->base.rbParent = Qnil; @@ -151,16 +162,18 @@ function_allocate(VALUE klass) } static void -function_mark(Function *fn) +function_mark(void *data) { + Function *fn = (Function *)data; rb_gc_mark(fn->base.rbParent); rb_gc_mark(fn->rbProc); rb_gc_mark(fn->rbFunctionInfo); } static void -function_free(Function *fn) +function_free(void *data) { + Function *fn = (Function *)data; if (fn->methodHandle != NULL) { rbffi_MethodHandle_Free(fn->methodHandle); } @@ -254,7 +267,7 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc) /* If the first callback reference has the same function function signature, use it */ if (cbref != Qnil && CLASS_OF(cbref) == rbffi_FunctionClass) { Function* fp; - Data_Get_Struct(cbref, Function, fp); + TypedData_Get_Struct(cbref, Function, &function_data_type, fp); if (fp->rbFunctionInfo == rbFunctionInfo) { return cbref; } @@ -298,7 +311,7 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc) { Function* fn = NULL; - Data_Get_Struct(self, Function, fn); + TypedData_Get_Struct(self, Function, &function_data_type, fn); fn->rbFunctionInfo = rbFunctionInfo; @@ -306,7 +319,7 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc) if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) { Pointer* orig; - Data_Get_Struct(rbProc, Pointer, orig); + TypedData_Get_Struct(rbProc, Pointer, &rbffi_pointer_data_type, orig); fn->base.memory = orig->memory; fn->base.rbParent = rbProc; @@ -360,7 +373,7 @@ function_call(int argc, VALUE* argv, VALUE self) { Function* fn; - Data_Get_Struct(self, Function, fn); + TypedData_Get_Struct(self, Function, &function_data_type, fn); return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info); } @@ -378,7 +391,7 @@ function_attach(VALUE self, VALUE module, VALUE name) Function* fn; char var[1024]; - Data_Get_Struct(self, Function, fn); + TypedData_Get_Struct(self, Function, &function_data_type, fn); if (fn->info->parameterCount == -1) { rb_raise(rb_eRuntimeError, "cannot attach variadic functions"); @@ -421,7 +434,7 @@ function_set_autorelease(VALUE self, VALUE autorelease) { Function* fn; - Data_Get_Struct(self, Function, fn); + TypedData_Get_Struct(self, Function, &function_data_type, fn); fn->autorelease = RTEST(autorelease); @@ -433,7 +446,7 @@ function_autorelease_p(VALUE self) { Function* fn; - Data_Get_Struct(self, Function, fn); + TypedData_Get_Struct(self, Function, &function_data_type, fn); return fn->autorelease ? Qtrue : Qfalse; } @@ -448,7 +461,7 @@ function_release(VALUE self) { Function* fn; - Data_Get_Struct(self, Function, fn); + TypedData_Get_Struct(self, Function, &function_data_type, fn); if (fn->closure == NULL) { rb_raise(rb_eRuntimeError, "cannot free function which was not allocated"); @@ -796,7 +809,9 @@ invoke_callback(VALUE data) break; case NATIVE_POINTER: if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) { - *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address; + AbstractMemory* memory; + TypedData_Get_Struct(rbReturnValue, AbstractMemory, &rbffi_abstract_memory_data_type, memory); + *((void **) retval) = memory->address; } else { /* Default to returning NULL if not a value pointer object. handles nil case as well */ *((void **) retval) = NULL; @@ -809,15 +824,20 @@ invoke_callback(VALUE data) case NATIVE_FUNCTION: if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) { + AbstractMemory* memory; + TypedData_Get_Struct(rbReturnValue, AbstractMemory, &rbffi_abstract_memory_data_type, memory); - *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address; + *((void **) retval) = memory->address; } else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) { VALUE function; function = rbffi_Function_ForProc(rbReturnType, rbReturnValue); - *((void **) retval) = ((AbstractMemory *) DATA_PTR(function))->address; + AbstractMemory* memory; + TypedData_Get_Struct(function, AbstractMemory, &rbffi_abstract_memory_data_type, memory); + + *((void **) retval) = memory->address; } else { *((void **) retval) = NULL; } |