Skip to content

FFI on darwin-aarch64 can't pass Ruby as a C callback #6995

@headius

Description

@headius

The Ruby FFI library supports passing a snippit of Ruby code to C as though it were a C callback. Unfortunately this does not work on Apple Silicon (e.g. M1) currently.

On M1, programs are restricted from executing code within memory that is designated for runtime data, as a security measure. The Ruby callback logic depends on being able to generate a small native stub that knows how to call through JNI back up into the specified code object. The way it does this currently does not appear to be compatible with the security restrictions on M1.

This leads to crashing in two FFI specs:

  it 'can be used as callback from C passing to it a block' do
    function_add = FFI::Function.new(:int, [:int, :int]) { |a, b| a + b }
    expect(LibTest.testFunctionAdd(10, 10, function_add)).to eq(20)
  end

  it 'can be used as callback from C passing to it a Proc object' do
    function_add = FFI::Function.new(:int, [:int, :int], Proc.new { |a, b| a + b })
    expect(LibTest.testFunctionAdd(10, 10, function_add)).to eq(20)
  end

Fixing this will take some doing; we need to figure out how to generate new executable code into an appropriately-marked memory segment and handle cleaning up that memory when we are done with the callback. This will need some finesse to avoid creating a new memory chunk for every callback.

I attempted to test whether the CRuby FFI passes these specs, but it does not appear to work currently on M1: ffi/ffi#922

I will be excluding these specs for now, and this will be a known M1 issue until we can resolve it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions