Skip to content

Commit 0b24621

Browse files
committed
[GR-15925] Correctly return a FFI::function if the return type is FFI::FunctionType.
PullRequest: truffleruby/826
2 parents aec8c03 + e711a0c commit 0b24621

File tree

3 files changed

+11
-0
lines changed

3 files changed

+11
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Bug fixes:
99
* Implemented `rb_eval_string_protect`.
1010
* Fixed `rb_get_kwargs` to correctly handle optional and rest arguments.
1111
* Calling `Kernel#raise` with a raised exception will no longer set the cause of the exception to itself (#1682).
12+
* Return a `FFI::Function` correctly for functions returning a callback.
1213

1314
Compatibility
1415

lib/truffle/truffle/ffi_backend/function.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ def free
170170
elsif FFI::Type::Builtin === type and type.unsigned?
171171
# TODO: NFI workaround
172172
type.signed2unsigned(value)
173+
elsif FFI::FunctionType === type
174+
ptr = FFI::Pointer.new(Truffle::Interop.as_pointer(value))
175+
FFI::Function.new(type, nil, ptr)
173176
else
174177
value
175178
end

spec/ffi/callback_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class S8F32S32 < FFI::Struct
7575
attach_function :testCallbackVrS64, :testClosureVrLL, [ :cbVrS64 ], :long_long
7676
attach_function :testCallbackVrU64, :testClosureVrLL, [ :cbVrU64 ], :ulong_long
7777
attach_function :testCallbackVrP, :testClosureVrP, [ :cbVrP ], :pointer
78+
attach_function :testCallbackReturningFunction, :testClosureVrP, [ :cbVrP ], :cbVrP
7879
attach_function :testCallbackVrY, :testClosureVrP, [ :cbVrY ], S8F32S32.ptr
7980
# struct by value
8081
# attach_function :testCallbackVrT, :testClosureVrT, [ :cbVrT ], S8F32S32.by_value
@@ -267,6 +268,12 @@ class S8F32S32 < FFI::Struct
267268
expect(LibTest.testCallbackVrP { p }).to eq(p)
268269
end
269270

271+
it "returning a callback function" do
272+
ret = LibTest.testCallbackReturningFunction { FFI::Pointer.new(42) }
273+
expect(ret).to be_kind_of(FFI::Function)
274+
expect(ret.address).to eq(42)
275+
end
276+
270277
it "returning struct by value" do
271278
next # struct by value
272279
skip "Segfault on 32 bit MINGW" if RUBY_PLATFORM == 'i386-mingw32'

0 commit comments

Comments
 (0)