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 | |
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.
-rw-r--r-- | ext/ffi_c/AbstractMemory.c | 40 | ||||
-rw-r--r-- | ext/ffi_c/AbstractMemory.h | 1 | ||||
-rw-r--r-- | ext/ffi_c/Buffer.c | 57 | ||||
-rw-r--r-- | ext/ffi_c/Call.c | 14 | ||||
-rw-r--r-- | ext/ffi_c/DynamicLibrary.c | 23 | ||||
-rw-r--r-- | ext/ffi_c/Function.c | 52 | ||||
-rw-r--r-- | ext/ffi_c/MemoryPointer.c | 22 | ||||
-rw-r--r-- | ext/ffi_c/Pointer.c | 57 | ||||
-rw-r--r-- | ext/ffi_c/Pointer.h | 1 | ||||
-rw-r--r-- | ext/ffi_c/Struct.c | 10 | ||||
-rw-r--r-- | ext/ffi_c/Types.c | 2 |
11 files changed, 192 insertions, 87 deletions
diff --git a/ext/ffi_c/AbstractMemory.c b/ext/ffi_c/AbstractMemory.c index 1a7fcde..76f2d22 100644 --- a/ext/ffi_c/AbstractMemory.c +++ b/ext/ffi_c/AbstractMemory.c @@ -60,12 +60,22 @@ VALUE rbffi_AbstractMemoryClass = Qnil; static VALUE NullPointerErrorClass = Qnil; static ID id_to_ptr = 0, id_plus = 0, id_call = 0; +const rb_data_type_t rbffi_abstract_memory_data_type = { /* extern */ + .wrap_struct_name = "FFI::AbstractMemory", + .function = { + .dmark = NULL, + .dfree = RUBY_TYPED_DEFAULT_FREE, + .dsize = NULL, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY +}; + static VALUE memory_allocate(VALUE klass) { AbstractMemory* memory; VALUE obj; - obj = Data_Make_Struct(klass, AbstractMemory, NULL, -1, memory); + obj = TypedData_Make_Struct(klass, AbstractMemory, &rbffi_abstract_memory_data_type, memory); memory->flags = MEM_RD | MEM_WR; return obj; @@ -87,7 +97,7 @@ static VALUE \ memory_put_##name(VALUE self, VALUE offset, VALUE value) \ { \ AbstractMemory* memory; \ - Data_Get_Struct(self, AbstractMemory, memory); \ + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, memory); \ memory_op_put_##name(memory, NUM2LONG(offset), value); \ return self; \ } \ @@ -96,7 +106,7 @@ static VALUE \ memory_write_##name(VALUE self, VALUE value) \ { \ AbstractMemory* memory; \ - Data_Get_Struct(self, AbstractMemory, memory); \ + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, memory); \ memory_op_put_##name(memory, 0, value); \ return self; \ } \ @@ -115,7 +125,7 @@ static VALUE \ memory_get_##name(VALUE self, VALUE offset) \ { \ AbstractMemory* memory; \ - Data_Get_Struct(self, AbstractMemory, memory); \ + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, memory); \ return memory_op_get_##name(memory, NUM2LONG(offset)); \ } \ static VALUE memory_read_##name(VALUE self); \ @@ -123,7 +133,7 @@ static VALUE \ memory_read_##name(VALUE self) \ { \ AbstractMemory* memory; \ - Data_Get_Struct(self, AbstractMemory, memory); \ + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, memory); \ return memory_op_get_##name(memory, 0); \ } \ static MemoryOp memory_op_##name = { memory_op_get_##name, memory_op_put_##name }; \ @@ -321,7 +331,7 @@ memory_size(VALUE self) { AbstractMemory* ptr; - Data_Get_Struct(self, AbstractMemory, ptr); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); return LONG2NUM(ptr->size); } @@ -344,7 +354,7 @@ memory_get(VALUE self, VALUE type_name, VALUE offset) nType = rbffi_Type_Lookup(type_name); if(NIL_P(nType)) goto undefined_type; - Data_Get_Struct(self, AbstractMemory, ptr); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); Data_Get_Struct(nType, Type, type); MemoryOp *op = get_memory_op(type); @@ -376,7 +386,7 @@ memory_put(VALUE self, VALUE type_name, VALUE offset, VALUE value) nType = rbffi_Type_Lookup(type_name); if(NIL_P(nType)) goto undefined_type; - Data_Get_Struct(self, AbstractMemory, ptr); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); Data_Get_Struct(nType, Type, type); MemoryOp *op = get_memory_op(type); @@ -442,7 +452,7 @@ memory_get_array_of_string(int argc, VALUE* argv, VALUE self) count = (countnum == Qnil ? 0 : NUM2INT(countnum)); retVal = rb_ary_new2(count); - Data_Get_Struct(self, AbstractMemory, ptr); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); checkRead(ptr); if (countnum != Qnil) { @@ -633,7 +643,7 @@ memory_type_size(VALUE self) { AbstractMemory* ptr; - Data_Get_Struct(self, AbstractMemory, ptr); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); return INT2NUM(ptr->typeSize); } @@ -651,7 +661,7 @@ memory_aref(VALUE self, VALUE idx) AbstractMemory* ptr; VALUE rbOffset = Qnil; - Data_Get_Struct(self, AbstractMemory, ptr); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); rbOffset = ULONG2NUM(NUM2ULONG(idx) * ptr->typeSize); @@ -661,7 +671,9 @@ memory_aref(VALUE self, VALUE idx) static inline char* memory_address(VALUE obj) { - return ((AbstractMemory *) DATA_PTR(obj))->address; + AbstractMemory *mem; + TypedData_Get_Struct(obj, AbstractMemory, &rbffi_abstract_memory_data_type, mem); + return mem->address; } static VALUE @@ -669,7 +681,7 @@ memory_copy_from(VALUE self, VALUE rbsrc, VALUE rblen) { AbstractMemory* dst; - Data_Get_Struct(self, AbstractMemory, dst); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, dst); memcpy(dst->address, rbffi_AbstractMemory_Cast(rbsrc, rbffi_AbstractMemoryClass)->address, NUM2INT(rblen)); @@ -681,7 +693,7 @@ rbffi_AbstractMemory_Cast(VALUE obj, VALUE klass) { if (rb_obj_is_kind_of(obj, klass)) { AbstractMemory* memory; - Data_Get_Struct(obj, AbstractMemory, memory); + TypedData_Get_Struct(obj, AbstractMemory, &rbffi_abstract_memory_data_type, memory); return memory; } diff --git a/ext/ffi_c/AbstractMemory.h b/ext/ffi_c/AbstractMemory.h index 1119288..8c75373 100644 --- a/ext/ffi_c/AbstractMemory.h +++ b/ext/ffi_c/AbstractMemory.h @@ -86,6 +86,7 @@ struct AbstractMemory_ { }; +extern const rb_data_type_t rbffi_abstract_memory_data_type; extern VALUE rbffi_AbstractMemoryClass; extern MemoryOps rbffi_AbstractMemoryOps; diff --git a/ext/ffi_c/Buffer.c b/ext/ffi_c/Buffer.c index b5f39a4..e3ed90b 100644 --- a/ext/ffi_c/Buffer.c +++ b/ext/ffi_c/Buffer.c @@ -49,10 +49,33 @@ typedef struct Buffer { static VALUE buffer_allocate(VALUE klass); static VALUE buffer_initialize(int argc, VALUE* argv, VALUE self); -static void buffer_release(Buffer* ptr); -static void buffer_mark(Buffer* ptr); +static void buffer_release(void *data); +static void buffer_mark(void *data); static VALUE buffer_free(VALUE self); +static const rb_data_type_t buffer_data_type = { + .wrap_struct_name = "FFI::Buffer", + .function = { + .dmark = buffer_mark, + .dfree = RUBY_TYPED_DEFAULT_FREE, + .dsize = NULL, + }, + .parent = &rbffi_abstract_memory_data_type, + .flags = RUBY_TYPED_FREE_IMMEDIATELY +}; + +static const rb_data_type_t allocated_buffer_data_type = { + .wrap_struct_name = "FFI::Buffer(allocated)", + .function = { + .dmark = NULL, + .dfree = buffer_release, + .dsize = NULL, + }, + .parent = &buffer_data_type, + .flags = RUBY_TYPED_FREE_IMMEDIATELY +}; + + static VALUE BufferClass = Qnil; static VALUE @@ -61,7 +84,7 @@ buffer_allocate(VALUE klass) Buffer* buffer; VALUE obj; - obj = Data_Make_Struct(klass, Buffer, NULL, buffer_release, buffer); + obj = TypedData_Make_Struct(klass, Buffer, &allocated_buffer_data_type, buffer); buffer->data.rbParent = Qnil; buffer->memory.flags = MEM_RD | MEM_WR; @@ -69,8 +92,9 @@ buffer_allocate(VALUE klass) } static void -buffer_release(Buffer* ptr) +buffer_release(void *data) { + Buffer *ptr = (Buffer *)data; if ((ptr->memory.flags & MEM_EMBED) == 0 && ptr->data.storage != NULL) { xfree(ptr->data.storage); ptr->data.storage = NULL; @@ -95,7 +119,7 @@ buffer_initialize(int argc, VALUE* argv, VALUE self) Buffer* p; int nargs; - Data_Get_Struct(self, Buffer, p); + TypedData_Get_Struct(self, Buffer, &buffer_data_type, p); nargs = rb_scan_args(argc, argv, "12", &rbSize, &rbCount, &rbClear); p->memory.typeSize = rbffi_type_size(rbSize); @@ -137,8 +161,8 @@ buffer_initialize_copy(VALUE self, VALUE other) { AbstractMemory* src; Buffer* dst; - - Data_Get_Struct(self, Buffer, dst); + + TypedData_Get_Struct(self, Buffer, &buffer_data_type, dst); src = rbffi_AbstractMemory_Cast(other, BufferClass); if ((dst->memory.flags & MEM_EMBED) == 0 && dst->data.storage != NULL) { xfree(dst->data.storage); @@ -171,11 +195,11 @@ slice(VALUE self, long offset, long len) Buffer* ptr; Buffer* result; VALUE obj = Qnil; - - Data_Get_Struct(self, Buffer, ptr); + + TypedData_Get_Struct(self, Buffer, &buffer_data_type, ptr); checkBounds(&ptr->memory, offset, len); - obj = Data_Make_Struct(BufferClass, Buffer, buffer_mark, -1, result); + obj = TypedData_Make_Struct(BufferClass, Buffer, &buffer_data_type, result); result->memory.address = ptr->memory.address + offset; result->memory.size = len; result->memory.flags = ptr->memory.flags; @@ -197,7 +221,7 @@ buffer_plus(VALUE self, VALUE rbOffset) Buffer* ptr; long offset = NUM2LONG(rbOffset); - Data_Get_Struct(self, Buffer, ptr); + TypedData_Get_Struct(self, Buffer, &buffer_data_type, ptr); return slice(self, offset, ptr->memory.size - offset); } @@ -226,7 +250,7 @@ buffer_inspect(VALUE self) char tmp[100]; Buffer* ptr; - Data_Get_Struct(self, Buffer, ptr); + TypedData_Get_Struct(self, Buffer, &buffer_data_type, ptr); snprintf(tmp, sizeof(tmp), "#<FFI:Buffer:%p address=%p size=%ld>", ptr, ptr->memory.address, ptr->memory.size); @@ -255,7 +279,7 @@ buffer_order(int argc, VALUE* argv, VALUE self) { Buffer* ptr; - Data_Get_Struct(self, Buffer, ptr); + TypedData_Get_Struct(self, Buffer, &buffer_data_type, ptr); if (argc == 0) { int order = (ptr->memory.flags & MEM_SWAP) == 0 ? BYTE_ORDER : SWAPPED_ORDER; return order == BIG_ENDIAN ? ID2SYM(rb_intern("big")) : ID2SYM(rb_intern("little")); @@ -279,7 +303,7 @@ buffer_order(int argc, VALUE* argv, VALUE self) Buffer* p2; VALUE retval = slice(self, 0, ptr->memory.size); - Data_Get_Struct(retval, Buffer, p2); + TypedData_Get_Struct(retval, Buffer, &buffer_data_type, p2); p2->memory.flags |= MEM_SWAP; return retval; } @@ -294,7 +318,7 @@ buffer_free(VALUE self) { Buffer* ptr; - Data_Get_Struct(self, Buffer, ptr); + TypedData_Get_Struct(self, Buffer, &buffer_data_type, ptr); if ((ptr->memory.flags & MEM_EMBED) == 0 && ptr->data.storage != NULL) { xfree(ptr->data.storage); ptr->data.storage = NULL; @@ -304,8 +328,9 @@ buffer_free(VALUE self) } static void -buffer_mark(Buffer* ptr) +buffer_mark(void *data) { + Buffer *ptr = (Buffer *)data; rb_gc_mark(ptr->data.rbParent); } diff --git a/ext/ffi_c/Call.c b/ext/ffi_c/Call.c index bd6c277..87dd554 100644 --- a/ext/ffi_c/Call.c +++ b/ext/ffi_c/Call.c @@ -420,7 +420,9 @@ getPointer(VALUE value, int type) { if (likely(type == T_DATA && rb_obj_is_kind_of(value, rbffi_AbstractMemoryClass))) { - return ((AbstractMemory *) DATA_PTR(value))->address; + AbstractMemory *mem; + TypedData_Get_Struct(value, AbstractMemory, &rbffi_abstract_memory_data_type, mem); + return mem->address; } else if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_StructClass)) { @@ -439,7 +441,9 @@ getPointer(VALUE value, int type) VALUE ptr = rb_funcall2(value, id_to_ptr, 0, NULL); if (rb_obj_is_kind_of(ptr, rbffi_AbstractMemoryClass) && TYPE(ptr) == T_DATA) { - return ((AbstractMemory *) DATA_PTR(ptr))->address; + AbstractMemory *mem; + TypedData_Get_Struct(ptr, AbstractMemory, &rbffi_abstract_memory_data_type, mem); + return mem->address; } rb_raise(rb_eArgError, "to_ptr returned an invalid pointer"); } @@ -466,14 +470,16 @@ callback_param(VALUE proc, VALUE cbInfo) /* Handle Function pointers here */ if (rb_obj_is_kind_of(proc, rbffi_FunctionClass)) { AbstractMemory* ptr; - Data_Get_Struct(proc, AbstractMemory, ptr); + TypedData_Get_Struct(proc, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); return ptr->address; } callback = rbffi_Function_ForProc(cbInfo, proc); RB_GC_GUARD(callback); - return ((AbstractMemory *) DATA_PTR(callback))->address; + AbstractMemory *mem; + TypedData_Get_Struct(callback, AbstractMemory, &rbffi_abstract_memory_data_type, mem); + return mem->address; } diff --git a/ext/ffi_c/DynamicLibrary.c b/ext/ffi_c/DynamicLibrary.c index 78b3de6..eb55fc2 100644 --- a/ext/ffi_c/DynamicLibrary.c +++ b/ext/ffi_c/DynamicLibrary.c @@ -54,13 +54,25 @@ typedef struct LibrarySymbol_ { VALUE name; } LibrarySymbol; + static VALUE library_initialize(VALUE self, VALUE libname, VALUE libflags); static void library_free(Library* lib); static VALUE symbol_allocate(VALUE klass); static VALUE symbol_new(VALUE library, void* address, VALUE name); -static void symbol_mark(LibrarySymbol* sym); +static void symbol_mark(void *data); + +static const rb_data_type_t library_symbol_data_type = { + .wrap_struct_name = "FFI::DynamicLibrary::Symbol", + .function = { + .dmark = symbol_mark, + .dfree = RUBY_TYPED_DEFAULT_FREE, + .dsize = NULL, + }, + .parent = &rbffi_pointer_data_type, + .flags = RUBY_TYPED_FREE_IMMEDIATELY +}; static VALUE LibraryClass = Qnil, SymbolClass = Qnil; @@ -198,7 +210,7 @@ static VALUE symbol_allocate(VALUE klass) { LibrarySymbol* sym; - VALUE obj = Data_Make_Struct(klass, LibrarySymbol, NULL, -1, sym); + VALUE obj = TypedData_Make_Struct(klass, LibrarySymbol, &library_symbol_data_type, sym); sym->name = Qnil; sym->library = Qnil; sym->base.rbParent = Qnil; @@ -224,7 +236,7 @@ static VALUE symbol_new(VALUE library, void* address, VALUE name) { LibrarySymbol* sym; - VALUE obj = Data_Make_Struct(SymbolClass, LibrarySymbol, symbol_mark, -1, sym); + VALUE obj = TypedData_Make_Struct(SymbolClass, LibrarySymbol, &library_symbol_data_type, sym); sym->base.memory.address = address; sym->base.memory.size = LONG_MAX; @@ -237,8 +249,9 @@ symbol_new(VALUE library, void* address, VALUE name) } static void -symbol_mark(LibrarySymbol* sym) +symbol_mark(void *data) { + LibrarySymbol *sym = (LibrarySymbol *)data; rb_gc_mark(sym->library); rb_gc_mark(sym->name); } @@ -254,7 +267,7 @@ symbol_inspect(VALUE self) LibrarySymbol* sym; char buf[256]; - Data_Get_Struct(self, LibrarySymbol, sym); + TypedData_Get_Struct(self, LibrarySymbol, &library_symbol_data_type, sym); snprintf(buf, sizeof(buf), "#<FFI::Library::Symbol name=%s address=%p>", StringValueCStr(sym->name), sym->base.memory.address); return rb_str_new2(buf); 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; } diff --git a/ext/ffi_c/MemoryPointer.c b/ext/ffi_c/MemoryPointer.c index 1a64f2e..cfdfa60 100644 --- a/ext/ffi_c/MemoryPointer.c +++ b/ext/ffi_c/MemoryPointer.c @@ -39,7 +39,7 @@ static VALUE memptr_allocate(VALUE klass); -static void memptr_release(Pointer* ptr); +static void memptr_release(void *data); static VALUE memptr_malloc(VALUE self, long size, long count, bool clear); static VALUE memptr_free(VALUE self); @@ -53,11 +53,22 @@ rbffi_MemoryPointer_NewInstance(long size, long count, bool clear) return memptr_malloc(memptr_allocate(rbffi_MemoryPointerClass), size, count, clear); } +static const rb_data_type_t memory_pointer_data_type = { + .wrap_struct_name = "FFI::MemoryPointer", + .function = { + .dmark = NULL, + .dfree = memptr_release, + .dsize = NULL, + }, + .parent = &rbffi_pointer_data_type, + .flags = RUBY_TYPED_FREE_IMMEDIATELY +}; + static VALUE memptr_allocate(VALUE klass) { Pointer* p; - VALUE obj = Data_Make_Struct(klass, Pointer, NULL, memptr_release, p); + VALUE obj = TypedData_Make_Struct(klass, Pointer, &memory_pointer_data_type, p); p->rbParent = Qnil; p->memory.flags = MEM_RD | MEM_WR; @@ -94,7 +105,7 @@ memptr_malloc(VALUE self, long size, long count, bool clear) Pointer* p; unsigned long msize; - Data_Get_Struct(self, Pointer, p); + TypedData_Get_Struct(self, Pointer, &memory_pointer_data_type, p); msize = size * count; @@ -122,7 +133,7 @@ memptr_free(VALUE self) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &memory_pointer_data_type, ptr); if (ptr->allocated) { if (ptr->storage != NULL) { @@ -136,8 +147,9 @@ memptr_free(VALUE self) } static void -memptr_release(Pointer* ptr) +memptr_release(void *data) { + Pointer *ptr = (Pointer *)data; if (ptr->autorelease && ptr->allocated && ptr->storage != NULL) { xfree(ptr->storage); ptr->storage = NULL; diff --git a/ext/ffi_c/Pointer.c b/ext/ffi_c/Pointer.c index 7988681..3d26555 100644 --- a/ext/ffi_c/Pointer.c +++ b/ext/ffi_c/Pointer.c @@ -41,8 +41,19 @@ VALUE rbffi_PointerClass = Qnil; VALUE rbffi_NullPointerSingleton = Qnil; -static void ptr_release(Pointer* ptr); -static void ptr_mark(Pointer* ptr); +static void ptr_release(void *data); +static void ptr_mark(void *data); + +const rb_data_type_t rbffi_pointer_data_type = { /* extern */ + .wrap_struct_name = "FFI::Pointer", + .function = { + .dmark = ptr_mark, + .dfree = ptr_release, + .dsize = NULL, + }, + .parent = &rbffi_abstract_memory_data_type, + .flags = RUBY_TYPED_FREE_IMMEDIATELY +}; VALUE rbffi_Pointer_NewInstance(void* addr) @@ -54,7 +65,7 @@ rbffi_Pointer_NewInstance(void* addr) return rbffi_NullPointerSingleton; } - obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p); + obj = TypedData_Make_Struct(rbffi_PointerClass, Pointer, &rbffi_pointer_data_type, p); p->memory.address = addr; p->memory.size = LONG_MAX; p->memory.flags = (addr == NULL) ? 0 : (MEM_RD | MEM_WR); @@ -70,7 +81,7 @@ ptr_allocate(VALUE klass) Pointer* p; VALUE obj; - obj = Data_Make_Struct(klass, Pointer, ptr_mark, ptr_release, p); + obj = TypedData_Make_Struct(klass, Pointer, &rbffi_pointer_data_type, p); p->rbParent = Qnil; p->memory.flags = MEM_RD | MEM_WR; @@ -95,7 +106,7 @@ ptr_initialize(int argc, VALUE* argv, VALUE self) VALUE rbType = Qnil, rbAddress = Qnil; int typeSize = 1; - Data_Get_Struct(self, Pointer, p); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, p); switch (rb_scan_args(argc, argv, "11", &rbType, &rbAddress)) { case 1: @@ -124,7 +135,7 @@ ptr_initialize(int argc, VALUE* argv, VALUE self) Pointer* orig; p->rbParent = rbAddress; - Data_Get_Struct(rbAddress, Pointer, orig); + TypedData_Get_Struct(rbAddress, Pointer, &rbffi_pointer_data_type, orig); p->memory = orig->memory; } else { rb_raise(rb_eTypeError, "wrong argument type, expected Integer or FFI::Pointer"); @@ -153,7 +164,7 @@ ptr_initialize_copy(VALUE self, VALUE other) AbstractMemory* src; Pointer* dst; - Data_Get_Struct(self, Pointer, dst); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, dst); src = POINTER(other); if (src->size == LONG_MAX) { rb_raise(rb_eRuntimeError, "cannot duplicate unbounded memory area"); @@ -195,10 +206,10 @@ slice(VALUE self, long offset, long size) Pointer* p; VALUE retval; - Data_Get_Struct(self, AbstractMemory, ptr); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); checkBounds(ptr, offset, size == LONG_MAX ? 1 : size); - retval = Data_Make_Struct(rbffi_PointerClass, Pointer, ptr_mark, -1, p); + retval = TypedData_Make_Struct(rbffi_PointerClass, Pointer, &rbffi_pointer_data_type, p); p->memory.address = ptr->address + offset; p->memory.size = size; @@ -222,7 +233,7 @@ ptr_plus(VALUE self, VALUE offset) AbstractMemory* ptr; long off = NUM2LONG(offset); - Data_Get_Struct(self, AbstractMemory, ptr); + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, ptr); return slice(self, off, ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off); } @@ -252,7 +263,7 @@ ptr_inspect(VALUE self) char buf[100]; Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); if (ptr->memory.size != LONG_MAX) { snprintf(buf, sizeof(buf), "#<%s address=%p size=%lu>", @@ -275,7 +286,7 @@ ptr_null_p(VALUE self) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); return ptr->memory.address == NULL ? Qtrue : Qfalse; } @@ -291,7 +302,7 @@ ptr_equals(VALUE self, VALUE other) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); if (NIL_P(other)) { return ptr->memory.address == NULL ? Qtrue : Qfalse; @@ -310,7 +321,7 @@ ptr_address(VALUE self) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); return ULL2NUM((uintptr_t) ptr->memory.address); } @@ -335,7 +346,7 @@ ptr_order(int argc, VALUE* argv, VALUE self) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); if (argc == 0) { int order = (ptr->memory.flags & MEM_SWAP) == 0 ? BYTE_ORDER : SWAPPED_ORDER; return order == BIG_ENDIAN ? ID2SYM(rb_intern("big")) : ID2SYM(rb_intern("little")); @@ -361,7 +372,7 @@ ptr_order(int argc, VALUE* argv, VALUE self) Pointer* p2; VALUE retval = slice(self, 0, ptr->memory.size); - Data_Get_Struct(retval, Pointer, p2); + TypedData_Get_Struct(retval, Pointer, &rbffi_pointer_data_type, p2); p2->memory.flags |= MEM_SWAP; return retval; } @@ -381,7 +392,7 @@ ptr_free(VALUE self) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); if (ptr->allocated) { if (ptr->storage != NULL) { @@ -404,7 +415,7 @@ ptr_type_size(VALUE self) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); return INT2NUM(ptr->memory.typeSize); } @@ -420,7 +431,7 @@ ptr_autorelease(VALUE self, VALUE autorelease) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); ptr->autorelease = autorelease == Qtrue; return autorelease; @@ -436,15 +447,16 @@ ptr_autorelease_p(VALUE self) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr); return ptr->autorelease ? Qtrue : Qfalse; } static void -ptr_release(Pointer* ptr) +ptr_release(void *data) { + Pointer *ptr = (Pointer *)data; if (ptr->autorelease && ptr->allocated && ptr->storage != NULL) { xfree(ptr->storage); ptr->storage = NULL; @@ -453,8 +465,9 @@ ptr_release(Pointer* ptr) } static void -ptr_mark(Pointer* ptr) +ptr_mark(void *data) { + Pointer *ptr = (Pointer *)data; rb_gc_mark(ptr->rbParent); } diff --git a/ext/ffi_c/Pointer.h b/ext/ffi_c/Pointer.h index b3d6c85..0dfd8b2 100644 --- a/ext/ffi_c/Pointer.h +++ b/ext/ffi_c/Pointer.h @@ -40,6 +40,7 @@ extern "C" { extern void rbffi_Pointer_Init(VALUE moduleFFI); extern VALUE rbffi_Pointer_NewInstance(void* addr); +extern const rb_data_type_t rbffi_pointer_data_type; extern VALUE rbffi_PointerClass; extern VALUE rbffi_NullPointerSingleton; diff --git a/ext/ffi_c/Struct.c b/ext/ffi_c/Struct.c index 92731c8..894d16f 100644 --- a/ext/ffi_c/Struct.c +++ b/ext/ffi_c/Struct.c @@ -79,7 +79,9 @@ static ID id_get = 0, id_put = 0, id_to_ptr = 0, id_to_s = 0, id_layout = 0; static inline char* memory_address(VALUE self) { - return ((AbstractMemory *)DATA_PTR((self)))->address; + AbstractMemory *mem; + TypedData_Get_Struct(self, AbstractMemory, &rbffi_abstract_memory_data_type, mem); + return mem->address; } static VALUE @@ -236,7 +238,7 @@ struct_malloc(Struct* s) rb_raise(rb_eRuntimeError, "invalid pointer in struct"); } - s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer); + TypedData_Get_Struct(s->rbPointer, AbstractMemory, &rbffi_abstract_memory_data_type, s->pointer); } static void @@ -384,7 +386,7 @@ struct_set_pointer(VALUE self, VALUE pointer) Data_Get_Struct(self, Struct, s); - Data_Get_Struct(pointer, AbstractMemory, memory); + TypedData_Get_Struct(pointer, AbstractMemory, &rbffi_abstract_memory_data_type, memory); layout = struct_layout(self); if ((int) layout->base.ffiType->size > memory->size) { @@ -525,7 +527,7 @@ inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField) array->rbMemory = rbMemory; array->rbField = rbField; - Data_Get_Struct(rbMemory, AbstractMemory, array->memory); + TypedData_Get_Struct(rbMemory, AbstractMemory, &rbffi_abstract_memory_data_type, array->memory); Data_Get_Struct(rbField, StructField, array->field); Data_Get_Struct(array->field->rbType, ArrayType, array->arrayType); Data_Get_Struct(array->arrayType->rbComponentType, Type, array->componentType); diff --git a/ext/ffi_c/Types.c b/ext/ffi_c/Types.c index 77741e0..8695a3b 100644 --- a/ext/ffi_c/Types.c +++ b/ext/ffi_c/Types.c @@ -97,7 +97,7 @@ rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr) AbstractMemory* mem; VALUE rbMemory = rbffi_MemoryPointer_NewInstance(1, sbv->base.ffiType->size, false); - Data_Get_Struct(rbMemory, AbstractMemory, mem); + TypedData_Get_Struct(rbMemory, AbstractMemory, &rbffi_abstract_memory_data_type, mem); memcpy(mem->address, ptr, sbv->base.ffiType->size); RB_GC_GUARD(rbMemory); RB_GC_GUARD(rbType); |