<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Pratik Devkota</title>
    <subtitle>Pratik&#x27;s stupid blog</subtitle>
    <link rel="self" type="application/atom+xml" href="https://sudw1n.gitlab.io/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://sudw1n.gitlab.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-02-16T00:00:00+00:00</updated>
    <id>https://sudw1n.gitlab.io/atom.xml</id>
    <entry xml:lang="en">
        <title>Detecting Virtualization</title>
        <published>2025-02-16T00:00:00+00:00</published>
        <updated>2025-02-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sudw1n.gitlab.io/posts/detecting-virtualization/"/>
        <id>https://sudw1n.gitlab.io/posts/detecting-virtualization/</id>
        
        <content type="html" xml:base="https://sudw1n.gitlab.io/posts/detecting-virtualization/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;&#x2F;h2&gt;
&lt;p&gt;A few months ago, I was listening to an episode of &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@TechOverTea&quot;&gt;Tech Over
Tea&lt;&#x2F;a&gt; by &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@BrodieRobertson&quot;&gt;Brodie
Robertson&lt;&#x2F;a&gt;, featuring &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@EricParker&quot;&gt;Eric
Parker&lt;&#x2F;a&gt; as a guest. One part of their discussion that stood out to me was about the feasibility of VM escapes.&lt;&#x2F;p&gt;
&lt;p&gt;What really caught my attention was Eric&#x27;s explanation of how malware detects whether it&#x27;s running
inside a virtual machine (and basically not even bother if so). Among the various techniques he
mentioned, the most interesting one (to me) involved measuring the clock cycles required to execute
certain instructions, such as &lt;code&gt;cpuid&lt;&#x2F;code&gt;. If the execution time is significantly higher than expected
(e.g., 500), it&#x27;s a strong indicator that the code is running in a VM. You can check out that part
of the discussion &lt;a href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;9XVZdS897Uo?si=r4mRrMjz51mw_ohO&amp;amp;t=304&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Ever since, I had been meaning to try this myself but kept putting it off, until a few days ago. So
in this post, I&#x27;ll walk through the code I used to test this trick.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hardware-virtualization&quot;&gt;Hardware Virtualization&lt;&#x2F;h2&gt;
&lt;p&gt;At first, you might wonder: wouldn&#x27;t every instruction be slower in a VM since it runs on top of a
hypervisor and requires emulation? Well, not exactly. Modern processors support virtualization
extensions (e.g., Intel VT-x, AMD-V) that allow the hypervisor to run the guest OS directly on the
hardware, avoiding the need for full emulation. This enables most instructions to execute at
near-native speed.&lt;&#x2F;p&gt;
&lt;p&gt;That was my understanding too: under setups like QEMU+KVM, guest instructions should generally run
as if they were on bare metal. However, as Eric pointed out, some instructions are still emulated. I
have yet to explore all of them, but &lt;code&gt;cpuid&lt;&#x2F;code&gt; stood out as a good candidate to test.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;: how hardware virtualization works. and why &lt;code&gt;cpuid&lt;&#x2F;code&gt; is an exception.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;measuring-clock-cycles&quot;&gt;Measuring Clock Cycles&lt;&#x2F;h2&gt;
&lt;p&gt;How do we measure execution time at such a fine level? In most benchmarks, we&#x27;d use a
high-resolution timer provided by the OS. However, OS timers might not be precise enough for
measuring a single instruction&#x27;s execution. Instead, a better approach I had learned a while back is
to use the &lt;strong&gt;Time Stamp Counter (TSC)&lt;&#x2F;strong&gt; provided by the CPU.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;strong&gt;TSC&lt;&#x2F;strong&gt; is a 64-bit register that increments with each clock cycle&#x2F;tick (1 every CPU Hz)&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. On
x86_64 processors, we can read the TSC using the &lt;code&gt;rdtsc&lt;&#x2F;code&gt; instruction. Executing the instruction will
store the current value of the TSC in the &lt;code&gt;edx:eax&lt;&#x2F;code&gt; register pair (lower 32 bits in &lt;code&gt;eax&lt;&#x2F;code&gt; and upper
in &lt;code&gt;edx&lt;&#x2F;code&gt;). So to get the complete 64-bit value, we will need to combine the two registers with some
bitwise operations.&lt;&#x2F;p&gt;
&lt;p&gt;We can use Zig&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;0.13.0&#x2F;#Assembly&quot;&gt;inline assembly&lt;&#x2F;a&gt; features to
execute the &lt;code&gt;rdtsc&lt;&#x2F;code&gt; instruction, like so:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;rdtsc&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; higher and lower 32-bits
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;high&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;low&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;asm &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;volatile &lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;rdtsc&amp;quot;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; execute the instruction
&lt;&#x2F;span&gt;&lt;span&gt;        : [eax] &amp;quot;={eax}&amp;quot; (low),  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; put value of eax in `low`
&lt;&#x2F;span&gt;&lt;span&gt;          [edx] &amp;quot;={edx}&amp;quot; (high), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; put value of edx in `high`
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; combine the two values
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return @as&lt;&#x2F;span&gt;&lt;span&gt;(u64, (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;@as&lt;&#x2F;span&gt;&lt;span&gt;(u64, high) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;lt;&amp;lt; 32&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;(low));
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can now use this function to measure the time taken to execute an instruction:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; start &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;rdtsc&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; execute the instruction
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; find the delta
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; cycles_taken &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;rdtsc&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; start;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;using-cpuid&quot;&gt;Using &lt;code&gt;cpuid&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now, as for the &lt;code&gt;cpuid&lt;&#x2F;code&gt; instruction, Wikipedia has a really good article on it. But basically, its
usage depends on the value of &lt;code&gt;eax&lt;&#x2F;code&gt; before executing it. If &lt;code&gt;eax&lt;&#x2F;code&gt; is 0, it returns the &lt;strong&gt;CPU
manufacturer ID string&lt;&#x2F;strong&gt; in &lt;code&gt;ebx&lt;&#x2F;code&gt;, &lt;code&gt;edx&lt;&#x2F;code&gt; and &lt;code&gt;ecx&lt;&#x2F;code&gt; (among other things)&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. So we can use this to
identify which processor we are running on.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s see an example usage:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @import&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;std&amp;quot;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;printVendor&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;printVendor&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;ebx&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;edx&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;ecx&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;asm &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;volatile &lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; EAX=0: Manufacturer ID
&lt;&#x2F;span&gt;&lt;span&gt;        \\xorl %%eax, %%eax
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; output to EBX, EDX, ECX
&lt;&#x2F;span&gt;&lt;span&gt;        \\cpuid
&lt;&#x2F;span&gt;&lt;span&gt;        : [ebx] &amp;quot;={ebx}&amp;quot; (ebx),
&lt;&#x2F;span&gt;&lt;span&gt;          [edx] &amp;quot;={edx}&amp;quot; (edx),
&lt;&#x2F;span&gt;&lt;span&gt;          [ecx] &amp;quot;={ecx}&amp;quot; (ecx),
&lt;&#x2F;span&gt;&lt;span&gt;        :
&lt;&#x2F;span&gt;&lt;span&gt;        : &amp;quot;eax&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;vendor&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{ ebx, edx, ecx, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; vendorStr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @as&lt;&#x2F;span&gt;&lt;span&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; u8, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;@ptrCast&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;@alignCast&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;vendor)))[0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;..12&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    std.debug.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;VendorID: {s}&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a2ba43;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, .{ vendorStr});
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here&#x27;s what running this code on my machine gives:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; zig run cpuid.zig
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;VendorID:&lt;&#x2F;span&gt;&lt;span&gt; GenuineIntel
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;combining-the-two&quot;&gt;Combining the Two&lt;&#x2F;h2&gt;
&lt;p&gt;So, after combining the knowledge we have gather so far, here&#x27;s the final code for my TSC check:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @import&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;std&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;printVendor&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;printVendor&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;ebx&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;edx&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;ecx&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; start &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;rdtsc&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;asm &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;volatile &lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; EAX=0: Manufacturer ID
&lt;&#x2F;span&gt;&lt;span&gt;        \\xorl %%eax, %%eax
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; output to EBX, EDX, ECX
&lt;&#x2F;span&gt;&lt;span&gt;        \\cpuid
&lt;&#x2F;span&gt;&lt;span&gt;        : [ebx] &amp;quot;={ebx}&amp;quot; (ebx),
&lt;&#x2F;span&gt;&lt;span&gt;          [edx] &amp;quot;={edx}&amp;quot; (edx),
&lt;&#x2F;span&gt;&lt;span&gt;          [ecx] &amp;quot;={ecx}&amp;quot; (ecx),
&lt;&#x2F;span&gt;&lt;span&gt;        :
&lt;&#x2F;span&gt;&lt;span&gt;        : &amp;quot;eax&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; end &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;rdtsc&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;vendor&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{ ebx, edx, ecx, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; vendorStr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @as&lt;&#x2F;span&gt;&lt;span&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; u8, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;@ptrCast&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;@alignCast&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;vendor)))[0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;..12&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    std.debug.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;VendorID: {s}, took: {d}&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a2ba43;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, .{ vendorStr, end &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; start });
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;rdtsc&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;high&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;low&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;asm &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;volatile &lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;rdtsc&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        : [eax] &amp;quot;={eax}&amp;quot; (low),
&lt;&#x2F;span&gt;&lt;span&gt;          [edx] &amp;quot;={edx}&amp;quot; (high),
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return @as&lt;&#x2F;span&gt;&lt;span&gt;(u64, (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;@as&lt;&#x2F;span&gt;&lt;span&gt;(u64, high) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;lt;&amp;lt; 32&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;(low));
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running this on my Ubuntu VM (top) and my host machine (bottom):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;detecting-virtualization&#x2F;cpuid.png&quot; alt=&quot;cpuid&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As expected, the execution time is significantly higher in the VM compared to my bare metal host.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for reading! I hope you found this as interesting as I did. I plan to dig deeper about this
(for which I am deliberately leaving a TODO for now). So if you&#x27;re knowledgeable about this topic or
have any insights, feel free to contact me!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;&#x2F;h3&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20180916070251&#x2F;http:&#x2F;&#x2F;www.mcs.anl.gov&#x2F;~kazutomo&#x2F;rdtsc.html&quot;&gt;Time Stamp Counter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;CPUID&quot;&gt;CPUID&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Dynamic Memory Allocation: Implementation and Misuse</title>
        <published>2024-07-10T00:00:00+00:00</published>
        <updated>2024-07-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sudw1n.gitlab.io/posts/dynamic-memory-allocation/"/>
        <id>https://sudw1n.gitlab.io/posts/dynamic-memory-allocation/</id>
        
        <content type="html" xml:base="https://sudw1n.gitlab.io/posts/dynamic-memory-allocation/">&lt;p&gt;This article has been published at &lt;a href=&quot;https:&#x2F;&#x2F;themedicon.com&#x2F;engineeringthemes&quot;&gt;The Medicon Engineering
