Test on GitHub: https://github.com/wraitii/0ad/tree/WASM
This is, I stress, a proof of concept. I'm mostly uploading it so that it's out there.
Requires D3807 (Promises), an little extra (hacked in in ScriptContext), and D4575 (and a little extra). Also done on SM91 (D4428) because I could.
The idea is the following:
- WebAssembly is a low-level language that runs in a VM. It is designed to be fast, and with some further JITTING about as fast as native code.
- Many languages can be compiled to wasm. This includes C++, rust, and many others.
- Spidermonkey can run web-assembly.
This would also lead to enabling loading of other WASM modules written in other languages, if modders want to do it, which ultimately may make 0 A.D. _more_ moddable.
Ultimately, I think we might consider this approach for things that are too slow in JS, but also too annoying to move to C++. Perhaps some components, more likely for example the UnitAI FSM or the modifier multimap as first targets. If performance is indeed improved, it might be a worthwhile approach.
More generally, I think running WASM is a net positive -> it makes it easier to write for 0 A.D., and that's just good.
What is actually done here:
- Loading WebAssembly module basically just requires us to provide an OffThread promise runner (the bit added to ScriptContext). Then that basically just works™
- Running the AssemblyScript compiler is a little trickier, since it's designed to run in a browser/Node environment.
- We need to shim console.
- We need to have ES module support.
- We need to modify the files a little so that the import paths are correct.
- We need support for the module 'meta' hook, which loads import.meta (trivial, I do nothing).
- We need to ship the files. I've put them in a separate mod for convenience, ultimately I think we would want to abstract that away from the JS entirely is we were to support it.
What the example is:
- Upon arriving in the main menu, it loads an ES Module
- That ES Module loads the ASC compiler function
- Then it compiles a trivial AS module
- Then it runs it for demo.