We’ve gotten libjxl built for wasm. It was a struggle, but we got it done, and we’re ready to run it. WASM is a straightforward standard designed for ease of implementation, so this should be a walk in the park.
wazero
Let’s start with wazero: the zero dependency WebAssembly runtime for Go developers. “Import wazero and extend your Go application with code written in any language!”
The initial download, install, whatever you call it goes smoothly enough. Start with one of their tiny examples, verify it works, then switch out the wasm file.
import[17] memory[a.a]: invalid byte for limits: 0x3 != 0x00 or 0x01
I don’t know what this means. Searching for “invalid byte” finds one line.
err = fmt.Errorf("%w: invalid byte for importdesc: %#x", ErrInvalidByte, b)
Except that’s not an exact match. The real error line is cleverly obfuscated and required searching for “for limits”. There’s a comment.
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#limits%E2%91%A6
Sure enough, the standard says there is a flag of 0 or 1. Not 3. Or 0x3. Or 0x03.
wasmer
Let’s try wasmer-go, a complete and mature WebAssembly runtime for Go based on Wasmer.
We have a new error!
Validation error: threads must be enabled for shared memories (at offset 513)
Let’s browse the detailed API documentation full of examples. Well, I can’t see any means to enable threads. The word thread doesn’t even appear on the page.
I feel like I’ve just been told to draw the rest of the owl.
wasmtime
We’ve got one more wish, wasmtime-go. This Go library uses CGO to consume the C API of the Wasmtime project which is written in Rust. No bragging about completeness. Good or bad sign?
The first sign of danger appears before we even run our code. Upon linking, we get this warning.
/usr/bin/ld: warning: x86_64.o: missing .note.GNU-stack section implies executable stack
Good grief, what demons is wasmtime summoning that it needs an executable stack in 2023? I guess it’s good that people only ever use wasmtime in their programs, and never mix in any other unsafe code.
A new error emerges when we run this demon spawn.
Invalid input WebAssembly code at offset 513: threads must be enabled for shared memories
But wasmtime has the long sought answer!
config.SetWasmThreads(true)
And now we’re getting closer to running our wasm library. It’s parsed and processed and locked and loaded. But not actually runnable.
expected 18 imports, found 0
Fair enough, I need to provide a little runtime support. I think it would have saved some time had these requirements been documented, but once we see what’s missing it should be pretty easy to get back on track.
for _, imp := range mod.Imports() {
fmt.Printf("missing import: %sn", *imp.Name())
}
Let’s run this again.
missing import: b
missing impo