Themes&lt;&#x2F;a&gt;. Find the pdf
&lt;a href=&quot;https:&#x2F;&#x2F;themedicon.com&#x2F;pdf&#x2F;engineeringthemes&#x2F;MCET-06-204.pdf&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <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>
            
              Unknown
            
          </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&#x27;s supposedly
called &lt;strong&gt;direct threaded code&lt;&#x2F;strong&gt; or &lt;strong&gt;threaded code interpretation&lt;&#x2F;strong&gt;, but my implementation is a lot
simpler than how that sounds... What&#x27;s in a name?&lt;&#x2F;p&gt;
&lt;p&gt;Before I get into it, let&#x27;s first have some context. Following the second part of Robert Nystrom&#x27;s
&lt;a href=&quot;https:&#x2F;&#x2F;craftinginterpreters.com&quot;&gt;Crafting Interpreters&lt;&#x2F;a&gt;, I have reached the part where they show
how to build &lt;a href=&quot;https:&#x2F;&#x2F;craftinginterpreters.com&#x2F;a-virtual-machine.html&quot;&gt;a virtual machine&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I have my implementation written in Zig, but the implementation is easily application to other
languages.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s an enum that is used to determine which instruction is currently being executed:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;Opcode &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;(u8) {
&lt;&#x2F;span&gt;&lt;span&gt;    Constant,
&lt;&#x2F;span&gt;&lt;span&gt;    Return,
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;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;&#x2F;code&gt;). Some of the bytes in
that slice correspond to instructions (opcode and operand) and some is just data.
Here&#x27;s a rough sketch of how the VM is structured:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;VM &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;chunk&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;chunk&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            .chunk &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; chunk,
&lt;&#x2F;span&gt;&lt;span&gt;        };
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; interpret instructions from `chunk`
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;VM&lt;&#x2F;code&gt; just stores a slice of bytes which the &lt;code&gt;run()&lt;&#x2F;code&gt; function is supposed to use. The &lt;code&gt;run()&lt;&#x2F;code&gt;
function is the actual meat of our VM. It fetches, decodes and executes one bytecode at a time.&lt;&#x2F;p&gt;
&lt;p&gt;Typically, we would implement the function like so:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;VM &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; instruction pointer
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span&gt;(ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; self.chunk.len) {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; fetch a byte and convert it into an instance of `Opcode`
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;opcode&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Opcode &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @enumFromInt&lt;&#x2F;span&gt;&lt;span&gt;(self.chunk[ip]);
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;switch &lt;&#x2F;span&gt;&lt;span&gt;(opcode) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;                .Constant &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; possibly a large block of code
&lt;&#x2F;span&gt;&lt;span&gt;                },
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;                .Return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; possibly a large block of code
&lt;&#x2F;span&gt;&lt;span&gt;                },
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;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;&#x2F;code&gt;. In a loop, we
fetch a byte and use &lt;code&gt;@enumFromInt&lt;&#x2F;code&gt;, a built-in function provided by Zig, that converts an integer
into an enum value&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Then follows the dispatcher code. We look up which &lt;code&gt;Opcode&lt;&#x2F;code&gt; variant our &lt;code&gt;opcode&lt;&#x2F;code&gt; represents, and
jump to the appropriate label for handling that variant.&lt;&#x2F;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;&#x2F;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 href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Branch_predictor&quot;&gt;branch
predictor&lt;&#x2F;a&gt; can remember. Moreover, the target
address calculation consists of instructions being executed at every iteration, which is mostly
redundant.&lt;&#x2F;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;&#x2F;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;&#x2F;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;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;VM &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;chunk&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;chunk&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            .chunk &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; chunk,
&lt;&#x2F;span&gt;&lt;span&gt;        };
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; interpret instructions from `chunk`
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;handle_return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; code to handle Return
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;handle_constant&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; code to handle Constant
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then we add a field to &lt;code&gt;VM&lt;&#x2F;code&gt; that holds function pointers. For convenience, I have also defined a new
type: &lt;code&gt;OpcodeHandler&lt;&#x2F;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;&#x2F;code&gt;s.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;VM &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; a function that handles a particular Opcode variant
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; OpcodeHandler &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;chunk&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;handlers&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;OpcodeHandler
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;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;&#x2F;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;&#x2F;code&gt; variant might
hold. That value should be the length of our &lt;code&gt;handlers&lt;&#x2F;code&gt; array. The implementation of
&lt;code&gt;get_handlers()&lt;&#x2F;code&gt; should make this clearer.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;VM &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; OpcodeHandler &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;chunk&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;handlers&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;OpcodeHandler
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;allocator&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Allocator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;chunk&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            .chunk &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; chunk,
&lt;&#x2F;span&gt;&lt;span&gt;            .handlers &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;get_handlers&lt;&#x2F;span&gt;&lt;span&gt;(allocator),
&lt;&#x2F;span&gt;&lt;span&gt;        };
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;get_handlers&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;allocator&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Allocator&lt;&#x2F;span&gt;&lt;span&gt;) []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;OpcodeHandler &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; total number of variants in Opcode
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; total &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @typeInfo&lt;&#x2F;span&gt;&lt;span&gt;(Opcode).Enum.fields.len;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; handlers &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; allocator.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;alloc&lt;&#x2F;span&gt;&lt;span&gt;(OpcodeHandler, total) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;catch @panic&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;OOM&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; store the function pointers at the index corresponding to the opcode value
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;(0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;total) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;opcode&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Opcode &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @enumFromInt&lt;&#x2F;span&gt;&lt;span&gt;(i);
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;switch &lt;&#x2F;span&gt;&lt;span&gt;(opcode) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;                .Return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    handlers[i] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; VM.handle_return;
&lt;&#x2F;span&gt;&lt;span&gt;                },
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;                .Constant &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    handlers[i] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; VM.handle_constant;
&lt;&#x2F;span&gt;&lt;span&gt;                },
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; handlers;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;handle_return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; code to handle Return
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;handle_constant&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; code to handle Constant
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;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;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;VM &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;VM&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= 0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span&gt;(ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; self.chunk.len) {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;opcode&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Opcode &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @enumFromInt&lt;&#x2F;span&gt;&lt;span&gt;(self.chunk[ip]);
&lt;&#x2F;span&gt;&lt;span&gt;            self.handlers[opcode](self, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;ip);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And there you go, a much simpler and more efficient solution!&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;errors aren&#x27;t possible and the sun rises from the west&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Generating documentation from zig build</title>
        <published>2023-11-16T00:00:00+00:00</published>
        <updated>2023-11-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sudw1n.gitlab.io/posts/zig-build-docs/"/>
        <id>https://sudw1n.gitlab.io/posts/zig-build-docs/</id>
        
        <content type="html" xml:base="https://sudw1n.gitlab.io/posts/zig-build-docs/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;&#x2F;h2&gt;
&lt;p&gt;So a few days ago, I began following the second part of Robert Nystrom&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;craftinginterpreters.com&quot;&gt;Crafting
Interpreters&lt;&#x2F;a&gt;. The author is doing it in C, but I figured Zig
would be the better tool because I get to enjoy some modern features like the build system while
also having the low-level power of C. I took this project to also serve as a means to get more
familiar with Zig. So, I have been forcing myself to go on whatever tangent ideas that occur to me.
One of those ideas was a way to generate documentation on demand.&lt;&#x2F;p&gt;
&lt;p&gt;I had done the first part of the book in Rust, so I was very used to &lt;code&gt;cargo&lt;&#x2F;code&gt; and running &lt;code&gt;cargo doc&lt;&#x2F;code&gt;
to generate my package&#x27;s documentation. Zig has the &lt;code&gt;-femit-docs&lt;&#x2F;code&gt; flag (with &lt;code&gt;zig build-exe&lt;&#x2F;code&gt;) that
triggers generation of documentation when building an executable. However, I couldn&#x27;t find a way to
do the same with the build system. The default &lt;code&gt;build.zig&lt;&#x2F;code&gt; file created when we run &lt;code&gt;zig init-exe&lt;&#x2F;code&gt;
doesn&#x27;t enable emitting docs. The &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ziglang&#x2F;zig&#x2F;pull&#x2F;6375&quot;&gt;one place&lt;&#x2F;a&gt; where I
found a way to enable it was apparently also outdated. To clarify, what I wanted was something
similar to &lt;code&gt;cargo doc&lt;&#x2F;code&gt; where running something like &lt;code&gt;zig build docs&lt;&#x2F;code&gt; would generate the
documentation for me.&lt;&#x2F;p&gt;
&lt;p&gt;For some reason&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; I got stuck on this for days although I did stumble across some
&lt;a href=&quot;https:&#x2F;&#x2F;zig.news&#x2F;xq&#x2F;series&#x2F;2&quot;&gt;great&lt;&#x2F;a&gt; &lt;a href=&quot;https:&#x2F;&#x2F;mitchellh.com&#x2F;zig&#x2F;build-internals&quot;&gt;articles&lt;&#x2F;a&gt; along
the way, and some nice folks on IRC who helped me figure this out. All in all, I feel like I have a
better understanding of not just the build system but Zig in general because of this endeavour.&lt;&#x2F;p&gt;
&lt;p&gt;I started this blog promising myself that I&#x27;d document the things I learned. So, I figured I should
write an article about it; summarising this little rabbit hole I just came out of.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-build-binary&quot;&gt;The build binary&lt;&#x2F;h2&gt;
&lt;p&gt;Couldn&#x27;t I just pass the regular &lt;code&gt;-femit-docs&lt;&#x2F;code&gt; flag to &lt;code&gt;zig build&lt;&#x2F;code&gt;? Apparently not.&lt;&#x2F;p&gt;
&lt;p&gt;Executing &lt;code&gt;zig build&lt;&#x2F;code&gt; is actually a two-step process. First, &lt;code&gt;zig&lt;&#x2F;code&gt; builds a binary from the
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ziglang&#x2F;zig&#x2F;blob&#x2F;caae40c216000be156f87c9e27cba3d0c45bb8c7&#x2F;lib&#x2F;build_runner.zig&quot;&gt;lib&#x2F;build_runner.zig&lt;&#x2F;a&gt;
file. We can see that the file is supposed to be an executable, due to the presence of an
entrypoint (&lt;code&gt;pub fn main() !void&lt;&#x2F;code&gt;)&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Reading its contents, we can infer the arguments that the executable expects. Some of those
arguments may even seem familiar to that of &lt;code&gt;zig&lt;&#x2F;code&gt; itself, but it&#x27;s a completely different binary
with its own set of arguments.&lt;&#x2F;p&gt;
&lt;p&gt;So, this binary combined with the &lt;code&gt;build.zig&lt;&#x2F;code&gt; file that we have defined is what&#x27;s going to actually
build our project. Two steps: first the build binary, then our binary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;steps&quot;&gt;Steps&lt;&#x2F;h2&gt;
&lt;p&gt;The whole build system is modelled as a &lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;learn&#x2F;build-system&#x2F;&quot;&gt;directed acyclic
graph&lt;&#x2F;a&gt; composed of
&lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;0.11.0&#x2F;std&#x2F;#A;std:Build.Step&quot;&gt;Step&lt;&#x2F;a&gt;s. The &lt;code&gt;build&lt;&#x2F;code&gt; function in our
&lt;code&gt;build.zig&lt;&#x2F;code&gt; file is given a pointer to an instance of &lt;code&gt;std.build.Build&lt;&#x2F;code&gt;. Inside the function, we
declaratively define a set of &lt;code&gt;Step&lt;&#x2F;code&gt;s that the build binary should execute. The &lt;code&gt;build&lt;&#x2F;code&gt; function
doesn&#x27;t actually execute anything, it only defines the steps and their dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;The documentation for &lt;code&gt;Step&lt;&#x2F;code&gt; shows that every step has an &lt;code&gt;id&lt;&#x2F;code&gt; field which corresponds to the type
of the step. A &lt;em&gt;top level step&lt;&#x2F;em&gt; is one that can be invoked by a name: &lt;code&gt;zig build &amp;lt;name&amp;gt;&lt;&#x2F;code&gt;.
Remembering our goal - getting &lt;code&gt;zig build docs&lt;&#x2F;code&gt; to work - we probably should look into creating a
top level step.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-install-step&quot;&gt;The Install step&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s first look at what we have. Here&#x27;s a minimal &lt;code&gt;build.zig&lt;&#x2F;code&gt; that we&#x27;re starting with:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @import&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;std&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;std.Build&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; exe &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;addExecutable&lt;&#x2F;span&gt;&lt;span&gt;(.{
&lt;&#x2F;span&gt;&lt;span&gt;        .name &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;myprogram&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;        .root_source_file &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{ .path &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;src&#x2F;main.zig&amp;quot; },
&lt;&#x2F;span&gt;&lt;span&gt;        .target &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;standardTargetOptions&lt;&#x2F;span&gt;&lt;span&gt;(.{}),
&lt;&#x2F;span&gt;&lt;span&gt;        .optimize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;standardOptimizeOption&lt;&#x2F;span&gt;&lt;span&gt;(.{}),
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;    b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;installArtifact&lt;&#x2F;span&gt;&lt;span&gt;(exe);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running &lt;code&gt;zig build -l&lt;&#x2F;code&gt; with this file gives us the two default top-level steps: &lt;code&gt;install&lt;&#x2F;code&gt; and
&lt;code&gt;uninstall&lt;&#x2F;code&gt;. The purpose of the &lt;em&gt;Install&lt;&#x2F;em&gt; step is to copy build artifacts to a prefix path. A build
artifact is any file or directory that is created during the build process which isn&#x27;t the primary
output of the program. This includes things like object files, libraries, and executables. The
prefix path is usually just &lt;code&gt;.&#x2F;zig-out&#x2F;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Defining a step by itself doesn&#x27;t do anything. It&#x27;s the dependencies it has that specify what to
install.&lt;&#x2F;p&gt;
&lt;p&gt;In the example above, we call the &lt;code&gt;addExecutable&lt;&#x2F;code&gt; function. Here&#x27;s its function signature:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;addExecutable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Build&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;options&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;ExecutableOptions&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Step.Compile
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It returns a &lt;code&gt;Step.Compile&lt;&#x2F;code&gt; pointer. That function creates a step declaring intent for producing an
executable. That pointer (stored as the &lt;code&gt;exe&lt;&#x2F;code&gt; constant) is then passed to &lt;code&gt;installArtifact()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F;&#x2F; This creates a new step and adds it to the dependencies of the top-level install step, using all the default options.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;installArtifact&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Build&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;artifact&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Step.Compile&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It should be clear from the doc comment that the function adds a dependency to the install step.
There are functions for installing a file or a directory as well: &lt;code&gt;installFile()&lt;&#x2F;code&gt;, &lt;code&gt;installDirectory()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creating-a-step&quot;&gt;Creating a step&lt;&#x2F;h2&gt;
&lt;p&gt;If you&#x27;ve used &lt;code&gt;zig init-exe&lt;&#x2F;code&gt; before, you should find that the default &lt;code&gt;build.zig&lt;&#x2F;code&gt; file it creates
has several additional top-level steps defined. Those steps are defined with the &lt;code&gt;step()&lt;&#x2F;code&gt; function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Build&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;description&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Step
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You should be able to guess by now about how I want to relate that information to getting &lt;code&gt;zig build docs&lt;&#x2F;code&gt;. Let&#x27;s create ourselves a &lt;code&gt;docs&lt;&#x2F;code&gt; step:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;std.Build&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; docs_step &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;docs&amp;quot;, &amp;quot;Copy documentation to prefix path&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here&#x27;s what we have now:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#31333d;color:#ffffffc4;&quot;&gt;&lt;code&gt;&lt;span&gt;❯ zig build -l
&lt;&#x2F;span&gt;&lt;span&gt;  install (default)            Copy build artifacts to prefix path
&lt;&#x2F;span&gt;&lt;span&gt;  uninstall                    Remove build artifacts from prefix path
&lt;&#x2F;span&gt;&lt;span&gt;  docs                         Copy documentation to prefix path
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Again, this step by itself doesn&#x27;t do anything. So let&#x27;s dig deeper.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;triggering-documentation-generation&quot;&gt;Triggering documentation generation&lt;&#x2F;h2&gt;
&lt;p&gt;If we pass the &lt;code&gt;--verbose&lt;&#x2F;code&gt; flag to &lt;code&gt;zig build&lt;&#x2F;code&gt;, it prints us the command that the build binary is
executing:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#31333d;color:#ffffffc4;&quot;&gt;&lt;code&gt;&lt;span&gt;❯ zig build --verbose
&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;home&#x2F;dev&#x2F;bin&#x2F;zig build-exe &#x2F;home&#x2F;dev&#x2F;myprogram&#x2F;src&#x2F;main.zig
&lt;&#x2F;span&gt;&lt;span&gt;--cache-dir &#x2F;home&#x2F;dev&#x2F;myprogram&#x2F;zig-cache
&lt;&#x2F;span&gt;&lt;span&gt;--global-cache-dir &#x2F;home&#x2F;dev&#x2F;.cache&#x2F;zig
&lt;&#x2F;span&gt;&lt;span&gt;--name myprogram --listen=-
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We now need to find a way to add the &lt;code&gt;-femit-docs&lt;&#x2F;code&gt; flag to that output. Alas, as much as I&#x27;d enjoy
showing a gradual path to finding these things out, I&#x27;ll have to eventually come to reality. Like
all of what I&#x27;ve just explained, the actual path to learning these things isn&#x27;t linear at all. It
wasn&#x27;t until someone nicked &lt;code&gt;ifreund&lt;&#x2F;code&gt; on Zig&#x27;s IRC channel gave me the pointers did I figure this
out.&lt;&#x2F;p&gt;
&lt;p&gt;Our &lt;code&gt;exe&lt;&#x2F;code&gt; constant is a pointer to
&lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;std&#x2F;#A;std:Build.LibExeObjStep&quot;&gt;Step.Compile&lt;&#x2F;a&gt; which
contains a member function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#707180;&quot;&gt;&#x2F;&#x2F; Returns the path to the generated documentation directory.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;getEmittedDocs&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Compile&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;LazyPath
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;ve copied the comment from the source as-is. This is what made me stuck: I misunderstood the
comment to mean that there&#x27;s already a generated path and calling the function just returns a path
to it. However, if we look at the source:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;getEmittedDocs&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Compile&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;LazyPath &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; self.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;getEmittedFileGeneric&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;self.generated_docs);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;getEmittedFileGeneric&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Compile&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;output_file&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*?*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;GeneratedFile&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;LazyPath &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(output_file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;.*&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; .{ .generated &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; g };
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; arena &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; self.step.owner.allocator;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; generated_file &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; arena.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(GeneratedFile) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;catch @panic&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;OOM&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;    generated_file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;.* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .step &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;self.step };
&lt;&#x2F;span&gt;&lt;span&gt;    output_file&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;.* =&lt;&#x2F;span&gt;&lt;span&gt; generated_file;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; .{ .generated &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; generated_file };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, I am not comfortable in Zig enough to be certain about all of the code but here&#x27;s what I can
analyze:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;self.generated_docs&lt;&#x2F;code&gt; field, being passed to &lt;code&gt;getEmittedFileGeneric()&lt;&#x2F;code&gt;, supposedly contains the
final path to the generated documentation.&lt;&#x2F;li&gt;
&lt;li&gt;Inside &lt;code&gt;getEmittedFileGeneric()&lt;&#x2F;code&gt;, the first check ensures we don&#x27;t generate files more than once.&lt;&#x2F;li&gt;
&lt;li&gt;The rest of the body creates or obtains a
&lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;std&#x2F;#A;std:Build.GeneratedFile&quot;&gt;GeneratedFile&lt;&#x2F;a&gt; and
returns it as part of a
&lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;0.11.0&#x2F;std&#x2F;#A;std:Build.LazyPath&quot;&gt;LazyPath&lt;&#x2F;a&gt;.
All in all, we can infer that calling &lt;code&gt;exe.getEmittedDocs()&lt;&#x2F;code&gt; actually &lt;em&gt;triggers&lt;&#x2F;em&gt; the documentation
generation and gives us the path.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;installing-the-documentation&quot;&gt;Installing the documentation&lt;&#x2F;h2&gt;
&lt;p&gt;We have a path to the documentation, but it won&#x27;t be in our prefix path. As mentioned above, we need to
define directories to be installed to the &lt;code&gt;Install&lt;&#x2F;code&gt; step. Let&#x27;s update our &lt;code&gt;build.zig&lt;&#x2F;code&gt; file.&lt;&#x2F;p&gt;
&lt;p&gt;Now, there are two ways to go about doing that. The first one:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;std.Build&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;    b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;installDirectory&lt;&#x2F;span&gt;&lt;span&gt;(.{
&lt;&#x2F;span&gt;&lt;span&gt;        .source_dir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; exe.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;getEmittedDocs&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;        .install_dir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt; .prefix&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        .install_subdir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;docs&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Doing this would add a dependency to the top-level &lt;code&gt;Install&lt;&#x2F;code&gt; step so that the docs are installed
every time the &lt;code&gt;Install&lt;&#x2F;code&gt; step is performed. However, we want to generate documentation on demand.
Heck, we haven&#x27;t even used the &lt;code&gt;docs&lt;&#x2F;code&gt; step we created. So, we have to use a more flexible approach.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adding-dependency-to-the-docs-step&quot;&gt;Adding dependency to the docs step&lt;&#x2F;h2&gt;
&lt;p&gt;The build system offers this function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;addInstallDirectory&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;Build&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;options&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;InstallDirectoryOptions&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Step.InstallDir
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is similar to &lt;code&gt;installDirectory()&lt;&#x2F;code&gt; but returns us a &lt;code&gt;Step&lt;&#x2F;code&gt; rather than automatically adding the
specified directory as a dependency to the &lt;code&gt;Install&lt;&#x2F;code&gt; step. Now we can choose which &lt;code&gt;Step&lt;&#x2F;code&gt; this
&lt;code&gt;InstallDir&lt;&#x2F;code&gt; step should depend on. As you may have guessed, we&#x27;re going to make it depend on our
&lt;code&gt;docs&lt;&#x2F;code&gt; step.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;std.Build&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; install_docs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;addInstallDirectory&lt;&#x2F;span&gt;&lt;span&gt;(.{
&lt;&#x2F;span&gt;&lt;span&gt;        .source_dir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; exe.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;getEmittedDocs&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;        .install_dir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt; .prefix&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        .install_subdir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;docs&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; docs_step &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;docs&amp;quot;, &amp;quot;Copy documentation artifacts to prefix path&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;    docs_step.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;dependOn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;install_docs.step);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And there you go! Having this as our &lt;code&gt;build.zig&lt;&#x2F;code&gt; gives us the &lt;code&gt;zig build docs&lt;&#x2F;code&gt; command. If we do a
&lt;code&gt;zig build --verbose docs&lt;&#x2F;code&gt;, we should see the &lt;code&gt;-femit-docs&lt;&#x2F;code&gt; we wanted:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#31333d;color:#ffffffc4;&quot;&gt;&lt;code&gt;&lt;span&gt;❯ zig build docs --verbose
&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;home&#x2F;dev&#x2F;bin&#x2F;zig build-exe &#x2F;home&#x2F;dev&#x2F;myprogram&#x2F;src&#x2F;main.zig -femit-docs
&lt;&#x2F;span&gt;&lt;span&gt;--cache-dir &#x2F;home&#x2F;dev&#x2F;myprogram&#x2F;zig-cache
&lt;&#x2F;span&gt;&lt;span&gt;--global-cache-dir &#x2F;home&#x2F;dev&#x2F;.cache&#x2F;zig
&lt;&#x2F;span&gt;&lt;span&gt;--name myprogram --listen=-
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For convenience, here&#x27;s the final version of our &lt;code&gt;build.zig&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;zig&quot; style=&quot;background-color:#31333d;color:#ffffffc4;&quot; class=&quot;language-zig &quot;&gt;&lt;code class=&quot;language-zig&quot; data-lang=&quot;zig&quot;&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= @import&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;std&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a2ba43;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;std.Build&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3cbe3;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; exe &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;addExecutable&lt;&#x2F;span&gt;&lt;span&gt;(.{
&lt;&#x2F;span&gt;&lt;span&gt;        .name &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;myprogram&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;        .root_source_file &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{ .path &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;src&#x2F;main.zig&amp;quot; },
&lt;&#x2F;span&gt;&lt;span&gt;        .target &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;standardTargetOptions&lt;&#x2F;span&gt;&lt;span&gt;(.{}),
&lt;&#x2F;span&gt;&lt;span&gt;        .optimize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;standardOptimizeOption&lt;&#x2F;span&gt;&lt;span&gt;(.{}),
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;installArtifact&lt;&#x2F;span&gt;&lt;span&gt;(exe);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; install_docs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;addInstallDirectory&lt;&#x2F;span&gt;&lt;span&gt;(.{
&lt;&#x2F;span&gt;&lt;span&gt;        .source_dir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; exe.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;getEmittedDocs&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;        .install_dir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt; .prefix&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        .install_subdir &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;docs&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#dbbb3d;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; docs_step &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;docs&amp;quot;, &amp;quot;Copy documentation artifacts to prefix path&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;    docs_step.&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#a3cbe3;&quot;&gt;dependOn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db7c6d;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;install_docs.step);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Thanks for reading!&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;skill issue, obviously&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;you know C, right?&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
</feed>
