Skip to main content

deep-dive

7 parts

01
Part 1 · · 9 min read

Decide in MIR, carry in nothing: why we deleted the MLIR backend before shipping a binary

The backend cutover for v0.5 — the borrowed-String double-free that took six revisions to kill, why each revision grew the C++ walker registry, and how I convinced myself it was safe to delete a 1,568-file MLIR subtree and lower straight from MIR to LLVM IR.

02
Part 2 · · 11 min read

Sends are method calls, crashes carry codes: the actor and supervision model

A walk down the actor stack in v0.5. Why I deleted the `<-` send operator, how a method call lowers to spawn/send/ask through an execution context, and how supervision fires `#[on(crash)]` with the real trap code.

03
Part 3 · · 10 min read

WASM parity for free, almost: four targets from one MIR and the seams that weren't free

Native and wasm32 share the same MIR and the same textual LLVM IR — they only diverge at the TargetMachine. That makes most of WASM support genuinely free. This is about the parts that weren't — traps, blocking recv, timers, and a use-after-free that only exists on WASM.

04
Part 4 · · 11 min read

State as a type: how machine declarations become tagged-union dispatch

The machine construct in detail — what the front end checks before a single instruction is emitted, how a state declaration becomes a tagged-union LLVM layout, and why I'd rather reject an illegal transition at compile time than catch it at runtime. Includes the parts that don't fully work yet.

05
Part 5 · · 11 min read

Talking between nodes: the CBOR wire envelope and a SWIM cluster that gossips

The distributed substrate for v0.5 — replacing a hand-rolled binary wire format with a CBOR envelope described by a CDDL schema, deleting 2,498 lines of wire.rs, and giving the cluster a phi-accrual failure detector that adapts instead of a fixed timeout. Plus cross-node sends that stay type-checked.

06
Part 6 · · 11 min read

No GC, no double-free: ownership, copy-on-write strings, and fail-loud traps

How Hew's memory model actually works underneath — single ownership with compiler-inserted drops, strings as copy-on-write refcounted values over a header-aware allocator, and arithmetic that traps with distinct exit codes instead of wrapping silently.

07
Part 7 · · 11 min read

Two ways to be generic: monomorphisation, and the day abstract types lowered without one

How Hew lowers generics, told as the evolution it actually was — from stamping out one mangled LLVM function per instantiation, through unifying dispatch under a single call authority, to representing an abstract type parameter directly in MIR so a generic body can lower once even when its type is never made concrete.