Private symbols auto-unwrapping proxies (was: Security Demands Simplicity (was: Private Slots))

Tom Van Cutsem tomvc.be at gmail.com
Tue Jan 29 00:19:00 PST 2013


2013/1/29 Brandon Benvie <brandon at brandonbenvie.com>

> I realized the discrepancy between my thinking and what you said. In the
> case of a membrane, you are correct. A membrane will always unwrap
> everything, so you will only ever end up with dry method/dry this. That
> makes all the different forms of private equivalent. The difference arises
> when you're not dealing with a membrane, rather just a one shot proxy. In
> this case, you often do end up with (to borrow membrane the membrane
> terminology) dry method/wet this. this is the specific circumstance (and
> I believe the likely most commonly encountered one) in which auto-unwrapped
> private symbols do the right thing when the other private forms fail to
> work correctly.
>

Indeed. To summarize, the "dry method / wet this" case is easy to
achieve considering the current default behavior of proxies:
- proxies by default forward property |get| to the target, so the returned
method is unwrapped ("dry")
- proxies by default leave |this| bound to the proxy for method
invocations, so the |this| value is wrapped ("wet")

As previously noted, this pattern breaks down for methods that expect
|this| to:
- have particular private state (keyed by private symbols)
- have a particular identity (e.g. the object may be a key in a WeakMap)
- be of a particular built-in or exotic type (Date, NodeList, ...)

What I argued for in defense of proposal #2 is that the auto-unwrapping
solution (proposal #1), while it seemingly makes things "just work", also
inherently breaks the abstraction boundary of the proxy. The proxy's target
could be a closely held object that should not be exposed to the dry method.

Instead, what I feel is the right way to deal with this dry method / wet
this problem is that it's the proxy's responsibility to explicitly bind
|this| to the right target upon forwarding.

The problem with this "right way" is that binding |this| is expensive
(requires an allocation) in the absence of an invoke() trap.
Membranes can cope because they have to return a wrapped function anyway,
but in general binding |this| costs.

In conclusion, I don't feel this dry method / wet this problem should stand
in the way of proposal #2. The problem touches upon a deeper issue
unrelated to symbols per se. Instead, we should probably (separately)
discuss alternative mechanisms by which a proxy can choose to either leave
|this| bound to the proxy, or rebind it to another target object upon
forwarding, with minimal overhead.

Cheers,
Tom
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130129/9691f54d/attachment.html>


More information about the es-discuss mailing list