Hi,

2011/3/31 David Bruant <[email protected]>

>  Hi,
>
> First, I'd like to say that I'm glad proxy-related issues have been
> discussed during the last TC-39 meeting and that all have found an
> agreement.
>
> Then I have a something to say on
> http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy
> Quoting relevant parts:
> "Andreas: experimenting with DOM wrappers. All prototype-climbing traps
> require access to the receiver object (which is not necessarily the proxy
> object), not just the get/set traps. The get and set trap may want access to
> both the receiver and the proxy. "
> "Current consensus:
> * add receiver as a first argument to all prototype-climbing traps (get,
> set, has, getPropertyNames, getPropertyDescriptor traps)"
>
> The intention I understand is that these proto-climbing traps should first
> be applied to the own layer (or rather, their "own" equivalent) then be
> applied recursively while climbing the prototype chain.
> However, I think that with current ES5 internal method definitions and
> proxies semantics (
> http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics), this
> doesn't work as the intention goes. For instance, [[Get]] (ES5 8.12.3) uses
> [[GetProperty]] and calls [[GetProperty]] recursively on the prototype
> object instead of the [[Get]] internal method. And currently (it was the
> case before the meeting. I'm just realizing now), semantics of
> [[GetProperty]] is to return undefined.
> Similar issues goes with current "has" trap and [[HasProperty]] internal
> methods which delegates inheritance responsibility to [[GetProperty]] (back
> to previous problem).
>
> However, getPropertyNames and getPropertyDescriptor traps, recently
> "promoted" as derived traps are still underspecified. Interestingly, the
> current implementation (
> http://wiki.ecmascript.org/doku.php?id=strawman:proxy_derived_traps) isn't
> recursive, but iterative. This is inconsistent with the current model and
> should certainly be redefined as a recursive function:
> ---
> getPropertyDescriptor: function(receiver, name, proxy) {
>   var pd = Object.getOwnPropertyDescriptor(receiver, name, proxy);
>   var proto = Object.getPrototypeOf(proxy);
>   if(proto === null || pd !== undefined)
>     return pd;
>   return Object.getPropertyDescriptor(proto); // recursive version.
> receiver is passed in some way (?)
> }
> ---
>

I think you're right. The spec uses recursion, so a proxy higher up the
inheritance chain could terminate the lookup early.

I also don't see how the original object to which
Object.getPropertyDescriptor was applied could be passed up the chain.
I also don't see the need for it, other than perhaps calling
|bind(receiver)| on the found property descriptor's value, get or set
attribute?


> I'd like to remind that if Object.getPropertyDescriptor isn't a native
> function with a native underlying internal method, but a monkey patch, it
> will not call a proxy trap (maybe this should be addressed?).
>

There's a Harmony proposal that proposes adding Object.getPropertyDescriptor
as a new built-in on Object for precisely this reason: <
http://wiki.ecmascript.org/doku.php?id=harmony:extended_object_api>


>
> The iterative model differs from the recursive one in a way that the engine
> is in control of making sure all layers are well-traversed and not
> "hijacked" by one particular layer. This is actually the idea I called
> "inheritance-safe proxies" (
> https://mail.mozilla.org/pipermail/es-discuss/2011-March/013366.html).
>
> I am wondering if by providing both proxy and receiver to all
> proto-climbing methods, we're not providing too much power to proxies. Let's
> imagine the following object with prototype chain:
> o --> a --> b --> null.
> a is a proxy and o and b are regular objects (or even proxies, it doesn't
> really matter with the current model). First, with the current model, since
> when a call is trapped, inheritance and actual prototype can be faked, a has
> the power of denying b and messing up with be through Object.getPrototypeOf.
> Now, if a gets access to 'receiver', it means it can mess up with o. Aren't
> we providing too much power to a?
>

Proxies would always be able to "deny" lookup proceeding to their prototype,
since you could implement a proxy that pretends to have all possible
properties as own properties. But granted: if the handler never gets access
to the proxy, then I don't think it can otherwise influence the proxy's
prototype.

As for |a| getting access to |o|, it needs this to faithfully emulate
accessor properties (see below).


> The more I think about it, the more I question the idea of provinding
> receiver as an argument to proto-climbing traps. What was the initial
> rationale behind it? I understand that it is different from proxy, but is it
> necessary? What are the use cases that require it?
>

For the get and set traps, a proxy needs the original |receiver| as the
|this|-binding when calling the get/set functions of accessor properties.
Cf. their use in the default implementations of |get| and |set| here: <
http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>

I'm not sure why it's needed in the other prototype-climbing traps
(getPropertyDescriptor, getPropertyNames, has, enumerate). Perhaps Andreas
can explain.

Cheers,
Tom
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to