diff options
author | Lars Kanis <lars@greiz-reinsdorf.de> | 2023-04-26 14:00:17 +0200 |
---|---|---|
committer | Lars Kanis <lars@greiz-reinsdorf.de> | 2023-04-27 13:47:57 +0200 |
commit | 4fc6a8c5ec8a9a720330946af9d1103015c62942 (patch) | |
tree | e8aa241415e858a4e422e9a0a86abc1711403f22 /lib/ffi/library.rb | |
parent | e987ab50366a4b08617a20568eabdaa1fb761317 (diff) | |
download | ffi-4fc6a8c5ec8a9a720330946af9d1103015c62942.tar.gz |
Store each FFI::Function in it's own instance variabe in the module to be attached
This allows to freeze the FFI::Function immediately, so that it is shareable by Ractor without the need to freeze the module explicit.
To make it shareable the typedef hash used for variadic functions is duplicated and made frozen.
This creates a small compatibility issue:
Only typedefs defined above the variadic function can be used by that function.
If a typedef is created after the definition of the variadic function, then this typedef can no longer be used as parameter to that variadic function.
Also fix the retrieval of simple (non-struct) global variables per #attached_variables.
Closes #975
Diffstat (limited to 'lib/ffi/library.rb')
-rw-r--r-- | lib/ffi/library.rb | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/lib/ffi/library.rb b/lib/ffi/library.rb index 5656b2d..e681b3e 100644 --- a/lib/ffi/library.rb +++ b/lib/ffi/library.rb @@ -209,7 +209,7 @@ module FFI end raise LoadError unless function - invokers << if arg_types.length > 0 && arg_types[arg_types.length - 1] == FFI::NativeType::VARARGS + invokers << if arg_types[-1] == FFI::NativeType::VARARGS VariadicInvoker.new(function, arg_types, find_type(ret_type), options) else @@ -295,10 +295,9 @@ module FFI # If it is a global struct, just attach directly to the pointer s = s = type.new(address) # Assigning twice to suppress unused variable warning self.module_eval <<-code, __FILE__, __LINE__ - @ffi_gvars = {} unless defined?(@ffi_gvars) - @ffi_gvars[#{mname.inspect}] = s + @ffi_gsvar_#{mname} = s def self.#{mname} - @ffi_gvars[#{mname.inspect}] + @ffi_gsvar_#{mname} end code @@ -310,13 +309,12 @@ module FFI # Attach to this module as mname/mname= # self.module_eval <<-code, __FILE__, __LINE__ - @ffi_gvars = {} unless defined?(@ffi_gvars) - @ffi_gvars[#{mname.inspect}] = s + @ffi_gvar_#{mname} = s def self.#{mname} - @ffi_gvars[#{mname.inspect}][:gvar] + @ffi_gvar_#{mname}[:gvar] end def self.#{mname}=(value) - @ffi_gvars[#{mname.inspect}][:gvar] = value + @ffi_gvar_#{mname}[:gvar] = value end code @@ -543,18 +541,20 @@ module FFI end def attached_functions - @ffi_functions || {} - end - - def attached_variables - (@ffi_gvars || {}).map do |name, gvar| - [name, gvar.class] + instance_variables.grep(/\A@ffi_function_(.*)/) do |m| + [$1, instance_variable_get(m)] end.to_h end - def freeze - super - FFI.make_shareable(@ffi_functions) + def attached_variables + ( + instance_variables.grep(/\A@ffi_gsvar_(.*)/) do |m| + [$1, instance_variable_get(m).class] + end + + instance_variables.grep(/\A@ffi_gvar_(.*)/) do |m| + [$1, instance_variable_get(m).layout[:gvar].type] + end + ).to_h end end end |