diff options
author | Lars Kanis <lars@greiz-reinsdorf.de> | 2023-03-03 20:47:15 +0100 |
---|---|---|
committer | Lars Kanis <lars@greiz-reinsdorf.de> | 2023-03-03 20:47:15 +0100 |
commit | 5daf2d381badcafcc71f18832d7933a9dab4dadb (patch) | |
tree | 359b87705a172f1e5aeb73a5f745f2704870d635 | |
parent | e196971d7e422cd87ebbf67060cefb79659bf4d9 (diff) | |
parent | d2f913c8aebb49fbb554519e0643ed7e2a480ad7 (diff) | |
download | ffi-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.c | 4 | ||||
-rw-r--r-- | ext/ffi_c/Function.c | 4 | ||||
-rw-r--r-- | ext/ffi_c/Struct.c | 46 | ||||
-rw-r--r-- | ext/ffi_c/Struct.h | 2 |
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; |