summaryrefslogtreecommitdiff
path: root/ext/ffi_c/Function.c
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2023-03-02 16:42:24 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-03-02 16:45:06 +0100
commitca2744aed44da7486b3839b879388af3f6307a88 (patch)
treec98b63bdeb16cbc6e443f384ffae3a1f1de95b8c /ext/ffi_c/Function.c
parent227d1ce472ec90144249f8cf85b52d85cbab925c (diff)
downloadffi-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.c52
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;
}