Assert that generated bytecode manipulates stack correctly

There are two invariants in generated bytecode related to the stack:

  1. Branches of a condition must move the stack pointer in the same way.

  2. Body of a loop can't move the stack pointer.

These invariants were always true, but they were not checked. Now we
check them at least when compiling with optimization for speed, because
there we analyze the stack pointer movements statically.
redux
David Majda 11 years ago
parent 0bcf7bc61b
commit 44e03187a7

@ -379,15 +379,24 @@ module.exports = function(ast, options) {
thenLength = bc[ip + baseLength - 2],
elseLength = bc[ip + baseLength - 1],
baseSp = stack.sp,
thenCode, elseCode;
thenCode, elseCode, thenSp, elseSp;
ip += baseLength;
thenCode = compile(bc.slice(ip, ip + thenLength));
thenSp = stack.sp;
ip += thenLength;
if (elseLength > 0) {
stack.sp = baseSp;
elseCode = compile(bc.slice(ip, ip + elseLength));
elseSp = stack.sp;
ip += elseLength;
if (thenSp !== elseSp) {
throw new Error(
"Branches of a condition must move the stack pointer in the same way."
);
}
}
parts.push('if (' + cond + ') {');
@ -402,12 +411,18 @@ module.exports = function(ast, options) {
function compileLoop(cond) {
var baseLength = 2,
bodyLength = bc[ip + baseLength - 1],
bodyCode;
baseSp = stack.sp,
bodyCode, bodySp;
ip += baseLength;
bodyCode = compile(bc.slice(ip, ip + bodyLength));
bodySp = stack.sp;
ip += bodyLength;
if (bodySp !== baseSp) {
throw new Error("Body of a loop can't move the stack pointer.");
}
parts.push('while (' + cond + ') {');
parts.push(indent2(bodyCode));
parts.push('}');

Loading…
Cancel
Save