Invoke trap (was: May 21, 22, 23 TC39 Meeting Notes)

David Bruant bruant.d at gmail.com
Fri Jun 7 12:53:13 PDT 2013


Le 02/06/2013 09:46, Rick Waldron a écrit :
> 4.4 Proxies
>
> Proxy Invoke Trap and wrong |this|-binding on built-in methods
>
> AWB: with current default behavior of “get”, “Caretaker” will break on 
> built-ins such as Date, because the |this| binding is by default set 
> to the proxy, so the Date built-in method will not find the correct 
> private state.
> ARB: Same issue with binary methods
> ...
> STH: We should add invoke trap but not change the object model
> MM: Pleasant to have. Separate from private state.
> AWB: used to think this was an issue with proxies, but convinced that 
> it’s an API issue: we need to provide default handlers that do the 
> right thing, and which users can subclass. In particular, want a 
> handler that, on forwarding, rebinds |this| to the target.
> STH: If you want to proxy a Date method the underlying `this` needs to 
> be a non wrapped Date object.
Doesn't this break encapsulation?

var d = new Date();
var pd = new Proxy(d, {
invoke: function(target, name, thisArg, args){
return target[name].apply(thisArg, args)
}
})

var pt = pd.getTime(); // calls the invoke trap

// in a mixed-trusted context with access to pd:
var ppd = new Proxy(pd, {
invoke: function(target, name, thisArg, args){
// does the actual unwrapped date object leak through thisArg?
}
});

var ppt = ppd.getTime();

In any case, what is the following supposed to do:

Date.prototype.getTime.call( new Proxy(new Date(), handler) )

I imagine we would want this to work too. Is this going through the 
invoke trap as well? The question stands for all new "class-specific" 
(Map, Set, etc.) methods that would be dot-called with a proxy as first 
argument.

If the problem being solved is making Date (and Map, Set, etc) built-in 
methods works on wrapped objects, I feel the invoke trap is only a 
partial solution.


I intuit (but have no proof) that for Date.prototype.getTime.call to 
work on proxies, there is a need for class-specific traps.
* Object properties have specific traps to intermediate access 
(has/get/set/defineProperty/keys, etc.),
* [[Prototype]] has specific traps to intermediate access 
(get/setPrototypeOf)
* [[Extensible]] has a specific trap to intermediate access 
(preventExtensions)
* [[Call]] has a specific trap to intermediate access (apply)
* [[Construct]] has a specific trap to intermediate access (construct)
* Some other things that are somewhat internal (@@iterator, @@class, 
etc.) are exposed as symbols and are mediated via object 
properties-related trap

The pattern I see is that a good share of object internal properties 
(ES5.1 - 8.6.2 - Table 8 and Table 9) have traps dedicated to mediate 
access.

The case of functions is interesting. There are traps that are only 
relevant when the target is a function. In that regard, adding traps 
that are specific to accessing the Date internal [[Time]] value or 
specific traps to mediate access to [[MapData]] isn't any different than 
the current specific traps that mediate [[Call]] or [[Construct]]

David


More information about the es-discuss mailing list