<rss version="2.0">
  <channel>
    <title>Zero&apos;s Archive</title>
    <link>https://cmdrzero.github.io/</link>
    <description>Zero&apos;s Archive - Devlog</description>
    <generator>Zine -- https://zine-ssg.io</generator>
    <language>en-US</language>
    <lastBuildDate>Mon, 03 Aug 2026 19:06:57 +0000</lastBuildDate>
    
      
        <item>
          <title>Trying and Failing (to make a Zig to Zig transpiler)
</title>
          <description>&lt;div id=&quot;2026-09-03T13:49:00&quot;&gt;&lt;h2&gt;&lt;a class=&quot;&quot; href=&quot;#2026-09-03T13:49:00&quot;&gt;Trying and Failing (to make a Zig to Zig transpiler)&lt;/a&gt;&lt;/h2&gt;&lt;h4&gt;Tags: Ziglang, Memory Safety&lt;/h4&gt;&lt;p&gt;If you read the last post, then you would know that memory safety has been only mind. I would love to make the thing I described below work, but its driving me crazy, so I’ll just opensource the code and come back to it later. What I did was make a scuffed PEG grammar that can read Zig, then try and fail to iterate over tree and emit valid Zig code wrapping with my own safety features. I have spent many hours and the fact I keep hitting walls is annoying. A brief rant over how needlessly complex this is: &lt;code&gt;a.b()&lt;/code&gt; is ambiguous, it could be a field called b which is callable or a method on a. Arghhh, because arithmetic is defined on multi-pointers I have to wrap addition and subtraction. Plus to make locals work I need to wrap every expression result in a special object which includes a type tag.&lt;/p&gt;&lt;p&gt;Then, much to my display I have to inline some functions like the field syntax but this breaks for things like namespaces, but this corrupts the panic traces. Not to mention when I assign to a variable I shouldnt get out the inner value but store the whole object and I have to be careful to pass pointers so it doesnt just copy the inner object and lose the typeguard.&lt;/p&gt;&lt;p&gt;Idk, if this at all sounds interesting its &lt;a href=&quot;https://github.com/CMDRZero/FailedZigPtrVerif&quot;&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;</description>
          <link>https://cmdrzero.github.io/thoughts/#2026-09-03T13:49:00</link>
          <pubDate>Thu, 03 Sep 2026 13:49:00 +0000</pubDate>
          <guid>https://cmdrzero.github.io/thoughts/#2026-09-03T13:49:00</guid>
        </item>
      
        <item>
          <title>Zig Pointer Safety
</title>
          <description>&lt;div id=&quot;2026-07-30T12:51:00&quot;&gt;&lt;h2&gt;&lt;a class=&quot;&quot; href=&quot;#2026-07-30T12:51:00&quot;&gt;Zig Pointer Safety&lt;/a&gt;&lt;/h2&gt;&lt;h4&gt;Tags: Ziglang, Memory Safety&lt;/h4&gt;&lt;p&gt;Wow, a real post. Ok, I’m writing this because I want to document my thinking. I was playing around with a system inspried by Fil-C for Zig. Its not at all as close to as powerful, but I wanted to be able to get at least a small glimse of it. So I made a special allocator which returns types plus a little sha256 hash of the type string before it so that when you load a pointer we can check the hash to ensure the object is typed correctly. This actually kind of worked, like it can trap on basic illegal behavior like below:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Local&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;is_auth&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;defer&lt;/span&gt; destroy&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

