Untitled
unknown
javascript
2 years ago
2.4 kB
30
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