This repository contains an example of the following pipeline:
- Compile Rust code exporting a function into WebAssembly linkable object
- Compile Haskell code containing FFI to import the function from above into WebAssembly
- Link the two object files together
- Use the WebAssembly file in browser
You'll need cargo and rustup
You'll also need to install plugin for targeting wasm:
rustup target add wasm32-unknown-unknownAfter that, compilation can be performed with
RUSTFLAGS="--emit=obj" cargo build --release --target=wasm32-unknown-unknownThis will produce the linkable object file in target/wasm32-unknown-unknown/release/deps/hello_wasm.o
This library can be compiled into Web assembly and used in a browser.
You'll need to install GHC wasm backend first. See full article for more details.
The GHCup approach was tested and confirmed to work with some extra steps:
export CONFIGURE_ARGS="--host=x86_64-linux --with-intree-gmp --with-system-libffi"
curl https://gitlab.haskell.org/haskell-wasm/ghc-wasm-meta/-/raw/master/bootstrap.sh | SKIP_GHC=1 sh
source ~/.ghc-wasm/env
ghcup config add-release-channel https://gitlab.haskell.org/haskell-wasm/ghc-wasm-meta/-/raw/master/ghcup-wasm-0.0.9.yaml
ghcup install ghc wasm32-wasi-9.12 -- $CONFIGURE_ARGSFirst, copy the compiled Rust object file into libs/librust.a.
After that, the library can be compiled with
cabal --with-compiler=wasm32-wasi-ghc-9.12 --with-hc-pkg=wasm32-wasi-ghc-pkg-9.12 --with-hsc2hs=wasm32-wasi-hsc2hs-9.12 buildThe compiler will output a file a.out in the root directory. This is the WASM module that can be imported and used in a browser.
It currently exports two functions, mkProofBytesWasm and mkProofBytesMockWasm, which produce Plonkup proofs that the user possesses a valid JSON Web Token issued by Google.
The library uses JS FFI, so one last step is required to generate a helper file:
$(wasm32-wasi-ghc-9.12 --print-libdir)/post-link.mjs -i a.out -o ghc_wasm_jsffi.jsYou'll need Deno to run the example
Copy the compiled Haskell code (a.out and ghc_wasm_jsffi.js) into the js directory. Rename a.out into linked.wasm.
Then, run
deno index.mjsGrant access to the file.
This should print 89 as the 10th Fibonacci number
The whole pipeline can be run with
./build.shThis should print 89 as the 10th Fibonacci number
Further reading:
https://ghc.gitlab.haskell.org/ghc/doc/users_guide/wasm.html