<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Pratik Devkota - interpreters</title>
    <subtitle>Pratik&#39;s stupid blog</subtitle>
    <link rel="self" type="application/atom+xml" href="https://sudw1n.gitlab.io/tags/interpreters/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://sudw1n.gitlab.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2023-11-18T00:00:00+00:00</updated>
    <id>https://sudw1n.gitlab.io/tags/interpreters/atom.xml</id>
    <entry xml:lang="en">
        <title>An interesting approach for bytecode dispatch</title>
        <published>2023-11-18T00:00:00+00:00</published>
        <updated>2023-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>Pratik Devkota</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sudw1n.gitlab.io/posts/bytecode-dispatch/"/>
        <id>https://sudw1n.gitlab.io/posts/bytecode-dispatch/</id>
        
        <content type="html" xml:base="https://sudw1n.gitlab.io/posts/bytecode-dispatch/">&lt;p&gt;Today I implemented a way to perform bytecode dispatch that I found interesting. It&#39;s supposedly
called &lt;strong&gt;direct threaded code&lt;/strong&gt; or &lt;strong&gt;threaded code interpretation&lt;/strong&gt;, but my implementation is a lot
simpler than how that sounds... What&#39;s in a name?&lt;/p&gt;
&lt;p&gt;Before I get into it, let&#39;s first have some context. Following the second part of Robert Nystrom&#39;s
&lt;a rel=&quot;external&quot; href=&quot;https://craftinginterpreters.com&quot;&gt;Crafting Interpreters&lt;/a&gt;, I have reached the part where they show
how to build &lt;a rel=&quot;external&quot; href=&quot;https://craftinginterpreters.com/a-virtual-machine.html&quot;&gt;a virtual machine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I have my implementation written in Zig, but the implementation is easily application to other
languages.&lt;/p&gt;
&lt;p&gt;There&#39;s an enum that is used to determine which instruction is currently being executed:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; Opcode&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; enum&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;u8&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;    Constant&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;    Return&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have kept it short for brevity, but assume this is all of the opcode supported by our virtual
machine. The VM is given a value containing a slice of bytes (&lt;code&gt;[]u8&lt;/code&gt;). Some of the bytes in
that slice correspond to instructions (opcode and operand) and some is just data.
Here&#39;s a rough sketch of how the VM is structured:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;    chunk&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;u8&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; chunk&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; interpret instructions from `chunk`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;VM&lt;/code&gt; just stores a slice of bytes which the &lt;code&gt;run()&lt;/code&gt; function is supposed to use. The &lt;code&gt;run()&lt;/code&gt;
function is the actual meat of our VM. It fetches, decodes and executes one bytecode at a time.&lt;/p&gt;
&lt;p&gt;Typically, we would implement the function like so:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; instruction pointer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        var&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; ip&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;ip&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;len&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;            //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; fetch a byte and convert it into an instance of `Opcode`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; opcode&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; Opcode&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; @enumFromInt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;ip&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;            switch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;opcode&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;Constant&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;                    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; possibly a large block of code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;Return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;                    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; possibly a large block of code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We use a virtual instruction pointer to keep track of where we are inside the &lt;code&gt;chunk&lt;/code&gt;. In a loop, we
fetch a byte and use &lt;code&gt;@enumFromInt&lt;/code&gt;, a built-in function provided by Zig, that converts an integer
into an enum value&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://sudw1n.gitlab.io/posts/bytecode-dispatch/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Then follows the dispatcher code. We look up which &lt;code&gt;Opcode&lt;/code&gt; variant our &lt;code&gt;opcode&lt;/code&gt; represents, and
jump to the appropriate label for handling that variant.&lt;/p&gt;
&lt;p&gt;Since every instruction is handled from that function, that makes it the most performance critical
part of our virtual machine.&lt;/p&gt;
&lt;p&gt;However, this approach has several inefficiencies. First of all, it is difficult for a processor to
predict where a jump is going to occur. The switch may translate to a jump that covers most, perhaps
even all, of the opcodes. I may have shown only two jump targets, but a real VM would need to handle
a lot more than that. There are limits to how many jump targets that the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Branch_predictor&quot;&gt;branch
predictor&lt;/a&gt; can remember. Moreover, the target
address calculation consists of instructions being executed at every iteration, which is mostly
redundant.&lt;/p&gt;
&lt;p&gt;Modern processors use instruction caches to drastically improve performance. However, the code to
handle each of the opcode variants may be arbitrarily large such that our interpreter loop may not
fit into the cache.&lt;/p&gt;
&lt;p&gt;Such inefficiencies have led programmers to find clever approaches to perform bytecode dispatch. The
direct threaded code approach involves creating a buffer holding addresses to all of the jump
targets. The buffer is populated once in advance and outside the interpreter loop.
Each of the element in the buffer is indexed by the numerical value of the opcode. Thus, the
bytecode dispatch corresponds to fetching the opcode and jumping directly to the target indexed by
the opcode.&lt;/p&gt;
&lt;p&gt;For our implementation, I have first defined various functions to handle each of the opcode variants
separately. Our VM structure may look something like:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;    chunk&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;u8&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; chunk&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; interpret instructions from `chunk`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; handle_return&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; ip&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;usize&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; code to handle Return&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; handle_constant&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; ip&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;usize&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; code to handle Constant&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we add a field to &lt;code&gt;VM&lt;/code&gt; that holds function pointers. For convenience, I have also defined a new
type: &lt;code&gt;OpcodeHandler&lt;/code&gt;, which is a constant pointer to a function that handles an opcode. Then I add
a new field to the structure for storing those &lt;code&gt;OpcodeHandler&lt;/code&gt;s.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; a function that handles a particular Opcode variant&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; OpcodeHandler&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;fn&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; ip&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;usize&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;    chunk&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;    handlers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;OpcodeHandler&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have updated the initializer slightly so that it accepts an allocator. Now in the initializer, we
call a new function &lt;code&gt;get_handlers()&lt;/code&gt; that allocates an array and populates it with the required
values. I am using a feature provided by Zig that allows us to get the number of variants contained
in an enum. We use that length to find the maximum integer value that an &lt;code&gt;Opcode&lt;/code&gt; variant might
hold. That value should be the length of our &lt;code&gt;handlers&lt;/code&gt; array. The implementation of
&lt;code&gt;get_handlers()&lt;/code&gt; should make this clearer.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; OpcodeHandler&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;fn&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; ip&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;usize&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;    chunk&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;    handlers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;OpcodeHandler&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;allocator&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; Allocator&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; chunk&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;u8&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; chunk&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;handlers&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; get_handlers&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;allocator&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; get_handlers&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;allocator&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; Allocator&lt;/span&gt;&lt;span&gt;) []&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;OpcodeHandler&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; total number of variants in Opcode&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; total&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; @typeInfo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;Opcode&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;Enum&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;fields&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;len&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        var&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; handlers&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; allocator&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;alloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;OpcodeHandler&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; total&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; @panic&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;OOM&lt;/span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; store the function pointers at the index corresponding to the opcode value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;total&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; opcode&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; Opcode&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; @enumFromInt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;            switch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;opcode&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;Return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;                    handlers&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;i&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;handle_return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;Constant&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;                    handlers&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;i&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;handle_constant&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; handlers&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; handle_return&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; ip&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;usize&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; code to handle Return&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; handle_constant&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; ip&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;usize&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;        //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; code to handle Constant&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the interpreter loop only needs to fetch an opcode and call the function at the index given by
the opcode value, instead of doing the switch.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; VM&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;VM&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        var&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; ip&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;ip&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;len&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; opcode&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; Opcode&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; @enumFromInt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;chunk&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;ip&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;            self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;handlers&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;opcode&lt;/span&gt;&lt;span&gt;](&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;ip&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And there you go, a much simpler and more efficient solution!&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;errors aren&#39;t possible and the sun rises from the west &lt;a href=&quot;https://sudw1n.gitlab.io/posts/bytecode-dispatch/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
</feed>
