Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// opcode, since it bleeds directly into its clause.
for (let clause of clauses.slice(0, -1)) {
out.push(op(Op.JumpEq, label(clause.label), clause.match));
}
// Enumerate the clauses in reverse order. Earlier matches will
// require fewer checks.
for (let i = clauses.length - 1; i >= 0; i--) {
let clause = clauses[i];
out.push(op('Label', clause.label), op(Op.Pop, 2), clause.callback());
// The first match is special: it is placed directly before the END
// label, so no additional jump is needed at the end of it.
if (i !== 0) {
out.push(op(MachineOp.Jump, label('END')));
}
}
out.push(op('Label', 'END'), op('StopLabels'), op(Op.Exit));
return out;
}
op(Op.PutIterator),
op(Op.JumpUnless, label('ELSE')),
op(MachineOp.PushFrame),
op(Op.Dup, $fp, 1),
op(MachineOp.ReturnTo, label('ITER')),
op(Op.EnterList, label('BODY')),
op('Label', 'ITER'),
op(Op.Iterate, label('BREAK')),
op('Label', 'BODY'),
invokeStaticBlockWithStack(unwrap(blocks.get('default')), 2),
op(Op.Pop, 2),
op(MachineOp.Jump, label('FINALLY')),
op('Label', 'BREAK'),
op(Op.ExitList),
op(MachineOp.PopFrame),
op(MachineOp.Jump, label('FINALLY')),
op('Label', 'ELSE'),
];
if (blocks.has('else')) {
out.push(invokeStaticBlock(blocks.get('else')!));
}
return out;
},
});
evaluateMachine(opcode: RuntimeOp) {
switch (opcode.type) {
case MachineOp.PushFrame:
return this.pushFrame();
case MachineOp.PopFrame:
return this.popFrame();
case MachineOp.InvokeStatic:
return this.call(opcode.op1);
case MachineOp.InvokeVirtual:
return this.call(this.stack.pop());
case MachineOp.Jump:
return this.goto(opcode.op1);
case MachineOp.Return:
return this.return();
case MachineOp.ReturnTo:
return this.returnTo(opcode.op1);
}
}
MACHINE_METADATA[MachineOp.InvokeStatic] = {
name: 'InvokeStatic',
mnemonic: 'scall',
before: null,
stackChange: 0,
ops: [
{
name: 'offset',
type: 'u32',
},
],
operands: 1,
check: true,
};
MACHINE_METADATA[MachineOp.Jump] = {
name: 'Jump',
mnemonic: 'goto',
before: null,
stackChange: 0,
ops: [
{
name: 'to',
type: 'u32',
},
],
operands: 1,
check: true,
};
MACHINE_METADATA[MachineOp.Return] = {
name: 'Return',
body() {
let out: StatementCompileActions = [
op(Op.PutIterator),
op(Op.JumpUnless, label('ELSE')),
op(MachineOp.PushFrame),
op(Op.Dup, $fp, 1),
op(MachineOp.ReturnTo, label('ITER')),
op(Op.EnterList, label('BODY')),
op('Label', 'ITER'),
op(Op.Iterate, label('BREAK')),
op('Label', 'BODY'),
invokeStaticBlockWithStack(unwrap(blocks.get('default')), 2),
op(Op.Pop, 2),
op(MachineOp.Jump, label('FINALLY')),
op('Label', 'BREAK'),
op(Op.ExitList),
op(MachineOp.PopFrame),
op(MachineOp.Jump, label('FINALLY')),
op('Label', 'ELSE'),
];
if (blocks.has('else')) {
out.push(invokeStaticBlock(blocks.get('else')!));
}
return out;
},
});