Open ajvincent opened 2 years ago
Why would a function be unable to cross realms? ShadowRealms auto-wrap callables and produce a callable.
@ljharb because the wrapped function does not "unwrapped" when transfer back to the original realm.
The signal wouldn’t be the function itself tho, it’d be invoking the function - if the signal has identity that matters, only a symbol makes sense.
My thinking is that we're reduced to one of two options: either the signal is callable, or the signal has to be passed to a callable as an argument to force the revocation.
As an analogy to Caridy's argument, I'd ask: what happens when we pass a regular Proxy revoker from Proxy.revocable()
across a realm boundary, and then call the wrapped revoker? I don't see a real difference between that and the current proposal.
I shudder to think what would happen to the "pass as an argument" option across realms when the realm receiving the signal is a Compartment (i.e. has its own top-level globals like Function, Object, Proxy, etc.).
A Proxy revoker is a function, so calling the wrapped revoker would absolutely just call the original revoker.
A Proxy revoker is a function, so calling the wrapped revoker would absolutely just call the original revoker.
That's what I thought - and that's why I don't see a difference. It may be that Caridy is thinking about the return value of our signal callable... which we haven't specified. (I was thinking undefined, again just like the existing revoker specification.)
It is not about the fact that you can call it from another realm... it is about the fact that you can't use it as a signal to create proxies on the other side under the same umbrella (same signal). Basically, the wrapped version of the signal is not good in new Proxy({}, {}, { signal })
ah, if the signal is an identity, rather than an action, then it ofc would have to be a symbol.
It is not about the fact that you can call it from another realm... it is about the fact that you can't use it as a signal to create proxies on the other side under the same umbrella (same signal). Basically, the wrapped version of the signal is not good in
new Proxy({}, {}, { signal })
Oops. I completely misunderstood your argument in the SES meeting. Thank you for the clarification. I've updated the start of this issue to reflect this.
:thinking:
Let's assume signal
must be a Symbol. The simplest solution would be to have a static method of Proxy
which takes the signal as its first (and only) argument.
From there, it becomes a naming convention / API debate: one for the creation of the signal, one for exercising the signal to force revocation. I would propose two methods of Proxy. In TypeScript:
interface ProxyConstructor {
createSignal() : symbol;
finalizeSignal(signal: symbol): void;
}
declare var Proxy: ProxyConstructor;
The names are flexible. I just wanted to get away from my proposal's Proxy.revocationController()
name for autocomplete purposes (too similar to "revocable").
I still wonder if we'd need a carve-out in the compartments implementation so that a symbol from one compartment could be passed into finalizeSignal()
in another compartment.
@caridy has challenged whether the signal property of my proposed options dictionary should be a callable function.
non-callable in realms it doesn't originate from.unusable for creating new proxies to have revocation. (Updated per Caridy's comment below.)I am completely open to any workable mechanism. I suggested a function as the signal in the naive belief that calling the function would trigger the mass revocation.
Ideas most welcome!