summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Kanis <lars@greiz-reinsdorf.de>2023-03-03 20:47:15 +0100
committerLars Kanis <lars@greiz-reinsdorf.de>2023-03-03 20:47:15 +0100
commit5daf2d381badcafcc71f18832d7933a9dab4dadb (patch)
tree359b87705a172f1e5aeb73a5f745f2704870d635
parente196971d7e422cd87ebbf67060cefb79659bf4d9 (diff)
parentd2f913c8aebb49fbb554519e0643ed7e2a480ad7 (diff)
downloadffi-5daf2d381badcafcc71f18832d7933a9dab4dadb.tar.gz
Merge branch 'typed-data-struct' of https://github.com/casperisfine/ffi into casperisfine-typed-data-struct
-rw-r--r--ext/ffi_c/Call.c4
-rw-r--r--ext/ffi_c/Function.c4
-rw-r--r--ext/ffi_c/Struct.c46
-rw-r--r--ext/ffi_c/Struct.h2
4 files changed, 37 insertions, 19 deletions
diff --git a/ext/ffi_c/Call.c b/ext/ffi_c/Call.c
index 87dd554..ccb711c 100644
--- a/ext/ffi_c/Call.c
+++ b/ext/ffi_c/Call.c
@@ -426,7 +426,9 @@ getPointer(VALUE value, int type)
} else if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_StructClass)) {
- AbstractMemory* memory = ((Struct *) DATA_PTR(value))->pointer;
+ Struct* s;
+ TypedData_Get_Struct(value, Struct, &rbffi_struct_data_type, s);
+ AbstractMemory* memory = s->pointer;
return memory != NULL ? memory->address : NULL;
} else if (type == T_STRING) {
diff --git a/ext/ffi_c/Function.c b/ext/ffi_c/Function.c
index 88847aa..20822da 100644
--- a/ext/ffi_c/Function.c
+++ b/ext/ffi_c/Function.c
@@ -845,7 +845,9 @@ invoke_callback(VALUE data)
case NATIVE_STRUCT:
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_StructClass)) {
- AbstractMemory* memory = ((Struct *) DATA_PTR(rbReturnValue))->pointer;
+ Struct* s;
+ TypedData_Get_Struct(rbReturnValue, Struct, &rbffi_struct_data_type, s);
+ AbstractMemory* memory = s->pointer;
if (memory->address != NULL) {
memcpy(retval, memory->address, returnType->ffiType->size);
diff --git a/ext/ffi_c/Struct.c b/ext/ffi_c/Struct.c
index 8d7b64d..f2466c8 100644
--- a/ext/ffi_c/Struct.c
+++ b/ext/ffi_c/Struct.c
@@ -61,13 +61,22 @@ typedef struct InlineArray_ {
} InlineArray;
-static void struct_mark(Struct *);
-static void struct_free(Struct *);
+static void struct_mark(void *data);
+static void struct_free(void *data);
static VALUE struct_class_layout(VALUE klass);
static void struct_malloc(Struct* s);
static void inline_array_mark(void *);
static void store_reference_value(StructField* f, Struct* s, VALUE value);
+const rb_data_type_t rbffi_struct_data_type = { /* extern */
+ .wrap_struct_name = "FFI::Struct",
+ .function = {
+ .dmark = struct_mark,
+ .dfree = struct_free,
+ .dsize = NULL,
+ },
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
VALUE rbffi_StructClass = Qnil;
VALUE rbffi_StructInlineArrayClass = Qnil;
@@ -88,7 +97,7 @@ static VALUE
struct_allocate(VALUE klass)
{
Struct* s;
- VALUE obj = Data_Make_Struct(klass, Struct, struct_mark, struct_free, s);
+ VALUE obj = TypedData_Make_Struct(klass, Struct, &rbffi_struct_data_type, s);
s->rbPointer = Qnil;
s->rbLayout = Qnil;
@@ -110,7 +119,7 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
VALUE rbPointer = Qnil, rest = Qnil, klass = CLASS_OF(self);
int nargs;
- Data_Get_Struct(self, Struct, s);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
nargs = rb_scan_args(argc, argv, "01*", &rbPointer, &rest);
@@ -148,8 +157,8 @@ struct_initialize_copy(VALUE self, VALUE other)
Struct* src;
Struct* dst;
- Data_Get_Struct(self, Struct, dst);
- Data_Get_Struct(other, Struct, src);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, dst);
+ TypedData_Get_Struct(other, Struct, &rbffi_struct_data_type, src);
if (dst == src) {
return self;
}
@@ -198,7 +207,8 @@ struct_class_layout(VALUE klass)
static StructLayout*
struct_layout(VALUE self)
{
- Struct* s = (Struct *) DATA_PTR(self);
+ Struct* s;
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
if (s->layout != NULL) {
return s->layout;
}
@@ -215,7 +225,7 @@ static Struct*
struct_validate(VALUE self)
{
Struct* s;
- Data_Get_Struct(self, Struct, s);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
if (struct_layout(self) == NULL) {
rb_raise(rb_eRuntimeError, "struct layout == null");
@@ -242,8 +252,9 @@ struct_malloc(Struct* s)
}
static void
-struct_mark(Struct *s)
+struct_mark(void *data)
{
+ Struct *s = (Struct *)data;
rb_gc_mark(s->rbPointer);
rb_gc_mark(s->rbLayout);
if (s->rbReferences != NULL) {
@@ -252,8 +263,9 @@ struct_mark(Struct *s)
}
static void
-struct_free(Struct* s)
+struct_free(void *data)
{
+ Struct *s = (Struct *)data;
xfree(s->rbReferences);
xfree(s);
}
@@ -385,7 +397,7 @@ struct_set_pointer(VALUE self, VALUE pointer)
}
- Data_Get_Struct(self, Struct, s);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
TypedData_Get_Struct(pointer, AbstractMemory, &rbffi_abstract_memory_data_type, memory);
layout = struct_layout(self);
@@ -411,7 +423,7 @@ struct_get_pointer(VALUE self)
{
Struct* s;
- Data_Get_Struct(self, Struct, s);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
return s->rbPointer;
}
@@ -426,7 +438,7 @@ static VALUE
struct_set_layout(VALUE self, VALUE layout)
{
Struct* s;
- Data_Get_Struct(self, Struct, s);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
@@ -450,7 +462,7 @@ struct_get_layout(VALUE self)
{
Struct* s;
- Data_Get_Struct(self, Struct, s);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
return s->rbLayout;
}
@@ -465,7 +477,7 @@ struct_null_p(VALUE self)
{
Struct* s;
- Data_Get_Struct(self, Struct, s);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
return s->pointer->address == NULL ? Qtrue : Qfalse;
}
@@ -478,7 +490,7 @@ struct_order(int argc, VALUE* argv, VALUE self)
{
Struct* s;
- Data_Get_Struct(self, Struct, s);
+ TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
if (argc == 0) {
return rb_funcall(s->rbPointer, rb_intern("order"), 0);
@@ -646,7 +658,7 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
checkWrite(array->memory);
checkBounds(array->memory, offset, array->componentType->ffiType->size);
- Data_Get_Struct(rbValue, Struct, s);
+ TypedData_Get_Struct(rbValue, Struct, &rbffi_struct_data_type, s);
checkRead(s->pointer);
checkBounds(s->pointer, 0, array->componentType->ffiType->size);
diff --git a/ext/ffi_c/Struct.h b/ext/ffi_c/Struct.h
index 73a5888..1cba8bb 100644
--- a/ext/ffi_c/Struct.h
+++ b/ext/ffi_c/Struct.h
@@ -101,6 +101,8 @@ extern "C" {
VALUE rbPointer;
};
+ extern const rb_data_type_t rbffi_struct_data_type;
+ extern const rb_data_type_t rbffi_struct_field_data_type;
extern VALUE rbffi_StructClass, rbffi_StructLayoutClass;
extern VALUE rbffi_StructLayoutFieldClass, rbffi_StructLayoutFunctionFieldClass;
extern VALUE rbffi_StructLayoutArrayFieldClass;