I have a C library that looks like this:
struct timeseries *ts_create(void) {
    /* Allocate some memory and return a pointer. */
}
void ts_free(struct timeseries *p) {
    /* Free the memory block pointed to by p. */
}
/* And many other functions that receive a struct timeseries * and
 * do things to it.
 */
I've compiled this with emscripten and I'm creating a JavaScript interface (wrapper) to it, like this:
const timeseries = {
  ptimeseries: 0,
  initialize() {
    this.ptimeseries = cfunctions.ts_create();
  },
  destroy() {
    cfunctions.ts_free(this.ptimeseries);
  },
  // And many other functions
}
You could use it like this:
const myTimeseries = Object.create(timeseries);
try {
  myTimeseries.initialize();
  // do more things
} finally {
  myTimeseries.destroy();
}
The problem is that I'd like to keep the "dangerous" stuff, i.e. the memory allocation and freeing, in C (or in the JavaScript wrapper), so that the JavaScript programmer can use the resulting library safely. JavaScript programmers are used to objects freeing themselves automatically, and requiring them to add some kind of try ... finally statement is error prone.
But as far as I can see JavaScript doesn't have any object destructors or any kind of onGarbageCollect(object) event.
What can I do about this?
There is a new JavaScript feature known as FinalizationRegistry which you can use for this functionality, but note that it is not yet supported across all browsers (https://caniuse.com/mdn-javascript_builtins_finalizationregistry)
const registry = new FinalizationRegistry((heldValue) => {
  cfunctions.ts_free(heldValue);
});
class Timeseries {
  constructor() {
    this.ptimeseries = cfunctions.ts_create();
    registry.register(this, this.ptimeseries, this);
  }
  destroy() { // manual destructor for backup, you don't have to call this
    registry.unregister(this);
    cfunctions.ts_free(this.ptimeseries);
  }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With