mirror of
https://github.com/ruby/ruby.git
synced 2025-09-16 00:54:01 +02:00
Use JRuby implementation for TruffleRuby (#149)
Fix GH-145 Rename `lib/fiddle/jruby.rb` to `lib/fiddle/ffi_backend.rb` as a generic ffi gem API based implementation. JRuby and TruffleRuby use `lib/fiddle/ffi_backend.rb`. --------- Co-authored-by: Benoit Daloze <eregontp@gmail.com>
This commit is contained in:
parent
bbd5b8ddae
commit
8d127c9b59
13 changed files with 155 additions and 108 deletions
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require 'mkmf'
|
require 'mkmf'
|
||||||
|
|
||||||
if RUBY_ENGINE == "jruby"
|
unless RUBY_ENGINE == "ruby"
|
||||||
File.write('Makefile', dummy_makefile("").join)
|
File.write('Makefile', dummy_makefile("").join)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,11 +38,10 @@ Gem::Specification.new do |spec|
|
||||||
"lib/fiddle.rb",
|
"lib/fiddle.rb",
|
||||||
"lib/fiddle/closure.rb",
|
"lib/fiddle/closure.rb",
|
||||||
"lib/fiddle/cparser.rb",
|
"lib/fiddle/cparser.rb",
|
||||||
|
"lib/fiddle/ffi_backend.rb",
|
||||||
"lib/fiddle/function.rb",
|
"lib/fiddle/function.rb",
|
||||||
"lib/fiddle/import.rb",
|
"lib/fiddle/import.rb",
|
||||||
"lib/fiddle/jruby.rb",
|
|
||||||
"lib/fiddle/pack.rb",
|
"lib/fiddle/pack.rb",
|
||||||
"lib/fiddle/ruby.rb",
|
|
||||||
"lib/fiddle/struct.rb",
|
"lib/fiddle/struct.rb",
|
||||||
"lib/fiddle/types.rb",
|
"lib/fiddle/types.rb",
|
||||||
"lib/fiddle/value.rb",
|
"lib/fiddle/value.rb",
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "fiddle/#{RUBY_ENGINE}"
|
if RUBY_ENGINE == 'ruby'
|
||||||
|
require 'fiddle.so'
|
||||||
|
else
|
||||||
|
require 'fiddle/ffi_backend'
|
||||||
|
end
|
||||||
require 'fiddle/closure'
|
require 'fiddle/closure'
|
||||||
require 'fiddle/function'
|
require 'fiddle/function'
|
||||||
require 'fiddle/version'
|
require 'fiddle/version'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# This is part of JRuby's FFI-based fiddle implementation.
|
# This is based on JRuby's FFI-based fiddle implementation.
|
||||||
|
|
||||||
require 'ffi'
|
require 'ffi'
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ module Fiddle
|
||||||
|
|
||||||
WINDOWS = FFI::Platform.windows?
|
WINDOWS = FFI::Platform.windows?
|
||||||
|
|
||||||
module JRuby
|
module FFIBackend
|
||||||
FFITypes = {
|
FFITypes = {
|
||||||
'c' => FFI::Type::INT8,
|
'c' => FFI::Type::INT8,
|
||||||
'h' => FFI::Type::INT16,
|
'h' => FFI::Type::INT16,
|
||||||
|
@ -104,16 +104,16 @@ module Fiddle
|
||||||
Types::VARIADIC => FFI::Type::Builtin::VARARGS,
|
Types::VARIADIC => FFI::Type::Builtin::VARARGS,
|
||||||
}
|
}
|
||||||
|
|
||||||
def self.__ffi_type__(dl_type)
|
def self.to_ffi_type(fiddle_type)
|
||||||
if dl_type.is_a?(Symbol)
|
if fiddle_type.is_a?(Symbol)
|
||||||
dl_type = Types.const_get(dl_type.to_s.upcase)
|
fiddle_type = Types.const_get(fiddle_type.to_s.upcase)
|
||||||
end
|
end
|
||||||
if !dl_type.is_a?(Integer) && dl_type.respond_to?(:to_int)
|
if !fiddle_type.is_a?(Integer) && fiddle_type.respond_to?(:to_int)
|
||||||
dl_type = dl_type.to_int
|
fiddle_type = fiddle_type.to_int
|
||||||
end
|
end
|
||||||
ffi_type = FFITypes[dl_type]
|
ffi_type = FFITypes[fiddle_type]
|
||||||
ffi_type = FFITypes[-dl_type] if ffi_type.nil? && dl_type.is_a?(Integer) && dl_type < 0
|
ffi_type = FFITypes[-fiddle_type] if ffi_type.nil? && fiddle_type.is_a?(Integer) && fiddle_type < 0
|
||||||
raise TypeError.new("cannot convert #{dl_type} to ffi") unless ffi_type
|
raise TypeError.new("cannot convert #{fiddle_type} to ffi") unless ffi_type
|
||||||
ffi_type
|
ffi_type
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -133,8 +133,8 @@ module Fiddle
|
||||||
@ptr, @args, @return_type, @abi = ptr, args, return_type, abi
|
@ptr, @args, @return_type, @abi = ptr, args, return_type, abi
|
||||||
raise TypeError.new "invalid argument types" unless args.is_a?(Array)
|
raise TypeError.new "invalid argument types" unless args.is_a?(Array)
|
||||||
|
|
||||||
ffi_return_type = Fiddle::JRuby::__ffi_type__(@return_type)
|
ffi_return_type = Fiddle::FFIBackend.to_ffi_type(@return_type)
|
||||||
ffi_args = @args.map { |t| Fiddle::JRuby.__ffi_type__(t) }
|
ffi_args = @args.map { |t| Fiddle::FFIBackend.to_ffi_type(t) }
|
||||||
pointer = FFI::Pointer.new(ptr.to_i)
|
pointer = FFI::Pointer.new(ptr.to_i)
|
||||||
options = {convention: @abi}
|
options = {convention: @abi}
|
||||||
if ffi_args.last == FFI::Type::Builtin::VARARGS
|
if ffi_args.last == FFI::Type::Builtin::VARARGS
|
||||||
|
@ -149,14 +149,25 @@ module Fiddle
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(*args, &block);
|
def call(*args, &block)
|
||||||
if @function.is_a?(FFI::VariadicInvoker)
|
if @function.is_a?(FFI::VariadicInvoker)
|
||||||
n_fixed_args = @args.size - 1
|
n_fixed_args = @args.size - 1
|
||||||
n_fixed_args.step(args.size - 1, 2) do |i|
|
n_fixed_args.step(args.size - 1, 2) do |i|
|
||||||
if args[i] == :const_string || args[i] == Types::CONST_STRING
|
if args[i] == :const_string || args[i] == Types::CONST_STRING
|
||||||
args[i + 1] = String.try_convert(args[i + 1]) || args[i + 1]
|
args[i + 1] = String.try_convert(args[i + 1]) || args[i + 1]
|
||||||
end
|
end
|
||||||
args[i] = Fiddle::JRuby.__ffi_type__(args[i])
|
args[i] = Fiddle::FFIBackend.to_ffi_type(args[i])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
args.map! do |arg|
|
||||||
|
if arg.respond_to?(:to_ptr)
|
||||||
|
begin
|
||||||
|
arg = arg.to_ptr
|
||||||
|
end until arg.is_a?(FFI::Pointer) || !arg.respond_to?(:to_ptr)
|
||||||
|
arg
|
||||||
|
else
|
||||||
|
arg
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
result = @function.call(*args, &block)
|
result = @function.call(*args, &block)
|
||||||
|
@ -170,19 +181,21 @@ module Fiddle
|
||||||
raise TypeError.new "invalid argument types" unless args.is_a?(Array)
|
raise TypeError.new "invalid argument types" unless args.is_a?(Array)
|
||||||
|
|
||||||
@ctype, @args = ret, args
|
@ctype, @args = ret, args
|
||||||
ffi_args = @args.map { |t| Fiddle::JRuby.__ffi_type__(t) }
|
ffi_args = @args.map { |t| Fiddle::FFIBackend.to_ffi_type(t) }
|
||||||
if ffi_args.size == 1 && ffi_args[0] == FFI::Type::Builtin::VOID
|
if ffi_args.size == 1 && ffi_args[0] == FFI::Type::Builtin::VOID
|
||||||
ffi_args = []
|
ffi_args = []
|
||||||
end
|
end
|
||||||
@function = FFI::Function.new(
|
return_type = Fiddle::FFIBackend.to_ffi_type(@ctype)
|
||||||
Fiddle::JRuby.__ffi_type__(@ctype),
|
raise "#{self.class} must implement #call" unless respond_to?(:call)
|
||||||
ffi_args,
|
callable = method(:call)
|
||||||
self,
|
@function = FFI::Function.new(return_type, ffi_args, callable, convention: abi)
|
||||||
:convention => abi
|
|
||||||
)
|
|
||||||
@freed = false
|
@freed = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_ptr
|
||||||
|
@function
|
||||||
|
end
|
||||||
|
|
||||||
def to_i
|
def to_i
|
||||||
@function.to_i
|
@function.to_i
|
||||||
end
|
end
|
||||||
|
@ -550,51 +563,51 @@ module Fiddle
|
||||||
RUBY_FREE = Fiddle::Pointer::LibC::FREE.address
|
RUBY_FREE = Fiddle::Pointer::LibC::FREE.address
|
||||||
NULL = Fiddle::Pointer.new(0)
|
NULL = Fiddle::Pointer.new(0)
|
||||||
|
|
||||||
ALIGN_VOIDP = Fiddle::JRuby::FFITypes[Types::VOIDP].alignment
|
ALIGN_VOIDP = Fiddle::FFIBackend::FFITypes[Types::VOIDP].alignment
|
||||||
ALIGN_CHAR = Fiddle::JRuby::FFITypes[Types::CHAR].alignment
|
ALIGN_CHAR = Fiddle::FFIBackend::FFITypes[Types::CHAR].alignment
|
||||||
ALIGN_SHORT = Fiddle::JRuby::FFITypes[Types::SHORT].alignment
|
ALIGN_SHORT = Fiddle::FFIBackend::FFITypes[Types::SHORT].alignment
|
||||||
ALIGN_INT = Fiddle::JRuby::FFITypes[Types::INT].alignment
|
ALIGN_INT = Fiddle::FFIBackend::FFITypes[Types::INT].alignment
|
||||||
ALIGN_LONG = Fiddle::JRuby::FFITypes[Types::LONG].alignment
|
ALIGN_LONG = Fiddle::FFIBackend::FFITypes[Types::LONG].alignment
|
||||||
ALIGN_LONG_LONG = Fiddle::JRuby::FFITypes[Types::LONG_LONG].alignment
|
ALIGN_LONG_LONG = Fiddle::FFIBackend::FFITypes[Types::LONG_LONG].alignment
|
||||||
ALIGN_INT8_T = Fiddle::JRuby::FFITypes[Types::INT8_T].alignment
|
ALIGN_INT8_T = Fiddle::FFIBackend::FFITypes[Types::INT8_T].alignment
|
||||||
ALIGN_INT16_T = Fiddle::JRuby::FFITypes[Types::INT16_T].alignment
|
ALIGN_INT16_T = Fiddle::FFIBackend::FFITypes[Types::INT16_T].alignment
|
||||||
ALIGN_INT32_T = Fiddle::JRuby::FFITypes[Types::INT32_T].alignment
|
ALIGN_INT32_T = Fiddle::FFIBackend::FFITypes[Types::INT32_T].alignment
|
||||||
ALIGN_INT64_T = Fiddle::JRuby::FFITypes[Types::INT64_T].alignment
|
ALIGN_INT64_T = Fiddle::FFIBackend::FFITypes[Types::INT64_T].alignment
|
||||||
ALIGN_FLOAT = Fiddle::JRuby::FFITypes[Types::FLOAT].alignment
|
ALIGN_FLOAT = Fiddle::FFIBackend::FFITypes[Types::FLOAT].alignment
|
||||||
ALIGN_DOUBLE = Fiddle::JRuby::FFITypes[Types::DOUBLE].alignment
|
ALIGN_DOUBLE = Fiddle::FFIBackend::FFITypes[Types::DOUBLE].alignment
|
||||||
ALIGN_BOOL = Fiddle::JRuby::FFITypes[Types::BOOL].alignment
|
ALIGN_BOOL = Fiddle::FFIBackend::FFITypes[Types::BOOL].alignment
|
||||||
ALIGN_SIZE_T = Fiddle::JRuby::FFITypes[Types::SIZE_T].alignment
|
ALIGN_SIZE_T = Fiddle::FFIBackend::FFITypes[Types::SIZE_T].alignment
|
||||||
ALIGN_SSIZE_T = ALIGN_SIZE_T
|
ALIGN_SSIZE_T = ALIGN_SIZE_T
|
||||||
ALIGN_PTRDIFF_T = Fiddle::JRuby::FFITypes[Types::PTRDIFF_T].alignment
|
ALIGN_PTRDIFF_T = Fiddle::FFIBackend::FFITypes[Types::PTRDIFF_T].alignment
|
||||||
ALIGN_INTPTR_T = Fiddle::JRuby::FFITypes[Types::INTPTR_T].alignment
|
ALIGN_INTPTR_T = Fiddle::FFIBackend::FFITypes[Types::INTPTR_T].alignment
|
||||||
ALIGN_UINTPTR_T = Fiddle::JRuby::FFITypes[Types::UINTPTR_T].alignment
|
ALIGN_UINTPTR_T = Fiddle::FFIBackend::FFITypes[Types::UINTPTR_T].alignment
|
||||||
|
|
||||||
SIZEOF_VOIDP = Fiddle::JRuby::FFITypes[Types::VOIDP].size
|
SIZEOF_VOIDP = Fiddle::FFIBackend::FFITypes[Types::VOIDP].size
|
||||||
SIZEOF_CHAR = Fiddle::JRuby::FFITypes[Types::CHAR].size
|
SIZEOF_CHAR = Fiddle::FFIBackend::FFITypes[Types::CHAR].size
|
||||||
SIZEOF_UCHAR = Fiddle::JRuby::FFITypes[Types::UCHAR].size
|
SIZEOF_UCHAR = Fiddle::FFIBackend::FFITypes[Types::UCHAR].size
|
||||||
SIZEOF_SHORT = Fiddle::JRuby::FFITypes[Types::SHORT].size
|
SIZEOF_SHORT = Fiddle::FFIBackend::FFITypes[Types::SHORT].size
|
||||||
SIZEOF_USHORT = Fiddle::JRuby::FFITypes[Types::USHORT].size
|
SIZEOF_USHORT = Fiddle::FFIBackend::FFITypes[Types::USHORT].size
|
||||||
SIZEOF_INT = Fiddle::JRuby::FFITypes[Types::INT].size
|
SIZEOF_INT = Fiddle::FFIBackend::FFITypes[Types::INT].size
|
||||||
SIZEOF_UINT = Fiddle::JRuby::FFITypes[Types::UINT].size
|
SIZEOF_UINT = Fiddle::FFIBackend::FFITypes[Types::UINT].size
|
||||||
SIZEOF_LONG = Fiddle::JRuby::FFITypes[Types::LONG].size
|
SIZEOF_LONG = Fiddle::FFIBackend::FFITypes[Types::LONG].size
|
||||||
SIZEOF_ULONG = Fiddle::JRuby::FFITypes[Types::ULONG].size
|
SIZEOF_ULONG = Fiddle::FFIBackend::FFITypes[Types::ULONG].size
|
||||||
SIZEOF_LONG_LONG = Fiddle::JRuby::FFITypes[Types::LONG_LONG].size
|
SIZEOF_LONG_LONG = Fiddle::FFIBackend::FFITypes[Types::LONG_LONG].size
|
||||||
SIZEOF_ULONG_LONG = Fiddle::JRuby::FFITypes[Types::ULONG_LONG].size
|
SIZEOF_ULONG_LONG = Fiddle::FFIBackend::FFITypes[Types::ULONG_LONG].size
|
||||||
SIZEOF_INT8_T = Fiddle::JRuby::FFITypes[Types::INT8_T].size
|
SIZEOF_INT8_T = Fiddle::FFIBackend::FFITypes[Types::INT8_T].size
|
||||||
SIZEOF_UINT8_T = Fiddle::JRuby::FFITypes[Types::UINT8_T].size
|
SIZEOF_UINT8_T = Fiddle::FFIBackend::FFITypes[Types::UINT8_T].size
|
||||||
SIZEOF_INT16_T = Fiddle::JRuby::FFITypes[Types::INT16_T].size
|
SIZEOF_INT16_T = Fiddle::FFIBackend::FFITypes[Types::INT16_T].size
|
||||||
SIZEOF_UINT16_T = Fiddle::JRuby::FFITypes[Types::UINT16_T].size
|
SIZEOF_UINT16_T = Fiddle::FFIBackend::FFITypes[Types::UINT16_T].size
|
||||||
SIZEOF_INT32_T = Fiddle::JRuby::FFITypes[Types::INT32_T].size
|
SIZEOF_INT32_T = Fiddle::FFIBackend::FFITypes[Types::INT32_T].size
|
||||||
SIZEOF_UINT32_T = Fiddle::JRuby::FFITypes[Types::UINT32_T].size
|
SIZEOF_UINT32_T = Fiddle::FFIBackend::FFITypes[Types::UINT32_T].size
|
||||||
SIZEOF_INT64_T = Fiddle::JRuby::FFITypes[Types::INT64_T].size
|
SIZEOF_INT64_T = Fiddle::FFIBackend::FFITypes[Types::INT64_T].size
|
||||||
SIZEOF_UINT64_T = Fiddle::JRuby::FFITypes[Types::UINT64_T].size
|
SIZEOF_UINT64_T = Fiddle::FFIBackend::FFITypes[Types::UINT64_T].size
|
||||||
SIZEOF_FLOAT = Fiddle::JRuby::FFITypes[Types::FLOAT].size
|
SIZEOF_FLOAT = Fiddle::FFIBackend::FFITypes[Types::FLOAT].size
|
||||||
SIZEOF_DOUBLE = Fiddle::JRuby::FFITypes[Types::DOUBLE].size
|
SIZEOF_DOUBLE = Fiddle::FFIBackend::FFITypes[Types::DOUBLE].size
|
||||||
SIZEOF_BOOL = Fiddle::JRuby::FFITypes[Types::BOOL].size
|
SIZEOF_BOOL = Fiddle::FFIBackend::FFITypes[Types::BOOL].size
|
||||||
SIZEOF_SIZE_T = Fiddle::JRuby::FFITypes[Types::SIZE_T].size
|
SIZEOF_SIZE_T = Fiddle::FFIBackend::FFITypes[Types::SIZE_T].size
|
||||||
SIZEOF_SSIZE_T = SIZEOF_SIZE_T
|
SIZEOF_SSIZE_T = SIZEOF_SIZE_T
|
||||||
SIZEOF_PTRDIFF_T = Fiddle::JRuby::FFITypes[Types::PTRDIFF_T].size
|
SIZEOF_PTRDIFF_T = Fiddle::FFIBackend::FFITypes[Types::PTRDIFF_T].size
|
||||||
SIZEOF_INTPTR_T = Fiddle::JRuby::FFITypes[Types::INTPTR_T].size
|
SIZEOF_INTPTR_T = Fiddle::FFIBackend::FFITypes[Types::INTPTR_T].size
|
||||||
SIZEOF_UINTPTR_T = Fiddle::JRuby::FFITypes[Types::UINTPTR_T].size
|
SIZEOF_UINTPTR_T = Fiddle::FFIBackend::FFITypes[Types::UINTPTR_T].size
|
||||||
SIZEOF_CONST_STRING = Fiddle::JRuby::FFITypes[Types::VOIDP].size
|
SIZEOF_CONST_STRING = Fiddle::FFIBackend::FFITypes[Types::VOIDP].size
|
||||||
end
|
end
|
|
@ -1 +0,0 @@
|
||||||
require "fiddle.so"
|
|
|
@ -183,6 +183,10 @@ module Fiddle
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ffi_backend?
|
||||||
|
RUBY_ENGINE != 'ruby'
|
||||||
|
end
|
||||||
|
|
||||||
def under_gc_stress
|
def under_gc_stress
|
||||||
stress, GC.stress = GC.stress, true
|
stress, GC.stress = GC.stress, true
|
||||||
yield
|
yield
|
||||||
|
|
|
@ -58,9 +58,9 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_const_string
|
def test_const_string
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Closure with :const_string works but " +
|
omit("Closure with :const_string works but " +
|
||||||
"Function with :const_string doesn't work with JRuby")
|
"Function with :const_string doesn't work with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
closure_class = Class.new(Closure) do
|
closure_class = Class.new(Closure) do
|
||||||
|
@ -119,9 +119,14 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'objspace'
|
require 'objspace'
|
||||||
|
closure_class = Class.new(Closure) do
|
||||||
|
def call
|
||||||
|
10
|
||||||
|
end
|
||||||
|
end
|
||||||
n = 10000
|
n = 10000
|
||||||
n.times do
|
n.times do
|
||||||
Closure.create(:int, [:void]) do |closure|
|
closure_class.create(:int, [:void]) do |closure|
|
||||||
ObjectSpace.memsize_of(closure)
|
ObjectSpace.memsize_of(closure)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,8 +6,8 @@ end
|
||||||
|
|
||||||
class TestFiddle < Fiddle::TestCase
|
class TestFiddle < Fiddle::TestCase
|
||||||
def test_nil_true_etc
|
def test_nil_true_etc
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle::Q* aren't supported with JRuby")
|
omit("Fiddle::Q* aren't supported with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal Fiddle::Qtrue, Fiddle.dlwrap(true)
|
assert_equal Fiddle::Qtrue, Fiddle.dlwrap(true)
|
||||||
|
@ -30,6 +30,10 @@ class TestFiddle < Fiddle::TestCase
|
||||||
if Dir.glob("/usr/lib/*/libncurses.so").empty?
|
if Dir.glob("/usr/lib/*/libncurses.so").empty?
|
||||||
omit("libncurses.so is needed")
|
omit("libncurses.so is needed")
|
||||||
end
|
end
|
||||||
|
if ffi_backend?
|
||||||
|
omit("Fiddle::Handle#file_name doesn't exist in FFI backend")
|
||||||
|
end
|
||||||
|
|
||||||
# libncurses.so uses INPUT() on Debian GNU/Linux
|
# libncurses.so uses INPUT() on Debian GNU/Linux
|
||||||
# $ cat /usr/lib/x86_64-linux-gnu/libncurses.so
|
# $ cat /usr/lib/x86_64-linux-gnu/libncurses.so
|
||||||
# INPUT(libncurses.so.6 -ltinfo)
|
# INPUT(libncurses.so.6 -ltinfo)
|
||||||
|
@ -44,6 +48,10 @@ class TestFiddle < Fiddle::TestCase
|
||||||
|
|
||||||
def test_dlopen_linker_script_group_linux
|
def test_dlopen_linker_script_group_linux
|
||||||
omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
|
omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
|
||||||
|
if ffi_backend?
|
||||||
|
omit("Fiddle::Handle#file_name doesn't exist in FFI backend")
|
||||||
|
end
|
||||||
|
|
||||||
# libc.so uses GROUP() on Debian GNU/Linux
|
# libc.so uses GROUP() on Debian GNU/Linux
|
||||||
# $ cat /usr/lib/x86_64-linux-gnu/libc.so
|
# $ cat /usr/lib/x86_64-linux-gnu/libc.so
|
||||||
# /* GNU ld script
|
# /* GNU ld script
|
||||||
|
|
|
@ -64,6 +64,10 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_qsort1
|
def test_qsort1
|
||||||
|
if RUBY_ENGINE == "jruby"
|
||||||
|
omit("The untouched sanity check is broken on JRuby: https://github.com/jruby/jruby/issues/8365")
|
||||||
|
end
|
||||||
|
|
||||||
closure_class = Class.new(Closure) do
|
closure_class = Class.new(Closure) do
|
||||||
def call(x, y)
|
def call(x, y)
|
||||||
Pointer.new(x)[0] <=> Pointer.new(y)[0]
|
Pointer.new(x)[0] <=> Pointer.new(y)[0]
|
||||||
|
@ -74,27 +78,32 @@ module Fiddle
|
||||||
qsort = Function.new(@libc['qsort'],
|
qsort = Function.new(@libc['qsort'],
|
||||||
[TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T, TYPE_VOIDP],
|
[TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T, TYPE_VOIDP],
|
||||||
TYPE_VOID)
|
TYPE_VOID)
|
||||||
buff = "9341"
|
untouched = "9341"
|
||||||
|
buff = +"9341"
|
||||||
qsort.call(buff, buff.size, 1, callback)
|
qsort.call(buff, buff.size, 1, callback)
|
||||||
assert_equal("1349", buff)
|
assert_equal("1349", buff)
|
||||||
|
|
||||||
bug4929 = '[ruby-core:37395]'
|
bug4929 = '[ruby-core:37395]'
|
||||||
buff = "9341"
|
buff = +"9341"
|
||||||
under_gc_stress do
|
under_gc_stress do
|
||||||
qsort.call(buff, buff.size, 1, callback)
|
qsort.call(buff, buff.size, 1, callback)
|
||||||
end
|
end
|
||||||
assert_equal("1349", buff, bug4929)
|
assert_equal("1349", buff, bug4929)
|
||||||
|
|
||||||
|
# Ensure the test didn't mutate String literals
|
||||||
|
assert_equal("93" + "41", untouched)
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
# We can't use ObjectSpace with JRuby.
|
# We can't use ObjectSpace with JRuby.
|
||||||
return if RUBY_ENGINE == "jruby"
|
unless RUBY_ENGINE == "jruby"
|
||||||
# Ensure freeing all closures.
|
# Ensure freeing all closures.
|
||||||
# See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 .
|
# See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 .
|
||||||
not_freed_closures = []
|
not_freed_closures = []
|
||||||
ObjectSpace.each_object(Fiddle::Closure) do |closure|
|
ObjectSpace.each_object(Fiddle::Closure) do |closure|
|
||||||
not_freed_closures << closure unless closure.freed?
|
not_freed_closures << closure unless closure.freed?
|
||||||
|
end
|
||||||
|
assert_equal([], not_freed_closures)
|
||||||
end
|
end
|
||||||
assert_equal([], not_freed_closures)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_snprintf
|
def test_snprintf
|
||||||
|
|
|
@ -41,6 +41,9 @@ module Fiddle
|
||||||
if RUBY_ENGINE == "jruby"
|
if RUBY_ENGINE == "jruby"
|
||||||
omit("rb_str_dup() doesn't exist in JRuby")
|
omit("rb_str_dup() doesn't exist in JRuby")
|
||||||
end
|
end
|
||||||
|
if RUBY_ENGINE == "truffleruby"
|
||||||
|
omit("rb_str_dup() doesn't work with TruffleRuby")
|
||||||
|
end
|
||||||
|
|
||||||
libruby = Fiddle.dlopen(nil)
|
libruby = Fiddle.dlopen(nil)
|
||||||
rb_str_dup = Function.new(libruby['rb_str_dup'],
|
rb_str_dup = Function.new(libruby['rb_str_dup'],
|
||||||
|
@ -109,8 +112,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_last_error
|
def test_last_error
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle.last_error doesn't work with JRuby")
|
omit("Fiddle.last_error doesn't work with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
func = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
|
func = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
|
||||||
|
@ -219,6 +222,9 @@ module Fiddle
|
||||||
if RUBY_ENGINE == "jruby"
|
if RUBY_ENGINE == "jruby"
|
||||||
omit("rb_obj_frozen_p() doesn't exist in JRuby")
|
omit("rb_obj_frozen_p() doesn't exist in JRuby")
|
||||||
end
|
end
|
||||||
|
if RUBY_ENGINE == "truffleruby"
|
||||||
|
omit("memory leak detection is fragile with TruffleRuby")
|
||||||
|
end
|
||||||
|
|
||||||
if respond_to?(:assert_nothing_leaked_memory)
|
if respond_to?(:assert_nothing_leaked_memory)
|
||||||
rb_obj_frozen_p_symbol = Fiddle.dlopen(nil)["rb_obj_frozen_p"]
|
rb_obj_frozen_p_symbol = Fiddle.dlopen(nil)["rb_obj_frozen_p"]
|
||||||
|
|
|
@ -9,8 +9,8 @@ module Fiddle
|
||||||
include Fiddle
|
include Fiddle
|
||||||
|
|
||||||
def test_to_i
|
def test_to_i
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle::Handle#to_i is unavailable with JRuby")
|
omit("Fiddle::Handle#to_i is unavailable with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
handle = Fiddle::Handle.new(LIBC_SO)
|
handle = Fiddle::Handle.new(LIBC_SO)
|
||||||
|
@ -18,8 +18,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_to_ptr
|
def test_to_ptr
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle::Handle#to_i is unavailable with JRuby")
|
omit("Fiddle::Handle#to_i is unavailable with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
handle = Fiddle::Handle.new(LIBC_SO)
|
handle = Fiddle::Handle.new(LIBC_SO)
|
||||||
|
@ -34,8 +34,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_static_sym
|
def test_static_sym
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("We can't assume static symbols with JRuby")
|
omit("We can't assume static symbols with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -133,8 +133,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_file_name
|
def test_file_name
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle::Handle#file_name doesn't exist in JRuby")
|
omit("Fiddle::Handle#file_name doesn't exist in FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
file_name = Handle.new(LIBC_SO).file_name
|
file_name = Handle.new(LIBC_SO).file_name
|
||||||
|
@ -155,8 +155,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_NEXT
|
def test_NEXT
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle::Handle::NEXT doesn't exist in JRuby")
|
omit("Fiddle::Handle::NEXT doesn't exist in FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -154,8 +154,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_io()
|
def test_io()
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("BUILD_RUBY_PLATFORM doesn't exist in JRuby")
|
omit("BUILD_RUBY_PLATFORM doesn't exist in FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
if( RUBY_PLATFORM != BUILD_RUBY_PLATFORM ) || !defined?(LIBC.fprintf)
|
if( RUBY_PLATFORM != BUILD_RUBY_PLATFORM ) || !defined?(LIBC.fprintf)
|
||||||
|
|
|
@ -11,8 +11,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_can_read_write_memory
|
def test_can_read_write_memory
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle::Pointer.{read,write} don't exist in JRuby")
|
omit("Fiddle::Pointer.{read,write} don't exist in FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Allocate some memory
|
# Allocate some memory
|
||||||
|
@ -113,8 +113,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_inspect
|
def test_inspect
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle::Pointer#inspect is incompatible on JRuby")
|
omit("Fiddle::Pointer#inspect is incompatible with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
ptr = Pointer.new(0)
|
ptr = Pointer.new(0)
|
||||||
|
@ -132,8 +132,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_to_ptr_io
|
def test_to_ptr_io
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle::Pointer.to_ptr(IO) isn't supported with JRuby")
|
omit("Fiddle::Pointer.to_ptr(IO) isn't supported with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
Pointer.malloc(10, Fiddle::RUBY_FREE) do |buf|
|
Pointer.malloc(10, Fiddle::RUBY_FREE) do |buf|
|
||||||
|
@ -183,8 +183,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_ref_ptr
|
def test_ref_ptr
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle.dlwrap([]) isn't supported with JRuby")
|
omit("Fiddle.dlwrap([]) isn't supported with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
ary = [0,1,2,4,5]
|
ary = [0,1,2,4,5]
|
||||||
|
@ -195,8 +195,8 @@ module Fiddle
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_to_value
|
def test_to_value
|
||||||
if RUBY_ENGINE == "jruby"
|
if ffi_backend?
|
||||||
omit("Fiddle.dlwrap([]) isn't supported with JRuby")
|
omit("Fiddle.dlwrap([]) isn't supported with FFI backend")
|
||||||
end
|
end
|
||||||
|
|
||||||
ary = [0,1,2,4,5]
|
ary = [0,1,2,4,5]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue