[Harmony proxies] Another idea to give handler access to proxies

David Bruant bruant at enseirb-matmeca.fr
Tue Mar 1 03:11:53 PST 2011


Le 01/03/2011 11:10, Tom Van Cutsem a écrit :
> Hi,
>
> I had also thought of this, but quickly discarded it as too
> imperative. It just seems like a bad idea, and it interacts horribly
> with nested handler traps (you'd need to maintain a stack of
> "currentProxies" to make traps reentrant) and functional idioms
> (anonymous closures defined within a trap won't capture the current
> value of "currentProxy" as they would if it were a formal parameter to
> the trap).
oh right... That's kind of a terrible idea.

> Another way of looking at this: your suggestion implements a
> dynamically scoped binding, passing "proxy" as a parameter to the trap
> implements a lexically scoped binding. The latter is almost always
> what you want.
Here is another idea:
Adding a 'currentProxy' property to the arguments object of a handler
methods when it's called as a trap (otherwise, the method is just a
regular function). It's very close to the idea of adding an argument
without the inconvenient/embarassement of placing it. It's generic, so
it solves the issue for future traps. It obviously comes to the price of
some sort of inconsistency, because adding things to the arguments
object hasn't been done before (not that i'd be aware of, at least).

Within a handler method, there would be a subtle difference. Let's take
the example of a derived trap implementation (has trap):
--------------------------
var h = {
getPropertyDescriptor: function(name){return arguments.currentProxy;},
has: function(name) { return !!this.getPropertyDescriptor(name); }
}
var p = Proxy.create(h);

'a' in p; // false
--------------------------
When 'has' is trapped, it calls the handler method like a regular
method, so there is no special treatment to arguments
(arguments.currentProxy === undefined =>
!!this.getPropertyDescriptor(name) === false)

If 'has' was implemented as:
has: function(name) { return
!!Object.getPropertyDescriptor(arguments.currentProxy, name); }
then the 'getPropertyDescriptor' handler would be called as a trap, so
'currentProxy' would be 'magically' added to the arguments object.


I'm realizing that my idea raises a question that had no reason to exist
before.
Before, proxy weren't accessible from handler methods, so in order to
implement derived traps, one handler method could only have access to
other handler methods through 'this'. However, if 'proxy' becomes
accessible within handler methods (no matter how), it could be
considered to reimplement derived traps with actual fundamental trap
trapping. I would personnally feel this to be more consistent with the
idea of a mapping between traps and internal methods.
However, as of today, besides my arguments-proxy-patching idea, I do not
see how to notice a difference between
'this.getPropertyDescriptor(/*proxy, */ name)' (proxy argument depending
on how we give proxy access to handler methods) and being trapped on
'Object.getPropertyDescriptor(proxy, name)'.

Cheers,

David


>
> Cheers,
> Tom
>
> 2011/2/28 David Bruant <bruant at enseirb-matmeca.fr
> <mailto:bruant at enseirb-matmeca.fr>>
>
>     Hi,
>
>     After reading this page
>     (http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy),
>     I thought of another idea.
>     Maybe that instead of adding an argument to all handler methods,
>     we could add a property to the handler.
>     Each time a proxy p method m is trapped (with handler h):
>     - Object.defineProperty(h, 'currentProxy',  {value: p,
>     configurable:true})
>     - call the m trap (which can freely use this.currentProxy)
>     - delete h.currentProxy (that's why the property has to be
>     configurable)
>
>     An implementation could run some static analysis to see if the
>     handler is an actual object and if this.currentProxyis actually
>     used in the trap to avoid the overhead of define+delete. They
>     would have to be performed if the handler is itself a proxy.
>     In order to reserve the 'currentProxy' (no strong conviction on
>     the name. It could also be 'proxy') name, Proxy.create and
>     Proxy.createFunction could throw an error is such a property is
>     already defined.
>
>     On issue is that within a handler method, I could do:
>     {keys: function(){
>         Object.defineProperty(this, 'currentProxy', {value: 'gotcha',
>     configurable:false});
>         }
>     }
>     This is notoriously stupid, but it would make the "inner delete"
>     throw an error. The issue I'm raising is that 'configurable'
>     controls both the fact that a property can be redefined through
>     Object.defineProperty and deleted.
>
>     Anyway, this solution sweeps away any argument positionning issue.
>     It is very generic and for sure, any trap current or future will
>     need access to the proxy, so it solves the problem for potential
>     future traps.
>     On the other hand, there may be some property configuration issues
>     and maybe some performance issue since the two additional calls
>     may be needed at each trap call (even though static analysis could
>     help out with this).
>
>     This idea is unperfect like the others, but it might be worth
>     investigating in that direction.
>
>     David
>
>     _______________________________________________
>     es-discuss mailing list
>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     https://mail.mozilla.org/listinfo/es-discuss
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110301/66bfa147/attachment-0001.html>


More information about the es-discuss mailing list