I'm trying to port the little language interpreter I've been working on to run within a browser. So far I've got most of it working: I can cross-compile the code to WASM, I've added an xterm.js widget to a webpage, and I'm handling onKey events on the xterm.js widget to buffer enough data to feed a line of input to the interpreter via its REPL. All of this logic is in Rust, not JS.
But things get tricky when the interpreter itself wants to stop and ask for further user input: e.g. "read a line from stdin". In my mind, this "stop and wait for input" means blocking... but it seems that Rust's WASM doesn't like that. I'm blocking with a
Condvar to synchronize with the fetching of a line from the onKey events... and it complains with
can't block with web assembly.
I've been trying a few things and it seems that there is experimental support for a
Condvar based on WASM atomics... but that seems to require the nightly toolchain, rebuilding the world with an
atomics feature, seemingly enabling shared memory in Firefox... and I haven't gotten it to work yet.
So. I cannot believe this has to be that complicated, and therefore I'm assuming my mental model on this whole thing is wrong given that I have done little JS before.
How would you go about this? In particular, how would you implement the line entering part based on asynchronous events from JS in a way that can be consumed whenever the program needs a line, blocking until such line is ready?
Maybe the answer is... forget about WASM to workaround the threading/blocking limitations, and implement this part of the logic on the JS side, using
await in the Rust code to fetch the line from a JS
I fear my explanation above is too confusing... so please let me know if you'd need any extra details to better understand what I'm doing...
Thanks a lot!