aapoalas / denonomicon

The Dark Arts of Deno Foreign Function Interface Programming
MIT License
27 stars 0 forks source link

Question about FFI and garbage collection. #12

Open audetto opened 2 hours ago

audetto commented 2 hours ago

I am trying to port a c++ library to deno and I am not clear on how gc with ffi buffers works.

This is a great explanation of how ffi works, but I cannot understand the connection with gc.

I saw this example

https://github.com/aapoalas/denonomicon/blob/5da9957a350e146aec203b93bb8621805569f8c0/examples/cpp/inheritedClass.ts#L225C7-L225C26

but I do not understand how the gc is informed that it needs to call a destructor when the buffer/pointer goes out of scope in deno.

I have done the same in node and a function like this

https://nodejs.org/api/n-api.html#napi_create_external

makes it super easy.

I could not understand what is the equivalent in deno.

aapoalas commented 2 hours ago

Ah, you're absolutely correct that the GC isn't being informed here. I seem to have forgotten to do that binding here; this example was ... I don't quite remember but probably done as a quick aside.

Here's a more "complete" example (though with a C API, not C++, if that makes a difference to you): https://github.com/aapoalas/libclang_deno/blob/main/lib/mod.ts#L286-L308

So basically, I use a FinalizationRegistry that is given the pointer to hold, while the class instance "owning" the pointer is the weak value that controls the finalization lifetime. I also support explicit destruction via https://github.com/aapoalas/libclang_deno/blob/main/lib/mod.ts#L486-L497 which is just a manual call to the destructor and an unregister from the FinalizationRegistry to avoid double-free. This, IMO, the preferred way that FFI binding classes should be dropped but naturally in the JS world this is an odd API and fraught with danger, so the FinalizationRegistry is definitely a necessary "evil" backup.

aapoalas commented 2 hours ago

Also just FYI, Deno does support N-API so you may want to consider that route if you're more familiar with it.

Though, of course, I love FFI to death.