bytecodealliance/jco

Supporting explicit resource management

Closed this issue · 4 comments

For integration with https://github.com/tc39/proposal-explicit-resource-management it would be useful to define some explicit disposability of resources in JS using the Symbol.dispose function on the resource.

This Symbol.dispose functionality would only apply to currently valid own resources.

Disposing borrowed resources would be a noop, since the borrowed handle lifetime doesn't affect the underlying resource disposal.

For exported resources that are created within JS code itself, we would conversely need the ability to define the destructor, and we could use Symbol.dispose as that mechanism again, although this would indicate the underlying disposal that is run for JS-created resources as opposed to being the mediator of that disposal.

There are some edge cases with this kind of an integration - if you dispose of a JS resource using Symbol.dispose when that resource is JS-exported but currently owned by Wasm, then Wasm's own disposal would be a second dispose. But in a sense, the JS disposal would sit at a higher layer so that this doesn't seem like a huge gotcha to me, given that JS "owns" in the theoretical sense its own classes, since there is no concept of ownership in JS. Importantly within the Wasm-JS interactions the model remains well-defined. Alternatively we could do something fancy to avoid this like eg masking the Symbol.dispose function with a wrapper function, but we could always add that kind of support later I think.

Importantly, if Symbol.dispose is not called - the usual finalization registry disposal would still apply. That is Symbol.dispose for the imported own resources offers a way to eagerly dispose without relying on finalization. But GC finalization will still always be enabled as the fallback for all disposal.

I thought WIT didn't have a notion of destructors? Given you're writing a PR there clearly seems to be a way to figure this out. How do we know which methods to place inside the Symbol.dispose context?

The component model defines the notion of a destructor for a component model resource. Note this is separate from the drop of a handle which doesn't necessarily call the destructor - it is only own drops that call the destructor. See eg the mention under resource.drop in https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#canonical-built-ins.

Landed in #237.