diff options
Diffstat (limited to 'ext/ffi_c')
-rw-r--r-- | ext/ffi_c/AbstractMemory.c | 18 | ||||
-rw-r--r-- | ext/ffi_c/ArrayType.c | 2 | ||||
-rw-r--r-- | ext/ffi_c/Buffer.c | 4 | ||||
-rw-r--r-- | ext/ffi_c/DynamicLibrary.c | 4 | ||||
-rw-r--r-- | ext/ffi_c/Function.c | 3 | ||||
-rw-r--r-- | ext/ffi_c/FunctionInfo.c | 2 | ||||
-rw-r--r-- | ext/ffi_c/LastError.c | 3 | ||||
-rw-r--r-- | ext/ffi_c/MappedType.c | 2 | ||||
-rw-r--r-- | ext/ffi_c/MemoryPointer.c | 3 | ||||
-rw-r--r-- | ext/ffi_c/Pointer.c | 5 | ||||
-rw-r--r-- | ext/ffi_c/Struct.c | 8 | ||||
-rw-r--r-- | ext/ffi_c/StructByValue.c | 2 | ||||
-rw-r--r-- | ext/ffi_c/StructLayout.c | 4 | ||||
-rw-r--r-- | ext/ffi_c/Type.c | 4 | ||||
-rw-r--r-- | ext/ffi_c/Variadic.c | 2 | ||||
-rw-r--r-- | ext/ffi_c/compat.h | 11 | ||||
-rw-r--r-- | ext/ffi_c/ffi.c | 4 |
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 * |