summaryrefslogtreecommitdiff
path: root/lib/ffi/library.rb
diff options
context:
space:
mode:
authorLars Kanis <lars@greiz-reinsdorf.de>2023-04-26 14:00:17 +0200
committerLars Kanis <lars@greiz-reinsdorf.de>2023-04-27 13:47:57 +0200
commit4fc6a8c5ec8a9a720330946af9d1103015c62942 (patch)
treee8aa241415e858a4e422e9a0a86abc1711403f22 /lib/ffi/library.rb
parente987ab50366a4b08617a20568eabdaa1fb761317 (diff)
downloadffi-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.rb34
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