Untitled
unknown
javascript
a month ago
5.9 kB
2
Indexable
Never
var indentLevel = 0; function log(message) { console.log(" ".repeat(indentLevel) + message); } class VMContext { constructor(bytecode) { this.ip = 0; this.registers = new Array(32).fill(0); this.stack = []; this.frames = []; this.bytecode = bytecode; } readNextValue() { const valueType = this.bytecode[this.ip++]; if (valueType === 1) { return this.bytecode[this.ip++]; } if (valueType === 2) { return (this.bytecode[this.ip++] << 8) | this.bytecode[this.ip++]; } if (valueType === 4) { const value = this.bytecode.slice(this.ip, this.ip + 4); this.ip += 4; return (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; } if (valueType === 5) { const value = this.bytecode.slice(this.ip, this.ip + 4); this.ip += 4; const buffer = new ArrayBuffer(4); const view = new DataView(buffer); for (let i = 0; i < 4; i++) { view.setUint8(i, value[i]); } return view.getFloat32(0); } if (valueType === 3) { const length = this.bytecode[this.ip++] | (this.bytecode[this.ip++] << 8); const value = this.bytecode.slice(this.ip, this.ip + length); this.ip += length; return String.fromCharCode(...value); } throw new Error("Invalid value type"); } } const handlers = [ null, (context) => { const a = context.stack.pop(); const b = context.stack.pop(); context.stack.push(a ^ b); }, (context) => { const address = context.readNextValue(); const value = context.stack.pop(); if (value === 0) { context.ip = address; } }, (context) => { const reg = context.readNextValue(); const value = context.stack.pop(); context.registers[reg] = value; }, (context) => { context.stack.push(context.readNextValue()); }, (context) => { const a = context.stack.pop(); const b = context.stack.pop(); context.stack.push(a + b); }, (context) => { const a = context.stack.pop(); const b = context.stack.pop(); context.stack.push(b !== a ? 1 : 0); }, (context) => { const a = context.stack.pop(); const b = context.stack.pop(); context.stack.push(a & b); }, (context) => { const a = context.stack.pop(); const b = context.stack.pop(); context.stack.push(b << a); }, (context) => { indentLevel--; var ret_address = context.stack.pop(); var ret_value = context.stack.pop(); context.ip = ret_address; context.stack.push(ret_value); context.registers = context.frames.pop(); return 3; }, (context) => { const address = context.readNextValue(); context.ip = address; }, (context) => { const reg = context.readNextValue(); context.stack.push(context.registers[reg]); }, ]; /* annotations.js */ /* Experiment with distinct markers for functions, classes, and fields. */ /** * @virtualize */ function testFunction() { { const bytecode = [ 0x03, 0x01, 0x00, 0x04, 0x02, 0x05, 0x39, 0x0b, 0x01, 0x00, 0x09, ]; let vm = new VMContext(bytecode); vm.stack.push(-1); while (true) { const opcode = bytecode[vm.ip++]; if (handlers[opcode](vm) == 3) { return vm.stack.pop(); } } } } function testString() { return "Hello, World!"; } /** * @virtualize */ function testParam(a) { { const bytecode = [ 0x03, 0x01, 0x00, 0x03, 0x01, 0x01, 0x0b, 0x01, 0x01, 0x04, 0x01, 0x01, 0x05, 0x0b, 0x01, 0x00, 0x09, ]; let vm = new VMContext(bytecode); vm.stack.push(a); vm.stack.push(-1); while (true) { const opcode = bytecode[vm.ip++]; if (handlers[opcode](vm) == 3) { return vm.stack.pop(); } } } } /** * @virtualize */ function stringConcat(a, b) { { const bytecode = [ 0x03, 0x01, 0x00, 0x03, 0x01, 0x01, 0x03, 0x01, 0x02, 0x0b, 0x01, 0x01, 0x0b, 0x01, 0x02, 0x05, 0x0b, 0x01, 0x00, 0x09, ]; let vm = new VMContext(bytecode); vm.stack.push(a); vm.stack.push(b); vm.stack.push(-1); while (true) { const opcode = bytecode[vm.ip++]; if (handlers[opcode](vm) == 3) { return vm.stack.pop(); } } } } /** * @virtualize */ function bitwiseAdd(a, b) { { const bytecode = [ 0x03, 0x01, 0x00, 0x03, 0x01, 0x01, 0x03, 0x01, 0x02, 0x0b, 0x01, 0x01, 0x0b, 0x01, 0x02, 0x07, 0x03, 0x01, 0x03, 0x0b, 0x01, 0x01, 0x0b, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x0b, 0x01, 0x03, 0x04, 0x01, 0x00, 0x06, 0x02, 0x04, 0x00, 0x00, 0x00, 0x4e, 0x0b, 0x01, 0x03, 0x04, 0x01, 0x01, 0x08, 0x03, 0x01, 0x05, 0x0b, 0x01, 0x04, 0x0b, 0x01, 0x05, 0x07, 0x03, 0x01, 0x03, 0x0b, 0x01, 0x04, 0x0b, 0x01, 0x05, 0x01, 0x03, 0x01, 0x04, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x1d, 0x0b, 0x01, 0x03, 0x04, 0x01, 0x00, 0x0b, 0x01, 0x03, 0x04, 0x01, 0x01, 0x0b, 0x01, 0x04, 0x0b, 0x01, 0x05, 0x0b, 0x01, 0x04, 0x0b, 0x01, 0x05, 0x0b, 0x01, 0x04, 0x0b, 0x01, 0x00, 0x09, ]; let vm = new VMContext(bytecode); vm.stack.push(a); vm.stack.push(b); vm.stack.push(-1); while (true) { const opcode = bytecode[vm.ip++]; if (handlers[opcode](vm) == 3) { return vm.stack.pop(); } } } } var a = testFunction(); console.log(`testFunction() returned ${a}`); var b = testString(); console.log(`testString() returned ${b}`); var c = testParam(42); console.log(`testParam( 42 ) returned ${c}`); var d = stringConcat("Hello, ", "World!"); console.log(`stringConcat( "Hello, ", "World!" ) returned ${d}`); var e = bitwiseAdd(18, 2); console.log(`bitwiseAdd( 18, 2 ) returned ${e}`);
Leave a Comment