Description
I experimented with wasm2js to see the difference in their design of using and growing the WebAssembly.memory. It turns out that they implement the reallocation and growing logic loosely making it even possible to instead of only growing but also shrinking it, because the implementation is simply: allocate a new and bigger ArrayBuffer and then set the content with the old heap. And the program works just fine when it already have memory freed (zero'd) then shrinked (with the exact steps except the ArrayBuffer is ofcourse, smaller). This is something that doesn't exist yet on current WebAssembly design, and I don't know if there is a difference in WebAssembly's internal implementation that prevents the memory works that way. Because if there's no difference, making the buffer property of WebAssembly.memory to be configurable would solve this issue completely.
Furthermore, I try to find a way to mitigate the limitation of non-shrinkable memory of wasm. The obvious solution is, you guessed it, running wasm on a web worker (or worker-thread on nodejs) so the whole memory and the worker itself can be copied then destroyed easily. While this should be a non-issue on nodejs as every nodejs' feature works in worker-thread, pretty much every DOM api even something comical like DOMParser (which should work fine in worker as it doesn't have any connection to DOM manipulation) doesn't work on web worker. And yes there is some project like worker-dom or comlink that tries to create a bridge to DOM api or any main-thread only api but the majority of it is still WIP or work differently (comlink is async only). Another solution is to keep reference or simply copy the buffer of currently running wasm instance, then unreference the instance (null will work fine) and reinstantiate a new wasm instance but don't run the main function just now, create a TypedArray view of the current memory buffer (instance.exports.memory.buffer), then set the content with the copied buffer in the early steps. With this steps the program will run just fine but... it is so anti-intuitive it feels like using comlink is now more approachable than doing this, not to mention that this process should run everytime we want to shrink the memory.
Even, in retrospect, if WebAssembly supports swapping or switching its current memory with a new one, or, supports cloning an instance so it shouldn't be reinstantiated (preferably synchronous, but async works fine) this would also solve this issue.