如何在JavaScript中直接实例化WebAssembly模块

时间:2018-07-20 23:16:44

标签: javascript webassembly

我见过的examples本质上显示了这一点:

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

但是我想这样做而不发出额外的HTTP请求。想知道是否唯一的方法是这种方法(或某些方法的变化,这将有助于您了解):

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)
}

想知道我是否需要忍耐力或类似的事情。

我不确定,也许用URL和blob做某事可能会更好。

1 个答案:

答案 0 :(得分:3)

是的,是的,为了内联wasm模块并避免HTTP请求,您必须执行某种编码。我建议使用Base64编码的字符串,因为它们是最紧凑的形式。

您可以编码如下:

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

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

然后您可以按以下方式加载模块:

    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), {});