Import memory buffer


The Code

Download string-passing.rs
Download string-passing.wat (WebAssembly text format)

The Rust code for this example does nothing but returning the data passed to it (plus some allocation functions). It uses one special attribute though:

#![wasm_import_memory]
With this attribute the WebAssembly module will not export its own memory buffer, but instead import the memory from the environment, letting the caller set it up. In the future it will be possible to use a SharedArrayBuffer in order to share memory between multiple modules easily.

The code (without allocation functions) is:

#![feature(wasm_import_memory)]
#![wasm_import_memory]

use std::os::raw::c_char;

#[no_mangle]
pub extern "C" fn roundtrip(data: *mut c_char) -> *mut c_char {
    data
}

The calling JavaScript code needs to instantiate a WebAssembly.Memory object and pass it on instantiation.

window.Module = {}

// Initializing the memory with 20 pages (20 * 64KiB = 1.25 MiB)
const memory = new WebAssembly.Memory({initial: 20});
const imports = {
  env: {
    memory: memory
  }
};

// On instantiation we pass the imports object
fetchAndInstantiate("./string-passing.wasm", imports)
  .then(mod => {
    Module.memory      = memory;
    Module.alloc       = mod.exports.alloc;
    Module.dealloc     = mod.exports.dealloc;
    Module.dealloc_str = mod.exports.dealloc_str;
    Module.roundtrip   = function(str) {
      let buf = newString(Module, str);
      let outptr = mod.exports.roundtrip(buf);
      let result = copyCStr(Module, outptr);
      return result;
    };

    var output = document.getElementById("output");
    output.value = Module.roundtrip("This string was passed through WebAssembly")
  });