Files
cs-252/lab17/vm.js
2026-04-22 11:03:07 -07:00

69 lines
1.6 KiB
JavaScript

'use strict';
const fs = require('fs');
const opcodes = require('./op-codes.js').opcodes;
/**
* The VM is responsible for executing the bytecode format.
*/
class VirtualMachine {
/**
* Initializes the virtual machine with the specified amount of
* gas. The stack and memory are both initially empty.
*
* @param {Number} gas - Amount of gas the VM begins with.
*/
constructor() {
this.stack = [];
this.memory = [];
}
/**
* Loads a bytecode file and returns an array of strings,
* which are the commands within the file.
*/
static loadBytecode(bytecodeFile) {
let contents = fs.readFileSync(bytecodeFile);
return Buffer.from(contents);
}
/**
* Evaluates the specified file.
*/
evaluate(bytecodeFile) {
this.bytecode = this.constructor.loadBytecode(bytecodeFile);
// Initializing the program counter to keep track of our
// place within the program.
this.pc = 0;
while (this.pc < this.bytecode.length) {
let opcode = this.bytecode.readUInt8(this.pc);
//console.log(`Evaluating ${opcode.toString(16)}`);
let operation = opcodes[opcode];
if (operation === undefined) {
throw new Error(`Unable to find instruction for ${opcode.toString(16)}`);
}
operation.evaluate(this);
this.pc++;
}
}
}
// Handling command line arguments.
if (process.argv0 === 'node') {
process.argv.shift();
}
if (process.argv.length !== 2) {
console.log("vm.js <bytecode file>");
process.exit(1);
}
let bytecodeFile = process.argv[1];
console.log(`Executing ${bytecodeFile}...`);
let vm = new VirtualMachine();
vm.evaluate(bytecodeFile);