Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export function executeStackFrame(
{ program }: IR,
offset: number,
firstFrame: StackFrame
): ?StackLocal {
assertRuntimeError(typeof program === "object");
const callStack: Array = [firstFrame];
// because it's used a macros
// eslint-disable-next-line prefer-const
let framepointer = 0;
function getLocalByIndex(frame: StackFrame, index: number) {
const local = frame.locals[index];
if (typeof local === "undefined") {
throw newRuntimeError(
"Assertion error: no local value at index " + index
);
}
const subroutine = frame.allocator.get(funcaddr);
if (typeof subroutine !== "object") {
throw newRuntimeError(
`Cannot call function at address ${funcaddr}: not a function`
);
}
// 4. Invoke the function instance at address a
// FIXME(sven): assert that res has type of resultType
const [argTypes, resultType] = subroutine.type;
const args = popArrayOfValTypes(frame, argTypes);
assertRuntimeError(subroutine.isExternal);
const res = subroutine.code(args.map(arg => arg.value));
if (typeof res !== "undefined") {
pushResult(frame, castIntoStackLocalOfType(resultType, res));
}
break;
}
}
switch (instruction.id) {
case "const": {
// https://webassembly.github.io/spec/core/exec/instructions.html#exec-const
// $FlowIgnore
assertRuntimeError(framepointer > -1, "call stack underflow");
const frame = callStack[framepointer];
assertRuntimeError(frame !== undefined, "no frame at " + framepointer);
return frame;
}
const offsets = Object.keys(program);
let pc = offsets.indexOf(String(offset));
while (true) {
const frame = getActiveStackFrame();
const instruction = program[parseInt(offsets[pc])];
assertRuntimeError(
instruction !== undefined,
`no instruction at pc ${pc} in frame ${framepointer}`
);
// $FlowIgnore
trace(`exec ${instruction.type}(${instruction.id || ""})`);
if (typeof frame.trace === "function") {
frame.trace(framepointer, pc, instruction, frame);
}
pc++;
switch (instruction.type) {
case "InternalEndAndReturn": {
if (frame.returnAddress !== -1) {
function getActiveStackFrame(): StackFrame {
assertRuntimeError(framepointer > -1, "call stack underflow");
const frame = callStack[framepointer];
assertRuntimeError(frame !== undefined, "no frame at " + framepointer);
return frame;
}
function getActiveStackFrame(): StackFrame {
assertRuntimeError(framepointer > -1, "call stack underflow");
const frame = callStack[framepointer];
assertRuntimeError(frame !== undefined, "no frame at " + framepointer);
return frame;
}
function getActiveStackFrame(): StackFrame {
assertRuntimeError(framepointer > -1, "call stack underflow");
const frame = callStack[framepointer];
assertRuntimeError(frame !== undefined, "no frame at " + framepointer);
return frame;
}
function getActiveStackFrame(): StackFrame {
assertRuntimeError(framepointer > -1, "call stack underflow");
const frame = callStack[framepointer];
assertRuntimeError(frame !== undefined, "no frame at " + framepointer);
return frame;
}
function setLocalByIndex(
frame: StackFrame,
index: number,
value: StackLocal
) {
assertRuntimeError(typeof index === "number");
frame.locals[index] = value;
}