Hello and thanks in advance for your help.
So, I am writing an executable semantics of ES2021. For a bit of context, this formalization aims to be a formal copy of the specification. We have decided to take almost no implementation choices. Exceptions are the data structures for the state, and all its components(Objects, ExecutionContexts, EnvironmentRecords, etc..). By the way, now I am working on function expressions and function calls.
A practical example is:
let id = function (v) {return v;};
id("ciao")
The example is trivial, but its interpretation is not.
My problems start in FunctionDeclarationInstantiation and precisely in steps 24,25 and 26.
Let's start with step 24 and the createListIteratorRecord method call with the list ["ciao"], corresponding
to the arguments list. At this point, we are still in the callee execution context created by the ordinary function [[Call]]. Here basically we create a GeneratorObject and the return is an iterator record, with the generator object as iterator and %Generator.prototype.next% as next method.
Question 1:
After creating this object, we perform GeneratorStart. Step 4 of GeneratorStart defines a closure to assign to the callee execution context. Does this imply that the execution context is suspended in that step?
However, once we return the iterator record and so the control flow to FunctionDeclarationInstantiation,
it is time to bind the names in the context to a value. Indeed, steps 25 and 26 deal with this, depending on the presence of duplicated names.
IteratorBindingInitialization deals with it. And here I have problems(We consider the syntactic production that matches with SingleNameBinding). This method takes a parse node, an iterator record, and - in the example case - an environment, and returns an updated state, in which the environment is updated with the bindings for each of the names that live within the context of the called function.
Morally, what makes things awkward is the IteratorStep call! At a certain point, through IteratorNext, we call %Generator.prototype.next% using the Built-In Function [[Call]. At this point, a new context is created and pushed into the stack. The callee context was already suspended by GeneratorStart. Then, the algorithmic steps of %Generator.prototype.next% are executed. This method calls GeneratorResume with this value(the generator object created in CreateListIteratorRecord, and a value, that happens to be the aforementioned object.
This method, after some steps, suspends the running execution context(The new one created by the built-in function [[Call]]), pushes into the stack the callee context(We have a context duplication in the stack), and then it is resumed. Its resumption executes the closure defined in step 4 of GeneratorStart.
In the first steps of the resumption closure, another closure is executed, The one defined in CreateListIteratorRecord. Yield is executed for each of the arguments list.
Question 2:
The definition of Suspension and resumption is not defined precisely. Indeed, here things break, and I am quite sure that it is not an implementation dependant error. As a reminder, we are visually close to the specification, so it is difficult to make mistakes. We have a doubt, that can maybe solve our dilemmas. Basically, the Yield loop is executed all at once, regardless of the context suspensions/resumptions.
We then return the result and the control to the abstract closure in GeneratorStart.
- Does a suspension imply implicitly a sort of continuation(CPS)?
- In case a closure is not given, does a resumption make the context resume in the same algorithmic step in which it was suspended? Or it simply changes its CodeEvaluationState?
Here things really break, because, at the top of the execution context stack, we get the wrong contexts at the top of the stack, and this makes the binding initialization break.
I think that a nice proposal is to detail more what happens in context switches.
Thanks in advance!
P.S. I tried to detail as much as possible, but a lot of things are left out. If not, the thread would have been really confusing.