[Proxies] Refactoring prototype climbing in the spec

Tom Van Cutsem tomvc.be at gmail.com
Tue Nov 8 02:54:02 PST 2011


>
> I am a big fan of this refactoring.
> I like the idea that the algorithm transfers full control to the proxy.
> Also, accepting this strawman would solve my inherited event properties
> problem because I would have access to the receiver from the get trap
> and would be able to do the binding I want.
>

Glad to hear that.


> About [[SetP]]:
> * It seems to me that we've traded a duplicated [[GetProperty]] call for
> a duplicated [[GetOwnProperty]] (Step 1 and 5.a) call on the receiver.
> This could be avoided by storing the property descriptor at the
> beginning (when O.[[setP]](Receiver, P, V) is called and O ===
> receiver). Step 5.a could be remove by the change.
>

The double [[GetOwnProperty]] invocation on the initial receiver should not
be observable: if the initial Receiver of [[SetP]] is a proxy, the proxy's
[[SetP]] algorithm (which triggers the "set" trap) executes instead of this
algorithm. So it's only if the initial Receiver is a normal object that
this code executes, and then the call to [[GetOwnProperty]] on line 1 will
never trigger proxy code.

When [[SetP]] is called by evaluating a property assignment expression,
Receiver also always denotes a normal non-proxy object. However, with the
proposed Object.getProperty built-in one can write:

Object.getProperty(aProxy, name, aNormalObject)

which would trigger aNormalObject.[[SetP]](aProxy, name), so then Receiver
would indeed be a proxy. Line 1 then calls
aNormalObject.[[GetOwnProperty]], while line 5.a, if reached, would trigger
aProxy.[[GetOwnProperty]].

Long story short: the "O" variable in the [[SetP]] algorithm always denotes
a normal non-proxy object. In general, the "Receiver" variable can be any
object.


> * If step 5.a is removed, I think that step 5.b.i is useless, because we
> would have returned from the set when O was the receiver (by step 2.a of
> [[setP]])
> * If step 5.a is removed, then step 5.c is useless, because if the desc
> had a [[set]], then we would have already returned from one of the
> substep of step 3 when O was the receiver
>
> Why not redefining [[Get]] as what you have defined as [[GetP]] and
> equivalent for [[Set]] and [[SetP]]?
> Current 8.12.3 [[Get]] (P) would become [[Get]] (Receiver, P). It would
> be called with O as initial value for Receiver pretty much everywhere in
> the spec except within [[Get]] recursive calls.
> Equivalent for [[Set]].
> It would prevent the replacement of 2 Object.* methods by 2 others.
>

The reason I introduced separate [[GetP]] and [[SetP]] methods is simply so
that the "public API" of Objects remained intact. Your suggestion is
reasonable: trade proliferation of built-in methods for a small public API
change in the spec. I guess this is just a matter of find/replacing all the
calls to [[Get]]/[[Put]]. Might even be an opportunity to get rid of "put"
and use "set" consistently throughout the spec.


> With the refactoring, on the direct proxy strawman, I don't think we
> need the "proxy" argument for the get and set traps anymore. It was here
> as the receiver, but since we have the receiver itself, the get and set
> trap can just have the receiver and the target as argument.
>

Good point. I'd wager that in most use cases, knowing that |receiver| is
either your own proxy or a descendant of that proxy is sufficient. I can't
currently think of a use case where the get/set trap would really want to
be able to access the proxy itself, not just the proxy or a descendant.
That doesn't mean that use cases for it don't exist, however. I guess if
access to the proxy is really needed, it's easy enough to accomplish:

var p = Proxy.for(target, handler);
handler.proxy = p;

Now the proxy is accessible as |this.proxy| in all traps. This may seem
like a hassle, but if the use cases for accessing a proxy are sufficiently
minor, getting rid of the proxy argument to the get/set traps seems like a
good tradeoff.

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


More information about the es-discuss mailing list