WebAssembly backend merged into GHC

Wasm support has landed in GHC master!

28 Likes

The blog post talks about “runs on a variety of wasm engines that support wasi”, but is it also possible to produce code that runs on “pure” wasm, using Wasm-level FFI to talk to whatever non-standard API is provided in a given environment?

3 Likes

@TerrorJack may be in the best position to answer this.

I know what environment you have in mind :slight_smile:

Calling those system imports in Haskell is trivial, the same C FFI mechanism works out of the box.

The real hard issue is libc; you need to have a libc sysroot that doesn’t use WASI at all, and instead uses those system imports for side effects (possibly panicking at runtime for some libc functions that won’t work, or just don’t expose those functions and expect linker errors). Once you manage to build the libc sysroot that’s suited for that environment, you can try building a cross ghc that uses it and patch ghc if needed.

Another potential approach is a post-link wasm rewriting pass that changes the wasi imports to use those system imports, and for unsupported wasi imports, trap at runtime.

Feel free to ping me if there is commercial interest.

1 Like

No commercial interest, at least not from me, sorry :slight_smile:

Another potential approach is a post-link wasm rewriting pass that changes the wasi imports to use those system imports, and for unsupported wasi imports, trap at runtime.

That might be the easiest to get started; I’d hope a “pure IO program” that only uses those custom C FFI functions, but none that use filesystem/network/etc. will not use many of the WASI imports. But so far it’s just a hope.

Not sure if I’ll get around to verify that theory… we’ll see .

Fascinating.

I tried to load compiled output through WASI Web Polyfill, nothing happened. Am I missing something?

Console error:

error! TypeError: import object field 'wasi_snapshot_preview1' is not an Object

That polyfill is outdated, I recommend giving GitHub - wasmerio/wasmer-js: Monorepo for Javascript WebAssembly packages by Wasmer a try :slight_smile:

Thanks.

But I have a feeling that I have simply misunderstood how it’s supposed to work, according to their docs:

The output `.wasm` modules are known to run on latest versions of at least these runtimes:

* [`wasmtime`](https://wasmtime.dev)
* [`wasmedge`](https://wasmedge.org)
* [`wasmer`](https://wasmer.io)
* [`wasm3`](https://github.com/wasm3/wasm3) (needs latest `main` revision)
* [`deno`](https://deno.land) (using [`wasi`](https://deno.land/std/wasi/snapshot_preview1.ts) as WASI implementation)
* [`node`](https://nodejs.org)

Perhaps I should have not expected it could work for any browser wasm runtime in the first place?