Skip to content

Instantly share code, notes, and snippets.

@jorendorff
Created February 3, 2012 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jorendorff/1730064 to your computer and use it in GitHub Desktop.
Save jorendorff/1730064 to your computer and use it in GitHub Desktop.
for (let V = INIT; TEST; UPD) STMT
===>
{
let %tmp = INIT, %first = true;
while (true) {
// A fresh binding for V gets either the initializer-expression value(s)
// or the value(s) from the end of the previous loop iteration.
let V = %tmp;
// Run the update-expression, if necessary.
if (%first)
%first = false;
else
UPD;
// Check the test-expression.
if (!(TEST))
break;
// Run the body of the loop. Make sure the values in V
// are saved for the next iteration, even if STMT hits a ContinueStatement.
try {
STMT;
} finally {
%tmp = V;
}
}
}
@jorendorff
Copy link
Author

The above desugaring looks complicated, but the implementation is much simpler. I think SpiderMonkey will be able to switch from per-loop binding to per-iteration binding by adding a single extra bytecode instruction per loop. (In the case where no closures capture the loop variable, even that can be optimized away, but I'm not sure we'll bother.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment