summaryrefslogtreecommitdiff
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
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.
-rw-r--r--ext/ffi_c/AbstractMemory.c40
-rw-r--r--ext/ffi_c/AbstractMemory.h1
-rw-r--r--ext/ffi_c/Buffer.c57
-rw-r--r--ext/ffi_c/Call.c14
-rw-r--r--ext/ffi_c/DynamicLibrary.c23
-rw-r--r--ext/ffi_c/Function.c52
-rw-r--r--ext/ffi_c/MemoryPointer.c22
-rw-r--r--ext/ffi_c/Pointer.c57
-rw-r--r--ext/ffi_c/Pointer.h1
-rw-r--r--ext/ffi_c/Struct.c10
-rw-r--r--ext/ffi_c/Types.c2
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);