summaryrefslogtreecommitdiff
path: root/lib/ffi
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ffi')
-rw-r--r--lib/ffi/autopointer.rb29
-rw-r--r--lib/ffi/compat.rb43
-rw-r--r--lib/ffi/data_converter.rb4
-rw-r--r--lib/ffi/dynamic_library.rb89
-rw-r--r--lib/ffi/ffi.rb2
-rw-r--r--lib/ffi/function.rb71
-rw-r--r--lib/ffi/library.rb114
-rw-r--r--lib/ffi/managedstruct.rb2
-rw-r--r--lib/ffi/platform.rb28
-rw-r--r--lib/ffi/platform/hppa1.1-linux/types.conf178
-rw-r--r--lib/ffi/platform/hppa2.0-linux/types.conf178
-rw-r--r--lib/ffi/platform/sparcv9-linux/types.conf (renamed from lib/ffi/platform/sparc64-linux/types.conf)0
-rw-r--r--lib/ffi/platform/sw_64-linux/types.conf141
-rw-r--r--lib/ffi/struct.rb3
-rw-r--r--lib/ffi/struct_layout.rb2
-rw-r--r--lib/ffi/struct_layout_builder.rb2
-rw-r--r--lib/ffi/types.rb35
-rw-r--r--lib/ffi/variadic.rb27
18 files changed, 833 insertions, 115 deletions
diff --git a/lib/ffi/autopointer.rb b/lib/ffi/autopointer.rb
index 679d7e6..bbcb6db 100644
--- a/lib/ffi/autopointer.rb
+++ b/lib/ffi/autopointer.rb
@@ -76,21 +76,21 @@ module FFI
# going to be useful if you subclass {AutoPointer}, and override
# #release, which by default does nothing.
def initialize(ptr, proc=nil, &block)
+ raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) ||
+ ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
super(ptr.type_size, ptr)
- raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) \
- || ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
@releaser = if proc
if not proc.respond_to?(:call)
raise RuntimeError.new("proc must be callable")
end
- CallableReleaser.new(ptr, proc)
+ Releaser.new(ptr, proc)
else
- if not self.class.respond_to?(:release)
+ if not self.class.respond_to?(:release, true)
raise RuntimeError.new("no release method defined")
end
- DefaultReleaser.new(ptr, self.class)
+ Releaser.new(ptr, self.class.method(:release))
end
ObjectSpace.define_finalizer(self, @releaser)
@@ -107,6 +107,7 @@ module FFI
# @return [Boolean] +autorelease+
# Set +autorelease+ property. See {Pointer Autorelease section at Pointer}.
def autorelease=(autorelease)
+ raise FrozenError.new("can't modify frozen #{self.class}") if frozen?
@releaser.autorelease=(autorelease)
end
@@ -149,23 +150,7 @@ module FFI
def call(*args)
release(@ptr) if @autorelease && @ptr
end
- end
-
- # DefaultReleaser is a {Releaser} used when an {AutoPointer} is defined
- # without Proc or Method. In this case, the pointer to release must be of
- # a class derived from AutoPointer with a {release} class method.
- class DefaultReleaser < Releaser
- # @param [Pointer] ptr
- # @return [nil]
- # Release +ptr+ using the {release} class method of its class.
- def release(ptr)
- @proc.release(ptr)
- end
- end
- # CallableReleaser is a {Releaser} used when an {AutoPointer} is defined with a
- # Proc or a Method.
- class CallableReleaser < Releaser
# Release +ptr+ by using Proc or Method defined at +ptr+
# {AutoPointer#initialize initialization}.
#
@@ -182,7 +167,7 @@ module FFI
# @return [Type::POINTER]
# @raise {RuntimeError} if class does not implement a +#release+ method
def self.native_type
- if not self.respond_to?(:release)
+ if not self.respond_to?(:release, true)
raise RuntimeError.new("no release method defined for #{self.inspect}")
end
Type::POINTER
diff --git a/lib/ffi/compat.rb b/lib/ffi/compat.rb
new file mode 100644
index 0000000..7569013
--- /dev/null
+++ b/lib/ffi/compat.rb
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2023-2023 Lars Kanis
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+module FFI
+ if defined?(Ractor.make_shareable)
+ # This is for FFI internal use only.
+ def self.make_shareable(obj)
+ Ractor.make_shareable(obj)
+ end
+ else
+ def self.make_shareable(obj)
+ obj.freeze
+ end
+ end
+end
diff --git a/lib/ffi/data_converter.rb b/lib/ffi/data_converter.rb
index 1527588..7852e7e 100644
--- a/lib/ffi/data_converter.rb
+++ b/lib/ffi/data_converter.rb
@@ -31,7 +31,7 @@
module FFI
# This module is used to extend somes classes and give then a common API.
#
- # Most of methods defined here must be overriden.
+ # Most of methods defined here must be overridden.
module DataConverter
# Get native type.
#
@@ -41,7 +41,7 @@ module FFI
# Get native type from +type+.
#
# @overload native_type
- # @raise {NotImplementedError} This method must be overriden.
+ # @raise {NotImplementedError} This method must be overridden.
def native_type(type = nil)
if type
@native_type = FFI.find_type(type)
diff --git a/lib/ffi/dynamic_library.rb b/lib/ffi/dynamic_library.rb
new file mode 100644
index 0000000..b415033
--- /dev/null
+++ b/lib/ffi/dynamic_library.rb
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2008-2010 Wayne Meissner
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
+
+module FFI
+ class DynamicLibrary
+ SEARCH_PATH = %w[/usr/lib /usr/local/lib /opt/local/lib]
+ if FFI::Platform::ARCH == 'aarch64' && FFI::Platform.mac?
+ SEARCH_PATH << '/opt/homebrew/lib'
+ end
+
+ SEARCH_PATH_MESSAGE = "Searched in <system library path>, #{SEARCH_PATH.join(', ')}".freeze
+
+ def self.load_library(name, flags)
+ if name == FFI::CURRENT_PROCESS
+ FFI::DynamicLibrary.open(nil, RTLD_LAZY | RTLD_LOCAL)
+ else
+ flags ||= RTLD_LAZY | RTLD_LOCAL
+
+ libnames = (name.is_a?(::Array) ? name : [name])
+ libnames = libnames.map(&:to_s).map { |n| [n, FFI.map_library_name(n)].uniq }.flatten.compact
+ errors = []
+
+ libnames.each do |libname|
+ lib = try_load(libname, flags, errors)
+ return lib if lib
+
+ unless libname.start_with?("/") || FFI::Platform.windows?
+ SEARCH_PATH.each do |prefix|
+ path = "#{prefix}/#{libname}"
+ if File.exist?(path)
+ lib = try_load(path, flags, errors)
+ return lib if lib
+ end
+ end
+ end
+ end
+
+ raise LoadError, [*errors, SEARCH_PATH_MESSAGE].join(".\n")
+ end
+ end
+ private_class_method :load_library
+
+ def self.try_load(libname, flags, errors)
+ begin
+ lib = FFI::DynamicLibrary.open(libname, flags)
+ return lib if lib
+
+ # LoadError for C ext & JRuby, RuntimeError for TruffleRuby
+ rescue LoadError, RuntimeError => ex
+ if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/
+ if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
+ return try_load($1, flags, errors)
+ end
+ end
+
+ errors << ex
+ nil
+ end
+ end
+ private_class_method :try_load
+ end
+end
diff --git a/lib/ffi/ffi.rb b/lib/ffi/ffi.rb
index dfffa8c..bc1b2e6 100644
--- a/lib/ffi/ffi.rb
+++ b/lib/ffi/ffi.rb
@@ -28,6 +28,7 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+require 'ffi/compat'
require 'ffi/platform'
require 'ffi/data_converter'
require 'ffi/types'
@@ -45,3 +46,4 @@ require 'ffi/autopointer'
require 'ffi/variadic'
require 'ffi/enum'
require 'ffi/version'
+require 'ffi/function'
diff --git a/lib/ffi/function.rb b/lib/ffi/function.rb
new file mode 100644
index 0000000..ac4daf0
--- /dev/null
+++ b/lib/ffi/function.rb
@@ -0,0 +1,71 @@
+#
+# Copyright (C) 2008-2010 JRuby project
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+module FFI
+ class Function
+ # Only MRI allows function type queries
+ if private_method_defined?(:type)
+ # Retrieve the return type of the function
+ #
+ # This method returns FFI type returned by the function.
+ #
+ # @return [FFI::Type]
+ def return_type
+ type.return_type
+ end
+
+ # Retrieve Array of parameter types
+ #
+ # This method returns an Array of FFI types accepted as function parameters.
+ #
+ # @return [Array<FFI::Type>]
+ def param_types
+ type.param_types
+ end
+ end
+
+ # Stash the Function in a module variable so it can be inspected by attached_functions.
+ # On CRuby it also ensures that it does not get garbage collected.
+ module RegisterAttach
+ def attach(mod, name)
+ funcs = mod.instance_variable_get("@ffi_functions")
+ unless funcs
+ funcs = {}
+ mod.instance_variable_set("@ffi_functions", funcs)
+ end
+ funcs[name.to_sym] = self
+ # Jump to the native attach method of CRuby, JRuby or Tuffleruby
+ super
+ end
+ end
+ private_constant :RegisterAttach
+ prepend RegisterAttach
+ end
+end
diff --git a/lib/ffi/library.rb b/lib/ffi/library.rb
index c2628ab..2556975 100644
--- a/lib/ffi/library.rb
+++ b/lib/ffi/library.rb
@@ -28,8 +28,10 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
+require 'ffi/dynamic_library'
+
module FFI
- CURRENT_PROCESS = USE_THIS_PROCESS_AS_LIBRARY = Object.new
+ CURRENT_PROCESS = USE_THIS_PROCESS_AS_LIBRARY = FFI.make_shareable(Object.new)
class LibraryPath < ::Struct.new(:name, :abi_number, :root)
PATTERN = /(#{Platform::LIBPREFIX})?(?<name>.*?)(\.|\z)/
@@ -134,62 +136,11 @@ module FFI
def ffi_lib(*names)
raise LoadError.new("library names list must not be empty") if names.empty?
- lib_flags = defined?(@ffi_lib_flags) ? @ffi_lib_flags : FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL
- ffi_libs = names.map do |name|
-
- if name == FFI::CURRENT_PROCESS
- FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
-
- else
- libnames = (name.is_a?(::Array) ? name : [ name ]).map(&:to_s).map { |n| [ n, FFI.map_library_name(n) ].uniq }.flatten.compact
- lib = nil
- errors = {}
-
- libnames.each do |libname|
- begin
- orig = libname
- lib = FFI::DynamicLibrary.open(libname, lib_flags)
- break if lib
-
- rescue Exception => ex
- ldscript = false
- if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/
- if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
- libname = $1
- ldscript = true
- end
- end
-
- if ldscript
- retry
- else
- # TODO better library lookup logic
- unless libname.start_with?("/") || FFI::Platform.windows?
- path = ['/usr/lib/','/usr/local/lib/','/opt/local/lib/', '/opt/homebrew/lib/'].find do |pth|
- File.exist?(pth + libname)
- end
- if path
- libname = path + libname
- retry
- end
- end
-
- libr = (orig == libname ? orig : "#{orig} #{libname}")
- errors[libr] = ex
- end
- end
- end
-
- if lib.nil?
- raise LoadError.new(errors.values.join(".\n"))
- end
+ lib_flags = defined?(@ffi_lib_flags) && @ffi_lib_flags
- # return the found lib
- lib
- end
+ @ffi_libs = names.map do |name|
+ FFI::DynamicLibrary.send(:load_library, name, lib_flags)
end
-
- @ffi_libs = ffi_libs
end
# Set the calling convention for {#attach_function} and {#callback}
@@ -297,7 +248,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
@@ -369,6 +320,7 @@ module FFI
# Attach C variable +cname+ to this module.
def attach_variable(mname, a1, a2 = nil)
cname, type = a2 ? [ a1, a2 ] : [ mname.to_s, a1 ]
+ mname = mname.to_sym
address = nil
ffi_libraries.each do |lib|
begin
@@ -383,9 +335,10 @@ 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_gvar_#{mname} = s
+ @ffi_gsvars = {} unless defined?(@ffi_gsvars)
+ @ffi_gsvars[#{mname.inspect}] = s
def self.#{mname}
- @@ffi_gvar_#{mname}
+ @ffi_gsvars[#{mname.inspect}]
end
code
@@ -397,12 +350,13 @@ module FFI
# Attach to this module as mname/mname=
#
self.module_eval <<-code, __FILE__, __LINE__
- @@ffi_gvar_#{mname} = s
+ @ffi_gvars = {} unless defined?(@ffi_gvars)
+ @ffi_gvars[#{mname.inspect}] = s
def self.#{mname}
- @@ffi_gvar_#{mname}[:gvar]
+ @ffi_gvars[#{mname.inspect}][:gvar]
end
def self.#{mname}=(value)
- @@ffi_gvar_#{mname}[:gvar] = value
+ @ffi_gvars[#{mname.inspect}][:gvar] = value
end
code
@@ -627,5 +581,43 @@ module FFI
end || FFI.find_type(t)
end
+
+ # Retrieve all attached functions and their function signature
+ #
+ # This method returns a Hash of method names of attached functions connected by #attach_function and the corresponding function type.
+ # The function type responds to #return_type and #param_types which return the FFI types of the function signature.
+ #
+ # @return [Hash< Symbol => [FFI::Function, FFI::VariadicInvoker] >]
+ def attached_functions
+ @ffi_functions || {}
+ end
+
+ # Retrieve all attached variables and their type
+ #
+ # This method returns a Hash of variable names and the corresponding type or variables connected by #attach_variable .
+ #
+ # @return [Hash< Symbol => ffi_type >]
+ def attached_variables
+ (
+ (@ffi_gsvars || {}).map do |name, gvar|
+ [name, gvar.class]
+ end +
+ (@ffi_gvars || {}).map do |name, gvar|
+ [name, gvar.layout[:gvar].type]
+ end
+ ).to_h
+ end
+
+ # Freeze all definitions of the module
+ #
+ # This freezes the module's definitions, so that it can be used in a Ractor.
+ # No further methods or variables can be attached and no further enums or typedefs can be created in this module afterwards.
+ def freeze
+ instance_variables.each do |name|
+ var = instance_variable_get(name)
+ FFI.make_shareable(var)
+ end
+ nil
+ end
end
end
diff --git a/lib/ffi/managedstruct.rb b/lib/ffi/managedstruct.rb
index b5ec8a3..5d243e5 100644
--- a/lib/ffi/managedstruct.rb
+++ b/lib/ffi/managedstruct.rb
@@ -75,7 +75,7 @@ module FFI
# @overload initialize
# A new instance of FFI::ManagedStruct.
def initialize(pointer=nil)
- raise NoMethodError, "release() not implemented for class #{self}" unless self.class.respond_to? :release
+ raise NoMethodError, "release() not implemented for class #{self}" unless self.class.respond_to?(:release, true)
raise ArgumentError, "Must supply a pointer to memory for the Struct" unless pointer
super AutoPointer.new(pointer, self.class.method(:release))
end
diff --git a/lib/ffi/platform.rb b/lib/ffi/platform.rb
index bf01a27..5ac4dd7 100644
--- a/lib/ffi/platform.rb
+++ b/lib/ffi/platform.rb
@@ -29,13 +29,15 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
require 'rbconfig'
+require_relative 'compat'
+
module FFI
class PlatformError < LoadError; end
# This module defines different constants and class methods to play with
# various platforms.
module Platform
- OS = case RbConfig::CONFIG['host_os'].downcase
+ OS = FFI.make_shareable(case RbConfig::CONFIG['host_os'].downcase
when /linux/
"linux"
when /darwin/
@@ -54,13 +56,13 @@ module FFI
"windows"
else
RbConfig::CONFIG['host_os'].downcase
- end
+ end)
OSVERSION = RbConfig::CONFIG['host_os'].gsub(/[^\d]/, '').to_i
- CPU = RbConfig::CONFIG['host_cpu']
+ CPU = FFI.make_shareable(RbConfig::CONFIG['host_cpu'])
- ARCH = case CPU.downcase
+ ARCH = FFI.make_shareable(case CPU.downcase
when /amd64|x86_64|x64/
"x86_64"
when /i\d86|x86|i86pc/
@@ -81,7 +83,7 @@ module FFI
end
else
RbConfig::CONFIG['host_cpu']
- end
+ end)
private
# @param [String) os
@@ -105,21 +107,21 @@ module FFI
# Add the version for known ABI breaks
name_version = "12" if IS_FREEBSD && OSVERSION >= 12 # 64-bit inodes
- NAME = "#{ARCH}-#{OS}#{name_version}"
- CONF_DIR = File.join(File.dirname(__FILE__), 'platform', NAME)
+ NAME = FFI.make_shareable("#{ARCH}-#{OS}#{name_version}")
+ CONF_DIR = FFI.make_shareable(File.join(File.dirname(__FILE__), 'platform', NAME))
public
- LIBPREFIX = case OS
+ LIBPREFIX = FFI.make_shareable(case OS
when /windows|msys/
''
when /cygwin/
'cyg'
else
'lib'
- end
+ end)
- LIBSUFFIX = case OS
+ LIBSUFFIX = FFI.make_shareable(case OS
when /darwin/
'dylib'
when /linux|bsd|solaris/
@@ -129,9 +131,9 @@ module FFI
else
# Punt and just assume a sane unix (i.e. anything but AIX)
'so'
- end
+ end)
- LIBC = if IS_WINDOWS
+ LIBC = FFI.make_shareable(if IS_WINDOWS
crtname = RbConfig::CONFIG["RUBY_SO_NAME"][/msvc\w+/] || 'ucrtbase'
"#{crtname}.dll"
elsif IS_GNU
@@ -143,7 +145,7 @@ module FFI
"msys-2.0.dll"
else
"#{LIBPREFIX}c.#{LIBSUFFIX}"
- end
+ end)
LITTLE_ENDIAN = 1234 unless defined?(LITTLE_ENDIAN)
BIG_ENDIAN = 4321 unless defined?(BIG_ENDIAN)
diff --git a/lib/ffi/platform/hppa1.1-linux/types.conf b/lib/ffi/platform/hppa1.1-linux/types.conf
new file mode 100644
index 0000000..c8a8141
--- /dev/null
+++ b/lib/ffi/platform/hppa1.1-linux/types.conf
@@ -0,0 +1,178 @@
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsword_t = int
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__int_least64_t = long_long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__intmax_t = long_long
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__kernel_caddr_t = string
+rbx.platform.typedef.__kernel_clock_t = long
+rbx.platform.typedef.__kernel_clockid_t = int
+rbx.platform.typedef.__kernel_daddr_t = int
+rbx.platform.typedef.__kernel_gid16_t = ushort
+rbx.platform.typedef.__kernel_gid32_t = uint
+rbx.platform.typedef.__kernel_gid_t = uint
+rbx.platform.typedef.__kernel_ino64_t = ulong_long
+rbx.platform.typedef.__kernel_ino_t = ulong
+rbx.platform.typedef.__kernel_ipc_pid_t = ushort
+rbx.platform.typedef.__kernel_key_t = int
+rbx.platform.typedef.__kernel_loff_t = long_long
+rbx.platform.typedef.__kernel_long_t = long
+rbx.platform.typedef.__kernel_mode_t = ushort
+rbx.platform.typedef.__kernel_mqd_t = int
+rbx.platform.typedef.__kernel_off64_t = long_long
+rbx.platform.typedef.__kernel_off_t = long
+rbx.platform.typedef.__kernel_old_dev_t = uint
+rbx.platform.typedef.__kernel_old_gid_t = uint
+rbx.platform.typedef.__kernel_old_time_t = long
+rbx.platform.typedef.__kernel_old_uid_t = uint
+rbx.platform.typedef.__kernel_pid_t = int
+rbx.platform.typedef.__kernel_ptrdiff_t = int
+rbx.platform.typedef.__kernel_size_t = uint
+rbx.platform.typedef.__kernel_ssize_t = int
+rbx.platform.typedef.__kernel_suseconds_t = long
+rbx.platform.typedef.__kernel_time64_t = long_long
+rbx.platform.typedef.__kernel_time_t = long
+rbx.platform.typedef.__kernel_timer_t = int
+rbx.platform.typedef.__kernel_uid16_t = ushort
+rbx.platform.typedef.__kernel_uid32_t = uint
+rbx.platform.typedef.__kernel_uid_t = uint
+rbx.platform.typedef.__kernel_ulong_t = ulong
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__priority_which_t = int
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__suseconds64_t = long_long
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__syscall_slong_t = long
+rbx.platform.typedef.__syscall_ulong_t = ulong
+rbx.platform.typedef.__thrd_t = ulong
+rbx.platform.typedef.__time64_t = long_long
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__tss_t = uint
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__uint_least64_t = ulong_long
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__uintmax_t = ulong_long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int_fast16_t = int
+rbx.platform.typedef.int_fast32_t = int
+rbx.platform.typedef.int_fast64_t = long_long
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long_long
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.intmax_t = long_long
+rbx.platform.typedef.intptr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.ptrdiff_t = int
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint_fast16_t = uint
+rbx.platform.typedef.uint_fast32_t = uint
+rbx.platform.typedef.uint_fast64_t = ulong_long
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong_long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uintmax_t = ulong_long
+rbx.platform.typedef.uintptr_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.wchar_t = long
diff --git a/lib/ffi/platform/hppa2.0-linux/types.conf b/lib/ffi/platform/hppa2.0-linux/types.conf
new file mode 100644
index 0000000..c8a8141
--- /dev/null
+++ b/lib/ffi/platform/hppa2.0-linux/types.conf
@@ -0,0 +1,178 @@
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsword_t = int
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__int_least64_t = long_long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__intmax_t = long_long
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__kernel_caddr_t = string
+rbx.platform.typedef.__kernel_clock_t = long
+rbx.platform.typedef.__kernel_clockid_t = int
+rbx.platform.typedef.__kernel_daddr_t = int
+rbx.platform.typedef.__kernel_gid16_t = ushort
+rbx.platform.typedef.__kernel_gid32_t = uint
+rbx.platform.typedef.__kernel_gid_t = uint
+rbx.platform.typedef.__kernel_ino64_t = ulong_long
+rbx.platform.typedef.__kernel_ino_t = ulong
+rbx.platform.typedef.__kernel_ipc_pid_t = ushort
+rbx.platform.typedef.__kernel_key_t = int
+rbx.platform.typedef.__kernel_loff_t = long_long
+rbx.platform.typedef.__kernel_long_t = long
+rbx.platform.typedef.__kernel_mode_t = ushort
+rbx.platform.typedef.__kernel_mqd_t = int
+rbx.platform.typedef.__kernel_off64_t = long_long
+rbx.platform.typedef.__kernel_off_t = long
+rbx.platform.typedef.__kernel_old_dev_t = uint
+rbx.platform.typedef.__kernel_old_gid_t = uint
+rbx.platform.typedef.__kernel_old_time_t = long
+rbx.platform.typedef.__kernel_old_uid_t = uint
+rbx.platform.typedef.__kernel_pid_t = int
+rbx.platform.typedef.__kernel_ptrdiff_t = int
+rbx.platform.typedef.__kernel_size_t = uint
+rbx.platform.typedef.__kernel_ssize_t = int
+rbx.platform.typedef.__kernel_suseconds_t = long
+rbx.platform.typedef.__kernel_time64_t = long_long
+rbx.platform.typedef.__kernel_time_t = long
+rbx.platform.typedef.__kernel_timer_t = int
+rbx.platform.typedef.__kernel_uid16_t = ushort
+rbx.platform.typedef.__kernel_uid32_t = uint
+rbx.platform.typedef.__kernel_uid_t = uint
+rbx.platform.typedef.__kernel_ulong_t = ulong
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__priority_which_t = int
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__suseconds64_t = long_long
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__syscall_slong_t = long
+rbx.platform.typedef.__syscall_ulong_t = ulong
+rbx.platform.typedef.__thrd_t = ulong
+rbx.platform.typedef.__time64_t = long_long
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__tss_t = uint
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__uint_least64_t = ulong_long
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__uintmax_t = ulong_long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int_fast16_t = int
+rbx.platform.typedef.int_fast32_t = int
+rbx.platform.typedef.int_fast64_t = long_long
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long_long
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.intmax_t = long_long
+rbx.platform.typedef.intptr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.ptrdiff_t = int
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint_fast16_t = uint
+rbx.platform.typedef.uint_fast32_t = uint
+rbx.platform.typedef.uint_fast64_t = ulong_long
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong_long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uintmax_t = ulong_long
+rbx.platform.typedef.uintptr_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.wchar_t = long
diff --git a/lib/ffi/platform/sparc64-linux/types.conf b/lib/ffi/platform/sparcv9-linux/types.conf
index 7626bfc..7626bfc 100644
--- a/lib/ffi/platform/sparc64-linux/types.conf
+++ b/lib/ffi/platform/sparcv9-linux/types.conf
diff --git a/lib/ffi/platform/sw_64-linux/types.conf b/lib/ffi/platform/sw_64-linux/types.conf
new file mode 100644
index 0000000..aa8716d
--- /dev/null
+++ b/lib/ffi/platform/sw_64-linux/types.conf
@@ -0,0 +1,141 @@
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__blkcnt64_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blksize_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__dev_t = ulong
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.__fsblkcnt64_t = ulong
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsword_t = long
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__ino64_t = ulong
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__int64_t = long
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__int_least64_t = long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__intmax_t = long
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__loff_t = long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off64_t = long
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__priority_which_t = int
+rbx.platform.typedef.__quad_t = long
+rbx.platform.typedef.__rlim64_t = ulong
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__syscall_slong_t = long
+rbx.platform.typedef.__syscall_ulong_t = ulong
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__u_quad_t = ulong
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__uint64_t = ulong
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__uint_least64_t = ulong
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__uintmax_t = ulong
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.blkcnt_t = long
+rbx.platform.typedef.blksize_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.ino_t = ulong
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int_fast16_t = long
+rbx.platform.typedef.int_fast32_t = long
+rbx.platform.typedef.int_fast64_t = long
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.intmax_t = long
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.loff_t = long
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.ptrdiff_t = long
+rbx.platform.typedef.quad_t = long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.u_quad_t = ulong
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint_fast16_t = ulong
+rbx.platform.typedef.uint_fast32_t = ulong
+rbx.platform.typedef.uint_fast64_t = ulong
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uintmax_t = ulong
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.wchar_t = int
diff --git a/lib/ffi/struct.rb b/lib/ffi/struct.rb
index 7028258..725b9cb 100644
--- a/lib/ffi/struct.rb
+++ b/lib/ffi/struct.rb
@@ -203,9 +203,10 @@ module FFI
# :field3, :string
# end
def layout(*spec)
- warn "[DEPRECATION] Struct layout is already defined for class #{self.inspect}. Redefinition as in #{caller[0]} will be disallowed in ffi-2.0." if defined?(@layout)
return @layout if spec.size == 0
+ warn "[DEPRECATION] Struct layout is already defined for class #{self.inspect}. Redefinition as in #{caller[0]} will be disallowed in ffi-2.0." if defined?(@layout)
+
builder = StructLayoutBuilder.new
builder.union = self < Union
builder.packed = @packed if defined?(@packed)
diff --git a/lib/ffi/struct_layout.rb b/lib/ffi/struct_layout.rb
index d5a78a7..3fd68cb 100644
--- a/lib/ffi/struct_layout.rb
+++ b/lib/ffi/struct_layout.rb
@@ -80,8 +80,8 @@ module FFI
class Mapped < Field
def initialize(name, offset, type, orig_field)
- super(name, offset, type)
@orig_field = orig_field
+ super(name, offset, type)
end
def get(ptr)
diff --git a/lib/ffi/struct_layout_builder.rb b/lib/ffi/struct_layout_builder.rb
index 4d6a464..d7d26a2 100644
--- a/lib/ffi/struct_layout_builder.rb
+++ b/lib/ffi/struct_layout_builder.rb
@@ -112,7 +112,7 @@ module FFI
Type::FLOAT64,
Type::LONGDOUBLE,
Type::BOOL,
- ]
+ ].freeze
# @param [String, Symbol] name name of the field
# @param [Array, DataConverter, Struct, StructLayout::Field, Symbol, Type] type type of the field
diff --git a/lib/ffi/types.rb b/lib/ffi/types.rb
index 90f50c1..8f5d897 100644
--- a/lib/ffi/types.rb
+++ b/lib/ffi/types.rb
@@ -33,12 +33,24 @@
# see {file:README}
module FFI
+ unless defined?(self.custom_typedefs)
+ # Truffleruby and JRuby don't support Ractor so far.
+ # So they don't need separation between builtin and custom types.
+ def self.custom_typedefs
+ TypeDefs
+ end
+ writable_typemap = true
+ end
+
# @param [Type, DataConverter, Symbol] old type definition used by {FFI.find_type}
# @param [Symbol] add new type definition's name to add
# @return [Type]
# Add a definition type to type definitions.
+ #
+ # The type definition is local per Ractor.
def self.typedef(old, add)
- TypeDefs[add] = self.find_type(old)
+ tm = custom_typedefs
+ tm[add] = self.find_type(old)
end
# (see FFI.typedef)
@@ -46,6 +58,14 @@ module FFI
typedef old, add
end
+ class << self
+ private def __typedef(old, add)
+ TypeDefs[add] = self.find_type(old)
+ end
+
+ private :custom_typedefs
+ end
+
# @param [Type, DataConverter, Symbol] name
# @param [Hash] type_map if nil, {FFI::TypeDefs} is used
@@ -57,9 +77,12 @@ module FFI
if name.is_a?(Type)
name
- elsif type_map && type_map.has_key?(name)
+ elsif type_map&.has_key?(name)
type_map[name]
+ elsif (tm=custom_typedefs).has_key?(name)
+ tm[name]
+
elsif TypeDefs.has_key?(name)
TypeDefs[name]
@@ -168,7 +191,7 @@ module FFI
end
end
- typedef(StrPtrConverter, :strptr)
+ __typedef(StrPtrConverter, :strptr)
# @param type +type+ is an instance of class accepted by {FFI.find_type}
# @return [Numeric]
@@ -184,11 +207,13 @@ module FFI
f.each_line { |line|
if line.index(prefix) == 0
new_type, orig_type = line.chomp.slice(prefix.length..-1).split(/\s*=\s*/)
- typedef(orig_type.to_sym, new_type.to_sym)
+ __typedef(orig_type.to_sym, new_type.to_sym)
end
}
end
- typedef :pointer, :caddr_t
+ __typedef :pointer, :caddr_t
rescue Errno::ENOENT
end
+
+ FFI.make_shareable(TypeDefs) unless writable_typemap
end
diff --git a/lib/ffi/variadic.rb b/lib/ffi/variadic.rb
index 743ce7f..ee33409 100644
--- a/lib/ffi/variadic.rb
+++ b/lib/ffi/variadic.rb
@@ -54,16 +54,27 @@ module FFI
invoker = self
params = "*args"
call = "call"
- mod.module_eval <<-code
- @@#{mname} = invoker
- def self.#{mname}(#{params})
- @@#{mname}.#{call}(#{params})
- end
- def #{mname}(#{params})
- @@#{mname}.#{call}(#{params})
- end
+ mname = mname.to_sym
+ mod.module_eval <<-code, __FILE__, __LINE__
+ @ffi_functions = {} unless defined?(@ffi_functions)
+ @ffi_functions[#{mname.inspect}] = invoker
+
+ def self.#{mname}(#{params})
+ @ffi_functions[#{mname.inspect}].#{call}(#{params})
+ end
+
+ define_method(#{mname.inspect}, &method(#{mname.inspect}))
code
invoker
end
+
+ # Retrieve Array of parameter types
+ #
+ # This method returns an Array of FFI types accepted as function parameters.
+ #
+ # @return [Array<FFI::Type>]
+ def param_types
+ [*@fixed, Type::Builtin::VARARGS]
+ end
end
end