Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

catch_all_ref: try_table Klausel

Die catch_all_ref Klausel fängt jede Ausnahme ab und schiebt einen exnref Wert, der die Ausnahme darstellt, auf den Stapel.

Probieren Sie es aus

(module
  ;; Import the error tag and the log function
  (tag $my_error (import "env" "my_error") (param i32))
  (import "env" "log" (func $log))

  (func $try_and_catch (param $value i32)
    ;; Define a variable to store an exnref
    (local $err exnref)
    ;; catch_all_ref catches any exception thrown and pushes an exnref
    (block $handler (result exnref)
      (try_table (catch_all_ref $handler)
        (call $might_throw (local.get $value))
      )
      (return)
    )
    ;; Save exnref before calling log to notify user
    ;; that exception has been thrown
    (local.set $err)
    (call $log)
    ;; Restore exnref
    (local.get $err)
    ;; rethrow original exception
    (throw_ref)
  )

  ;; Function that throws an error of type $my_error
  ;; when its parameter is less than 0
  (func $might_throw (param $value i32)
    (local.get $value)
    (i32.const 0)
    (i32.lt_s)
    (if
      (then
        (i32.const 42)
        (throw $my_error)
      )
    )
  )
  (export "try_and_catch" (func $try_and_catch))
)
// Define error tag in JS
const myErrorTag = new WebAssembly.Tag({ parameters: ["i32"] });

// Import the tag and the log function into the module
const env = {
  my_error: myErrorTag,
  log() {
    console.log("An error was caught!");
  },
};

WebAssembly.instantiateStreaming(fetch("{%wasm-url%}"), { env }).then(
  // Negative value causes function to throw
  (result) => result.instance.exports.try_and_catch(-1),
);

Syntax

catch_all_ref block_identifier
catch_all_ref

Die catch_all_ref Klausel.

block_identifier

Der Bezeichner für den block, zu dem verzweigt wird, wenn die Ausnahme gefangen wird. Dies kann sein:

  • Ein identifizierender Name, wie es durch den Bezeichner des entsprechenden Blocks definiert ist.
  • Eine Block-Indexnummer — 0 für den innersten Block, 1 für den nächstinneren, usw.

Typ

[] -> [exception_ref]
exception_ref

Ein exnref Wert, der die geworfene Ausnahme darstellt.

Dieser Wert wird nicht direkt an der Stelle der catch_all_ref Klausel auf den Stapel gestapelt, sondern an der Stelle des Blocks, zu dem bei geworfener Ausnahme verzweigt wird.

Binärcodierung

Klausel catch_all_ref Typ-Byte
catch_all_ref 0x03

catch_all_ref ist keine eigenständige Anweisung — stattdessen wird es als Klausel innerhalb einer try_table Anweisung mit einem Byte von 0x03 codiert. Eine try_table mit einer einzelnen catch_all_ref Klausel:

wat
(try_table (catch_all_ref $handler) ... )

würde so codiert werden:

... 0x01 0x03 0x00 ...

Beschreibung

Die catch_all_ref Klausel kann innerhalb eines try_table Blocks enthalten sein, um alle geworfenen Ausnahmen abzufangen. Wenn eine Ausnahme geworfen wird, verzweigt der Code zu dem angegebenen block, an welchem Punkt ein exnref Wert, der die geworfene Ausnahme darstellt, auf den Stapel gestapelt wird.

Die Ausnahme kann dann mit einer throw_ref Anweisung erneut geworfen werden.

catch_all_ref ist nützlich, wenn Sie berichten möchten, dass eine Art Ausnahme geworfen wurde, aber die Ausnahme auch erneut werfen möchten. Sie könnten beispielsweise eine Aktion wie Aufräumen oder Protokollierung durchführen wollen, aber dann den Benutzern dennoch mitteilen, dass ein Fehler aufgetreten ist.

Der referenzierte Block muss einen Ergebnistyp deklarieren, der dem gestapelten exnref entspricht. Im zuvor gezeigten Beispiel gibt der Block, zu dem bei gefangener Ausnahme verzweigt wird, einen exnref Typ in seinem result an:

wat
(block $handler (result exnref)
  ...
)

Spezifikationen

Spezifikation
WebAssembly Core Specification
# -hrefsyntax-instr-controlmathsfcatch_all_refl

Browser-Kompatibilität

Siehe auch