[[Invoke]] and implicit method calls

Allen Wirfs-Brock allen at wirfs-brock.com
Sat Sep 21 11:17:22 PDT 2013


On Sep 21, 2013, at 2:53 AM, Tom Van Cutsem wrote:

> 
> 2013/9/21 Allen Wirfs-Brock <allen at wirfs-brock.com>
> 
> On Sep 20, 2013, at 5:31 PM, Brendan Eich wrote:
>  > Given this, having the legacy internal calls continue to use get+call seems fine to me. A proxy implementing toString, e.g., can make it work using these traps just as well as via get+invoke, and without double lookup or boolean-trap-smelling (id | func) parameterization of invoke.
> 
> In that case,  why not just use [[Get]]+[[InvokeFunction]] in all cases (including obj.m(()) and not have the current [[Invoke]] at all.  It allows the proxy handler to correctly intercede on all method invocations including conditional cones.
> 
> Yes, except:
> 
> a) proxies must then still allocate a temporary function object in the get trap. Thus, the primary reason for having a derived trap (less allocations), disappears.

??? Not in the normal cases where function already exist for the method properties.  They would only have to be allocated for the more exceptional situation where the handler is trying to directly implemented method behavior within the handler (via a switch statement, etc)

or was there something else you had in mind with the above assertion?

> b) every method call on a proxy triggers at least 2 traps ("get" + "invoke"). Another selling point of invoke() was that method calls go through one trap only.

Yes, we do have the added overhead, of two traps but with the benefit is that we get a more consistent semantics that is a better match to current ES expectations.

If we really are worried about the overhead of two traps we could have a derived "invoke" trap that does "get"+"invokeFunction" but I'm not sure the complexity is worth it (or that there would actually be any saving, isn't the the default implementation of "invoke" just going to essentially trigger the other two traps?)

> c) double-lifting needs 2 traps (get + invoke) rather than just get.

I don't think so, using [[invokeFunction]] instead of [[Invoke]] eliminates the need for two:

the current dispatch mechanism for Proxy Mop operations is essentially
    let trap = handler.[[Get]]("handlerName");
    ...
    trap.[[Call]](handler,args);

if [[InvokeFunction]] was available this would become

    let trap = handler.[[Get]]("handlerName");
    ...
    handler.[[InvokeFunction]](trap, handler,args);

The default behavior of [[InvokeFunction]] on a Proxy that does not have a corresponding "invokeFunction" trap defined is equivalent to a [[Call]] of the passed function so the behavior would be exactly the same.  All the metameta handler needs to define is "get".

> 
> At that point, we're better off dropping [[InvokeFunction]] entirely.
> 
> As Brendan mentioned, methods are extractable in JS. A new MOP operation doesn't relieve proxies from honoring that contract.

It still appears to me that [[Get]]+[[InvokeFunction]] and respec'ing F.p.call/apply in terms of [[InvokeFunction]] is the closest semantic match to this expected behavior plus has the least anomalies WRT transparent proxying of built-ins with private state (and user defined classes that we WeakMaps for private state).

> 
> I believe we made the right trade-offs so far and still stand by the status-quo.

Which status-quo?  We have some fundamental semantic consistency issues involving Proxies and method invocation.

We have a number of alternatives that have been discussed and they all seem to have both pros and cons associated with them. I also believe that done of them perfectly resolves all of the semantic consistency issues and at the same time preserves perfect actual or conceptual backwards compatibility.  Personally, I'm finding it difficult to remember all of the various pros and cons that we have individually discussed for each alternative.  I suspect we need to put together a side-by-side for each alternative so we can compare them.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130921/6e2db835/attachment-0001.html>


More information about the es-discuss mailing list