Open ajvincent opened 1 year ago
Reading back on the TC39 plenary notes, there is a suggestion of passing the revoker to DisposableStack.defer(), and then the JS engine recognizing it as a revoker function and dropping the reference, so it can manage the proxy's slots directly.
I'm not sure how that will play out.
It will work if the engine chooses to optimize it. It still creates a little GC pressure. If you create a lot of proxies at once that might be a problem.
https://github.com/tc39/proposal-explicit-resource-management
At the November 2022 TC39 plenary, @rbuckton stated he believed the
DisposableStack
orAsyncDisposableStack
could help out with proxy revocation. I want to understand better how.There are four main objects we're dealing with when it comes to proxies, five if we count this proposal:
Which of these would be used with
DisposableStack
and how?If it's the revoker, that might be simplest via
stack.defer(revoker)
, but I'm skeptical of this. (a) We'd still have to create the revoker in the first place, to give to the stack - and avoiding the need to create revokers is a major goal of this proposal. (b) I've demonstrated both in V8 and in Spidermonkey that the revoker holds a strong reference to the proxy (a memory leak), something which is probably unintentional (but also not a spec bug).If it's the proxy, I have concerns about knocking out proxies which other objects or proxies might refer to via a property or a prototype chain.
If it's the proxy handler, I note the handler is likely to be shared by many proxies and the membrane likely holds a strong reference to it too.
If it's the proxy's shadow target, that might work, since it's supposed to be unique to the proxy. That said, a careful reading of the specification (section 10.5) shows that the traps aren't explicitly checking whether the shadow target still exists or not. So we could introduce a spec bug or a crash in implementing engines.
These are just my initial thoughts, other than a question for the other proposal, which is "What happens if two stacks reference the same object or callback?", or more generally, "what happens if two references own an object, and one of them is a disposable stack?"