WebAssembly - JavaScript API

  • 简述

    在本章中,我们将了解如何使用 javascript webassembly API 加载 wasm 代码并在浏览器中执行它们。
    这里有一些重要的 API,我们将在整个教程中使用来执行 wasm 代码。
    • fetch() 浏览器 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() 浏览器 API
    您还可以使用 XMLHttpRequest 方法来获取 wasm 网络资源。
  • WebAssembly.compile()

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

    句法

    语法如下 -
    
    WebAssembly.compile(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 编译
    该模块有一个带有导入、导出和 customSection 的构造函数对象。让我们看看下一个 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 中的代码必须转换为类型化数组或 arraybuffer,然后才能作为输入实例化。
    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>
    
    当你在浏览器中测试它时,你会看到一个错误 -
    错误
    为了让它在你的服务器端工作,你必须添加 mime 类型 application/wasm 或者使用 WebAssembly.instantiate(arraybuffer, importObject)。