Skip to content

Wrong union-by-value argument passing in JRuby #9329

Description

@larskanis

As part of ffi/ffi#1178 we added some more tests of union-by-value function arguments. There are some new specific measurements to fix ABI conventions on x86_64 and ARM64. See the description and code of the PR.

We also added tests to verify more union-by-value situations. Unfortunately they fail on JRuby, at different test cases on x86_64 and ARM64.

specs (ubuntu-latest, jruby-head)


Failures:

  1) Union by_value should correctly align/write a float value to union_float_test_t by value
     Failure/Error: expect((@u[name] - ByValueLibTest.send("#{uni}_val_align_#{k}", @u)).abs).to be < 0.00001

       expected: < 1.0e-05
            got:   2.71598704641059e+36
     # ./spec/ffi/union_spec.rb:141:in 'block in UnionSpec'

  2) Union by_value should correctly align/write a double value to union_float_test_t by value
     Failure/Error: expect((@u[name] - ByValueLibTest.send("#{uni}_val_align_#{k}", @u)).abs).to be < 0.00001

       expected: < 1.0e-05
            got:   2.0000000000001
     # ./spec/ffi/union_spec.rb:141:in 'block in UnionSpec'

  3) Union by_value should read a float value from memory of union_float_test_t by value
     Failure/Error: expect((@u[name] - val).abs).to be < 0.00001

       expected: < 1.0e-05
            got:   3.444
     # ./spec/ffi/union_spec.rb:152:in 'block in UnionSpec'

  4) Union by_value should read a double value from memory of union_float_test_t by value
     Failure/Error: expect((@u[name] - val).abs).to be < 0.00001

       expected: < 1.0e-05
            got:   2.0000000000001
     # ./spec/ffi/union_spec.rb:152:in 'block in UnionSpec'

specs (ubuntu-24.04-arm, jruby-head)

Failures:

  1) Union by_value should return a union of doubles by value
     Failure/Error: expect(u[:coord][:x]).to eq(1.5)

       expected: 1.5
            got: 1.4978809957e-313

       (compared using ==)
     # ./spec/ffi/union_spec.rb:162:in 'block in UnionSpec'

  2) Union by_value should pass a union of doubles by value
     Failure/Error: expect(ByValueLibTest.union_double_get_x(u)).to eq(10.0)

       expected: 10.0
            got: 1.4979119926e-313

       (compared using ==)
     # ./spec/ffi/union_spec.rb:170:in 'block in UnionSpec'

  3) Union by_value should pass and return a union of doubles by value
     Failure/Error: expect(r[:coord][:x]).to eq(1.5)

       expected: 1.5
            got: 1.49791841507e-313

       (compared using ==)
     # ./spec/ffi/union_spec.rb:180:in 'block in UnionSpec'

  4) Union by_value should access union doubles via array field
     Failure/Error: expect(u[:v].to_a).to eq([1.5, 2.5, 3.5, 4.5])

       expected: [1.5, 2.5, 3.5, 4.5]
            got: [1.4979237569e-313, 1.38697476291614e-309, 1.78e-321, 1.386978271489887e-309]

       (compared using ==)
     # ./spec/ffi/union_spec.rb:188:in 'block in UnionSpec'

For now we'll disable the specs in the FFI project https://github.com/ffi/ffi

Environment Information

Provide at least:

  • JRuby version (jruby -v) and command line (flags, JRUBY_OPTS, etc)
    • jruby 10.1.0.0-SNAPSHOT (4.0.0) 2026-03-15 6fbd5bc OpenJDK 64-Bit Server VM 21.0.10+7-LTS on 21.0.10+7-LTS +indy +jit [x86_64-linux]
    • jruby 10.1.0.0-SNAPSHOT (4.0.0) 2026-03-15 6fbd5bc OpenJDK 64-Bit Server VM 21.0.10+7-LTS on 21.0.10+7-LTS +indy +jit [aarch64-linux]

Expected Behavior

  • FFI should pass the union as value the same way as a C compiler
  • Provide an executable Ruby script or a link to an example repository.

Actual Behavior

  • The union by value is passed in some other way than the C compiler. The ABI seems to be different.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions