[Harmony proxies] "add receiver as a first argument to all prototype-climbing traps"

David Bruant david.bruant at labri.fr
Thu Mar 31 00:52:51 PDT 2011


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'd like to remind that if Object.getPropertyDescriptorisn'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?).

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?
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?

Cheers,
David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110331/8f2f5007/attachment.html>


More information about the es-discuss mailing list