JavaScript bindings: might want to add a `delete()` method to the classes that have a `create()` method
Closed this issue · 2 comments
When you want to create a variable from JavaScript, you will do something like const v = new libcellml.Variable()
and when you are done with v
, you will typically call v.delete()
since you can't rely on garbage collection working reliably (see emscripten-core/emscripten#20569). This will mark v
for later deletion.
This is also what I do in libOpenCOR, but to call .delete()
never seems to call my object's destructor. So, in the end, I had to create a special delete()
method for every class that I can create/delete using new
/delete()
from JavaScript. For instance, for my File
class, I have:
// file.h
#ifdef __EMSCRIPTEN__
void delete_();
#endif
// file.cpp
#ifdef __EMSCRIPTEN__
void File::delete_()
{
delete this;
}
#endif
// JavaScript bindings
emscripten::class_<libOpenCOR::File, emscripten::base<libOpenCOR::Logger>>("File")
.smart_ptr_constructor("File", &libOpenCOR::File::create)
.function("delete", &libOpenCOR::File::delete_)
...
Hmm... I am going to leave this issue open, but it may not be a good way forward. In the test where I "need" that delete()
method to delete the object straightaway, it all works fine probably but it looks like it might be because I do other things after calling my delete()
method on some objects. Indeed, in some other tests, I finish the test with a call to my delete()
method and it crashes with something like:
RuntimeError: table index is out of bounds
at null.<anonymous> (wasm:/wasm/00fdfeea:1:127342)
at null.<anonymous> (wasm:/wasm/00fdfeea:1:164484)
at runDestructor (libopencor.js:3931:25)
at releaseClassHandle (libopencor.js:3940:9)
at libopencor.js:4090:9
at FinalizationRegistry.cleanupSome (<anonymous>)
So, it looks like garbage collection is eventually doing its thing. So, I am starting to think that I have to rely on GC working fine, maybe just not as soon as I wish it did.
Having had time to think a bit more about it, I feel like we can close this issue. This is clearly the way things work in JavaScript, so... so be it.