Untitled
unknown
javascript
a year ago
2.4 kB
12
Indexable
class VMContext { constructor( bytecode ) { this.ip = 0; this.registers = new Array( 32 ).fill( 0 ); this.stack = []; this.bytecode = bytecode; } readNextValue( ) { const value = this.bytecode.slice( this.ip, this.ip + 4 ); this.ip += 4; return value[3] | (value[2] << 8) | (value[1] << 16) | (value[0] << 24); } } const handlers = [ ( context ) => { const a = context.stack.pop(); const b = context.stack.pop(); context.stack.push( b - a ); }, ( context ) => { context.stack.push( context.readNextValue() ); }, ( context ) => { const reg = context.readNextValue(); context.stack.push( context.registers[ reg ] ); }, null, ( context ) => { const a = context.stack.pop(); const b = context.stack.pop(); context.stack.push( b > a ? 1 : 0 ); }, ( context ) => { const reg = context.readNextValue(); const value = context.stack.pop(); context.registers[ reg ] = value; }, ( 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; } }, ]; const bytecode = [1,0,0,0,18,1,0,0,0,2,6,5,0,0,0,0,2,0,0,0,0,1,0,0,0,18,0,5,0,0,0,1,2,0,0,0,0,2,0,0,0,1,4,7,0,0,0,58,1,0,0,0,23,5,0,0,0,2,2,0,0,0,1]; function runVM( bytecode ) { const context = new VMContext( bytecode ); while( context.ip < bytecode.length ) { const opcode = bytecode[ context.ip++ ]; const handler = handlers[ opcode ]; if( handler === undefined ) { throw new Error( `Invalid opcode: ${opcode}` ); } handler( context ); } return context.stack.pop(); } runVM( bytecode );
Editor is loading...
Leave a Comment