Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add long double as callback return value #771

Merged
merged 1 commit into from Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion ext/ffi_c/Function.c
Expand Up @@ -721,7 +721,7 @@ invoke_callback(VALUE data)
param = rb_float_new(*(double *) parameters[i]);
break;
case NATIVE_LONGDOUBLE:
param = rbffi_longdouble_new(*(long double *) parameters[i]);
param = rbffi_longdouble_new(*(long double *) parameters[i]);
break;
case NATIVE_STRING:
param = (*(void **) parameters[i] != NULL) ? rb_str_new2(*(char **) parameters[i]) : Qnil;
Expand Down Expand Up @@ -793,6 +793,9 @@ invoke_callback(VALUE data)
case NATIVE_FLOAT64:
*((double *) retval) = NUM2DBL(rbReturnValue);
break;
case NATIVE_LONGDOUBLE:
*((long double *) retval) = rbffi_num2longdouble(rbReturnValue);
break;
case NATIVE_POINTER:
if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
*((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
Expand Down
2 changes: 2 additions & 0 deletions spec/ffi/fixtures/ClosureTest.c
Expand Up @@ -35,6 +35,7 @@ R(J, long long);
R(LL, long long);
R(F, float);
R(D, double);
R(LD, long double);
R(P, const void*);


Expand All @@ -47,6 +48,7 @@ P(J, long long);
P(LL, long long);
P(F, float);
P(D, double);
P(LD, long double);
P(P, const void*);
P(UL, unsigned long);

Expand Down
21 changes: 20 additions & 1 deletion spec/ffi/long_double_spec.rb
Expand Up @@ -7,10 +7,17 @@
require 'bigdecimal'

# long double not yet supported on TruffleRuby
describe ":long_double arguments and return values", if: RUBY_PLATFORM !~ /mingw|mswin/ do
describe ":long_double arguments and return values" do
module LibTest
extend FFI::Library
ffi_lib TestLibrary::PATH

callback :cbVrLD, [ ], :long_double
attach_function :testCallbackVrLD, :testClosureVrLD, [ :cbVrLD ], :long_double

callback :cbLDrV, [ :long_double ], :void
attach_function :testCallbackLDrV, :testClosureLDrV, [ :cbLDrV, :long_double ], :void

attach_function :add_f128, [ :long_double, :long_double ], :long_double
attach_function :ret_f128, [ :long_double ], :long_double
end
Expand All @@ -28,4 +35,16 @@ module LibTest
it "add two long double numbers" do
expect(LibTest.add_f128(0.1, 0.2)).to be_within(0.01).of(0.3)
end

describe "Callback" do
it "returning :long_double" do
expect(LibTest.testCallbackVrLD { -0.1 }).to be_within(0.01).of(-0.1)
end

it ":long_double argument" do
v = nil
LibTest.testCallbackLDrV(0.1) { |i| v = i }
expect(v).to be_within(0.01).of(0.1)
end
end
end if RUBY_ENGINE != "truffleruby"