From f0a39500ad1711f3a035914db2ad048e736d420c Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Sat, 30 Nov 2024 12:57:51 +0200 Subject: [PATCH 01/11] ffi_backend: convert int function args to pointers --- lib/fiddle/ffi_backend.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index eac469af..a54d189b 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -159,12 +159,14 @@ def call(*args, &block) args[i] = Fiddle::FFIBackend.to_ffi_type(args[i]) end else - args.map! do |arg| + args.map!.with_index do |arg, i| if arg.respond_to?(:to_ptr) begin arg = arg.to_ptr end until arg.is_a?(FFI::Pointer) || !arg.respond_to?(:to_ptr) arg + elsif arg.is_a?(Integer) && @args[i] == Types::VOIDP + FFI::Pointer.new(arg) else arg end From 14479d8150cdbede20cbb0bfdcec953f4b3f9a40 Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Thu, 5 Dec 2024 00:09:26 +0200 Subject: [PATCH 02/11] refactor to use zip --- lib/fiddle/ffi_backend.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index a54d189b..05547c33 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -159,13 +159,13 @@ def call(*args, &block) args[i] = Fiddle::FFIBackend.to_ffi_type(args[i]) end else - args.map!.with_index do |arg, i| + args.zip(@args).each do |arg, type| if arg.respond_to?(:to_ptr) begin arg = arg.to_ptr end until arg.is_a?(FFI::Pointer) || !arg.respond_to?(:to_ptr) arg - elsif arg.is_a?(Integer) && @args[i] == Types::VOIDP + elsif arg.is_a?(Integer) && type == Types::VOIDP FFI::Pointer.new(arg) else arg From abaf58e1b5d4cb1dd3cd89751a6ee35feaab718f Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Thu, 5 Dec 2024 00:09:42 +0200 Subject: [PATCH 03/11] add test for auto-converting integer to pointer --- test/fiddle/test_function.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/fiddle/test_function.rb b/test/fiddle/test_function.rb index 146dcc72..723c38ce 100644 --- a/test/fiddle/test_function.rb +++ b/test/fiddle/test_function.rb @@ -98,6 +98,14 @@ def test_call assert_in_delta 1.0, func.call(90 * Math::PI / 180), 0.0001 end + def test_integer_pointer_conversion + func = Function.new(@libc['memcpy'], [TYPE_VOIDP, TYPE_VOIDP, TYPE_SIZE_T], TYPE_VOIDP) + str = 'hello' + dst = Pointer.malloc(str.bytesize, Fiddle::RUBY_FREE) + func.call(dst.to_i, str, dst.size) + assert_equal str, dst.to_str + end + def test_argument_count closure_class = Class.new(Closure) do def call one From 081b96a08db6f0b98d4abf969163f8cec817d5a9 Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Thu, 5 Dec 2024 09:32:18 +0200 Subject: [PATCH 04/11] undo zip --- lib/fiddle/ffi_backend.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index 05547c33..b7572af2 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -159,13 +159,13 @@ def call(*args, &block) args[i] = Fiddle::FFIBackend.to_ffi_type(args[i]) end else - args.zip(@args).each do |arg, type| + args.map!.with_index do |arg, i| if arg.respond_to?(:to_ptr) begin arg = arg.to_ptr end until arg.is_a?(FFI::Pointer) || !arg.respond_to?(:to_ptr) arg - elsif arg.is_a?(Integer) && type == Types::VOIDP + elsif @args[i] == Types::VOIDP && arg.is_a?(Integer) FFI::Pointer.new(arg) else arg From 5f8ed16af0d54b335ef83062c147f6b2cd0e54cf Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Thu, 5 Dec 2024 11:27:25 +0200 Subject: [PATCH 05/11] align ffi pointer argument handling with function_call --- lib/fiddle/ffi_backend.rb | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index b7572af2..9975afa2 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -159,16 +159,12 @@ def call(*args, &block) args[i] = Fiddle::FFIBackend.to_ffi_type(args[i]) end else - args.map!.with_index do |arg, i| - if arg.respond_to?(:to_ptr) - begin - arg = arg.to_ptr - end until arg.is_a?(FFI::Pointer) || !arg.respond_to?(:to_ptr) - arg - elsif @args[i] == Types::VOIDP && arg.is_a?(Integer) - FFI::Pointer.new(arg) - else - arg + @args.each_with_index do |arg_type, i| + if @args[i] == Types::VOIDP + src = args[i] + next if src.nil? || src.is_a?(String) || src.is_a?(FFI::Pointer) + + args[i] = Pointer[src] end end end From 6d08b6a15d840ab00f770cab7afeacde699e5fa6 Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Thu, 5 Dec 2024 12:22:42 +0200 Subject: [PATCH 06/11] skip all ffi-handled pointer parameters --- lib/fiddle/ffi_backend.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index 9975afa2..0b8aa476 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -162,7 +162,10 @@ def call(*args, &block) @args.each_with_index do |arg_type, i| if @args[i] == Types::VOIDP src = args[i] - next if src.nil? || src.is_a?(String) || src.is_a?(FFI::Pointer) + next if src.nil? || + src.is_a?(String) || + src.is_a?(FFI::AbstractMemory) || + src.is_a?(FFI::Struct) args[i] = Pointer[src] end From e4f1307232ce8fe95153d86028cbc09084c36e01 Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Thu, 5 Dec 2024 12:45:48 +0200 Subject: [PATCH 07/11] ffi_backend: allow any integer coercible as pointer address --- lib/fiddle/ffi_backend.rb | 2 ++ test/fiddle/test_pointer.rb | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index 0b8aa476..dab6beb2 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -309,6 +309,8 @@ def initialize(addr, size = nil, free = nil) end elsif addr.is_a?(IO) raise NotImplementedError, "IO ptr isn't supported" + else + FFI::Pointer.new(Integer(addr)) end @size = size ? size : ptr.size diff --git a/test/fiddle/test_pointer.rb b/test/fiddle/test_pointer.rb index d46fb662..74777d9f 100644 --- a/test/fiddle/test_pointer.rb +++ b/test/fiddle/test_pointer.rb @@ -161,11 +161,16 @@ def test_to_ptr_with_ptr end end - def test_to_ptr_with_num + def test_to_ptr_with_int ptr = Pointer.new 0 assert_equal ptr, Pointer[0] end + def test_to_ptr_with_num + ptr = Pointer.new 0 + assert_equal ptr, Pointer[0.0] + end + def test_equals ptr = Pointer.new 0 ptr2 = Pointer.new 0 From 140ba75a81550471240dc560129a382be6f0b8f6 Mon Sep 17 00:00:00 2001 From: Dani Smith Date: Fri, 6 Dec 2024 22:23:36 +0200 Subject: [PATCH 08/11] Update lib/fiddle/ffi_backend.rb Co-authored-by: Benoit Daloze --- lib/fiddle/ffi_backend.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index dab6beb2..7875cce7 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -160,7 +160,7 @@ def call(*args, &block) end else @args.each_with_index do |arg_type, i| - if @args[i] == Types::VOIDP + if arg_type == Types::VOIDP src = args[i] next if src.nil? || src.is_a?(String) || From c8f635daf67e8df34fef6eb83e3f0f22b7dd4d0d Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Wed, 11 Dec 2024 10:21:54 +0200 Subject: [PATCH 09/11] ffi_backend: use guard clauses in Function#call --- lib/fiddle/ffi_backend.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index 7875cce7..040535d5 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -160,15 +160,15 @@ def call(*args, &block) end else @args.each_with_index do |arg_type, i| - if arg_type == Types::VOIDP - src = args[i] - next if src.nil? || - src.is_a?(String) || - src.is_a?(FFI::AbstractMemory) || - src.is_a?(FFI::Struct) - - args[i] = Pointer[src] - end + next unless arg_type == Types::VOIDP + + src = args[i] + next if src.nil? + next if src.is_a?(String) + next if src.is_a?(FFI::AbstractMemory) + next if src.is_a?(FFI::Struct) + + args[i] = Pointer[src] end end result = @function.call(*args, &block) From ecb9f9ec788216f732a260adb921ec75c62c78eb Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Wed, 11 Dec 2024 10:23:14 +0200 Subject: [PATCH 10/11] clean up function test --- test/fiddle/test_function.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/fiddle/test_function.rb b/test/fiddle/test_function.rb index 723c38ce..b408a14c 100644 --- a/test/fiddle/test_function.rb +++ b/test/fiddle/test_function.rb @@ -101,9 +101,10 @@ def test_call def test_integer_pointer_conversion func = Function.new(@libc['memcpy'], [TYPE_VOIDP, TYPE_VOIDP, TYPE_SIZE_T], TYPE_VOIDP) str = 'hello' - dst = Pointer.malloc(str.bytesize, Fiddle::RUBY_FREE) - func.call(dst.to_i, str, dst.size) - assert_equal str, dst.to_str + Pointer.malloc(str.bytesize, Fiddle::RUBY_FREE) do |dst| + func.call(dst.to_i, str, dst.size) + assert_equal(str, dst.to_str) + end end def test_argument_count From 091454ad26c6c922508ecd8bc5e5ba854c5bc43a Mon Sep 17 00:00:00 2001 From: Danielle Smith Date: Wed, 11 Dec 2024 19:38:05 +0200 Subject: [PATCH 11/11] make pointer to_ptr tests clearer --- test/fiddle/test_pointer.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/fiddle/test_pointer.rb b/test/fiddle/test_pointer.rb index 74777d9f..4afc3f89 100644 --- a/test/fiddle/test_pointer.rb +++ b/test/fiddle/test_pointer.rb @@ -166,9 +166,10 @@ def test_to_ptr_with_int assert_equal ptr, Pointer[0] end - def test_to_ptr_with_num + MimicInteger = Struct.new(:to_int) + def test_to_ptr_with_to_int ptr = Pointer.new 0 - assert_equal ptr, Pointer[0.0] + assert_equal ptr, Pointer[MimicInteger.new(0)] end def test_equals