4 ms·
How does this handle cycles? It seems to me that if JS holds on to a WebAssembly object, and that WebAssembly object holds on to another JS object that in turn
by pcwalton 5y ago
How does this handle cycles? It seems to me that if JS holds on to a WebAssembly object, and that WebAssembly object holds on to another JS object that in turn has a reference to the same WebAssembly object, this solution will leak.
This may seem like a contrived scenario, but it happens a lot with callback patterns. You might have code like:
// MyNativeButton is a native WebAssembly object
// Perhaps it's part of a WebAssembly GUI framework that renders to canvas
this.button = new MyNativeButton();
this.button.onclick = () => this.clicked = true;
This will leak the "this" object forever because there's a cycle: "this" -> MyNativeButton -> JS closure -> "this".
- eyelidlessness 5y agoI’d assume the baseline advice would be the same as I’d give without WASM: if you’re treating `this` as mutable outside of a constructor you’re probably already screwed. Maybe it gets more complicated if you can’t see clearly whether your instance is a value type in WASM, but like your example shows… people generally don’t build value types with this kind of semantics in JS anyway. They’re already incurring those costs. My hope would be that WASM library authors are focused enough on resource usage that they’ll be more mindful of that than the baseline.
- kevingadd 5y agomutability isn't really the problem here, even if 'this' is immutable the problem is that you closed over it with your event handler
- eyelidlessness 5y agoThe only closed reference to `this` in the example is a mutation, in an event handler. This is supposed retain the reference and it’s not even a leak. The simplest way to solve that would be to remove the event handler, but even simpler would be to treat `this` as a value type and never change it after construction. The other reference is easily rewritten as a WeakMap key and would not retain a reference, but easier still could be written as a local binding with no reference to `this` at all.
- brrrrrm 5y agoThe “WebAssembly object” doesn’t exist as you describe. You probably have an object that wraps WebAssembly function calls and primitive WebAssembly data (individual numbers). WebAssembly functions can only return numbers and can only take numbers as arguments. Everything else is a wrapper that lives in JavaScript. MyNativeButton works exactly as you’d expect. If the GC can clean it up, it might. Otherwise you have a leak that you’d have had in normal JavaScript.