One of my favorite techniques for implementing VMs is the "computed goto":<p><a href="https://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tables" rel="nofollow">https://eli.thegreenplace.net/2012/07/12/computed-goto-for-e...</a><p>Consider this example for dispatching instructions from the article:<p><pre><code> while (running)
{
uint16_t op = mem_read(reg[R_PC]++) >> 12;
switch (op)
{
case OP_ADD:
{ADD, 6}
break;
case OP_AND:
{AND, 7}
break;
case OP_NOT:
{NOT, 7}
break;
case OP_BR:
{BR, 7}
break;
...
}
}
</code></pre>
That code has a lot of branching. The <i>switch</i> statement has to jump to the corresponding <i>case</i>, the <i>break</i> statement branches to the bottom, and then there is third branch to get back to the top of the <i>while</i> loop. Three branches just to hit one instruction.<p>Now imagine we had written the above as:<p><pre><code> static void* dispatch_table[] = { &&OP_ADD, &&OP_AND, &&OP_NOT, &&OP_BR,
... };
#define DISPATCH() goto *dispatch_table[memory[reg[R_PC]++] >> 12]
DISPATCH();
OP_ADD:
{ADD, 6}
DISPATCH();
OP_AND:
{AND, 7}
DISPATCH();
OP_NOT:
{NOT, 7}
DISPATCH();
OP_BR:
{BR, 7}
DISPATCH();
...
</code></pre>
Now there is only one branch per instruction. The handler for each instruction directly jumps to the next location via the <i>goto</i>. There is no need to be in an explicit loop because the interpreter runs until it hits a halting instruction.<p>Many VMs now use this technique, including the canonical Ruby and Python interpreters.