Skip to content

Instantly share code, notes, and snippets.

@arkada38
Last active November 30, 2017 10:27
Show Gist options
  • Save arkada38/80d1ab55981335b79b904d7305abd806 to your computer and use it in GitHub Desktop.
Save arkada38/80d1ab55981335b79b904d7305abd806 to your computer and use it in GitHub Desktop.
Rust & WebAssembly

Rust & WebAssembly

Files tree

├── src
│   └── main.rs
├── build
│   └── main.wasm
├── index.html
├── script.js
├── run.but
└── README.md

Preparatory work

rustup update
rustup target add wasm32-unknown-unknown --toolchain nightly
cargo install --git https://github.com/alexcrichton/wasm-gc

Rust

Create main.rs file with some functions in src folder

#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

Wasm

Generate wasm module from rs file:

rustc +nightly --target wasm32-unknown-unknown -O --crate-type=cdylib src\main.rs -o build\main.big.wasm

Reduce the size by removing unused stuff from the module:

wasm-gc build\main.big.wasm build\main.wasm

Web

index.html

Create simple html page.

<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="utf-8">
      <title>WebAssembly</title>
      <script src="script.js"></script>
  </head>
  <body>
    <input type="number" id="a" value="0">+
    <input type="number" id="b" value="0">=
    <output id="c">0</output>
  </body>
</html>

script.js

The JavaScript code loads the WebAssembly module and has access to the exported function.

window.onload = function() {
    let a = document.querySelector('#a'),
        b = document.querySelector('#b'),
        c = document.querySelector('#c');

    let add;

    let calc = function() {
        c.value = add(a.value, b.value);
    };

    a.oninput = calc;
    b.oninput = calc;

    fetch('build/main.wasm')
    .then(response => response.arrayBuffer())
    .then(bytes => WebAssembly.instantiate(bytes, {}))
    .then(results => {
        add = results.instance.exports.add;
    });
};

Http server

For local testing http server needed. A good "ready-to-use tool" option could be browser-sync:

npm install -g browser-sync

To use it:

browser-sync start --server --port 3001 --files="./*"

Batch helper script

Batch script for generation .wasm in build folder for every .rs in src folder

@echo off

for /r %%a in (src\*.rs) do call :process "%%a"
goto :eof

:process
if "%~x1"==".rs" (
    rustc +nightly --target wasm32-unknown-unknown -O --crate-type=cdylib src\%~n1.rs -o build\%~n1.big.wasm
    wasm-gc build\%~n1.big.wasm build\%~n1.wasm
    del build\%~n1.big.wasm
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment