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 explorer 獲取 wasm 程式碼:

WASM Code

下載 WASM 程式碼並用它來測試 API。

fetch() 瀏覽器 API

fetch() API 用於載入 .wasm 網路資源。

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

它返回一個 Promise,如下所示:

fetch() Browser API

您也可以使用 XMLHttpRequest 方法來獲取 wasm 網路資源。

WebAssembly.compile()

該 API 的職責是從 .wasm 檔案中獲取並編譯模組詳細資訊。

語法

語法如下:

WebAssembly.compile(buffer);

引數

Buffer - 來自 .wasm 的程式碼必須先轉換為型別化陣列或 ArrayBuffer,然後再作為輸入提供給 compile 函式。

返回值

它將返回一個 Promise,其中包含已編譯的模組。

示例

讓我們看一個示例,該示例使用 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 Compile

該模組具有包含 imports、exports 和 customSections 的構造器物件。讓我們看看下一個 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 Instance

您可以看到我們從已編譯的 C 程式碼中獲得的 square 函式。

要執行 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,然後再作為輸入提供給 instantiate 函式。

importObject - importObject 必須包含模組內部使用的記憶體和匯入函式的詳細資訊。如果沒有任何內容需要共享,它可以是一個空的模組物件。

返回值

它將返回一個 Promise,其中包含模組和例項詳細資訊。

示例

<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 Instantiate

WebAssembly.instantiateStreaming

此 API 負責從給定的 .wasm 程式碼編譯和例項化 WebAssembly 模組。

語法

語法如下:

WebAssembly.instantiateStreaming(wasmcode, importObject);

引數

wasmcode - 來自 fetch 或任何其他 API 的響應,該響應提供 wasm 程式碼並返回一個 Promise。

importObject - importObject 必須包含模組內部使用的記憶體和匯入函式的詳細資訊。如果沒有任何內容需要共享,它可以是一個空的模組物件。

返回值

它將返回一個 Promise,其中包含模組和例項詳細資訊。

示例

下面討論一個示例:

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

廣告