It’s been a while since I’ve looked at the state of wasm in Rust, and there’s a lot more to be done for it to be really usable. Is anybody doing anything significant with Rust and emscripten yet?
Today I’ve triaged all the emscripten issues and put together a little roadmap. I’m hoping others can help fill in the gaps here and get this across the finish line.
I’ll start by outlining the near-term scope, some discussion of the state of things, then the tasks.
Goal: Make Rust on wasm + emscripten a reliable, 1st class Rust target.
Success measures:
- Cross-compilation works from macOS, Windows and Linux
- Tests are running against wasm on the bots
- All common crates without significant platform or I/O deps work as expected and pass their test suites
- One can test wasm via the ‘cross’ tool or some other tool
- The rustc and emcc LLVM versions are decoupled
- One can tweak relevant emcc options in a consistent way
- Rust on emcc is as fast as possible when building in release mode
Out of scope:
- Automatic installation of emscripten
- Retaining asm.js compatibility
Discussion
Today I read reports of problems compiling from Windows and macOS; some important crates that should obviously work just don’t, like regex; I have no idea whether the test suite still passes.
Setting up emcc is not foolproof, but I don’t think we should worry about solving it now, since no other cross target solves the problem of acquiring the linker. Perhaps something like the cross tool will suffice - it or something like it will be needed for testing emcc targets anyway.
The issue of LLVM coupling remains the worst, and with the pending llvm upgrade it’s a pressing matter. To recap, today rustc uses the emcc ‘fastcomp’ LLVM backend to communicate LLVM IR to emcc, to compile to wasm/asm.js. This forces rustc and emcc to share an LLVM fork, which is not sustainable (emcc LLVM development is basically complete - the only reason for them to upgrade LLVM is because we upgrade LLVM).
The only viable solution I see is to migrate to the upstream LLVM wasm backend, changing the rustc wasm model such that rustc produces wasm directly, and emcc links that. And this model unfortunately precludes asm.js support until somebody writes a wasm->asm.js translator. I think this is just the way it has to be. The future is wasm, and we can’t maintain LLVM in sync with emcc for long.
I don’t think though we can do the migration to the LLVM wasm backend before the next LLVM upgrade though, because that backend is not ready. So we’re probably going to be asking @azakai to upgrade emcc to LLVM 4.0 and continuing with the LLVM IR -> emcc -> wasm path for a while.
Tasks
- Upgrade LLVM to 4.0
- macOS link failures
- emscripten support broken by cargo file layout changes
- binaryen fails to validate wasm
- remove exception handling code with panic runtime
- optimize emscripten targets with emcc
- llc crashes linking regex test suite
- Get test suite working with wasm
- Set up testing bots for wasm and asm.js
- Run all crates.io tests against wasm to discover bugs
- Tool support for testing wasm targets
- Migrate wasm target to LLVM wasm backend