Untitled

 avatar
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