WebAssembly.instantiate()

Baseline 廣泛可用 *

此功能已非常成熟,可在多種裝置和瀏覽器版本上使用。自 2017 年 10 月以來,它已在各大瀏覽器中可用。

* 此特性的某些部分可能存在不同級別的支援。

WebAssembly.instantiate() 靜態方法允許您編譯和例項化 WebAssembly 程式碼。此函式有兩個過載。

  • 主要過載接收 WebAssembly 二進位制程式碼,形式為 型別化陣列ArrayBuffer,並在一個步驟中執行編譯和例項化。返回的 Promise 會解析為一個已編譯的 WebAssembly.Module 和它的第一個 WebAssembly.Instance
  • 次要過載接收一個已編譯的 WebAssembly.Module,並返回一個解析為該 ModuleInstancePromise。如果 Module 已經被編譯,則此過載很有用。

警告: 此方法不是獲取和例項化 Wasm 模組的最有效方式。如果可能,您應該使用新的 WebAssembly.instantiateStreaming() 方法,該方法直接從原始位元組碼獲取、編譯和例項化模組,因此不需要轉換為 ArrayBuffer

語法

js
// Taking Wasm binary code
WebAssembly.instantiate(bufferSource)
WebAssembly.instantiate(bufferSource, importObject)
WebAssembly.instantiate(bufferSource, importObject, compileOptions)

// Taking a module object instance
WebAssembly.instantiate(module)
WebAssembly.instantiate(module, importObject)
WebAssembly.instantiate(module, importObject, compileOptions)

引數

bufferSource

包含您要編譯的 Wasm 模組的二進位制程式碼的 型別化陣列ArrayBuffer

模組

要例項化的 WebAssembly.Module 物件。

importObject 可選

一個物件,包含要匯入到新建立的 Instance 中的值,例如函式或 WebAssembly.Memory 物件。對於已編譯模組宣告的每個匯入,都必須有一個匹配的屬性,否則將丟擲 WebAssembly.LinkError

compileOptions 可選

一個包含編譯選項的物件。屬性可以包括:

builtins 可選

一個字串陣列,用於啟用在已編譯的 Wasm 模組中使用 JavaScript 內建函式。這些字串定義了您要啟用的內建函式。目前唯一可用的值是 "js-string",它啟用 JavaScript 字串內建函式。

importedStringConstants 可選

一個字串,指定 匯入的全域性字串常量 的名稱空間。如果您希望在 Wasm 模組中使用匯入的全域性字串常量,則需要指定此屬性。

返回值

如果傳遞了 bufferSource,則返回一個 Promise,該 Promise 解析為一個 ResultObject,其中包含兩個欄位:

如果傳遞了 module,則返回一個 Promise,該 Promise 解析為一個 WebAssembly.Instance 物件。

異常

示例

注意:在大多數情況下,您可能希望使用 WebAssembly.instantiateStreaming(),因為它比 instantiate() 更高效。

第一個過載示例

使用 fetch 獲取一些 WebAssembly 位元組碼後,我們使用 WebAssembly.instantiate() 函式編譯和例項化模組,同時將 JavaScript 函式匯入到 WebAssembly 模組中。然後,我們呼叫由 Instance 匯出的匯出的 WebAssembly 函式

js
const importObject = {
  my_namespace: {
    imported_func(arg) {
      console.log(arg);
    },
  },
};

fetch("simple.wasm")
  .then((response) => response.arrayBuffer())
  .then((bytes) => WebAssembly.instantiate(bytes, importObject))
  .then((result) => result.instance.exports.exported_func());

注意:您也可以在 GitHub 上的 index.html 中找到此示例(也可以線上檢視)。

第二個過載示例

以下示例(請參閱 GitHub 上的 index-compile.html 演示,同樣也可以線上檢視)使用 WebAssembly.compileStreaming() 方法編譯載入的 simple.wasm 位元組碼,然後使用 postMessage() 將其傳送到 worker

js
const worker = new Worker("wasm_worker.js");

WebAssembly.compileStreaming(fetch("simple.wasm")).then((mod) =>
  worker.postMessage(mod),
);

在 worker 中(請參閱 wasm_worker.js),我們為模組定義了一個匯入物件,然後設定一個事件處理程式以接收主執行緒傳送過來的模組。收到模組後,我們使用 WebAssembly.instantiate() 方法從中建立一個例項,並呼叫其中匯出的一個函式。

js
const importObject = {
  my_namespace: {
    imported_func(arg) {
      console.log(arg);
    },
  },
};

onmessage = (e) => {
  console.log("module received from main thread");
  const mod = e.data;

  WebAssembly.instantiate(mod, importObject).then((instance) => {
    instance.exports.exported_func();
  });
};

啟用 JavaScript 內建函式和全域性字串匯入

此示例在使用 instantiate() 編譯和例項化 Wasm 模組時,啟用了 JavaScript 字串內建函式和匯入的全域性字串常量,然後執行匯出的 main() 函式(該函式會將 "hello world!" 記錄到控制檯)。線上檢視示例效果

js
const importObject = {
  // Regular import
  m: {
    log: console.log,
  },
};

const compileOptions = {
  builtins: ["js-string"], // Enable JavaScript string builtins
  importedStringConstants: "string_constants", // Enable imported global string constants
};

fetch("log-concat.wasm")
  .then((response) => response.arrayBuffer())
  .then((bytes) => WebAssembly.instantiate(bytes, importObject, compileOptions))
  .then((result) => result.instance.exports.main());

規範

規範
WebAssembly JavaScript 介面
# dom-webassembly-instantiate

瀏覽器相容性

另見