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.
Table of contents
Basics of Uxn emulationThreaded code in assemblyTail calls in RustImplementation detailsCodegen notesPerformance resultsOne more thingConclusionSort: