A developer implements a tail-call interpreter for the Uxn CPU emulator using Rust's nightly `become` keyword, which guarantees tail-call optimization. The approach stores VM state in function arguments (mapped to registers via calling convention) and ends each opcode handler with a tail call to the next. On ARM64, the tail-call interpreter outperforms both the original Rust VM and hand-written ARM64 assembly. On x86-64, it beats the VM but loses to hand-written assembly due to suboptimal codegen (register spills). WebAssembly performance is significantly worse than the simple VM. The implementation remains 100% safe Rust despite the low-level nature of the technique.

15m read timeFrom mattkeeter.com
Post cover image
Table of contents
Basics of Uxn emulationThreaded code in assemblyTail calls in RustImplementation detailsCodegen notesPerformance resultsOne more thingConclusion

Sort: