Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasm32-wasi support #1179

Merged
merged 10 commits into from
Nov 29, 2023
Merged

wasm32-wasi support #1179

merged 10 commits into from
Nov 29, 2023

Conversation

dhess
Copy link
Member

@dhess dhess commented Nov 22, 2023

This series of commits makes the necessary & sufficient changes to build the primer and primer-api packages using GHC 9.6's WebAssembly target, and to get their tests to pass using the wasmtime runtime. We expect these are the only 2 libraries we'll need in order to run Primer in the student's browser, as everything else is either very database or HTTP API-specific.

There are a few hacks needed to make this work, but nothing that's particularly objectionable. The main thing I would like to clean up are the 4 additional source-repository-package overrides we need for upstream Wasm-related fixes, but presumably those will come over time.

There are currently 3 1 other major limitations:

  1. Neither haskell.nix or nixpkgs.haskellPackages support the wasm32-wasi cross target at the moment. Therefore, we need to install the https://gitlab.haskell.org/ghc/ghc-wasm-meta flake and create a nix develop shell with the wasm32-wasi-* toolchain. This toolchain is currently only available for x86_64-linux, and doesn't use the Nix store to build packages, so it's not ideal, but should be good enough until one of the various Haskell Nix integrations supports wasm32-wasi.
  2. There's no CI integration yet, mainly due to point 1 and the fact that our Haskell CI is based entirely on Nix. (Fixed, though somewhat hacky.)
  3. The recently-merged Animation prototype (Animations #1164) pulls in dependencies that break the wasm32-wasi build for a number of reasons (zlib and fsnotify, at least). Unfortunately, we didn't discover this until after we'd merged Animations #1164, otherwise we might have sat on it for awhile. As we expect that the Animation implementation will get a fairly substantial refactor, mainly by moving the interpreter out of the backend and into the frontend, it's tempting to revert Animations #1164 in favor of merging WebAssembly support into main, but for now, we'll keep it, and relegate the WebAssembly support to this branch. (See chore: Disable animations support #1186, which addressed this.)

@dhess dhess added the Do not merge Do not merge label Nov 22, 2023
@dhess dhess force-pushed the dhess/wasm branch 7 times, most recently from ca61078 to 205c61b Compare November 29, 2023 14:41
dhess added 10 commits November 29, 2023 16:29
This Nix dev shell adds the `ghc-wasm-meta` tools to the shell via the
https://gitlab.haskell.org/ghc/ghc-wasm-meta flake. With
`wasm32-wasi-ghc-9_6`, we can now build `primer` and `primer-api` with
the Wasm backend target. (Note that these 2 packages are sufficient to
build and run Primer programs, but lack any persistent storage and/or
web service.)

To get a Nix shell with these tools installed, run:

```
nix develop .#wasm
```

Then run `wasm32-waasi-cabal` to build targets.

Caveats:

* This only works on `x86_64-linux`, unfortunately, as the required
GHC bindists aren't yet available for macOS.

* The generated code isn't yet tested, as bringing up the test suite
on Wasm is proving to be non-trivial.

* There's no haskell.nix support here, meaning no binary caching, and
no support for our CI suite, among other things. These tools are
available only for interactive builds at the moment.

* Though in theory any `primer` or `primer-api` function is now
callable via Wasm, there is still a lot of work to be done before
that's actually possible.

Signed-off-by: Drew Hess <[email protected]>
Specifically:

* `pretty-show` requires `happy` at build time, which doesn't work on
Wasm targets.

* `semirings` wants to define instances for a few Posix types, which
aren't available on Wasm (WASI) targets.

* `pretty-simple` uses a custom setup, which breaks on Wasm.

In each of these instances, we resort to a fork and a
`source-repository-package`. (At least 2 of these currently have
upstream unmerged PR fixes.)

Signed-off-by: Drew Hess <[email protected]>
Note that not all of these targets build successfully yet.

Signed-off-by: Drew Hess <[email protected]>
Notes:

* We "source repo" `splitmix`, which needs a few fixes that upstream
doesn't want to merge at the moment.

* We can't run `tasty-discover` via `wasmtime` at build time, so we
have to bake the discovered tests out. We do this via a `Makefile`
step, and `.gitignore` the generated test file.

* The GHC runtime in Wasm doesn't seem to work with `-threaded` or
`-rtsopts`, so these are disabled for that target.

* `tasty` needs to be built for Wasm without `-unix`, as that tries to
install signal handlers that aren't present in `wasmtime`.

Signed-off-by: Drew Hess <[email protected]>
Previously, we checked for GHCJS and disabled tests accordingly. I
think we're unlikely to use GHCJS at this point, so we remove these
checks.

I've also updated a related comment on why we add orphan instances for
some OpenAPI 3 instances, because I believe they're necessary for Wasm
support, in addition to GHCJS.

Signed-off-by: Drew Hess <[email protected]>
@dhess dhess added this pull request to the merge queue Nov 29, 2023
Merged via the queue into main with commit af21875 Nov 29, 2023
@dhess dhess deleted the dhess/wasm branch November 29, 2023 16:46
@dhess dhess removed the Do not merge Do not merge label Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant