On Sep 23, 2013, at 1:33 AM, Tom Van Cutsem wrote:

> 2013/9/21 Allen Wirfs-Brock <[email protected]>
...
> 
>> 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".
> 
> Ok, I stand corrected. But that default behavior surprised me. The default 
> behavior of all other traps is to forward the intercepted operation to the 
> target. The way you describe things, this would not be true of 
> "invokeFunction".

Except the above isn't showing the control flow for the default path through a 
Proxy mop operation it is showing the path when a trap is defined.  As it has 
done is replaced the [[Call]] to the trap (which passes the handler as the this 
value) with an [[InvokeFunction]] on the handler.    Since the Proxy object 
that is the handler (for example, https://gist.github.com/tvcutsem/6536442 ) 
does not define a "invokeFunctiuon" trap it takes its default which is to 
forward [[InvokeFunction]] to its target (dummy in the example).. That is an 
ordinary object so it will get default [[InvokeFunction]] behavior which is 
just to do a [[Call]] using the explicitly passed this value and arguments.

(BTW, this is somewhat tricky to work out, but I believe it all hangs together. 
 But we should keep looking at this double-lifting scenario to make sure I 
haven't missed something).


>  
>> 
>> 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).
> 
> Except that respec'ing F.p.call/apply changes the [[Call]] behavior of 
> existing non-proxy functions. Am I the only one to think this is potentially 
> a serious hazard?

Only if the this argument is a proxy and presumably no existing use of 
call/apply was written with the expectation that the this value it was passing 
might be a proxy.  It think it is much more likely that they expect the obj.m() 
:: obj.m.call(m) equivalent than anything else.
...
> 
> Indeed, there are trade-offs and there is no silver bullet.
> 
> The status-quo, which I advocated, entails:
> 
> - we keep the invoke() trap, with its current signature: invoke(target, 
> propertyName, argsArray, receiver)
> - conditional method calls in the spec are still expressed as [[Get]] + 
> [[Call]], following the common JS idiom
> 
> After your comments, I would add:
> - we change ForwardingHandler.get to automatically re-bind |this| by wrapping 
> function-valued data properties of its target
> 
> The only drawback of the status-quo, that I see, is that proxies that do not 
> subclass ForwardingHandler must exercise more care in their "get" trap if 
> they want to intercept the this-binding. Most other alternatives make it 
> easier for proxy authors to avoid this issue, but at the expense of making 
> the JS MOP strictly more complex/less intuitive.

You already have my challenge to try to define such a handler.  I'm actually 
more concerned about inconsistent behavior for both internal (eg, valueOf) and 
user coded conditional calls.  

Allen 






_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to