阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      JS WebAssembly.instantiate()

      这是一个实验中的功能 此功能某些浏览器尚在开发中。由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。

      WebAssembly.instantiate() 是编译和实例化 WebAssembly 代码的主要方法。这个方法有两个重载方式:

      • 第一种重载使用WebAssembly二进制代码的 typed array 或 [ArrayBuffer] 形式进行编译和实例化.  返回的 Promise 会携带已编译的 WebAssembly.Module 和它的第一个实例化对象 WebAssembly.Instance.
      • 第二种重载使用已编译的 WebAssembly.Module , 返回的 Promise 携带一个 Module的实例化对象 Instance. 如果这个 Module 已经被编译了或者是从缓存中获取的( retrieved from cache), 那么这种重载方式是非常有用的.

      语法

      主重载方式 — 使用 wasm 二进制代码

      Promise WebAssembly.instantiate(bufferSource, importObject);
      
      

      参数

      bufferSource

      一个包含你想编译的wasm模块二进制代码的 typed array(类型数组) or ArrayBuffer

      importObject 可选

      一个将被导入到新创建实例中的对象,它包含的值有函数、WebAssembly.Memory 对象等等。编译的模块中,对于每一个导入的值都要有一个与其匹配的属性与之相对应,否则将会抛出 [WebAssembly.LinkError]。

      返回值

      解析为包含两个字段的 ResultObject 的一个 Promise:

      异常

      第二种重载 — 使用模块对象

      Promise WebAssembly.instantiate(module, importObject);
      
      

      参数

      module

      将被实例化的 WebAssembly.Module 对象。

      importObject 可选

      一个将被导入到新创建实例中的对象,它包含的值有函数、WebAssembly.Memory 对象等等。编译的模块中,对于每一个导入的值都要有一个与其匹配的属性与之相对应,否则将会抛出 [WebAssembly.LinkError]。

      返回值

      一个解析为 WebAssembly.InstancePromise 对象。

      异常

      例子

      第一种重载例子

      使用 fetch 获取一些 WebAssembly 二进制代码后,我们使用 WebAssembly.instantiate()  方法编译并实例化模块,在此过程中,导入了一个 Javascript 方法在 WebAssembly 模块中, 接下来我们使用Instance 导出的Exported WebAssembly 方法。

      var importObject = {
        imports: {
          imported_func: function(arg) {
            console.log(arg);
          }
        },
        env: {
          abort: () => {},
        },
      };
      
      /* 2019-08-03:importObject必须存在env对象以及env对象的abort方法 */
      
      fetch('simple.wasm').then(response =>
        response.arrayBuffer()
      ).then(bytes =>
        WebAssembly.instantiate(bytes, importObject)
      ).then(result =>
        result.instance.exports
      );
      

      : 查看GitHub(在线实例)的 index.html 中一个相似的例子,使用了我们的[fetchAndInstantiate()](https://github.com/mdn/webassembly-examples/blob/master/wasm-utils.js#L1)库函数

      第二种重载例子

      下面的例子(查看我们GitHub的 index-compile.html 例子,可在线演示)使用 compile() 方法编译了 simple.wasm 字节码,然后通过 postMessage() 发送给一个线程 worker

      var worker = new Worker("wasm_worker.js");
      
      fetch('simple.wasm').then(response =>
        response.arrayBuffer()
      ).then(bytes =>
        WebAssembly.compile(bytes)
      ).then(mod =>
        worker.postMessage(mod)
      );
      

      在线程中 (查看 [wasm_worker.js](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/wasm_worker.js)) 我们定义了一个导入对象供模块使用,然后设置了一个事件处理函数来接收主线程发来的模块。当模块被接收到后,我们使用 WebAssembly.instantiate() 方法创建一个实例并且调用它从内部导出的函数。

      var importObject = {
        imports: {
          imported_func: function(arg) {
            console.log(arg);
          }
        }
      };
      
      onmessage = function(e) {
        console.log('module received from main thread');
        var mod = e.data;
      
        WebAssembly.instantiate(mod, importObject).then(function(instance) {
          instance.exports.exported_func();
        });
      };
      

      Specifications

      SpecificationStatusComment
      [WebAssembly JavaScript Interface
      instantiate()](https://webassembly.github.io/spec/js-api/#webassemblyinstantiate)Working DraftInitial draft definition.

      See also

      目录
      目录