WebAssembly - JavaScript API

在本章中,我们将了解如何使用 JavaScript WebAssembly API 加载 wasm 代码并在浏览器中执行它们。

这里有一些重要的 API,我们将在整个教程中使用它们来执行 wasm 代码。

  • fetch() Browser API
  • WebAssembly.compile
  • WebAssembly.instance
  • WebAssembly.instantiate
  • WebAssembly.instantiateStreaming

在我们讨论 WebAssembly javascript API 之前,为了测试 API 和输出,我们将使用以下 C 程序以及使用 wasm explorer 从该 c 程序生成的 .wasm 代码。

C程序示例如下 −

#include<stdio.h>
int square(int n) { 
   return n*n; 
}

我们将使用 WASM 浏览器来获取 wasm 代码 −

WASM 代码

下载 WASM 代码并使用它来测试 API。

fetch()浏览器API

fetch() API 用于加载 .wasm 网络资源。

<script>
   var result = fetch("findsquare.wasm");
   console.log(result);
</script>

它返回如下所示 −

fetch() Browser API

您还可以使用XMLHttpRequest方法来获取wasm网络资源。

WebAssembly.compile()

API 的职责是编译从 .wasm 获取的模块详细信息。

语法

语法如下所示 −

WebAssembly.compile(buffer);

参数

Buffer − .wasm 中的代码必须先转换为类型化数组或数组缓冲区,然后才能作为输入进行编译。

返回值

它将返回一个包含已编译模块的承诺。

示例

让我们看一个示例,它使用 webAssembly.compile() 将输出作为已编译模块提供。

<script> 
   fetch("findsquare.wasm") .then(bytes => bytes.arrayBuffer()) 
   .then(mod => {
      var compiledmod = WebAssembly.compile(mod);
      compiledmod.then(test=> {
         console.log(test); 
      })
   })
</script>

输出

在浏览器中检查console.log时,将为您提供已编译模块的详细信息 −

WebAssembly 编译

该模块有一个带有导入、导出和自定义部分的构造函数对象。 让我们看看下一个 API,以获取编译模块的更多详细信息。

WebAssembly.instance

使用 WebAssembly.instance,API 将为您提供已编译模块的可执行实例,可以进一步执行该实例以获得输出。

语法

语法如下所示 −

new WebAssembly.Instance(compiled module)

返回值

返回值将是一个包含可以执行的导出函数数组的对象。

示例

<script> 
   fetch("findsquare.wasm") 
      .then(bytes => bytes.arrayBuffer())
      .then(mod => WebAssembly.compile(mod)).then(module => {
         let instance = new WebAssembly.Instance(module); 
         console.log(instance); 
      })
</script>

输出

输出将为我们提供一个导出函数数组,如下所示 −

WebAssembly 实例

您可以看到我们从编译的 C 代码中获得的 square 函数。

要执行平方函数,您可以执行以下操作 −

<script>
   fetch("findsquare.wasm") 
   .then(bytes => bytes.arrayBuffer()) 
   .then(mod => WebAssembly.compile(mod)) 
   .then(module => { 
      let instance = new WebAssembly.Instance(module);
      console.log(instance.exports.square(15));
   })
</script>

输出结果将是 −

225

WebAssembly.instantiate

该 API 负责一起编译和实例化模块。

语法

语法如下 −

WebAssembly.instantiate(arraybuffer, importObject)

参数

arraybuffer − .wasm 中的代码必须先转换为类型化数组或数组缓冲区,然后才能作为输入进行实例化。

importObject − 导入对象必须具有内存的详细信息以及要在模块内部使用的导入函数。 它可以是一个空的模块对象,以防没有什么可共享的。

返回值

它将返回一个承诺,其中包含模块和实例详细信息。

示例

<script type="text/javascript">
   const importObj = {
      module: {}
   };
   fetch("findsquare.wasm")
      .then(bytes => bytes.arrayBuffer())
      .then(module => WebAssembly.instantiate(module, importObj)) 
      .then(finalcode => { 
         console.log(finalcode); console.log(finalcode.instance.exports.square(25)); 
      }); 
</script>

输出

当您执行代码时,您将得到下面提到的输出。

WebAssembly 实例化

WebAssembly.instantiateStreaming

此 API 负责根据给定的 .wasm 代码编译和实例化 WebAssembly 模块。

语法

语法如下所示 −

WebAssembly.instantiateStreaming(wasmcode, importObject);

参数

wasmcode − 来自 fetch 或任何其他提供 wasm 代码并返回承诺的 API 的响应。

importObject − 导入对象必须具有内存的详细信息以及要在模块内部使用的导入函数。 它可以是一个空模块对象,以防没有任何内容可共享。

返回值

它将返回一个承诺,其中包含模块和实例详细信息。

示例

下面讨论一个例子 −

<script type="text/javascript">     
   const importObj = { 
      module: {} 
   };
   WebAssembly.instantiateStreaming(fetch("findsquare.wasm"), importObj).then(obj => {
      console.log(obj); 
   }); 
</script>

当你在浏览器中测试时,你会看到一个错误 −

Error

要使其在服务器端工作,您必须添加 mime 类型 application/wasm 或使用 WebAssembly.instantiate(arraybuffer, importObject)。