diff options
Diffstat (limited to 'ext/ffi_c/MemoryPointer.c')
-rw-r--r-- | ext/ffi_c/MemoryPointer.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/ext/ffi_c/MemoryPointer.c b/ext/ffi_c/MemoryPointer.c index 1a64f2e..a60168e 100644 --- a/ext/ffi_c/MemoryPointer.c +++ b/ext/ffi_c/MemoryPointer.c @@ -39,13 +39,14 @@ static VALUE memptr_allocate(VALUE klass); -static void memptr_release(Pointer* ptr); +static void memptr_release(void *data); +static size_t memptr_memsize(const void *data); static VALUE memptr_malloc(VALUE self, long size, long count, bool clear); static VALUE memptr_free(VALUE self); VALUE rbffi_MemoryPointerClass; -#define MEMPTR(obj) ((MemoryPointer *) rbffi_AbstractMemory_Cast(obj, rbffi_MemoryPointerClass)) +#define MEMPTR(obj) ((MemoryPointer *) rbffi_AbstractMemory_Cast(obj, &memory_pointer_data_type)) VALUE rbffi_MemoryPointer_NewInstance(long size, long count, bool clear) @@ -53,12 +54,25 @@ 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 = memptr_memsize, + }, + .parent = &rbffi_pointer_data_type, + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE +}; + static VALUE memptr_allocate(VALUE klass) { Pointer* p; - VALUE obj = Data_Make_Struct(klass, Pointer, NULL, memptr_release, p); - p->rbParent = Qnil; + VALUE obj = TypedData_Make_Struct(klass, Pointer, &memory_pointer_data_type, p); + RB_OBJ_WRITE(obj, &p->rbParent, Qnil); p->memory.flags = MEM_RD | MEM_WR; return obj; @@ -94,7 +108,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 +136,8 @@ memptr_free(VALUE self) { Pointer* ptr; - Data_Get_Struct(self, Pointer, ptr); + rb_check_frozen(self); + TypedData_Get_Struct(self, Pointer, &memory_pointer_data_type, ptr); if (ptr->allocated) { if (ptr->storage != NULL) { @@ -136,8 +151,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; @@ -145,6 +161,17 @@ memptr_release(Pointer* ptr) xfree(ptr); } +static size_t +memptr_memsize(const void *data) +{ + const Pointer *ptr = (const Pointer *)data; + size_t memsize = sizeof(Pointer); + if (ptr->allocated) { + memsize += ptr->memory.size; + } + return memsize; +} + /* * call-seq: from_string(s) * @param [String] s string |