summaryrefslogtreecommitdiff
path: root/ext/ffi_c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffi_c')
-rw-r--r--ext/ffi_c/AbstractMemory.c18
-rw-r--r--ext/ffi_c/ArrayType.c2
-rw-r--r--ext/ffi_c/Buffer.c4
-rw-r--r--ext/ffi_c/DynamicLibrary.c4
-rw-r--r--ext/ffi_c/Function.c3
-rw-r--r--ext/ffi_c/FunctionInfo.c2
-rw-r--r--ext/ffi_c/LastError.c3
-rw-r--r--ext/ffi_c/MappedType.c2
-rw-r--r--ext/ffi_c/MemoryPointer.c3
-rw-r--r--ext/ffi_c/Pointer.c5
-rw-r--r--ext/ffi_c/Struct.c8
-rw-r--r--ext/ffi_c/StructByValue.c2
-rw-r--r--ext/ffi_c/StructLayout.c4
-rw-r--r--ext/ffi_c/Type.c4
-rw-r--r--ext/ffi_c/Variadic.c2
-rw-r--r--ext/ffi_c/compat.h11
-rw-r--r--ext/ffi_c/ffi.c4
17 files changed, 60 insertions, 21 deletions
diff --git a/ext/ffi_c/AbstractMemory.c b/ext/ffi_c/AbstractMemory.c
index 3cf16a7..3b076bb 100644
--- a/ext/ffi_c/AbstractMemory.c
+++ b/ext/ffi_c/AbstractMemory.c
@@ -70,7 +70,7 @@ const rb_data_type_t rbffi_abstract_memory_data_type = { /* extern */
},
// 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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static size_t
@@ -316,6 +316,7 @@ static VALUE
memory_clear(VALUE self)
{
AbstractMemory* ptr = MEMORY(self);
+ checkWrite(ptr);
memset(ptr->address, 0, ptr->size);
return self;
}
@@ -687,6 +688,20 @@ memory_copy_from(VALUE self, VALUE rbsrc, VALUE rblen)
return self;
}
+/*
+ * call-seq:
+ * res.freeze
+ *
+ * Freeze the AbstractMemory object and unset the writable flag.
+ */
+static VALUE
+memory_freeze(VALUE self)
+{
+ AbstractMemory* ptr = MEMORY(self);
+ ptr->flags &= ~MEM_WR;
+ return rb_call_super(0, NULL);
+}
+
AbstractMemory*
rbffi_AbstractMemory_Cast(VALUE obj, const rb_data_type_t *data_type)
{
@@ -1102,6 +1117,7 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
rb_define_method(classMemory, "type_size", memory_type_size, 0);
rb_define_method(classMemory, "[]", memory_aref, 1);
rb_define_method(classMemory, "__copy_from__", memory_copy_from, 2);
+ rb_define_method(classMemory, "freeze", memory_freeze, 0 );
id_to_ptr = rb_intern("to_ptr");
id_call = rb_intern("call");
diff --git a/ext/ffi_c/ArrayType.c b/ext/ffi_c/ArrayType.c
index 4bd77fd..b1cbcea 100644
--- a/ext/ffi_c/ArrayType.c
+++ b/ext/ffi_c/ArrayType.c
@@ -50,7 +50,7 @@ const rb_data_type_t rbffi_array_type_data_type = { /* extern */
.parent = &rbffi_type_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
diff --git a/ext/ffi_c/Buffer.c b/ext/ffi_c/Buffer.c
index 0bfcc02..78339f3 100644
--- a/ext/ffi_c/Buffer.c
+++ b/ext/ffi_c/Buffer.c
@@ -67,7 +67,7 @@ static const rb_data_type_t buffer_data_type = {
.parent = &rbffi_abstract_memory_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static const rb_data_type_t allocated_buffer_data_type = {
@@ -80,7 +80,7 @@ static const rb_data_type_t allocated_buffer_data_type = {
.parent = &buffer_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
diff --git a/ext/ffi_c/DynamicLibrary.c b/ext/ffi_c/DynamicLibrary.c
index 9bfe86e..9abafc7 100644
--- a/ext/ffi_c/DynamicLibrary.c
+++ b/ext/ffi_c/DynamicLibrary.c
@@ -73,7 +73,7 @@ static const rb_data_type_t rbffi_library_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static const rb_data_type_t library_symbol_data_type = {
@@ -87,7 +87,7 @@ static const rb_data_type_t library_symbol_data_type = {
.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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static VALUE LibraryClass = Qnil, SymbolClass = Qnil;
diff --git a/ext/ffi_c/Function.c b/ext/ffi_c/Function.c
index 0e68722..a74136a 100644
--- a/ext/ffi_c/Function.c
+++ b/ext/ffi_c/Function.c
@@ -108,7 +108,7 @@ static const rb_data_type_t function_data_type = {
.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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
VALUE rbffi_FunctionClass = Qnil;
@@ -462,6 +462,7 @@ function_set_autorelease(VALUE self, VALUE autorelease)
{
Function* fn;
+ rb_check_frozen(self);
TypedData_Get_Struct(self, Function, &function_data_type, fn);
fn->autorelease = RTEST(autorelease);
diff --git a/ext/ffi_c/FunctionInfo.c b/ext/ffi_c/FunctionInfo.c
index 7f77621..197c681 100644
--- a/ext/ffi_c/FunctionInfo.c
+++ b/ext/ffi_c/FunctionInfo.c
@@ -67,7 +67,7 @@ const rb_data_type_t rbffi_fntype_data_type = { /* extern */
.parent = &rbffi_type_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
VALUE rbffi_FunctionTypeClass = Qnil;
diff --git a/ext/ffi_c/LastError.c b/ext/ffi_c/LastError.c
index d5ef132..877a3d3 100644
--- a/ext/ffi_c/LastError.c
+++ b/ext/ffi_c/LastError.c
@@ -105,7 +105,7 @@ static const rb_data_type_t thread_data_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static ID id_thread_data;
@@ -173,7 +173,6 @@ get_last_winapi_error(VALUE self)
static VALUE
set_last_error(VALUE self, VALUE error)
{
-
#ifdef _WIN32
SetLastError(NUM2INT(error));
#else
diff --git a/ext/ffi_c/MappedType.c b/ext/ffi_c/MappedType.c
index b1532e1..e61af30 100644
--- a/ext/ffi_c/MappedType.c
+++ b/ext/ffi_c/MappedType.c
@@ -57,7 +57,7 @@ static const rb_data_type_t mapped_type_data_type = {
.parent = &rbffi_type_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
diff --git a/ext/ffi_c/MemoryPointer.c b/ext/ffi_c/MemoryPointer.c
index 8227183..a60168e 100644
--- a/ext/ffi_c/MemoryPointer.c
+++ b/ext/ffi_c/MemoryPointer.c
@@ -64,7 +64,7 @@ static const rb_data_type_t memory_pointer_data_type = {
.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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static VALUE
@@ -136,6 +136,7 @@ memptr_free(VALUE self)
{
Pointer* ptr;
+ rb_check_frozen(self);
TypedData_Get_Struct(self, Pointer, &memory_pointer_data_type, ptr);
if (ptr->allocated) {
diff --git a/ext/ffi_c/Pointer.c b/ext/ffi_c/Pointer.c
index a6e8eb7..dae853a 100644
--- a/ext/ffi_c/Pointer.c
+++ b/ext/ffi_c/Pointer.c
@@ -33,6 +33,7 @@
#include <ruby.h>
#include "rbffi.h"
#include "rbffi_endian.h"
+#include "compat.h"
#include "AbstractMemory.h"
#include "Pointer.h"
@@ -57,7 +58,7 @@ const rb_data_type_t rbffi_pointer_data_type = { /* extern */
.parent = &rbffi_abstract_memory_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
VALUE
@@ -397,6 +398,7 @@ ptr_free(VALUE self)
{
Pointer* ptr;
+ rb_check_frozen(self);
TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr);
if (ptr->allocated) {
@@ -436,6 +438,7 @@ ptr_autorelease(VALUE self, VALUE autorelease)
{
Pointer* ptr;
+ rb_check_frozen(self);
TypedData_Get_Struct(self, Pointer, &rbffi_pointer_data_type, ptr);
ptr->autorelease = autorelease == Qtrue;
diff --git a/ext/ffi_c/Struct.c b/ext/ffi_c/Struct.c
index b9b6b2c..99b164d 100644
--- a/ext/ffi_c/Struct.c
+++ b/ext/ffi_c/Struct.c
@@ -82,7 +82,7 @@ const rb_data_type_t rbffi_struct_data_type = { /* extern */
},
// 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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
VALUE rbffi_StructClass = Qnil;
@@ -382,6 +382,7 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
Struct* s;
StructField* f;
+ rb_check_frozen(self);
s = struct_validate(self);
f = struct_field(s, fieldName);
@@ -421,6 +422,7 @@ struct_set_pointer(VALUE self, VALUE pointer)
StructLayout* layout;
AbstractMemory* memory;
+ rb_check_frozen(self);
if (!rb_obj_is_kind_of(pointer, rbffi_AbstractMemoryClass)) {
rb_raise(rb_eTypeError, "wrong argument type %s (expected Pointer or Buffer)",
rb_obj_classname(pointer));
@@ -471,6 +473,7 @@ struct_set_layout(VALUE self, VALUE layout)
Struct* s;
TypedData_Get_Struct(self, Struct, &rbffi_struct_data_type, s);
+ rb_check_frozen(self);
if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
rb_obj_classname(layout), rb_class2name(rbffi_StructLayoutClass));
@@ -544,7 +547,7 @@ static const rb_data_type_t inline_array_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static VALUE
@@ -684,6 +687,7 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
{
InlineArray* array;
+ rb_check_frozen(self);
TypedData_Get_Struct(self, InlineArray, &inline_array_data_type, array);
if (array->op != NULL) {
diff --git a/ext/ffi_c/StructByValue.c b/ext/ffi_c/StructByValue.c
index 94061f3..df03684 100644
--- a/ext/ffi_c/StructByValue.c
+++ b/ext/ffi_c/StructByValue.c
@@ -67,7 +67,7 @@ static const rb_data_type_t sbv_type_data_type = {
.parent = &rbffi_type_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static VALUE
diff --git a/ext/ffi_c/StructLayout.c b/ext/ffi_c/StructLayout.c
index 548ddb5..613394a 100644
--- a/ext/ffi_c/StructLayout.c
+++ b/ext/ffi_c/StructLayout.c
@@ -77,7 +77,7 @@ const rb_data_type_t rbffi_struct_layout_data_type = { /* extern */
.parent = &rbffi_type_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
const rb_data_type_t rbffi_struct_field_data_type = { /* extern */
@@ -91,7 +91,7 @@ const rb_data_type_t rbffi_struct_field_data_type = { /* extern */
.parent = &rbffi_type_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static VALUE
diff --git a/ext/ffi_c/Type.c b/ext/ffi_c/Type.c
index 194c81e..3431681 100644
--- a/ext/ffi_c/Type.c
+++ b/ext/ffi_c/Type.c
@@ -64,7 +64,7 @@ const rb_data_type_t rbffi_type_data_type = { /* extern */
},
// 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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static const rb_data_type_t builtin_type_data_type = {
@@ -77,7 +77,7 @@ static const rb_data_type_t builtin_type_data_type = {
.parent = &rbffi_type_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
static size_t
diff --git a/ext/ffi_c/Variadic.c b/ext/ffi_c/Variadic.c
index a255969..2e9d790 100644
--- a/ext/ffi_c/Variadic.c
+++ b/ext/ffi_c/Variadic.c
@@ -81,7 +81,7 @@ static const rb_data_type_t variadic_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
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | FFI_RUBY_TYPED_FROZEN_SHAREABLE
};
diff --git a/ext/ffi_c/compat.h b/ext/ffi_c/compat.h
index 889a4be..a8fdcbe 100644
--- a/ext/ffi_c/compat.h
+++ b/ext/ffi_c/compat.h
@@ -79,6 +79,8 @@
# define RB_GC_GUARD(x) (x)
#endif
+
+/* For compatibility with ruby < 2.7 */
#ifdef HAVE_RB_GC_MARK_MOVABLE
#define ffi_compact_callback(x) .dcompact = (x),
#define ffi_gc_location(x) x = rb_gc_location(x)
@@ -88,4 +90,13 @@
#define ffi_gc_location(x)
#endif
+
+/* For compatibility with ruby < 3.0 */
+#ifndef RUBY_TYPED_FROZEN_SHAREABLE
+#define FFI_RUBY_TYPED_FROZEN_SHAREABLE 0
+#else
+#define FFI_RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
+#endif
+
+
#endif /* RBFFI_COMPAT_H */
diff --git a/ext/ffi_c/ffi.c b/ext/ffi_c/ffi.c
index 22ea3bf..e297f8a 100644
--- a/ext/ffi_c/ffi.c
+++ b/ext/ffi_c/ffi.c
@@ -60,6 +60,10 @@ static VALUE moduleFFI = Qnil;
void
Init_ffi_c(void)
{
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(1);
+ #endif
+
/*
* Document-module: FFI
*