Repository navigation
Support for multivalue ABI? #27418
Description
Activity
The status quo is that there is no support for the multi-value ABI in emscripten. Upstream support in llvm is still experimental. There have been plans over the years to try to move forward with it but IIUC its not currently in limbo and we are unlikely to support until it is officially blessed upstream.
There are at least tow possible ways forward here:
- Push for an official LLVM mulit-value C ABI upstream.
- Enable the JS/Wasm ABI to use mutli-value even if the default/official ABI does not. Since emscripten knows a lot about the JS/Wasm boundary this option seems reasonable, and would not require as much work upstream perhaps?
Finally, I assume by "allow substantially simpler JS FFI in certain cases" you are mostly referring to returning more than one value without using linear memory? (e.g. Result types?)
Finally, I assume by "allow substantially simpler JS FFI in certain cases" you are mostly referring to returning more than one value without using linear memory? (e.g. Result types?)
That's correct.
For more context, I and @hoodmane found this issue when working on SPy.
In SPy, each VM store its state into a wasmtime instance, and the interpreter can call into the runtime. There are quite a few cases in which we call functions which return structs by value, and with multivalue it's very easy to read them.Without multivalue, we would probably need some dance to allocate some scratch space, pass the pointer and read the result out of it, deallocate the scratch space (or maybe directly manipulate the aux/shadow stack to get the scratch space, but I'm not sure how recommented it is).
FWIW @alexcrichton is working on defining a non-experimental multivalue ABI in WebAssembly/tool-conventions#268. Consensus on a design and implementation in LLVM would be a prerequisite for Emscripten support.
There are no tests against the multivalue ABI, the sysroot does not build separately etc. Despite this, there seem to be quite few functions in libc and other system libraries whose ABI is different between multivalue and normal. Multivalue ABI can allow substantially simpler JS FFI in certain cases so it would be nice if it were a real thing with real support. Especially because it seems to work in surprisingly many cases in practice.
If it is not intended to work, it might be nice to get an actual link error rather than just doing something completely weird. Surprisingly, I have no example of a program that links and then behaves incorrectly (though I could probably get one from Claude quite easily). The closest is the example I have included below, which prints a warning at link time but actually works correctly at runtime for some reason.
Now that wasm-bindgen has migrated off of it perhaps nobody intends to support the multivalue abi in llvm but it's a bit of a shame because it seems clearly useful.
If Emscripten does want to support it, one problem seems to be that object files do not record what ABI they were linked with. We would either need to fix that or pass
-sMULTIVALUEto both compiler and linker.Example:
Version of emscripten/emsdk:
I checked that it reproduces on Emscripten 3.1.58, 5.0.3, and 6.0.3