OCaml/C FFI object lifetimes

I had some questions about FFI after watching ICFP 2018 video “Safely Mixing OCaml and Rust”.

Motivating example:

value pair(value a, value b) {
  CAMLparam2(a, b); /*required*/
  CAMLlocal1(r); /*required*/
  r = caml_alloc(2,0);
  Store_field(r,0,a);
  Store_field(r,1,b);
  CAMLreturn(r); /*required*/
}

The observation was that the C compiler does not tell you your code is incorrect if you leave out the /*required*/ lines. Another observation was that ctypes does not handle object lifetime issues (although its cstubs library does handle object layout issues).

So, could there be a C-like DSL tailored just for the OCaml/C FFI that, when the DSL is interpreted, outputs object-lifetime-safe C glue code? If the DSL were embedded in OCaml it could be checked against the six rules of the OCaml Manual’s “Living in harmony with the garbage collector” … perhaps through QuickCheck-like property testing, AFL fuzz testing, or even a rudimentary borrow checker.

Thoughts?

Note that the C code is still correct if you leave out the line CAMLlocal1(r). Moreover, if you know that a and b are immediate values because of their types, all the other “required” lines can also be removed without making the code incorrect. So, the six rules you mention should be taken with a grain of salt, they are not strictly needed, they are just here to make it “easier and safer”.

Anyway, a liveness analysis could indeed detect whether a non-immediate value is live across a potential call to the garbage collector. That said, I don’t see how a DSL would help. It seems like it would be better to just parse the C code and analyze it.

1 Like

If you’re willing to write your foreign functions in C++, you could probably arrange for this dynamically, using a combination of RAII and maybe some template metaprogramming.

1 Like

I’d be interested to know more about this. What kinds of object lifetime issues doesn’t ctypes handle?

1 Like