Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Directly Instantiate WebAssembly Module in JavaScript

The examples I've seen show essentially this:

fetch('simple.wasm').then(response =>
  response.arrayBuffer()
).then(bytes =>
  WebAssembly.instantiate(bytes, {})
).then(result =>
  result.instance.exports...
)

But I would like to do it without making that extra HTTP request. Wondering if the only way is this (or some variation of it, which would be helpful to know):

var binary = '...mywasmbinary...'
var buffer = new ArrayBuffer(binary.length)
var view = new DataView(buffer)
for (var i = 0, n = binary.length; i < n; i++) {
  var x = binary[i]
  view.setInt8(i * 8, x)
}

Wondering if I have to worry about endianess or anything like that.

Or perhaps doing something with URL and blobs might be better, I'm not sure.

like image 623
Lance Avatar asked Mar 06 '23 18:03

Lance


1 Answers

Yes, you are correct, in order to inline wasm modules and avoid the HTTP request, you'll have to perform some sort of encoding. I'd recommend using Base64 encoded strings as they are the most compact form.

You can encode as follows:

const readFileSync = require('fs').readFileSync;

const wasmCode = readFileSync(id);
const encoded = Buffer.from(wasmCode, 'binary').toString('base64');

You can then load the module as follows:

    var encoded = "... contents of encoded from above ...";

    function asciiToBinary(str) {
      if (typeof atob === 'function') {
        // this works in the browser
        return atob(str)
      } else {
        // this works in node
        return new Buffer(str, 'base64').toString('binary');
      }
    }

    function decode(encoded) {
      var binaryString =  asciiToBinary(encoded);
      var bytes = new Uint8Array(binaryString.length);
      for (var i = 0; i < binaryString.length; i++) {
          bytes[i] = binaryString.charCodeAt(i);
      }
      return bytes.buffer;
    }

    var module = WebAssembly.instantiate(decode(encoded), {});
like image 70
ColinE Avatar answered Mar 09 '23 07:03

ColinE