in packages/transform/src/emit.js [241:296]
Ep.getDispatchLoop = function() {
const self = this;
const t = util.getTypes();
let cases = [];
let current;
// If we encounter a break, continue, or return statement in a switch
// case, we can skip the rest of the statements until the next case.
let alreadyEnded = false;
self.listing.forEach(function(stmt, i) {
if (self.marked.hasOwnProperty(i)) {
cases.push(t.switchCase(
t.numericLiteral(i),
current = []));
alreadyEnded = false;
}
if (!alreadyEnded) {
current.push(stmt);
if (t.isCompletionStatement(stmt))
alreadyEnded = true;
}
});
// Now that we know how many statements there will be in this.listing,
// we can finally resolve this.finalLoc.value.
this.finalLoc.value = this.listing.length;
cases.push(
t.switchCase(this.finalLoc, [
// Intentionally fall through to the "end" case...
]),
// So that the runtime can jump to the final location without having
// to know its offset, we provide the "end" case as a synonym.
t.switchCase(t.stringLiteral("end"), [
// This will check/clear both context.thrown and context.rval.
t.returnStatement(
t.callExpression(this.contextProperty("stop"), [])
)
])
);
return t.whileStatement(
t.numericLiteral(1),
t.switchStatement(
t.assignmentExpression(
"=",
this.contextProperty("prev"),
this.contextProperty("next")
),
cases
)
);
};