Flycast WASM JIT v1 released (Dreamcast emulator in browser) with technical write-up
Write-up From r/emulation : Six months ago I got upstream Flycast compiling to WebAssembly and running as a libretro core. It booted games at about 2 FPS on the interpreter. Fun proof of concept, completely unplayable. Today, heavy 3D titles like Jet Grind Radio and Shenmue hold their target framerate at native resolution with clean audio, in a browser tab, on ordinary hardware. Here's how that gap closed. Why this wasn't supposed to work Every Dreamcast emulator that runs at full speed depends on a dynamic recompiler. A dynarec generates native code at runtime and jumps into it. WebAssembly makes that structurally impossible: code and data live in separate address spaces, so there's no writable-executable memory to generate into, and nothing you write into linear memory can ever be executed. Upstream had already declined WASM support, and the consensus was that this was a dead end. Browser Dreamcast would stay a slideshow. Fuck that. The workaround The JIT doesn't patch memory. It generates entire WebAssembly modules at runtime. SH4 code is decoded into Flycast's SHIL IR, lowered to wasm bytecode in the browser, compiled and instantiated through the wasm API, and dispatched via call_indirect from a C dispatch loop. The host boundary gets crossed once per module, at compile time. Steady-state execution is wasm calling wasm, with no JavaScript anywhere on the dispatch path. Getting from "it works" to "it's fast" Months of walls, and slightly less hair. Every one of these is documented with numbers in the writeup: Self-modifying code detection via per-page generation counters, eliminating 98% of runtime block hashing Fusing hot blocks into multi-block modules Inline fast paths for guest memory access. This was the big wall. Memory ops were crossing the wasm to JS import boundary about 500,000 times per frame. It's now about 700. A frame pacer that repays guest time instead of counting renders Compile storm management so scene transitions don't freeze An AudioWorklet r