The below code runs correctly in the REPL tab, but fails in the CSE machine tab:
const f = (...x) => x;
f(...[1, 2, 3]);
This is because the SpreadElement node is not handled inside the CSE machine interpreter.
Proposal
A SpreadElement node, when evaluated, should result in two new items inside the control:
A spread instruction
The expression on the right of the ellipsis.
Once the expression on the right is fully evaluated, there should be a runtime check that the result is indeed an array, and then the spread instruction should unpack the array in the stash, by removing it and adding the individual elements back into the stash.
This new spread instruction could also potentially allow spreading of array elements inside arrays, e.g. [...arr], instead of just being limited to the arguments of function calls.
Update
It appears that the call 1 instruction above the SpreadElement node would also be incorrect, and it should be call 3 instead. Unfortunately, the correct number of arguments can only be known after the array expression is evaluated, which is after the call instruction has already been pushed.
We also have to take note of more complex situations like below, where there can be multiple spread elements inside a function call:
The simplest solution would be to increase the value in the call instruction by the array length - 1 every time a spread instruction is run, and keep the limitation where array spread can only be used inside function calls, so it is guaranteed that there will be a call instruction somewhere above the spread instruction.
The below code runs correctly in the REPL tab, but fails in the CSE machine tab:
This is because the
SpreadElement
node is not handled inside the CSE machine interpreter.Proposal
A
SpreadElement
node, when evaluated, should result in two new items inside the control:spread
instructionOnce the expression on the right is fully evaluated, there should be a runtime check that the result is indeed an array, and then the
spread
instruction should unpack the array in the stash, by removing it and adding the individual elements back into the stash.This new
spread
instruction could also potentially allow spreading of array elements inside arrays, e.g.[...arr]
, instead of just being limited to the arguments of function calls.Update
It appears that the
call 1
instruction above theSpreadElement
node would also be incorrect, and it should becall 3
instead. Unfortunately, the correct number of arguments can only be known after the array expression is evaluated, which is after thecall
instruction has already been pushed.We also have to take note of more complex situations like below, where there can be multiple spread elements inside a function call:
The simplest solution would be to increase the value in the
call
instruction by the array length - 1 every time aspread
instruction is run, and keep the limitation where array spread can only be used inside function calls, so it is guaranteed that there will be acall
instruction somewhere above thespread
instruction.