Skip to content

Foreign Function Interface (FFI) implementation

Rodrigo Muino Tomonari requested to merge github/fork/bengl/bengl/ffi into main

Here's a first pass at implementing a foreign function interface (FFI). It's roughly based on my attempt at building an FFI library in userland. That implementation uses dyncall, which doesn't support all the platforms that Node.js does, so I've used libffi instead.

As an example, this works on my PR branch.

$ cat test.c 
int test_add(int a, int b) {
  return a + b;
}
$ clang -shared -undefined dynamic_lookup -o libtest.so test.c
$ ./node -p "require('node:ffi').getNativeFunction('./libtest.so', 'test_add', 'int', ['int', 'int'])(7, 5)"
12

Here is the new doc page for this.

Limitations

  • Structs aren't supported as return values or arguments (but pointers are, and, of course, pointers to structs).
  • Callbacks aren't supported. See Open Questions below.
  • Only the documented types are supported, even if a given type is a typedef or otherwise equivalent to a supported type.

Open Questions

  • How should libffi be updated/maintained?
  • Do callbacks need to be supported in this PR?
    • My thoughts: It's a bigger task, and I think there's plenty of utility without callbacks. I'd prefer to do this separately afterward.
  • Should pointers be obfuscated somehow? Right now they aren't. They very easily could be, though, with a Pointer class.
    • My thoughts: I don't particularly think it's necessary, considering there are certainly other ways, both in several npm modules and in this feature, to get at pointers. Also, not having raw values makes it difficult to pack them into structs inside buffers, or do any pointer arithmetic.
  • Should Buffers/ArrayBuffers/ArrayBufferViews be acceptable as pointer arguments? This might simplify userland code.
    • My thoughts: Maybe, but in a separate PR.
  • Similarly, should Strings be acceptable as char * arguments?
    • My thoughts: Maybe, but in a separate PR.

Merge request reports

Loading