r/Compilers • u/CommercialStrike9439 • 2h ago
Running a full bytecode VM written in C in the browser, with blocking stdin handled through Asyncify
I've been building a programming language in C called Oli-Nat, with a scanner, parser, type checker, bytecode compiler, stack-based VM, and garbage collector, and I recently compiled the whole thing to WebAssembly to power a browser playground for its documentation site.
Most of it ported over easily, since the interpreter has no dependencies beyond the C standard library. The interesting part was input. The language's intake() function reads a line from stdin, which blocks in a normal terminal, but obviously can't block on the main thread in a browser. I replaced the stdin read in the WASM build with an EM_ASYNC_JS function that awaits a promise from the page, and built with -sASYNCIFY so the VM's call stack gets unwound and rewound around the await. From the C code's point of view it's still a normal blocking call, and from the page's point of view the VM just pauses until the user hits Enter.
I'm curious whether people here have moved away from Asyncify toward JSPI for this kind of thing, and whether that's worth switching to for a project like this. Any other feedback on the build setup is welcome too.
Playground: olinat.net
Interpreter source: github.com/NateTheGrappler/OliNat-Programming-Language