4 ms·
I'm trying to implement a WASM to C compiler, and because of that not-quite-so-stack behavior, I can actually guarantee that it will always build an expression
by stevefan1999 6mo ago
I'm trying to implement a WASM to C compiler, and because of that not-quite-so-stack behavior, I can actually guarantee that it will always build an expression and I don't have to discard or reset stack value! Everything stays within that function, which is very neat, and I think it is one of the reason WAT, the textual format is so neat, that you can represent it with a S-Expression.
- jedisct1 6mo agoCompiling WASM to C is a really good option: https://00f.net/2023/12/11/webassembly-compilation-to-c/ https://00f.net/2023/12/11/webassembly-compilation-to-c/
- ncruces 6mo agoShameless plug… compiling it to Go is a great option too: https://github.com/ncruces/wasm2go https://github.com/ncruces/wasm2go I've used it to translate SQLite (with a few extensions) and, that I know of, it's been used (to varying degrees of success) to translate the MARISA trie library (C++), libghostty (Zig), zlib, Perl, and QuickJS. More on-topic, I use a mix of an unevaluated expression stack and a stack-to-locals approach to translate Wasm.
- lukevp 6mo agoDoes that mean you could compile a wasm program to go, then run it with wazero? How many levels deep can it go?? Might be a fun blog topic :)
- ncruces 6mo agoNot very deep. Go generates large Wasm modules, because it bundles its goroutine scheduler, garbage collector and standard library into the module. Translating that back to Go will give you a pretty big Go file. Go is "known" for being fast to compile, but that huge Go file will take (at least?) as long to compile as compiling the Go toolchain does. wasm2go is best used on moderately sized modules (like SQLite). Last I heard, the person who tried to translate Perl got a 80MB Go file that was taking them 20min to compile. https://github.com/ncruces/wasm2go/discussions/15 https://github.com/ncruces/wasm2go/discussions/15
- nu11ptr 6mo agoInteresting. I started working on this same idea a couple of years ago as a way to bypass CGo. Eventually I moved on to something else. Glad someone else is working on this. How does the generated Go performance compare to the original WASM performance?
- ncruces 6mo agoThat's going to depend on what you mean for "original Wasm performance". What were you using to run Wasm instead of this? I can compare with wazero, which I was previously using, and say performance stayed mostly in the same ballpark. Things that crossed the Go-to-Wasm boundary very often became much faster, things that stayed mostly in Wasm became slightly slower, as the wazero compiler is pretty good. wasm2go also does not support SIMD, so if your Wasm module uses/benefits from SIMD, you'll notice.
- bsder 6mo agoBut how do you handle arguments or loop index variables? Your liveness is the entire function? You have to compile all the WASM chunks together in order to do any optimization? That seems ... problematic. Edit: Yep. In article referenced from the original: http://troubles.md/posts/wasm-is-not-a-stack-machine/ http://troubles.md/posts/wasm-is-not-a-stack-machine/ Double edit: Some of this has already been fixed in WASM: https://github.com/WebAssembly/multi-value https://github.com/WebAssembly/multi-value
- rogerbinns 6mo agoCheck out wastrel https://codeberg.org/andywingo/wastrel https://codeberg.org/andywingo/wastrel Of note WASM 3 has garbage collection (GC), multi-memory, exception handling, tail calls and more which can be challenging to implement.