Calling JS function from Rust

04 Dec 2017 0 Comments

Files creation

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

window.onload = function() {
    window.exports = {};

    let imports = {
        js_func: (n) => b.value = n
    }

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

    let a = document.querySelector('#a'),
        b = document.querySelector('#b');
    
    a.oninput = () => exports.multiply_by_4(a.value);
};

fn main() {}

// These functions are provided by the runtime in env.imports object
extern "C" {
    fn js_func(_: i32);
}

#[no_mangle]
pub unsafe fn multiply_by_4(a: i32) {
    js_func(a * 4);
}

Save this file as main.wasm in build folder.
Or generate this file by
rustc +nightly --target wasm32-unknown-unknown -O --crate-type=cdylib src\main.rs -o build\main.big.wasm

Result

WebAssembly text format
(module
(type $t0 (func (param i32)))
(import "env" "js_func" (func $env.js_func (type $t0)))
(func $multiply_by_4 (export "multiply_by_4") (type $t0) (param $p0 i32)
  (call $env.js_func
    (i32.shl
      (get_local $p0)
      (i32.const 2))))
(table $T0 0 anyfunc)
(memory $memory (export "memory") 17)
(data (i32.const 4) "\10\00\10\00"))