On Sep 29, 2014, at 3:37 PM, Jason Orendorff wrote:

> On Mon, Sep 29, 2014 at 4:06 PM, Allen Wirfs-Brock
> <[email protected]> wrote:
>> On Sep 29, 2014, at 1:41 PM, Jason Orendorff wrote:
>>> Function.prototype.apply, Function.prototype.call, and Reflect.apply
>>> currently call PrepareForTailCall. Is this a bug?
>> 
>> No, I don't believe so.  Built-ins (whether implemented in ES or native) are 
>> specified to have an "execution context".
> 
> Oh, I see! Thanks. (This is specified in 9.3.1 [[Call]], for anyone
> following along.)
> 
> But in this case, the spec already has some non-ECMAScript functions
> performing tail calls, so now I am at a loss as to what your earlier
> line to Brendan could mean:

I guess we need to be a bit more careful about what kind of "call" we are 
talking about.

The ECMAScript spec. execution model uses a stack of "execution contexts" to 
tracks [[Call]]'s to and returns from function objects. [[Call]]'s to built-in 
functions are specified as creating an "execution context" so that, from a 
spec. perspective, both self-hosted and native implementations of built-ins can 
be treated uniformly within the spec.

The ES tail call resource rules are expressed in terms of manipulating the 
execution context  stack, immediately prior to performing a [[Call]].  Or to 
put it another way,  ES tail calls rules are only about  [[Call]] operations.  
So, ES tail calls can occur in a built-in's that invoke [[Call]].   Generally 
this is possible if the built-in is specified to immediately return the 
[[Call]] result.

When I said we couldn't specify tail call behavior for non-ECMAScript 
functions, I think about the actual "call" semantics used by the implementation 
language.  For example, if F.p.apply is implemented in C++ and if the last 
thing it does is a C++ call to another C++ function that is the [[Call]] 
implementation. I can't say anything about how C++ implements that C++ call.

However, from the ES perspective all the C++ execution state that is using to 
represent such an implementation of F.p.apply is just part of the ES execution 
context for the [[Call]] to F.p.apply. The C++ code could call thousands of 
levels deep before it performs its [[Call]] back to an ES function and from the 
ES perspective all of that C++ stack space is just part of the single F.p.apply 
execution context. 

When we perform PrepareForTailCall in F.p.apply we are saying that the current 
ES execution context (the one that potentially includes that deep C++ call 
stack) must be discard (or mae available for reuse) before performing the the 
subsequent ES [[Call]].  How that is actually accomplished is an implementation 
"detail".

I strongly support full employment opportunities for language implementations 
hacker.


> 
>> I can't imagine what you would want be to try to say about non-EMCAScript 
>> functions. Their internal "call" semantics is determined by the semantics of 
>> their implementation language.
> 
> It seems like to the full extent that the current draft manages to
> constrain Function.prototype.call, it could constrain bound functions
> too.

It does. The spec doesn't introduce an additional execution context between the 
[[Call]] of a bound function and the [[Call]] to the bound functions target.  
If the [[Call]] to the bound function is in tail position then the caller's 
execution context is discarded before the [[Call]] to the bound function.

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

Reply via email to