summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2023-03-02 13:15:58 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-03-02 13:45:26 +0100
commit830ea9b6aaf785b70184ff4f4fceb66388211f5e (patch)
tree6d22595c2716205d3bacfc200c92233372120017
parent227d1ce472ec90144249f8cf85b52d85cbab925c (diff)
downloadffi-830ea9b6aaf785b70184ff4f4fceb66388211f5e.tar.gz
Convert FFI::Type 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.c4
-rw-r--r--ext/ffi_c/ArrayType.c34
-rw-r--r--ext/ffi_c/ArrayType.h1
-rw-r--r--ext/ffi_c/Function.c2
-rw-r--r--ext/ffi_c/Function.h1
-rw-r--r--ext/ffi_c/FunctionInfo.c33
-rw-r--r--ext/ffi_c/MappedType.c37
-rw-r--r--ext/ffi_c/MappedType.h1
-rw-r--r--ext/ffi_c/Struct.c16
-rw-r--r--ext/ffi_c/Struct.h3
-rw-r--r--ext/ffi_c/StructByValue.c31
-rw-r--r--ext/ffi_c/StructLayout.c85
-rw-r--r--ext/ffi_c/Type.c44
-rw-r--r--ext/ffi_c/Type.h2
-rw-r--r--ext/ffi_c/Variadic.c12
-rwxr-xr-x[-rw-r--r--]ext/ffi_c/extconf.rb2
16 files changed, 205 insertions, 103 deletions
diff --git a/ext/ffi_c/AbstractMemory.c b/ext/ffi_c/AbstractMemory.c
index 1a7fcde..fc2d0c1 100644
--- a/ext/ffi_c/AbstractMemory.c
+++ b/ext/ffi_c/AbstractMemory.c
@@ -345,7 +345,7 @@ memory_get(VALUE self, VALUE type_name, VALUE offset)
if(NIL_P(nType)) goto undefined_type;
Data_Get_Struct(self, AbstractMemory, ptr);
- Data_Get_Struct(nType, Type, type);
+ TypedData_Get_Struct(nType, Type, &rbffi_type_data_type, type);
MemoryOp *op = get_memory_op(type);
if(op == NULL) goto undefined_type;
@@ -377,7 +377,7 @@ memory_put(VALUE self, VALUE type_name, VALUE offset, VALUE value)
if(NIL_P(nType)) goto undefined_type;
Data_Get_Struct(self, AbstractMemory, ptr);
- Data_Get_Struct(nType, Type, type);
+ TypedData_Get_Struct(nType, Type, &rbffi_type_data_type, type);
MemoryOp *op = get_memory_op(type);
if(op == NULL) goto undefined_type;
diff --git a/ext/ffi_c/ArrayType.c b/ext/ffi_c/ArrayType.c
index bfd666a..f6e6fc4 100644
--- a/ext/ffi_c/ArrayType.c
+++ b/ext/ffi_c/ArrayType.c
@@ -33,8 +33,20 @@
static VALUE array_type_s_allocate(VALUE klass);
static VALUE array_type_initialize(VALUE self, VALUE rbComponentType, VALUE rbLength);
-static void array_type_mark(ArrayType *);
-static void array_type_free(ArrayType *);
+static void array_type_mark(void *);
+static void array_type_free(void *);
+
+const rb_data_type_t rbffi_array_type_data_type = { /* extern */
+ .wrap_struct_name = "FFI::ArrayType",
+ .function = {
+ .dmark = array_type_mark,
+ .dfree = array_type_free,
+ .dsize = NULL,
+ },
+ .parent = &rbffi_type_data_type,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
+
VALUE rbffi_ArrayTypeClass = Qnil;
@@ -44,7 +56,7 @@ array_type_s_allocate(VALUE klass)
ArrayType* array;
VALUE obj;
- obj = Data_Make_Struct(klass, ArrayType, array_type_mark, array_type_free, array);
+ obj = TypedData_Make_Struct(klass, ArrayType, &rbffi_array_type_data_type, array);
array->base.nativeType = NATIVE_ARRAY;
array->base.ffiType = xcalloc(1, sizeof(*array->base.ffiType));
@@ -57,14 +69,16 @@ array_type_s_allocate(VALUE klass)
}
static void
-array_type_mark(ArrayType *array)
+array_type_mark(void *data)
{
+ ArrayType *array = (ArrayType *)data;
rb_gc_mark(array->rbComponentType);
}
static void
-array_type_free(ArrayType *array)
+array_type_free(void *data)
{
+ ArrayType *array = (ArrayType *)data;
xfree(array->base.ffiType);
xfree(array->ffiTypes);
xfree(array);
@@ -84,12 +98,12 @@ array_type_initialize(VALUE self, VALUE rbComponentType, VALUE rbLength)
ArrayType* array;
int i;
- Data_Get_Struct(self, ArrayType, array);
+ TypedData_Get_Struct(self, ArrayType, &rbffi_array_type_data_type, array);
array->length = NUM2UINT(rbLength);
array->rbComponentType = rbComponentType;
- Data_Get_Struct(rbComponentType, Type, array->componentType);
-
+ TypedData_Get_Struct(rbComponentType, Type, &rbffi_type_data_type, array->componentType);
+
array->ffiTypes = xcalloc(array->length + 1, sizeof(*array->ffiTypes));
array->base.ffiType->elements = array->ffiTypes;
array->base.ffiType->size = array->componentType->ffiType->size * array->length;
@@ -112,7 +126,7 @@ array_type_length(VALUE self)
{
ArrayType* array;
- Data_Get_Struct(self, ArrayType, array);
+ TypedData_Get_Struct(self, ArrayType, &rbffi_array_type_data_type, array);
return UINT2NUM(array->length);
}
@@ -127,7 +141,7 @@ array_type_element_type(VALUE self)
{
ArrayType* array;
- Data_Get_Struct(self, ArrayType, array);
+ TypedData_Get_Struct(self, ArrayType, &rbffi_array_type_data_type, array);
return array->rbComponentType;
}
diff --git a/ext/ffi_c/ArrayType.h b/ext/ffi_c/ArrayType.h
index 356ffb1..9b1eba0 100644
--- a/ext/ffi_c/ArrayType.h
+++ b/ext/ffi_c/ArrayType.h
@@ -48,6 +48,7 @@ typedef struct ArrayType_ {
} ArrayType;
extern void rbffi_ArrayType_Init(VALUE moduleFFI);
+extern const rb_data_type_t rbffi_array_type_data_type;
extern VALUE rbffi_ArrayTypeClass;
diff --git a/ext/ffi_c/Function.c b/ext/ffi_c/Function.c
index 1a57591..45d97d7 100644
--- a/ext/ffi_c/Function.c
+++ b/ext/ffi_c/Function.c
@@ -302,7 +302,7 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
fn->rbFunctionInfo = rbFunctionInfo;
- Data_Get_Struct(fn->rbFunctionInfo, FunctionType, fn->info);
+ TypedData_Get_Struct(fn->rbFunctionInfo, FunctionType, &rbffi_fntype_data_type, fn->info);
if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) {
Pointer* orig;
diff --git a/ext/ffi_c/Function.h b/ext/ffi_c/Function.h
index 406b4d8..89b22ec 100644
--- a/ext/ffi_c/Function.h
+++ b/ext/ffi_c/Function.h
@@ -68,6 +68,7 @@ struct FunctionType_ {
bool hasStruct;
};
+extern const rb_data_type_t rbffi_fntype_data_type;
extern VALUE rbffi_FunctionTypeClass, rbffi_FunctionClass;
void rbffi_Function_Init(VALUE moduleFFI);
diff --git a/ext/ffi_c/FunctionInfo.c b/ext/ffi_c/FunctionInfo.c
index 64e9874..d2c3376 100644
--- a/ext/ffi_c/FunctionInfo.c
+++ b/ext/ffi_c/FunctionInfo.c
@@ -51,8 +51,19 @@
static VALUE fntype_allocate(VALUE klass);
static VALUE fntype_initialize(int argc, VALUE* argv, VALUE self);
-static void fntype_mark(FunctionType*);
-static void fntype_free(FunctionType *);
+static void fntype_mark(void *);
+static void fntype_free(void *);
+
+const rb_data_type_t rbffi_fntype_data_type = { /* extern */
+ .wrap_struct_name = "FFI::FunctionType",
+ .function = {
+ .dmark = fntype_mark,
+ .dfree = fntype_free,
+ .dsize = NULL,
+ },
+ .parent = &rbffi_type_data_type,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
VALUE rbffi_FunctionTypeClass = Qnil;
@@ -60,7 +71,7 @@ static VALUE
fntype_allocate(VALUE klass)
{
FunctionType* fnInfo;
- VALUE obj = Data_Make_Struct(klass, FunctionType, fntype_mark, fntype_free, fnInfo);
+ VALUE obj = TypedData_Make_Struct(klass, FunctionType, &rbffi_fntype_data_type, fnInfo);
fnInfo->type.ffiType = &ffi_type_pointer;
fnInfo->type.nativeType = NATIVE_FUNCTION;
@@ -74,8 +85,9 @@ fntype_allocate(VALUE klass)
}
static void
-fntype_mark(FunctionType* fnInfo)
+fntype_mark(void *data)
{
+ FunctionType *fnInfo = (FunctionType *)data;
rb_gc_mark(fnInfo->rbReturnType);
rb_gc_mark(fnInfo->rbParameterTypes);
rb_gc_mark(fnInfo->rbEnums);
@@ -85,8 +97,9 @@ fntype_mark(FunctionType* fnInfo)
}
static void
-fntype_free(FunctionType* fnInfo)
+fntype_free(void *data)
{
+ FunctionType *fnInfo = (FunctionType *)data;
xfree(fnInfo->parameterTypes);
xfree(fnInfo->ffiParameterTypes);
xfree(fnInfo->nativeParameterTypes);
@@ -129,7 +142,7 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
Check_Type(rbParamTypes, T_ARRAY);
- Data_Get_Struct(self, FunctionType, fnInfo);
+ TypedData_Get_Struct(self, FunctionType, &rbffi_fntype_data_type, fnInfo);
fnInfo->parameterCount = (int) RARRAY_LEN(rbParamTypes);
fnInfo->parameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->parameterTypes));
fnInfo->ffiParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(ffi_type *));
@@ -158,7 +171,7 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
}
rb_ary_push(fnInfo->rbParameterTypes, type);
- Data_Get_Struct(type, Type, fnInfo->parameterTypes[i]);
+ TypedData_Get_Struct(type, Type, &rbffi_type_data_type, fnInfo->parameterTypes[i]);
fnInfo->ffiParameterTypes[i] = fnInfo->parameterTypes[i]->ffiType;
fnInfo->nativeParameterTypes[i] = fnInfo->parameterTypes[i]->nativeType;
}
@@ -173,7 +186,7 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
fnInfo->hasStruct = true;
}
- Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType);
+ TypedData_Get_Struct(fnInfo->rbReturnType, Type, &rbffi_type_data_type, fnInfo->returnType);
fnInfo->ffiReturnType = fnInfo->returnType->ffiType;
#if defined(X86_WIN32)
@@ -212,7 +225,7 @@ fntype_result_type(VALUE self)
{
FunctionType* ft;
- Data_Get_Struct(self, FunctionType, ft);
+ TypedData_Get_Struct(self, FunctionType, &rbffi_fntype_data_type, ft);
return ft->rbReturnType;
}
@@ -227,7 +240,7 @@ fntype_param_types(VALUE self)
{
FunctionType* ft;
- Data_Get_Struct(self, FunctionType, ft);
+ TypedData_Get_Struct(self, FunctionType, &rbffi_fntype_data_type, ft);
return rb_ary_dup(ft->rbParameterTypes);
}
diff --git a/ext/ffi_c/MappedType.c b/ext/ffi_c/MappedType.c
index d1a4189..304de86 100644
--- a/ext/ffi_c/MappedType.c
+++ b/ext/ffi_c/MappedType.c
@@ -38,17 +38,29 @@
static VALUE mapped_allocate(VALUE);
static VALUE mapped_initialize(VALUE, VALUE);
-static void mapped_mark(MappedType *);
+static void mapped_mark(void *);
static ID id_native_type, id_to_native, id_from_native;
VALUE rbffi_MappedTypeClass = Qnil;
+static const rb_data_type_t mapped_type_data_type = {
+ .wrap_struct_name = "FFI::Type::Mapped",
+ .function = {
+ .dmark = mapped_mark,
+ .dfree = RUBY_TYPED_DEFAULT_FREE,
+ .dsize = NULL,
+ },
+ .parent = &rbffi_type_data_type,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+
static VALUE
mapped_allocate(VALUE klass)
{
MappedType* m;
- VALUE obj = Data_Make_Struct(klass, MappedType, mapped_mark, -1, m);
+ VALUE obj = TypedData_Make_Struct(klass, MappedType, &mapped_type_data_type, m);
m->rbConverter = Qnil;
m->rbType = Qnil;
@@ -81,23 +93,24 @@ mapped_initialize(VALUE self, VALUE rbConverter)
if (!rb_respond_to(rbConverter, id_from_native)) {
rb_raise(rb_eNoMethodError, "from_native method not implemented");
}
-
- Data_Get_Struct(self, MappedType, m);
+
+ TypedData_Get_Struct(self, MappedType, &mapped_type_data_type, m);
m->rbType = rb_funcall2(rbConverter, id_native_type, 0, NULL);
if (!(rb_obj_is_kind_of(m->rbType, rbffi_TypeClass))) {
rb_raise(rb_eTypeError, "native_type did not return instance of FFI::Type");
}
m->rbConverter = rbConverter;
- Data_Get_Struct(m->rbType, Type, m->type);
+ TypedData_Get_Struct(m->rbType, Type, &rbffi_type_data_type, m->type);
m->base.ffiType = m->type->ffiType;
-
+
return self;
}
static void
-mapped_mark(MappedType* m)
+mapped_mark(void* data)
{
+ MappedType* m = (MappedType*)data;
rb_gc_mark(m->rbType);
rb_gc_mark(m->rbConverter);
}
@@ -111,7 +124,7 @@ static VALUE
mapped_native_type(VALUE self)
{
MappedType*m = NULL;
- Data_Get_Struct(self, MappedType, m);
+ TypedData_Get_Struct(self, MappedType, &mapped_type_data_type, m);
return m->rbType;
}
@@ -124,9 +137,8 @@ static VALUE
mapped_to_native(int argc, VALUE* argv, VALUE self)
{
MappedType*m = NULL;
-
- Data_Get_Struct(self, MappedType, m);
-
+ TypedData_Get_Struct(self, MappedType, &mapped_type_data_type, m);
+
return rb_funcall2(m->rbConverter, id_to_native, argc, argv);
}
@@ -138,8 +150,7 @@ static VALUE
mapped_from_native(int argc, VALUE* argv, VALUE self)
{
MappedType*m = NULL;
-
- Data_Get_Struct(self, MappedType, m);
+ TypedData_Get_Struct(self, MappedType, &mapped_type_data_type, m);
return rb_funcall2(m->rbConverter, id_from_native, argc, argv);
}
diff --git a/ext/ffi_c/MappedType.h b/ext/ffi_c/MappedType.h
index 4b26cc1..ac86a3c 100644
--- a/ext/ffi_c/MappedType.h
+++ b/ext/ffi_c/MappedType.h
@@ -50,7 +50,6 @@ void rbffi_MappedType_Init(VALUE moduleFFI);
extern VALUE rbffi_MappedTypeClass;
-
#ifdef __cplusplus
}
#endif
diff --git a/ext/ffi_c/Struct.c b/ext/ffi_c/Struct.c
index 92731c8..3528bf1 100644
--- a/ext/ffi_c/Struct.c
+++ b/ext/ffi_c/Struct.c
@@ -123,7 +123,7 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
rb_raise(rb_eRuntimeError, "Invalid Struct layout");
}
- Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
+ TypedData_Get_Struct(s->rbLayout, StructLayout, &rbffi_struct_layout_data_type, s->layout);
if (rbPointer != Qnil) {
s->pointer = MEMORY(rbPointer);
@@ -203,7 +203,7 @@ struct_layout(VALUE self)
if (s->layout == NULL) {
s->rbLayout = struct_class_layout(CLASS_OF(self));
- Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
+ TypedData_Get_Struct(s->rbLayout, StructLayout, &rbffi_struct_layout_data_type, s->layout);
}
return s->layout;
@@ -291,7 +291,7 @@ struct_field(Struct* s, VALUE fieldName)
}
/* Write the retrieved coder to the cache */
p_ce->fieldName = fieldName;
- p_ce->field = (StructField *) DATA_PTR(rbField);
+ TypedData_Get_Struct(rbField, StructField, &rbffi_struct_field_data_type, p_ce->field);
}
return p_ce->field;
@@ -432,7 +432,7 @@ struct_set_layout(VALUE self, VALUE layout)
return Qnil;
}
- Data_Get_Struct(layout, StructLayout, s->layout);
+ TypedData_Get_Struct(layout, StructLayout, &rbffi_struct_layout_data_type, s->layout);
rb_ivar_set(self, id_layout_ivar, layout);
return self;
@@ -526,9 +526,9 @@ inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
array->rbField = rbField;
Data_Get_Struct(rbMemory, AbstractMemory, 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);
+ TypedData_Get_Struct(rbField, StructField, &rbffi_struct_field_data_type, array->field);
+ TypedData_Get_Struct(array->field->rbType, ArrayType, &rbffi_array_type_data_type, array->arrayType);
+ TypedData_Get_Struct(array->arrayType->rbComponentType, Type, &rbffi_type_data_type, array->componentType);
array->op = get_memory_op(array->componentType);
if (array->op == NULL && array->componentType->nativeType == NATIVE_MAPPED) {
@@ -641,7 +641,7 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
} else {
ArrayType* arrayType;
- Data_Get_Struct(array->field->rbType, ArrayType, arrayType);
+ TypedData_Get_Struct(array->field->rbType, ArrayType, &rbffi_array_type_data_type, arrayType);
rb_raise(rb_eArgError, "set not supported for %s", rb_obj_classname(arrayType->rbComponentType));
return Qnil;
diff --git a/ext/ffi_c/Struct.h b/ext/ffi_c/Struct.h
index eb6edf2..73a5888 100644
--- a/ext/ffi_c/Struct.h
+++ b/ext/ffi_c/Struct.h
@@ -42,6 +42,9 @@ extern "C" {
extern void rbffi_Struct_Init(VALUE ffiModule);
extern void rbffi_StructLayout_Init(VALUE ffiModule);
+ extern const rb_data_type_t rbffi_struct_layout_data_type;
+ extern const rb_data_type_t rbffi_struct_field_data_type;
+
typedef struct StructField_ StructField;
typedef struct StructLayout_ StructLayout;
typedef struct Struct_ Struct;
diff --git a/ext/ffi_c/StructByValue.c b/ext/ffi_c/StructByValue.c
index a3255f4..b4927e6 100644
--- a/ext/ffi_c/StructByValue.c
+++ b/ext/ffi_c/StructByValue.c
@@ -49,17 +49,28 @@
static VALUE sbv_allocate(VALUE);
static VALUE sbv_initialize(VALUE, VALUE);
-static void sbv_mark(StructByValue *);
-static void sbv_free(StructByValue *);
+static void sbv_mark(void *);
+static void sbv_free(void *);
VALUE rbffi_StructByValueClass = Qnil;
+static const rb_data_type_t sbv_type_data_type = {
+ .wrap_struct_name = "FFI::StructByValue",
+ .function = {
+ .dmark = sbv_mark,
+ .dfree = sbv_free,
+ .dsize = NULL,
+ },
+ .parent = &rbffi_type_data_type,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
+
static VALUE
sbv_allocate(VALUE klass)
{
StructByValue* sbv;
- VALUE obj = Data_Make_Struct(klass, StructByValue, sbv_mark, sbv_free, sbv);
+ VALUE obj = TypedData_Make_Struct(klass, StructByValue, &sbv_type_data_type, sbv);
sbv->rbStructClass = Qnil;
sbv->rbStructLayout = Qnil;
@@ -85,8 +96,8 @@ sbv_initialize(VALUE self, VALUE rbStructClass)
rb_raise(rb_eTypeError, "wrong type in @layout ivar (expected FFI::StructLayout)");
}
- Data_Get_Struct(rbLayout, StructLayout, layout);
- Data_Get_Struct(self, StructByValue, sbv);
+ TypedData_Get_Struct(rbLayout, StructLayout, &rbffi_struct_layout_data_type, layout);
+ TypedData_Get_Struct(self, StructByValue, &sbv_type_data_type, sbv);
sbv->rbStructClass = rbStructClass;
sbv->rbStructLayout = rbLayout;
@@ -97,15 +108,17 @@ sbv_initialize(VALUE self, VALUE rbStructClass)
}
static void
-sbv_mark(StructByValue *sbv)
+sbv_mark(void *data)
{
+ StructByValue *sbv = (StructByValue *)data;
rb_gc_mark(sbv->rbStructClass);
rb_gc_mark(sbv->rbStructLayout);
}
static void
-sbv_free(StructByValue *sbv)
+sbv_free(void *data)
{
+ StructByValue *sbv = (StructByValue *)data;
xfree(sbv->base.ffiType);
xfree(sbv);
}
@@ -116,7 +129,7 @@ sbv_layout(VALUE self)
{
StructByValue* sbv;
- Data_Get_Struct(self, StructByValue, sbv);
+ TypedData_Get_Struct(self, StructByValue, &sbv_type_data_type, sbv);
return sbv->rbStructLayout;
}
@@ -125,7 +138,7 @@ sbv_struct_class(VALUE self)
{
StructByValue* sbv;
- Data_Get_Struct(self, StructByValue, sbv);
+ TypedData_Get_Struct(self, StructByValue, &sbv_type_data_type, sbv);
return sbv->rbStructClass;
}
diff --git a/ext/ffi_c/StructLayout.c b/ext/ffi_c/StructLayout.c
index d318b8c..08d01b6 100644
--- a/ext/ffi_c/StructLayout.c
+++ b/ext/ffi_c/StructLayout.c
@@ -51,9 +51,9 @@
#define FFI_ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
-static void struct_layout_mark(StructLayout *);
-static void struct_layout_free(StructLayout *);
-static void struct_field_mark(StructField* );
+static void struct_layout_mark(void *);
+static void struct_layout_free(void *);
+static void struct_field_mark(void *);
VALUE rbffi_StructLayoutFieldClass = Qnil;
VALUE rbffi_StructLayoutNumberFieldClass = Qnil, rbffi_StructLayoutPointerFieldClass = Qnil;
@@ -62,6 +62,27 @@ VALUE rbffi_StructLayoutFunctionFieldClass = Qnil, rbffi_StructLayoutArrayFieldC
VALUE rbffi_StructLayoutClass = Qnil;
+const rb_data_type_t rbffi_struct_layout_data_type = { /* extern */
+ .wrap_struct_name = "FFI::StructLayout",
+ .function = {
+ .dmark = struct_layout_mark,
+ .dfree = struct_layout_free,
+ .dsize = NULL,
+ },
+ .parent = &rbffi_type_data_type,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+const rb_data_type_t rbffi_struct_field_data_type = { /* extern */
+ .wrap_struct_name = "FFI::StructField",
+ .function = {
+ .dmark = struct_field_mark,
+ .dfree = RUBY_TYPED_DEFAULT_FREE,
+ .dsize = NULL,
+ },
+ .parent = &rbffi_type_data_type,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
static VALUE
struct_field_allocate(VALUE klass)
@@ -69,7 +90,7 @@ struct_field_allocate(VALUE klass)
StructField* field;
VALUE obj;
- obj = Data_Make_Struct(klass, StructField, struct_field_mark, -1, field);
+ obj = TypedData_Make_Struct(klass, StructField, &rbffi_struct_field_data_type, field);
field->rbType = Qnil;
field->rbName = Qnil;
@@ -77,8 +98,9 @@ struct_field_allocate(VALUE klass)
}
static void
-struct_field_mark(StructField* f)
+struct_field_mark(void *data)
{
+ StructField *f = (StructField *)data;
rb_gc_mark(f->rbType);
rb_gc_mark(f->rbName);
}
@@ -98,7 +120,7 @@ struct_field_initialize(int argc, VALUE* argv, VALUE self)
StructField* field;
int nargs;
- Data_Get_Struct(self, StructField, field);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
nargs = rb_scan_args(argc, argv, "3", &rbName, &rbOffset, &rbType);
@@ -117,7 +139,7 @@ struct_field_initialize(int argc, VALUE* argv, VALUE self)
field->offset = NUM2UINT(rbOffset);
field->rbName = (TYPE(rbName) == T_SYMBOL) ? rbName : rb_str_intern(rbName);
field->rbType = rbType;
- Data_Get_Struct(field->rbType, Type, field->type);
+ TypedData_Get_Struct(field->rbType, Type, &rbffi_type_data_type, field->type);
field->memoryOp = get_memory_op(field->type);
field->referenceIndex = -1;
@@ -147,7 +169,7 @@ static VALUE
struct_field_offset(VALUE self)
{
StructField* field;
- Data_Get_Struct(self, StructField, field);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
return UINT2NUM(field->offset);
}
@@ -160,7 +182,7 @@ static VALUE
struct_field_size(VALUE self)
{
StructField* field;
- Data_Get_Struct(self, StructField, field);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
return UINT2NUM(field->type->ffiType->size);
}
@@ -173,7 +195,7 @@ static VALUE
struct_field_alignment(VALUE self)
{
StructField* field;
- Data_Get_Struct(self, StructField, field);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
return UINT2NUM(field->type->ffiType->alignment);
}
@@ -186,7 +208,7 @@ static VALUE
struct_field_type(VALUE self)
{
StructField* field;
- Data_Get_Struct(self, StructField, field);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
return field->rbType;
}
@@ -200,7 +222,7 @@ static VALUE
struct_field_name(VALUE self)
{
StructField* field;
- Data_Get_Struct(self, StructField, field);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, field);
return field->rbName;
}
@@ -215,7 +237,7 @@ struct_field_get(VALUE self, VALUE pointer)
{
StructField* f;
- Data_Get_Struct(self, StructField, f);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
if (f->memoryOp == NULL) {
rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(f->rbType));
return Qnil;
@@ -236,7 +258,7 @@ struct_field_put(VALUE self, VALUE pointer, VALUE value)
{
StructField* f;
- Data_Get_Struct(self, StructField, f);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
if (f->memoryOp == NULL) {
rb_raise(rb_eArgError, "put not supported for %s", rb_obj_classname(f->rbType));
return self;
@@ -258,7 +280,7 @@ function_field_get(VALUE self, VALUE pointer)
{
StructField* f;
- Data_Get_Struct(self, StructField, f);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
return rbffi_Function_NewInstance(f->rbType, (*rbffi_AbstractMemoryOps.pointer->get)(MEMORY(pointer), f->offset));
}
@@ -278,7 +300,7 @@ function_field_put(VALUE self, VALUE pointer, VALUE proc)
StructField* f;
VALUE value = Qnil;
- Data_Get_Struct(self, StructField, f);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
if (NIL_P(proc) || rb_obj_is_kind_of(proc, rbffi_FunctionClass)) {
value = proc;
@@ -313,8 +335,8 @@ array_field_get(VALUE self, VALUE pointer)
ArrayType* array;
VALUE argv[2];
- Data_Get_Struct(self, StructField, f);
- Data_Get_Struct(f->rbType, ArrayType, array);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
+ TypedData_Get_Struct(f->rbType, ArrayType, &rbffi_array_type_data_type, array);
argv[0] = pointer;
argv[1] = self;
@@ -336,9 +358,8 @@ array_field_put(VALUE self, VALUE pointer, VALUE value)
StructField* f;
ArrayType* array;
-
- Data_Get_Struct(self, StructField, f);
- Data_Get_Struct(f->rbType, ArrayType, array);
+ TypedData_Get_Struct(self, StructField, &rbffi_struct_field_data_type, f);
+ TypedData_Get_Struct(f->rbType, ArrayType, &rbffi_array_type_data_type, array);
if (isCharArray(array) && rb_obj_is_instance_of(value, rb_cString)) {
VALUE argv[2];
@@ -416,7 +437,7 @@ struct_layout_allocate(VALUE klass)
StructLayout* layout;
VALUE obj;
- obj = Data_Make_Struct(klass, StructLayout, struct_layout_mark, struct_layout_free, layout);
+ obj = TypedData_Make_Struct(klass, StructLayout, &rbffi_struct_layout_data_type, layout);
layout->rbFieldMap = Qnil;
layout->rbFieldNames = Qnil;
layout->rbFields = Qnil;
@@ -443,7 +464,7 @@ struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
ffi_type* ltype;
int i;
- Data_Get_Struct(self, StructLayout, layout);
+ TypedData_Get_Struct(self, StructLayout, &rbffi_struct_layout_data_type, layout);
layout->fieldCount = (int) RARRAY_LEN(fields);
layout->rbFieldMap = rb_hash_new();
layout->rbFieldNames = rb_ary_new2(layout->fieldCount);
@@ -470,7 +491,7 @@ struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
}
rbName = rb_funcall2(rbField, rb_intern("name"), 0, NULL);
- Data_Get_Struct(rbField, StructField, field);
+ TypedData_Get_Struct(rbField, StructField, &rbffi_struct_field_data_type, field);
layout->fields[i] = field;
if (field->type == NULL || field->type->ffiType == NULL) {
@@ -515,7 +536,7 @@ struct_layout_union_bang(VALUE self)
ffi_type *t = NULL;
int count, i;
- Data_Get_Struct(self, StructLayout, layout);
+ TypedData_Get_Struct(self, StructLayout, &rbffi_struct_layout_data_type, layout);
for (i = 0; alignment_types[i] != NULL; ++i) {
if (alignment_types[i]->alignment == layout->align) {
@@ -545,7 +566,7 @@ struct_layout_aref(VALUE self, VALUE field)
{
StructLayout* layout;
- Data_Get_Struct(self, StructLayout, layout);
+ TypedData_Get_Struct(self, StructLayout, &rbffi_struct_layout_data_type, layout);
return rb_hash_aref(layout->rbFieldMap, field);
}
@@ -560,7 +581,7 @@ struct_layout_fields(VALUE self)
{
StructLayout* layout;
- Data_Get_Struct(self, StructLayout, layout);
+ TypedData_Get_Struct(self, StructLayout, &rbffi_struct_layout_data_type, layout);
return rb_ary_dup(layout->rbFields);
}
@@ -575,7 +596,7 @@ struct_layout_members(VALUE self)
{
StructLayout* layout;
- Data_Get_Struct(self, StructLayout, layout);
+ TypedData_Get_Struct(self, StructLayout, &rbffi_struct_layout_data_type, layout);
return rb_ary_dup(layout->rbFieldNames);
}
@@ -590,14 +611,15 @@ struct_layout_to_a(VALUE self)
{
StructLayout* layout;
- Data_Get_Struct(self, StructLayout, layout);
+ TypedData_Get_Struct(self, StructLayout, &rbffi_struct_layout_data_type, layout);
return rb_ary_dup(layout->rbFields);
}
static void
-struct_layout_mark(StructLayout *layout)
+struct_layout_mark(void *data)
{
+ StructLayout *layout = (StructLayout *)data;
rb_gc_mark(layout->rbFieldMap);
rb_gc_mark(layout->rbFieldNames);
rb_gc_mark(layout->rbFields);
@@ -608,8 +630,9 @@ struct_layout_mark(StructLayout *layout)
}
static void
-struct_layout_free(StructLayout *layout)
+struct_layout_free(void *data)
{
+ StructLayout *layout = (StructLayout *)data;
xfree(layout->ffiTypes);
xfree(layout->base.ffiType);
xfree(layout->fields);
diff --git a/ext/ffi_c/Type.c b/ext/ffi_c/Type.c
index 7776bb0..259ae97 100644
--- a/ext/ffi_c/Type.c
+++ b/ext/ffi_c/Type.c
@@ -45,7 +45,7 @@ typedef struct BuiltinType_ {
char* name;
} BuiltinType;
-static void builtin_type_free(BuiltinType *);
+static void builtin_type_free(void *);
VALUE rbffi_TypeClass = Qnil;
@@ -54,11 +54,32 @@ static VALUE moduleNativeType = Qnil;
static VALUE typeMap = Qnil, sizeMap = Qnil;
static ID id_find_type = 0, id_type_size = 0, id_size = 0;
+const rb_data_type_t rbffi_type_data_type = { /* extern */
+ .wrap_struct_name = "FFI::Type",
+ .function = {
+ .dmark = NULL,
+ .dfree = RUBY_TYPED_DEFAULT_FREE,
+ .dsize = NULL,
+ },
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static const rb_data_type_t builtin_type_data_type = {
+ .wrap_struct_name = "FFI::Type::Builtin",
+ .function = {
+ .dmark = NULL,
+ .dfree = builtin_type_free,
+ .dsize = NULL,
+ },
+ .parent = &rbffi_type_data_type,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
+};
+
static VALUE
type_allocate(VALUE klass)
{
Type* type;
- VALUE obj = Data_Make_Struct(klass, Type, NULL, -1, type);
+ VALUE obj = TypedData_Make_Struct(klass, Type, &rbffi_type_data_type, type);
type->nativeType = -1;
type->ffiType = &ffi_type_void;
@@ -78,12 +99,12 @@ type_initialize(VALUE self, VALUE value)
Type* type;
Type* other;
- Data_Get_Struct(self, Type, type);
+ TypedData_Get_Struct(self, Type, &rbffi_type_data_type, type);
if (FIXNUM_P(value)) {
type->nativeType = FIX2INT(value);
} else if (rb_obj_is_kind_of(value, rbffi_TypeClass)) {
- Data_Get_Struct(value, Type, other);
+ TypedData_Get_Struct(value, Type, &rbffi_type_data_type, other);
type->nativeType = other->nativeType;
type->ffiType = other->ffiType;
} else {
@@ -103,7 +124,7 @@ type_size(VALUE self)
{
Type *type;
- Data_Get_Struct(self, Type, type);
+ TypedData_Get_Struct(self, Type, &rbffi_type_data_type, type);
return INT2FIX(type->ffiType->size);
}
@@ -118,7 +139,7 @@ type_alignment(VALUE self)
{
Type *type;
- Data_Get_Struct(self, Type, type);
+ TypedData_Get_Struct(self, Type, &rbffi_type_data_type, type);
return INT2FIX(type->ffiType->alignment);
}
@@ -134,7 +155,7 @@ type_inspect(VALUE self)
char buf[100];
Type *type;
- Data_Get_Struct(self, Type, type);
+ TypedData_Get_Struct(self, Type, &rbffi_type_data_type, type);
snprintf(buf, sizeof(buf), "#<%s:%p size=%d alignment=%d>",
rb_obj_classname(self), type, (int) type->ffiType->size, (int) type->ffiType->alignment);
@@ -148,7 +169,7 @@ builtin_type_new(VALUE klass, int nativeType, ffi_type* ffiType, const char* nam
BuiltinType* type;
VALUE obj = Qnil;
- obj = Data_Make_Struct(klass, BuiltinType, NULL, builtin_type_free, type);
+ obj = TypedData_Make_Struct(klass, BuiltinType, &builtin_type_data_type, type);
type->name = strdup(name);
type->type.nativeType = nativeType;
@@ -158,8 +179,9 @@ builtin_type_new(VALUE klass, int nativeType, ffi_type* ffiType, const char* nam
}
static void
-builtin_type_free(BuiltinType *type)
+builtin_type_free(void *data)
{
+ BuiltinType *type = (BuiltinType *)data;
free(type->name);
xfree(type);
}
@@ -175,7 +197,7 @@ builtin_type_inspect(VALUE self)
char buf[100];
BuiltinType *type;
- Data_Get_Struct(self, BuiltinType, type);
+ TypedData_Get_Struct(self, BuiltinType, &builtin_type_data_type, type);
snprintf(buf, sizeof(buf), "#<%s:%s size=%d alignment=%d>",
rb_obj_classname(self), type->name, (int) type->type.ffiType->size, type->type.ffiType->alignment);
@@ -198,7 +220,7 @@ rbffi_type_size(VALUE type)
if ((nType = rb_hash_lookup(typeMap, type)) != Qnil) {
if (rb_obj_is_kind_of(nType, rbffi_TypeClass)) {
Type* type;
- Data_Get_Struct(nType, Type, type);
+ TypedData_Get_Struct(nType, Type, &rbffi_type_data_type, type);
return (int) type->ffiType->size;
} else if (rb_respond_to(nType, id_size)) {
diff --git a/ext/ffi_c/Type.h b/ext/ffi_c/Type.h
index b81995a..74a931b 100644
--- a/ext/ffi_c/Type.h
+++ b/ext/ffi_c/Type.h
@@ -53,6 +53,8 @@ struct Type_ {
extern VALUE rbffi_TypeClass;
extern VALUE rbffi_Type_Lookup(VALUE type);
+extern const rb_data_type_t rbffi_type_data_type;
+
#ifdef __cplusplus
}
#endif
diff --git a/ext/ffi_c/Variadic.c b/ext/ffi_c/Variadic.c
index 8ad38b1..77d9780 100644
--- a/ext/ffi_c/Variadic.c
+++ b/ext/ffi_c/Variadic.c
@@ -128,7 +128,7 @@ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE
rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
}
- Data_Get_Struct(rbReturnType, Type, invoker->returnType);
+ TypedData_Get_Struct(rbReturnType, Type, &rbffi_type_data_type, invoker->returnType);
invoker->paramCount = -1;
@@ -142,7 +142,7 @@ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE
VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
}
- Data_Get_Struct(rbType, Type, type);
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, type);
if (type->nativeType != NATIVE_VARARGS) {
rb_ary_push(fixed, entry);
}
@@ -192,25 +192,25 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
if (!rb_obj_is_kind_of(rbType, rbffi_TypeClass)) {
rb_raise(rb_eTypeError, "wrong type. Expected (FFI::Type)");
}
- Data_Get_Struct(rbType, Type, paramTypes[i]);
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, paramTypes[i]);
switch (paramTypes[i]->nativeType) {
case NATIVE_INT8:
case NATIVE_INT16:
case NATIVE_INT32:
rbType = rb_const_get(rbffi_TypeClass, rb_intern("INT32"));
- Data_Get_Struct(rbType, Type, paramTypes[i]);
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, paramTypes[i]);
break;
case NATIVE_UINT8:
case NATIVE_UINT16:
case NATIVE_UINT32:
rbType = rb_const_get(rbffi_TypeClass, rb_intern("UINT32"));
- Data_Get_Struct(rbType, Type, paramTypes[i]);
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, paramTypes[i]);
break;
case NATIVE_FLOAT32:
rbType = rb_const_get(rbffi_TypeClass, rb_intern("DOUBLE"));
- Data_Get_Struct(rbType, Type, paramTypes[i]);
+ TypedData_Get_Struct(rbType, Type, &rbffi_type_data_type, paramTypes[i]);
break;
case NATIVE_FUNCTION:
diff --git a/ext/ffi_c/extconf.rb b/ext/ffi_c/extconf.rb
index 720fb06..2484543 100644..100755
--- a/ext/ffi_c/extconf.rb
+++ b/ext/ffi_c/extconf.rb
@@ -33,7 +33,7 @@ if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
$CFLAGS.gsub!(/[\s+]-ansi/, '')
$CFLAGS.gsub!(/[\s+]-std=[^\s]+/, '')
# solaris 10 needs -c99 for <stdbool.h>
- $CFLAGS << " -std=c99" if RbConfig::CONFIG['host_os'] =~ /solaris(!?2\.11)/
+ $CFLAGS << " -g -std=c99" if RbConfig::CONFIG['host_os'] =~ /solaris(!?2\.11)/
# Check whether we use system libffi
system_libffi = enable_config('system-libffi', :try)