WebAssembly.Exception

Baseline 廣泛可用 *

此功能已成熟,並可在許多裝置和瀏覽器版本上使用。自 2022 年 5 月以來,它已在各個瀏覽器中可用。

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

注意:此功能在 Web Workers 中可用。

WebAssembly.Exception 物件表示從 WebAssembly 丟擲到 JavaScript 的執行時異常,或者從 JavaScript 丟擲到 WebAssembly 異常處理程式的異常。

建構函式接受一個WebAssembly.Tag、一個值陣列和一個 options 物件作為引數。標籤唯一地定義了異常的型別,包括其引數的順序和資料型別。為了訪問已丟擲異常的引數,需要使用建立 Exception 時使用的相同標籤。提供了方法來測試異常是否與特定標籤匹配,以及按索引獲取特定值(如果異常與指定的標籤匹配)。

僅當關聯的標籤共享時,JavaScript 和其他客戶端程式碼才能訪問 WebAssembly 異常值(反之亦然)(不能僅僅使用另一個碰巧定義了相同資料型別的標籤)。如果沒有匹配的標籤,可以捕獲並重新丟擲異常,但無法對其進行檢查。

為了使異常丟擲速度更快,從 WebAssembly 丟擲的異常通常不包含堆疊跟蹤。需要提供堆疊跟蹤的 WebAssembly 程式碼必須呼叫 JavaScript 函式來建立異常,在建構函式中傳遞 options.traceStack=true 引數。然後,建構函式可能會返回一個帶有附加到 stack 屬性的堆疊跟蹤的異常。

建構函式

WebAssembly.Exception()

建立一個新的 WebAssembly.Exception 物件。

例項方法

Exception.prototype.is()

測試異常是否與特定標籤匹配。

Exception.prototype.getArg()

返回與指定標籤匹配的異常的資料欄位。

例項屬性

Exception.prototype.stack 非標準

返回異常的堆疊跟蹤,或者 undefined

示例

此示例演示瞭如何定義一個標籤並將其匯入模組,然後使用它來丟擲一個在 JavaScript 中捕獲的異常。

考慮以下 WebAssembly 程式碼,假設它已被編譯為檔案 example.wasm

  • 模組匯入一個在內部稱為 $tagname 的標籤,該標籤具有單個 i32 引數。該標籤期望使用模組 extmod 和標籤 exttag 傳遞該標籤。
  • $throwException 函式使用 throw 指令丟擲一個異常,該異常接受 $tagname 和引數。
  • 模組匯出 run() 函式,該函式丟擲一個值為 "42" 的異常。
wat
(module
  ;; import tag that will be referred to here as $tagname
  (import "extmod" "exttag" (tag $tagname (param i32)))

  ;; $throwException function throws i32 param as a $tagname exception
  (func $throwException (param $errorValueArg i32)
    local.get $errorValueArg
    throw $tagname
  )

  ;; Exported function "run" that calls $throwException
  (func (export "run")
    i32.const 42
    call $throwException
  )
)

下面的程式碼呼叫 WebAssembly.instantiateStreaming 來匯入 example.wasm 檔案,並傳入一個“匯入物件”(importObject),該物件包含一個名為 tagToImport 的新 WebAssembly.Tag。匯入物件定義了一個屬性與 WebAssembly 程式碼中的 import 語句匹配的物件。

檔案例項化後,程式碼將呼叫匯出的 WebAssembly run() 方法,該方法將立即丟擲異常。

js
const tagToImport = new WebAssembly.Tag({ parameters: ["i32"] });

// Note: import object properties match the WebAssembly import statement!
const importObject = {
  extmod: {
    exttag: tagToImport,
  },
};

WebAssembly.instantiateStreaming(fetch("example.wasm"), importObject)
  .then((obj) => {
    console.log(obj.instance.exports.run());
  })
  .catch((e) => {
    console.error(e);
    // Check we have the right tag for the exception
    // If so, use getArg() to inspect it
    if (e.is(tagToImport)) {
      console.log(`getArg 0 : ${e.getArg(tagToImport, 0)}`);
    }
  });

/* Log output
example.js:40 WebAssembly.Exception: wasm exception
example.js:41 getArg 0 : 42
*/

異常使用 catch 塊在 JavaScript 中捕獲。我們可以看到它的型別是 WebAssembly.Exception,但如果我們沒有正確的標籤,我們就無法做太多其他事情。

但是,因為我們有標籤,所以我們使用 Exception.prototype.is() 來檢查它是否是正確的標籤,並且因為它是正確的,所以我們呼叫 Exception.prototype.getArg() 來讀取值 "42"。

規範

規範
WebAssembly JavaScript 介面:異常處理
# runtime-exceptions

瀏覽器相容性

另見