Skip to content
Divam edited this page Jul 12, 2018 · 4 revisions

Status

GHC cross compiler can compile all the packages included in GHC like ghc-prim, base, etc.

The runtime kernel can run simple "Hello world" program, ie it prints on the browser console.

Try it out

   # Make sure you add the binary key to fetch pre-compiled ghc and toolchain
   # hydra.webghc.org-1:knW30Yb8EXYxmUZKEl0Vc6t2BDjAUQ5kfC1BKJ9qEG8=

   $ git clone https://github.com/WebGHC/wasm-cross.git
   $ cd wasm-cross
   $ nix-build release.nix -o haskell-example-web -A wasm.haskell-example-web
   $ cd haskell-example-web
   $ hserv -p8080

Go to 127.0.0.1:8080 in firefox or chrome, and open console to view the print outputs. You will have to enable SharedArrayBuffer from the browser config settings. Or you can edit the wasm.js file and comment out the two lines containing SharedArrayBuffer.

Hack

GHC

GHC currently uses unregistered compilation, by generating C code and compiling using clang. The llvm native code generation cannot be used currently because wasm doesn't have tail-call support.

The runtime system (RTS) has been compiled to wasm with some minor modifications.

To build GHC cross compiler, first do this config

    $ git config --global url."git@github.com:WebGHC/packages-".insteadOf     git@github.com:WebGHC/packages/
    $ git config --global url."ssh://github.com/WebGHC/packages-".insteadOf     ssh://github.com/WebGHC/packages/
    $ git config --global url."https://github.com/WebGHC/packages-".insteadOf     https://github.com/WebGHC/packages/
    $ git config --global url."http://github.com/WebGHC/packages-".insteadOf     http://github.com/WebGHC/packages/
    $ git config --global url."git://github.com/WebGHC/packages-".insteadOf     git://github.com/WebGHC/packages/

Then fetch the sources and build

    $ git clone --recursive https://github.com/WebGHC/ghc.git

    # Obtain a nix-shell
    $ cd /path/to/wasm-cross
    $ nix-shell -A nixpkgsWasm.haskell.packages.ghcHEAD.ghc
    
    # Do build
    $ cd /path/to/ghc

    # Edit mk/build.mk if required 
    $ configurePhase
    $ make -j4

    # Run your local ghc cross compiler
    $ /path/to/ghc/inplace/bin/ghc-stage1 main.hs
    # use the generated *main* file

Webabi / kernel execution / System calls

The supporting kernel code (wasm.js) can do minimal operations like allocate heap memory, print to console..

The following are not supported currently (some of these might not be possible to support in wasm)

  • timer, interrupts
  • Concurrency
    # Get source
    $ git clone https://github.com/WebGHC/webabi
    $ cd webabi

    # obtain a shell with ghc
    $ cd wasm-cross
    $ nix-shell -A nixpkgsWasm.haskell.packages.ghcHEAD.hello

    # Copy some dependecies 
    $ cp /path/to/haskell-example-web/node_modules .
    $ cp /path/to/haskell-example-web/index.html .

After this you can compile haskell code using the ghc in this shell, and modify the files wasm.js, kernel.js, etc.

    # Compile haskell
    $ wasm32-unknown-unknown-wasm-ghc main.hs -o hello
    $ hserv
Clone this wiki locally