On Wed, Apr 27, 2011 at 2:46 PM, David Bruant <[email protected]> wrote:
> You're right. "get" and "set" default traps were chosen to follow
> closely internal methods (see [1]) and at the time when "proxy" wasn't
> an argument of all traps (so a proxy's prototype wasn't reachable from
> the handler).
> It may be a good idea to rethink default trap implementations by
> imposing the recursivity and start from there to rewrite internal methods.
> I think that pretty much all proto-climbing traps could be rewritten as:
> ---
> trap: function(/*arguments*/, proxy){
>        var res = Object.ownLayerTrap(proxy);
>        return satisfying(res)?
>          res:
>          Object.trap(Object.getPrototypeOf(proxy));
>      }
> ---
> The only exception I can think of is "set" which may me slightly more
> complicated.

When listing property names (i.e. "getPropertyNames", "enumerate",
"iterate") it is actually a concatenation of both own and prototype
values, not just one vs. the other.  Also with
"getPropertyDescriptor", there needs to be logic to return |undefined|
when the prototype is null.

> Actually, the leak already exists. If y has a "p" property which is an
> accessor, then when performing x.p, the |this| binding of "get" and
> "set" accessors is x (not y). ES5 8.12.3 [[Get]]:
> The descriptor /desc/ has been found *somewhere* in the prototype chain,
> /getter/ is extracted from it and O is bound as the |this| value (step 13)
> Same deal with [[Put]].
> So, proxies do not leak more than ES5 getters/setters do.
> Actually, the only place where "receiver" is used in the default get and
> set trap is as an argument for desc.get.call or desc.set.call.

Excellent point, the leak occurs either way.  However, the leak does
occur *differently* (i.e. via a "receiver" argument instead of a
|this| binding), which does not have to be the case.  As explained
before, the existing ES5 semantics would cause the proxy's
"getPropertyDescriptor" trap to be called thus obtaining any "getter"
/ "setter" that the proxy wants.  The |this| binding of this "getter"
/ "setter" will then be set to the "receiver" by ES5 8.12.3 step 13
for a "getter" or ES5 section 8.12.5 step 5.b for a "setter".  The
proxy's "get" / "set" trap would not get called, and thus would not
need the "receiver" arguments.

Thanks,
Sean Eagan
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to