[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


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

Then I have a something to say on
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
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"

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?

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