ptr&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;ABCDEDFG&amp;quot;&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;is_auth&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;fromAddr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We get a runtime panic because the string loading gets angry. This is basically a pretty bad implementation of InvisiCaps. But I’ve been thinking about this becuase how do we make field pointers safe?&lt;/p&gt;&lt;p&gt;Theres a sort of catch:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;in Fil-C: pointers have bounds that ensure even accessing correct mememory from an invalid pointer is illegal.&lt;ul&gt;&lt;li&gt;Consider this cursed but legal C code: &lt;code&gt;int *y, *x = ...; _ = x[y-x]&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;With a type-ID system you either hash the type itself which breaks for slices, or you hash the child and add metadata for the pointer type which kind of works.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Ok so lets say we have a pointer inside of the struct. Without type ID’s we just inherit the bounds of the outer struct since thats here the InvisiCap is. Now we could put an TypeHash on all fields of structs which bloats the shape and means we have to rebuild all included code. This is probably fine if this is internal to the compiler but kind of difficult for me writing a psuedo transpiler. Currently I can just wrap external structs and get all but structural safety. So, We could solve this by instead attaching more InvisiCaps outside the regular one that note that this is a field and pointer to a true lowerbound.&lt;/p&gt;&lt;p&gt;When we want to load a pointer, we offset the lowerbound to get a pointer to InvisiCaps, then we check if its a field, if so we offset to the true lowerbound, then use the upperbound and validate its in range. This DOES work for structs and provides structural safety. When we wrap a struct at compile time we compute how many of these fieldCaps are needed and allocate the space, then when we get a field via method on our special pointer type we return a pointer with a special InvisiCap low bound. The advantage of this is that our data is non-invasive, its fully outside and thus we can wrap say the standard library without particular difficulty. Downside? 4 usizes per field plus the normal 3 extra usizes per stored object.&lt;/p&gt;&lt;p&gt;The invasive approach is simpler and easier, but means I have to write code to transpile every file I want to pull in which is annoying.&lt;/p&gt;&lt;h4&gt;More Issues&lt;/h4&gt;&lt;p&gt;And none of this solves the issue of Use After Free’s. As it currently stands I can mark a special bit in our InvisiCaps noting the data is free, then set the upper bound to the lowerbound. On validation we see the &lt;code&gt;freed&lt;/code&gt; bit and error, and if we try to free &lt;code&gt;freed&lt;/code&gt; memory we error with &lt;code&gt;double free&lt;/code&gt;. Ok, so whats the issue? Stack allocated objects and we cant actually use free’d memory. To my understanding, Fil-C genuinely frees the memory via finding all reachable capabilities that point to free’d memory and remapping them to a free’d object singleton and then letting the GC reclaim memory. This is clever but unacceptable for Zig since Zig rejects silent allocations.&lt;/p&gt;&lt;p&gt;So I have a half solution: Make out Lowerbound instead point to a seperate page of memory where we store the true lowerbound + upperbound + data. Since its out of bounds, we can truely free the memory and keep a dead metadata object to trap. But wait, that means while it does reclaim most of the memory, its not all? Ok, so we attach an epoch marker to the dead markers, when we want a new one for a new heap allocation we look for any dead markers and increment the epoch marker if we find one. Part of any pointer will be an expected epoch marker which means that if we access memeory right after its free we trap since it says its dead. Then if the memory gets re-used we trap on a UAF since its been reused meaning it &lt;em&gt;was&lt;/em&gt; freed.&lt;/p&gt;&lt;p&gt;Yay, problem solved? No.&lt;/p&gt;&lt;p&gt;Stack objects. We dont allow silent allocations, so how do we handle a stack allocation? We cant have metadata on the stack since it will also die when the frame is dead. I’m genuinelty stumped here, but I have a half solution.&lt;/p&gt;&lt;p&gt;Assuming we use the non-invasive field tagging system or something like it, we know all of our capabilities are out of bounds for pointers, plus theyre all in a known traversable location. So what we &lt;em&gt;might&lt;/em&gt; be able to do is on function exit, search all of our capabilities for being in the area of the free’d stack. If we find them. Add a tag that it was a pointer to free-d local memory. This can’t stop however holding onto pointers in flight after a function call. Without a far more invasive check. A smart transpiler could also check all live variables tho. Tho I’m not sure how to feel a pointer a pointer to a pointer in the caller frame with a pointer to dead stack memory. Is this too contrived? Maybe, not sure.&lt;/p&gt;&lt;p&gt;Alternatively one could just rewrite al stack allocations as special allocations from a special stack allocator but I dislike this strategy.&lt;/p&gt;&lt;p&gt;If I make any more progress or think of something new I’ll update.&lt;/p&gt;&lt;/div&gt;</description>
          <link>https://cmdrzero.github.io/thoughts/#2026-07-30T12:51:00</link>
          <pubDate>Thu, 30 Jul 2026 12:51:00 +0000</pubDate>
          <guid>https://cmdrzero.github.io/thoughts/#2026-07-30T12:51:00</guid>
        </item>
      
        <item>
          <title>Website Moment
</title>
          <description>&lt;div id=&quot;2026-07-29T16:52:00&quot;&gt;&lt;h2&gt;&lt;a class=&quot;&quot; href=&quot;#2026-07-29T16:52:00&quot;&gt;Website Moment&lt;/a&gt;&lt;/h2&gt;&lt;h4&gt;Tags: Website&lt;/h4&gt;&lt;p&gt;Why is making a website so hard? I just wanted to add tags to the devlog page so one could filter by: &lt;code&gt;LLPC&lt;/code&gt; &lt;code&gt;Zig&lt;/code&gt; &lt;code&gt;Regalia&lt;/code&gt;, etc. Alas no cigar&lt;/p&gt;&lt;/div&gt;</description>
          <link>https://cmdrzero.github.io/thoughts/#2026-07-29T16:52:00</link>
          <pubDate>Wed, 29 Jul 2026 16:52:00 +0000</pubDate>
          <guid>https://cmdrzero.github.io/thoughts/#2026-07-29T16:52:00</guid>
        </item>
      
    
  </channel>
</rss>
