[[Invoke]] and implicit method calls

André Bargull andre.bargull at udo.edu
Tue Sep 24 01:26:53 PDT 2013


Short summary:

The current (rev18) [[Invoke]] design allows this code to work (use case A):
js```
var p = new Proxy(new Map, {});
// Map.prototype.get is not generic, requires proper Map instance
p.get(key);
```

But it does not allow to use (use case B):
js```
var p = new Proxy(new Map, {});
Map.prototype.get.call(p, key);
```

To make sure use case B works as well, [[InvokeFunction]] and changing 
Function.prototype.{call, apply} has been proposed. Proxies will also 
receive a new trap for [[InvokeFunction]]. Function.prototype.call will 
need to be changed as follows:

Change last step (step 4) from:
4. Return result of func.[[Call]] (thisArg, argList).

To:
4.  If Type(thisArg) is Object then
4.a  Return result of thisArg.[[InvokeFunction]] (func, argList).
5.  Else
5.a  Return result of func.[[Call]] (thisArg, argList).

(Note: The condition in step 4 may explicitly test for Proxies and only 
dispatch [[InvokeFunction]] if that's the case -- but this is not too 
important for now.)


The following objections have been raised so far:
(1) Calling Function.prototype.call on a function object no longer 
ensures the function object will be called.
(2) Calling Function.prototype.call on a function object let's the 
function object escape to the proxy object.

Example for (1):
js```
function thrower() { throw new Error }
var p = new Proxy({}, {invokeFunction(f, args) { /* do nothing */ }});
// no exception will be thrown here
thrower.call(p);
```

Example for (2):
See Kevin's example below.

In response to these objections, it was said that `Reflect.call()` will 
need to be used to ensure the original [[Call]] behaviour takes place.


- André


> Ok, I've only been skimming the thread but I obviously missed something
> crucial. How would
>
> f.call(obj)
>
> cause obj's handler to be invoked at all, much less be given access to f?
> And why?
>
>
>
> On Mon, Sep 23, 2013 at 7:14 PM, Allen Wirfs-Brock <allen at wirfs-brock.com  <https://mail.mozilla.org/listinfo/es-discuss>>wrote:
>
> >/  Sorry, I meant obj's handler
> />/
> />/
> />/  "Mark S. Miller" <erights at google.com  <https://mail.mozilla.org/listinfo/es-discuss>> wrote:
> />/
> />/  What does "f's handler" refer to? If obj is a proxy and f is not, then obj
> />/  has a proxy and f does not.
> />/
> />/
> />/  On Mon, Sep 23, 2013 at 6:32 PM, Allen Wirfs-Brock <allen at wirfs-brock.com  <https://mail.mozilla.org/listinfo/es-discuss>>wrote:
> />/
> />>/
> />>/  On Sep 23, 2013, at 6:14 PM, Kevin Smith wrote:
> />>/
> />>/  > Hi Allen,
> />>/  >
> />>/  > Your line of thinking has convinced me that `invoke` as it currently
> />>/  stands doesn't really fly.  However, I have an issue with your proposal.
> />>/   Take this fragment:
> />>/  >
> />>/  >     (1) function f() { doSomethingWith(this); }
> />>/  >     (2) f.call(obj);
> />>/  >
> />>/  > Presently, the expression at (2) grants the function `f` access to
> />>/  `obj`.  If I understand correctly, under your proposal the expression at
> />>/  (2), in the case where `obj` is a proxy, additionally grants `obj` access
> />>/  to `f`.  Is that right?
> />>/
> />>/  In the case where obj is a Proxy f.call(obj) would give f's handler
> />>/  access to f.
> />>/
> />>/  Allen/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130924/3c27f194/attachment.html>


More information about the es-discuss mailing list