@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
178 lines (148 loc) • 16.3 kB
JavaScript
import { APPEND_OPCODES } from '../opcodes';
import { $pc, $ra, $fp, $sp } from '@glimmer/vm';
import { assert } from '@glimmer/util';
export function initializeRegisters() {
return [0, -1, 0, 0];
}
export function initializeRegistersWithSP(sp) {
return [0, -1, sp, 0];
}
export function initializeRegistersWithPC(pc) {
return [pc, -1, 0, 0];
}
var LowLevelVM = /*#__PURE__*/function () {
function LowLevelVM(stack, heap, program, externs, registers) {
this.stack = stack;
this.heap = heap;
this.program = program;
this.externs = externs;
this.registers = registers;
this.currentOpSize = 0;
}
var _proto = LowLevelVM.prototype;
_proto.fetchRegister = function fetchRegister(register) {
return this.registers[register];
};
_proto.loadRegister = function loadRegister(register, value) {
this.registers[register] = value;
};
_proto.setPc = function setPc(pc) {
false && assert(typeof pc === 'number' && !isNaN(pc), 'pc is set to a number');
this.registers[$pc] = pc;
} // Start a new frame and save $ra and $fp on the stack
;
_proto.pushFrame = function pushFrame() {
this.stack.push(this.registers[$ra]);
this.stack.push(this.registers[$fp]);
this.registers[$fp] = this.registers[$sp] - 1;
} // Restore $ra, $sp and $fp
;
_proto.popFrame = function popFrame() {
this.registers[$sp] = this.registers[$fp] - 1;
this.registers[$ra] = this.stack.get(0);
this.registers[$fp] = this.stack.get(1);
};
_proto.pushSmallFrame = function pushSmallFrame() {
this.stack.push(this.registers[$ra]);
};
_proto.popSmallFrame = function popSmallFrame() {
this.registers[$ra] = this.stack.pop();
} // Jump to an address in `program`
;
_proto["goto"] = function goto(offset) {
this.setPc(this.target(offset));
};
_proto.target = function target(offset) {
return this.registers[$pc] + offset - this.currentOpSize;
} // Save $pc into $ra, then jump to a new address in `program` (jal in MIPS)
;
_proto.call = function call(handle) {
false && assert(handle < 0xffffffff, "Jumping to placeholder address");
this.registers[$ra] = this.registers[$pc];
this.setPc(this.heap.getaddr(handle));
} // Put a specific `program` address in $ra
;
_proto.returnTo = function returnTo(offset) {
this.registers[$ra] = this.target(offset);
} // Return to the `program` address stored in $ra
;
_proto["return"] = function _return() {
this.setPc(this.registers[$ra]);
};
_proto.nextStatement = function nextStatement() {
var registers = this.registers,
program = this.program;
var pc = registers[$pc];
false && assert(typeof pc === 'number', 'pc is a number');
if (pc === -1) {
return null;
} // We have to save off the current operations size so that
// when we do a jump we can calculate the correct offset
// to where we are going. We can't simply ask for the size
// in a jump because we have have already incremented the
// program counter to the next instruction prior to executing.
var opcode = program.opcode(pc);
var operationSize = this.currentOpSize = opcode.size;
this.registers[$pc] += operationSize;
return opcode;
};
_proto.evaluateOuter = function evaluateOuter(opcode, vm) {
if (false
/* LOCAL_DEBUG */
) {
var _this$externs = this.externs,
debugBefore = _this$externs.debugBefore,
debugAfter = _this$externs.debugAfter;
var state = debugBefore(opcode);
this.evaluateInner(opcode, vm);
debugAfter(state);
} else {
this.evaluateInner(opcode, vm);
}
};
_proto.evaluateInner = function evaluateInner(opcode, vm) {
if (opcode.isMachine) {
this.evaluateMachine(opcode);
} else {
this.evaluateSyscall(opcode, vm);
}
};
_proto.evaluateMachine = function evaluateMachine(opcode) {
switch (opcode.type) {
case 0
/* PushFrame */
:
return this.pushFrame();
case 1
/* PopFrame */
:
return this.popFrame();
case 3
/* InvokeStatic */
:
return this.call(opcode.op1);
case 2
/* InvokeVirtual */
:
return this.call(this.stack.pop());
case 4
/* Jump */
:
return this["goto"](opcode.op1);
case 5
/* Return */
:
return this["return"]();
case 6
/* ReturnTo */
:
return this.returnTo(opcode.op1);
}
};
_proto.evaluateSyscall = function evaluateSyscall(opcode, vm) {
APPEND_OPCODES.evaluate(vm, opcode, opcode.type);
};
return LowLevelVM;
}();
export { LowLevelVM as default };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL2xvdy1sZXZlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxTQUFBLGNBQUEsUUFBQSxZQUFBO0FBR0EsU0FBQSxHQUFBLEVBQUEsR0FBQSxFQUFBLEdBQUEsRUFBQSxHQUFBLFFBQUEsYUFBQTtBQUNBLFNBQUEsTUFBQSxRQUFBLGVBQUE7QUFTQSxPQUFNLFNBQUEsbUJBQUEsR0FBNkI7QUFDakMsU0FBTyxDQUFBLENBQUEsRUFBSSxDQUFKLENBQUEsRUFBQSxDQUFBLEVBQVAsQ0FBTyxDQUFQO0FBQ0Q7QUFFRCxPQUFNLFNBQUEseUJBQUEsQ0FBQSxFQUFBLEVBQThDO0FBQ2xELFNBQU8sQ0FBQSxDQUFBLEVBQUksQ0FBSixDQUFBLEVBQUEsRUFBQSxFQUFQLENBQU8sQ0FBUDtBQUNEO0FBRUQsT0FBTSxTQUFBLHlCQUFBLENBQUEsRUFBQSxFQUE4QztBQUNsRCxTQUFPLENBQUEsRUFBQSxFQUFLLENBQUwsQ0FBQSxFQUFBLENBQUEsRUFBUCxDQUFPLENBQVA7QUFDRDs7SUFhYSxVO0FBR1osc0JBQUEsS0FBQSxFQUFBLElBQUEsRUFBQSxPQUFBLEVBQUEsT0FBQSxFQUFBLFNBQUEsRUFLdUM7QUFKOUIsU0FBQSxLQUFBLEdBQUEsS0FBQTtBQUNBLFNBQUEsSUFBQSxHQUFBLElBQUE7QUFDQSxTQUFBLE9BQUEsR0FBQSxPQUFBO0FBQ0EsU0FBQSxPQUFBLEdBQUEsT0FBQTtBQUNFLFNBQUEsU0FBQSxHQUFBLFNBQUE7QUFQSixTQUFBLGFBQUEsR0FBQSxDQUFBO0FBUUg7Ozs7U0FFSixhLEdBQUEsdUJBQWEsUUFBYixFQUF1QztBQUNyQyxXQUFPLEtBQUEsU0FBQSxDQUFQLFFBQU8sQ0FBUDtBQUNELEc7O1NBRUQsWSxHQUFBLHNCQUFZLFFBQVosRUFBWSxLQUFaLEVBQXFEO0FBQ25ELFNBQUEsU0FBQSxDQUFBLFFBQUEsSUFBQSxLQUFBO0FBQ0QsRzs7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LEdBQU8sQ0FBUDtBQWRKO0FBZ0JELEc7O1NBRUQsZSxHQUFBLHlCQUFlLE1BQWYsRUFBZSxFQUFmLEVBQXlDO0FBQ3ZDLElBQUEsY0FBYyxDQUFkLFFBQUEsQ0FBQSxFQUFBLEVBQUEsTUFBQSxFQUFvQyxNQUFNLENBQTFDLElBQUE7QUFDRCxHOzs7OztTQTFJVyxVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgT3B0aW9uLCBSdW50aW1lSGVhcCwgTWFjaGluZU9wLCBSdW50aW1lUHJvZ3JhbSwgUnVudGltZU9wIH0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBBUFBFTkRfT1BDT0RFUyB9IGZyb20gJy4uL29wY29kZXMnO1xuaW1wb3J0IFZNIGZyb20gJy4vYXBwZW5kJztcbmltcG9ydCB7IExPQ0FMX0RFQlVHIH0gZnJvbSAnQGdsaW1tZXIvbG9jYWwtZGVidWctZmxhZ3MnO1xuaW1wb3J0IHsgTWFjaGluZVJlZ2lzdGVyLCAkcGMsICRyYSwgJGZwLCAkc3AgfSBmcm9tICdAZ2xpbW1lci92bSc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcblxuZXhwb3J0IGludGVyZmFjZSBMb3dMZXZlbFJlZ2lzdGVycyB7XG4gIFtNYWNoaW5lUmVnaXN0ZXIucGNdOiBudW1iZXI7XG4gIFtNYWNoaW5lUmVnaXN0ZXIucmFdOiBudW1iZXI7XG4gIFtNYWNoaW5lUmVnaXN0ZXIuc3BdOiBudW1iZXI7XG4gIFtNYWNoaW5lUmVnaXN0ZXIuZnBdOiBudW1iZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0aWFsaXplUmVnaXN0ZXJzKCk6IExvd0xldmVsUmVnaXN0ZXJzIHtcbiAgcmV0dXJuIFswLCAtMSwgMCwgMF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0aWFsaXplUmVnaXN0ZXJzV2l0aFNQKHNwOiBudW1iZXIpOiBMb3dMZXZlbFJlZ2lzdGVycyB7XG4gIHJldHVybiBbMCwgLTEsIHNwLCAwXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVSZWdpc3RlcnNXaXRoUEMocGM6IG51bWJlcik6IExvd0xldmVsUmVnaXN0ZXJzIHtcbiAgcmV0dXJuIFtwYywgLTEsIDAsIDBdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YWNrIHtcbiAgcHVzaCh2YWx1ZTogdW5rbm93bik6IHZvaWQ7XG4gIGdldChwb3NpdGlvbjogbnVtYmVyKTogbnVtYmVyO1xuICBwb3A8VD4oKTogVDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHRlcm5zIHtcbiAgZGVidWdCZWZvcmUob3Bjb2RlOiBSdW50aW1lT3ApOiB1bmtub3duO1xuICBkZWJ1Z0FmdGVyKHN0YXRlOiB1bmtub3duKTogdm9pZDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTG93TGV2ZWxWTSB7XG4gIHB1YmxpYyBjdXJyZW50T3BTaXplID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgc3RhY2s6IFN0YWNrLFxuICAgIHB1YmxpYyBoZWFwOiBSdW50aW1lSGVhcCxcbiAgICBwdWJsaWMgcHJvZ3JhbTogUnVudGltZVByb2dyYW0sXG4gICAgcHVibGljIGV4dGVybnM6IEV4dGVybnMsXG4gICAgcmVhZG9ubHkgcmVnaXN0ZXJzOiBMb3dMZXZlbFJlZ2lzdGVyc1xuICApIHt9XG5cbiAgZmV0Y2hSZWdpc3RlcihyZWdpc3RlcjogTWFjaGluZVJlZ2lzdGVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpc3RlcnNbcmVnaXN0ZXJdO1xuICB9XG5cbiAgbG9hZFJlZ2lzdGVyKHJlZ2lzdGVyOiBNYWNoaW5lUmVnaXN0ZXIsIHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLnJlZ2lzdGVyc1tyZWdpc3Rlcl0gPSB2YWx1ZTtcbiAgfVxuXG4gIHNldFBjKHBjOiBudW1iZXIpOiB2b2lkIHtcbiAgICBhc3NlcnQodHlwZW9mIHBjID09PSAnbnVtYmVyJyAmJiAhaXNOYU4ocGMpLCAncGMgaXMgc2V0IHRvIGEgbnVtYmVyJyk7XG4gICAgdGhpcy5yZWdpc3RlcnNbJHBjXSA9IHBjO1xuICB9XG5cbiAgLy8gU3RhcnQgYSBuZXcgZnJhbWUgYW5kIHNhdmUgJHJhIGFuZCAkZnAgb24gdGhlIHN0YWNrXG4gIHB1c2hGcmFtZSgpIHtcbiAgICB0aGlzLnN0YWNrLnB1c2godGhpcy5yZWdpc3RlcnNbJHJhXSk7XG4gICAgdGhpcy5zdGFjay5wdXNoKHRoaXMucmVnaXN0ZXJzWyRmcF0pO1xuICAgIHRoaXMucmVnaXN0ZXJzWyRmcF0gPSB0aGlzLnJlZ2lzdGVyc1skc3BdIC0gMTtcbiAgfVxuXG4gIC8vIFJlc3RvcmUgJHJhLCAkc3AgYW5kICRmcFxuICBwb3BGcmFtZSgpIHtcbiAgICB0aGlzLnJlZ2lzdGVyc1skc3BdID0gdGhpcy5yZWdpc3RlcnNbJGZwXSAtIDE7XG4gICAgdGhpcy5yZWdpc3RlcnNbJHJhXSA9IHRoaXMuc3RhY2suZ2V0KDApO1xuICAgIHRoaXMucmVnaXN0ZXJzWyRmcF0gPSB0aGlzLnN0YWNrLmdldCgxKTtcbiAgfVxuXG4gIHB1c2hTbWFsbEZyYW1lKCkge1xuICAgIHRoaXMuc3RhY2sucHVzaCh0aGlzLnJlZ2lzdGVyc1skcmFdKTtcbiAgfVxuXG4gIHBvcFNtYWxsRnJhbWUoKSB7XG4gICAgdGhpcy5yZWdpc3RlcnNbJHJhXSA9IHRoaXMuc3RhY2sucG9wKCk7XG4gIH1cblxuICAvLyBKdW1wIHRvIGFuIGFkZHJlc3MgaW4gYHByb2dyYW1gXG4gIGdvdG8ob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLnNldFBjKHRoaXMudGFyZ2V0KG9mZnNldCkpO1xuICB9XG5cbiAgdGFyZ2V0KG9mZnNldDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMucmVnaXN0ZXJzWyRwY10gKyBvZmZzZXQgLSB0aGlzLmN1cnJlbnRPcFNpemU7XG4gIH1cblxuICAvLyBTYXZlICRwYyBpbnRvICRyYSwgdGhlbiBqdW1wIHRvIGEgbmV3IGFkZHJlc3MgaW4gYHByb2dyYW1gIChqYWwgaW4gTUlQUylcbiAgY2FsbChoYW5kbGU6IG51bWJlcikge1xuICAgIGFzc2VydChoYW5kbGUgPCAweGZmZmZmZmZmLCBgSnVtcGluZyB0byBwbGFjZWhvbGRlciBhZGRyZXNzYCk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyc1skcmFdID0gdGhpcy5yZWdpc3RlcnNbJHBjXTtcbiAgICB0aGlzLnNldFBjKHRoaXMuaGVhcC5nZXRhZGRyKGhhbmRsZSkpO1xuICB9XG5cbiAgLy8gUHV0IGEgc3BlY2lmaWMgYHByb2dyYW1gIGFkZHJlc3MgaW4gJHJhXG4gIHJldHVyblRvKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy5yZWdpc3RlcnNbJHJhXSA9IHRoaXMudGFyZ2V0KG9mZnNldCk7XG4gIH1cblxuICAvLyBSZXR1cm4gdG8gdGhlIGBwcm9ncmFtYCBhZGRyZXNzIHN0b3JlZCBpbiAkcmFcbiAgcmV0dXJuKCkge1xuICAgIHRoaXMuc2V0UGModGhpcy5yZWdpc3RlcnNbJHJhXSk7XG4gIH1cblxuICBuZXh0U3RhdGVtZW50KCk6IE9wdGlvbjxSdW50aW1lT3A+IHtcbiAgICBsZXQgeyByZWdpc3RlcnMsIHByb2dyYW0gfSA9IHRoaXM7XG5cbiAgICBsZXQgcGMgPSByZWdpc3RlcnNbJHBjXTtcblxuICAgIGFzc2VydCh0eXBlb2YgcGMgPT09ICdudW1iZXInLCAncGMgaXMgYSBudW1iZXInKTtcblxuICAgIGlmIChwYyA9PT0gLTEpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIFdlIGhhdmUgdG8gc2F2ZSBvZmYgdGhlIGN1cnJlbnQgb3BlcmF0aW9ucyBzaXplIHNvIHRoYXRcbiAgICAvLyB3aGVuIHdlIGRvIGEganVtcCB3ZSBjYW4gY2FsY3VsYXRlIHRoZSBjb3JyZWN0IG9mZnNldFxuICAgIC8vIHRvIHdoZXJlIHdlIGFyZSBnb2luZy4gV2UgY2FuJ3Qgc2ltcGx5IGFzayBmb3IgdGhlIHNpemVcbiAgICAvLyBpbiBhIGp1bXAgYmVjYXVzZSB3ZSBoYXZlIGhhdmUgYWxyZWFkeSBpbmNyZW1lbnRlZCB0aGVcbiAgICAvLyBwcm9ncmFtIGNvdW50ZXIgdG8gdGhlIG5leHQgaW5zdHJ1Y3Rpb24gcHJpb3IgdG8gZXhlY3V0aW5nLlxuICAgIGxldCBvcGNvZGUgPSBwcm9ncmFtLm9wY29kZShwYyk7XG4gICAgbGV0IG9wZXJhdGlvblNpemUgPSAodGhpcy5jdXJyZW50T3BTaXplID0gb3Bjb2RlLnNpemUpO1xuICAgIHRoaXMucmVnaXN0ZXJzWyRwY10gKz0gb3BlcmF0aW9uU2l6ZTtcblxuICAgIHJldHVybiBvcGNvZGU7XG4gIH1cblxuICBldmFsdWF0ZU91dGVyKG9wY29kZTogUnVudGltZU9wLCB2bTogVk0pIHtcbiAgICBpZiAoTE9DQUxfREVCVUcpIHtcbiAgICAgIGxldCB7XG4gICAgICAgIGV4dGVybnM6IHsgZGVidWdCZWZvcmUsIGRlYnVnQWZ0ZXIgfSxcbiAgICAgIH0gPSB0aGlzO1xuICAgICAgbGV0IHN0YXRlID0gZGVidWdCZWZvcmUob3Bjb2RlKTtcbiAgICAgIHRoaXMuZXZhbHVhdGVJbm5lcihvcGNvZGUsIHZtKTtcbiAgICAgIGRlYnVnQWZ0ZXIoc3RhdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmV2YWx1YXRlSW5uZXIob3Bjb2RlLCB2bSk7XG4gICAgfVxuICB9XG5cbiAgZXZhbHVhdGVJbm5lcihvcGNvZGU6IFJ1bnRpbWVPcCwgdm06IFZNKSB7XG4gICAgaWYgKG9wY29kZS5pc01hY2hpbmUpIHtcbiAgICAgIHRoaXMuZXZhbHVhdGVNYWNoaW5lKG9wY29kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZXZhbHVhdGVTeXNjYWxsKG9wY29kZSwgdm0pO1xuICAgIH1cbiAgfVxuXG4gIGV2YWx1YXRlTWFjaGluZShvcGNvZGU6IFJ1bnRpbWVPcCkge1xuICAgIHN3aXRjaCAob3Bjb2RlLnR5cGUpIHtcbiAgICAgIGNhc2UgTWFjaGluZU9wLlB1c2hGcmFtZTpcbiAgICAgICAgcmV0dXJuIHRoaXMucHVzaEZyYW1lKCk7XG4gICAgICBjYXNlIE1hY2hpbmVPcC5Qb3BGcmFtZTpcbiAgICAgICAgcmV0dXJuIHRoaXMucG9wRnJhbWUoKTtcbiAgICAgIGNhc2UgTWFjaGluZU9wLkludm9rZVN0YXRpYzpcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FsbChvcGNvZGUub3AxKTtcbiAgICAgIGNhc2UgTWFjaGluZU9wLkludm9rZVZpcnR1YWw6XG4gICAgICAgIHJldHVybiB0aGlzLmNhbGwodGhpcy5zdGFjay5wb3AoKSk7XG4gICAgICBjYXNlIE1hY2hpbmVPcC5KdW1wOlxuICAgICAgICByZXR1cm4gdGhpcy5nb3RvKG9wY29kZS5vcDEpO1xuICAgICAgY2FzZSBNYWNoaW5lT3AuUmV0dXJuOlxuICAgICAgICByZXR1cm4gdGhpcy5yZXR1cm4oKTtcbiAgICAgIGNhc2UgTWFjaGluZU9wLlJldHVyblRvOlxuICAgICAgICByZXR1cm4gdGhpcy5yZXR1cm5UbyhvcGNvZGUub3AxKTtcbiAgICB9XG4gIH1cblxuICBldmFsdWF0ZVN5c2NhbGwob3Bjb2RlOiBSdW50aW1lT3AsIHZtOiBWTSkge1xuICAgIEFQUEVORF9PUENPREVTLmV2YWx1YXRlKHZtLCBvcGNvZGUsIG9wY29kZS50eXBlKTtcbiAgfVxufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==