WASM + dash (again!)

Samuel Marks <[email protected]> Mon, 13 Apr 2026 11:44:56 +1200
Newsgroups org.kernel.vger.dash
Message-ID <CAMfPbcbH6C6vd8Cp-sWfpZL5ih_q=2pTMcDbZ9PidQFjzc+3hg@mail.gmail.com>
http://samuelmarks.github.io/dash/
https://github.com/SamuelMarks/dash/tree/wasm

**How it works:**
Running a traditional Unix shell in the browser presents a unique
challenge: the browser's JavaScript event loop is strictly
non-blocking, but tools like `dash` expect to perform synchronous,
blocking reads from `stdin` (and use `fork`/`exec` for process
management).

Instead of relying on `SharedArrayBuffer` (which has strict CORS
requirements and isn't supported everywhere), I utilized Emscripten's
`Asyncify` pass.

1. **Fully Non-blocking I/O:** When `dash` calls `read()` on file
descriptor 0 and the JS input buffer is empty, Asyncify automatically
saves the C execution stack and yields to the browser. Once the user
types a character (via an `xterm.js` frontend), the worker resumes the
exact C call stack perfectly.
2. **Web Worker Isolation:** The entire `dash` engine and its Virtual
File System (VFS) run in a background Web Worker, ensuring the main
browser UI thread never hangs, even during infinite loops.
3. **No `fork()`:** Since WASM can't truly `fork`, the codebase
leverages a patched `vforkexec` to intercept process creation. It
currently executes built-ins directly and passes external command
requests (like `ls`, `cat`, `grep`) out to JavaScript to execute
against the Emscripten VFS.
4. **Canonical Line Editing:** Basic terminal interactions=E2=80=94like
`Backspace`, `Ctrl+W` (Erase Word), and `Ctrl+U` (Clear Line)=E2=80=94are
handled locally in the frontend buffer before being flushed to the
WASM shell on `Enter`.

The port successfully passes a headless Node.js adaptation of the
`dash` test suite.

I'd love to hear any thoughts, feedback, or ideas from the community!

PS: My next steps are to bring along `curl` and `jq` for my headless
compiler efforts; for both my OpenAPI =E2=9F=B7 /bin/sh and my new multiclo=
ud
devops system; but that's for another post!

Best,

Samuel Marks
https://github.com/SamuelMarks
https://linkedin.com/in/samuelmarks