UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

193 lines (156 loc) 16.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.initializeRegisters = initializeRegisters; exports.initializeRegistersWithSP = initializeRegistersWithSP; exports.initializeRegistersWithPC = initializeRegistersWithPC; exports.default = void 0; var _opcodes = require("../opcodes"); var _vm = require("@glimmer/vm"); var _util = require("@glimmer/util"); function initializeRegisters() { return [0, -1, 0, 0]; } function initializeRegistersWithSP(sp) { return [0, -1, sp, 0]; } 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 && (0, _util.assert)(typeof pc === 'number' && !isNaN(pc), 'pc is set to a number'); this.registers[_vm.$pc] = pc; } // Start a new frame and save $ra and $fp on the stack ; _proto.pushFrame = function pushFrame() { this.stack.push(this.registers[_vm.$ra]); this.stack.push(this.registers[_vm.$fp]); this.registers[_vm.$fp] = this.registers[_vm.$sp] - 1; } // Restore $ra, $sp and $fp ; _proto.popFrame = function popFrame() { this.registers[_vm.$sp] = this.registers[_vm.$fp] - 1; this.registers[_vm.$ra] = this.stack.get(0); this.registers[_vm.$fp] = this.stack.get(1); }; _proto.pushSmallFrame = function pushSmallFrame() { this.stack.push(this.registers[_vm.$ra]); }; _proto.popSmallFrame = function popSmallFrame() { this.registers[_vm.$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[_vm.$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 && (0, _util.assert)(handle < 0xffffffff, "Jumping to placeholder address"); this.registers[_vm.$ra] = this.registers[_vm.$pc]; this.setPc(this.heap.getaddr(handle)); } // Put a specific `program` address in $ra ; _proto.returnTo = function returnTo(offset) { this.registers[_vm.$ra] = this.target(offset); } // Return to the `program` address stored in $ra ; _proto["return"] = function _return() { this.setPc(this.registers[_vm.$ra]); }; _proto.nextStatement = function nextStatement() { var registers = this.registers, program = this.program; var pc = registers[_vm.$pc]; false && (0, _util.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[_vm.$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) { _opcodes.APPEND_OPCODES.evaluate(vm, opcode, opcode.type); }; return LowLevelVM; }(); exports.default = LowLevelVM; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL2xvdy1sZXZlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQ0E7O0FBR0E7O0FBQ0E7O0FBU00sU0FBQSxtQkFBQSxHQUE2QjtBQUNqQyxTQUFPLENBQUEsQ0FBQSxFQUFJLENBQUosQ0FBQSxFQUFBLENBQUEsRUFBUCxDQUFPLENBQVA7QUFDRDs7QUFFSyxTQUFBLHlCQUFBLENBQUEsRUFBQSxFQUE4QztBQUNsRCxTQUFPLENBQUEsQ0FBQSxFQUFJLENBQUosQ0FBQSxFQUFBLEVBQUEsRUFBUCxDQUFPLENBQVA7QUFDRDs7QUFFSyxTQUFBLHlCQUFBLENBQUEsRUFBQSxFQUE4QztBQUNsRCxTQUFPLENBQUEsRUFBQSxFQUFLLENBQUwsQ0FBQSxFQUFBLENBQUEsRUFBUCxDQUFPLENBQVA7QUFDRDs7SUFhYSxVO0FBR1osV0FBQSxVQUFBLENBQUEsS0FBQSxFQUFBLElBQUEsRUFBQSxPQUFBLEVBQUEsT0FBQSxFQUFBLFNBQUEsRUFLdUM7QUFKOUIsU0FBQSxLQUFBLEdBQUEsS0FBQTtBQUNBLFNBQUEsSUFBQSxHQUFBLElBQUE7QUFDQSxTQUFBLE9BQUEsR0FBQSxPQUFBO0FBQ0EsU0FBQSxPQUFBLEdBQUEsT0FBQTtBQUNFLFNBQUEsU0FBQSxHQUFBLFNBQUE7QUFQSixTQUFBLGFBQUEsR0FBQSxDQUFBO0FBUUg7Ozs7U0FFSixhLEdBQUEsU0FBQSxhQUFBLENBQUEsUUFBQSxFQUF1QztBQUNyQyxXQUFPLEtBQUEsU0FBQSxDQUFQLFFBQU8sQ0FBUDs7O1NBR0YsWSxHQUFBLFNBQUEsWUFBQSxDQUFBLFFBQUEsRUFBQSxLQUFBLEVBQXFEO0FBQ25ELFNBQUEsU0FBQSxDQUFBLFFBQUEsSUFBQSxLQUFBOzs7U0FHRixLLEdBQUEsU0FBQSxLQUFBLENBQUEsRUFBQSxFQUFnQjtBQUFBLGFBQ2Qsa0JBQU8sT0FBQSxFQUFBLEtBQUEsUUFBQSxJ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QkYsZSxHQUFBLFNBQUEsZUFBQSxDQUFBLE1BQUEsRUFBQSxFQUFBLEVBQXlDO0FBQ3ZDLDRCQUFBLFFBQUEsQ0FBQSxFQUFBLEVBQUEsTUFBQSxFQUFvQyxNQUFNLENBQTFDLElBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPcHRpb24sIFJ1bnRpbWVIZWFwLCBNYWNoaW5lT3AsIFJ1bnRpbWVQcm9ncmFtLCBSdW50aW1lT3AgfSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEFQUEVORF9PUENPREVTIH0gZnJvbSAnLi4vb3Bjb2Rlcyc7XG5pbXBvcnQgVk0gZnJvbSAnLi9hcHBlbmQnO1xuaW1wb3J0IHsgTE9DQUxfREVCVUcgfSBmcm9tICdAZ2xpbW1lci9sb2NhbC1kZWJ1Zy1mbGFncyc7XG5pbXBvcnQgeyBNYWNoaW5lUmVnaXN0ZXIsICRwYywgJHJhLCAkZnAsICRzcCB9IGZyb20gJ0BnbGltbWVyL3ZtJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIExvd0xldmVsUmVnaXN0ZXJzIHtcbiAgW01hY2hpbmVSZWdpc3Rlci5wY106IG51bWJlcjtcbiAgW01hY2hpbmVSZWdpc3Rlci5yYV06IG51bWJlcjtcbiAgW01hY2hpbmVSZWdpc3Rlci5zcF06IG51bWJlcjtcbiAgW01hY2hpbmVSZWdpc3Rlci5mcF06IG51bWJlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVSZWdpc3RlcnMoKTogTG93TGV2ZWxSZWdpc3RlcnMge1xuICByZXR1cm4gWzAsIC0xLCAwLCAwXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVSZWdpc3RlcnNXaXRoU1Aoc3A6IG51bWJlcik6IExvd0xldmVsUmVnaXN0ZXJzIHtcbiAgcmV0dXJuIFswLCAtMSwgc3AsIDBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5pdGlhbGl6ZVJlZ2lzdGVyc1dpdGhQQyhwYzogbnVtYmVyKTogTG93TGV2ZWxSZWdpc3RlcnMge1xuICByZXR1cm4gW3BjLCAtMSwgMCwgMF07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhY2sge1xuICBwdXNoKHZhbHVlOiB1bmtub3duKTogdm9pZDtcbiAgZ2V0KHBvc2l0aW9uOiBudW1iZXIpOiBudW1iZXI7XG4gIHBvcDxUPigpOiBUO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVybnMge1xuICBkZWJ1Z0JlZm9yZShvcGNvZGU6IFJ1bnRpbWVPcCk6IHVua25vd247XG4gIGRlYnVnQWZ0ZXIoc3RhdGU6IHVua25vd24pOiB2b2lkO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMb3dMZXZlbFZNIHtcbiAgcHVibGljIGN1cnJlbnRPcFNpemUgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBzdGFjazogU3RhY2ssXG4gICAgcHVibGljIGhlYXA6IFJ1bnRpbWVIZWFwLFxuICAgIHB1YmxpYyBwcm9ncmFtOiBSdW50aW1lUHJvZ3JhbSxcbiAgICBwdWJsaWMgZXh0ZXJuczogRXh0ZXJucyxcbiAgICByZWFkb25seSByZWdpc3RlcnM6IExvd0xldmVsUmVnaXN0ZXJzXG4gICkge31cblxuICBmZXRjaFJlZ2lzdGVyKHJlZ2lzdGVyOiBNYWNoaW5lUmVnaXN0ZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnJlZ2lzdGVyc1tyZWdpc3Rlcl07XG4gIH1cblxuICBsb2FkUmVnaXN0ZXIocmVnaXN0ZXI6IE1hY2hpbmVSZWdpc3RlciwgdmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMucmVnaXN0ZXJzW3JlZ2lzdGVyXSA9IHZhbHVlO1xuICB9XG5cbiAgc2V0UGMocGM6IG51bWJlcik6IHZvaWQge1xuICAgIGFzc2VydCh0eXBlb2YgcGMgPT09ICdudW1iZXInICYmICFpc05hTihwYyksICdwYyBpcyBzZXQgdG8gYSBudW1iZXInKTtcbiAgICB0aGlzLnJlZ2lzdGVyc1skcGNdID0gcGM7XG4gIH1cblxuICAvLyBTdGFydCBhIG5ldyBmcmFtZSBhbmQgc2F2ZSAkcmEgYW5kICRmcCBvbiB0aGUgc3RhY2tcbiAgcHVzaEZyYW1lKCkge1xuICAgIHRoaXMuc3RhY2sucHVzaCh0aGlzLnJlZ2lzdGVyc1skcmFdKTtcbiAgICB0aGlzLnN0YWNrLnB1c2godGhpcy5yZWdpc3RlcnNbJGZwXSk7XG4gICAgdGhpcy5yZWdpc3RlcnNbJGZwXSA9IHRoaXMucmVnaXN0ZXJzWyRzcF0gLSAxO1xuICB9XG5cbiAgLy8gUmVzdG9yZSAkcmEsICRzcCBhbmQgJGZwXG4gIHBvcEZyYW1lKCkge1xuICAgIHRoaXMucmVnaXN0ZXJzWyRzcF0gPSB0aGlzLnJlZ2lzdGVyc1skZnBdIC0gMTtcbiAgICB0aGlzLnJlZ2lzdGVyc1skcmFdID0gdGhpcy5zdGFjay5nZXQoMCk7XG4gICAgdGhpcy5yZWdpc3RlcnNbJGZwXSA9IHRoaXMuc3RhY2suZ2V0KDEpO1xuICB9XG5cbiAgcHVzaFNtYWxsRnJhbWUoKSB7XG4gICAgdGhpcy5zdGFjay5wdXNoKHRoaXMucmVnaXN0ZXJzWyRyYV0pO1xuICB9XG5cbiAgcG9wU21hbGxGcmFtZSgpIHtcbiAgICB0aGlzLnJlZ2lzdGVyc1skcmFdID0gdGhpcy5zdGFjay5wb3AoKTtcbiAgfVxuXG4gIC8vIEp1bXAgdG8gYW4gYWRkcmVzcyBpbiBgcHJvZ3JhbWBcbiAgZ290byhvZmZzZXQ6IG51bWJlcikge1xuICAgIHRoaXMuc2V0UGModGhpcy50YXJnZXQob2Zmc2V0KSk7XG4gIH1cblxuICB0YXJnZXQob2Zmc2V0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpc3RlcnNbJHBjXSArIG9mZnNldCAtIHRoaXMuY3VycmVudE9wU2l6ZTtcbiAgfVxuXG4gIC8vIFNhdmUgJHBjIGludG8gJHJhLCB0aGVuIGp1bXAgdG8gYSBuZXcgYWRkcmVzcyBpbiBgcHJvZ3JhbWAgKGphbCBpbiBNSVBTKVxuICBjYWxsKGhhbmRsZTogbnVtYmVyKSB7XG4gICAgYXNzZXJ0KGhhbmRsZSA8IDB4ZmZmZmZmZmYsIGBKdW1waW5nIHRvIHBsYWNlaG9sZGVyIGFkZHJlc3NgKTtcblxuICAgIHRoaXMucmVnaXN0ZXJzWyRyYV0gPSB0aGlzLnJlZ2lzdGVyc1skcGNdO1xuICAgIHRoaXMuc2V0UGModGhpcy5oZWFwLmdldGFkZHIoaGFuZGxlKSk7XG4gIH1cblxuICAvLyBQdXQgYSBzcGVjaWZpYyBgcHJvZ3JhbWAgYWRkcmVzcyBpbiAkcmFcbiAgcmV0dXJuVG8ob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLnJlZ2lzdGVyc1skcmFdID0gdGhpcy50YXJnZXQob2Zmc2V0KTtcbiAgfVxuXG4gIC8vIFJldHVybiB0byB0aGUgYHByb2dyYW1gIGFkZHJlc3Mgc3RvcmVkIGluICRyYVxuICByZXR1cm4oKSB7XG4gICAgdGhpcy5zZXRQYyh0aGlzLnJlZ2lzdGVyc1skcmFdKTtcbiAgfVxuXG4gIG5leHRTdGF0ZW1lbnQoKTogT3B0aW9uPFJ1bnRpbWVPcD4ge1xuICAgIGxldCB7IHJlZ2lzdGVycywgcHJvZ3JhbSB9ID0gdGhpcztcblxuICAgIGxldCBwYyA9IHJlZ2lzdGVyc1skcGNdO1xuXG4gICAgYXNzZXJ0KHR5cGVvZiBwYyA9PT0gJ251bWJlcicsICdwYyBpcyBhIG51bWJlcicpO1xuXG4gICAgaWYgKHBjID09PSAtMSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gV2UgaGF2ZSB0byBzYXZlIG9mZiB0aGUgY3VycmVudCBvcGVyYXRpb25zIHNpemUgc28gdGhhdFxuICAgIC8vIHdoZW4gd2UgZG8gYSBqdW1wIHdlIGNhbiBjYWxjdWxhdGUgdGhlIGNvcnJlY3Qgb2Zmc2V0XG4gICAgLy8gdG8gd2hlcmUgd2UgYXJlIGdvaW5nLiBXZSBjYW4ndCBzaW1wbHkgYXNrIGZvciB0aGUgc2l6ZVxuICAgIC8vIGluIGEganVtcCBiZWNhdXNlIHdlIGhhdmUgaGF2ZSBhbHJlYWR5IGluY3JlbWVudGVkIHRoZVxuICAgIC8vIHByb2dyYW0gY291bnRlciB0byB0aGUgbmV4dCBpbnN0cnVjdGlvbiBwcmlvciB0byBleGVjdXRpbmcuXG4gICAgbGV0IG9wY29kZSA9IHByb2dyYW0ub3Bjb2RlKHBjKTtcbiAgICBsZXQgb3BlcmF0aW9uU2l6ZSA9ICh0aGlzLmN1cnJlbnRPcFNpemUgPSBvcGNvZGUuc2l6ZSk7XG4gICAgdGhpcy5yZWdpc3RlcnNbJHBjXSArPSBvcGVyYXRpb25TaXplO1xuXG4gICAgcmV0dXJuIG9wY29kZTtcbiAgfVxuXG4gIGV2YWx1YXRlT3V0ZXIob3Bjb2RlOiBSdW50aW1lT3AsIHZtOiBWTSkge1xuICAgIGlmIChMT0NBTF9ERUJVRykge1xuICAgICAgbGV0IHtcbiAgICAgICAgZXh0ZXJuczogeyBkZWJ1Z0JlZm9yZSwgZGVidWdBZnRlciB9LFxuICAgICAgfSA9IHRoaXM7XG4gICAgICBsZXQgc3RhdGUgPSBkZWJ1Z0JlZm9yZShvcGNvZGUpO1xuICAgICAgdGhpcy5ldmFsdWF0ZUlubmVyKG9wY29kZSwgdm0pO1xuICAgICAgZGVidWdBZnRlcihzdGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZXZhbHVhdGVJbm5lcihvcGNvZGUsIHZtKTtcbiAgICB9XG4gIH1cblxuICBldmFsdWF0ZUlubmVyKG9wY29kZTogUnVudGltZU9wLCB2bTogVk0pIHtcbiAgICBpZiAob3Bjb2RlLmlzTWFjaGluZSkge1xuICAgICAgdGhpcy5ldmFsdWF0ZU1hY2hpbmUob3Bjb2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ldmFsdWF0ZVN5c2NhbGwob3Bjb2RlLCB2bSk7XG4gICAgfVxuICB9XG5cbiAgZXZhbHVhdGVNYWNoaW5lKG9wY29kZTogUnVudGltZU9wKSB7XG4gICAgc3dpdGNoIChvcGNvZGUudHlwZSkge1xuICAgICAgY2FzZSBNYWNoaW5lT3AuUHVzaEZyYW1lOlxuICAgICAgICByZXR1cm4gdGhpcy5wdXNoRnJhbWUoKTtcbiAgICAgIGNhc2UgTWFjaGluZU9wLlBvcEZyYW1lOlxuICAgICAgICByZXR1cm4gdGhpcy5wb3BGcmFtZSgpO1xuICAgICAgY2FzZSBNYWNoaW5lT3AuSW52b2tlU3RhdGljOlxuICAgICAgICByZXR1cm4gdGhpcy5jYWxsKG9wY29kZS5vcDEpO1xuICAgICAgY2FzZSBNYWNoaW5lT3AuSW52b2tlVmlydHVhbDpcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FsbCh0aGlzLnN0YWNrLnBvcCgpKTtcbiAgICAgIGNhc2UgTWFjaGluZU9wLkp1bXA6XG4gICAgICAgIHJldHVybiB0aGlzLmdvdG8ob3Bjb2RlLm9wMSk7XG4gICAgICBjYXNlIE1hY2hpbmVPcC5SZXR1cm46XG4gICAgICAgIHJldHVybiB0aGlzLnJldHVybigpO1xuICAgICAgY2FzZSBNYWNoaW5lT3AuUmV0dXJuVG86XG4gICAgICAgIHJldHVybiB0aGlzLnJldHVyblRvKG9wY29kZS5vcDEpO1xuICAgIH1cbiAgfVxuXG4gIGV2YWx1YXRlU3lzY2FsbChvcGNvZGU6IFJ1bnRpbWVPcCwgdm06IFZNKSB7XG4gICAgQVBQRU5EX09QQ09ERVMuZXZhbHVhdGUodm0sIG9wY29kZSwgb3Bjb2RlLnR5cGUpO1xuICB9XG59XG4iXSwic291cmNlUm9vdCI6IiJ9