From 830ea9b6aaf785b70184ff4f4fceb66388211f5e Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 2 Mar 2023 13:15:58 +0100 Subject: 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. --- ext/ffi_c/AbstractMemory.c | 4 +-- ext/ffi_c/ArrayType.c | 34 +++++++++++++------ ext/ffi_c/ArrayType.h | 1 + ext/ffi_c/Function.c | 2 +- ext/ffi_c/Function.h | 1 + ext/ffi_c/FunctionInfo.c | 33 ++++++++++++------ ext/ffi_c/MappedType.c | 37 +++++++++++++------- ext/ffi_c/MappedType.h | 1 - ext/ffi_c/Struct.c | 16 ++++----- ext/ffi_c/Struct.h | 3 ++ ext/ffi_c/StructByValue.c | 31 ++++++++++++----- ext/ffi_c/StructLayout.c | 85 +++++++++++++++++++++++++++++----------------- ext/ffi_c/Type.c | 44 ++++++++++++++++++------ ext/ffi_c/Type.h | 2 ++ ext/ffi_c/Variadic.c | 12 +++---- ext/ffi_c/extconf.rb | 2 +- 16 files changed, 205 insertions(+), 103 deletions(-) mode change 100644 => 100755 ext/ffi_c/extconf.rb 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 old mode 100644 new mode 100755 index 720fb06..2484543 --- 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 - $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) -- cgit v1.2.1