[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/WebAssembly/Guides/JavaScript_builtins [Back]  [Original]

WebAssembly JavaScript Builtins - WebAssembly | MDN

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

View in English Always switch to English

WebAssembly JavaScript Builtins

WebAssembly JavaScript Builtins sind die Wasm-quivalente von JavaScript-Operationen und bieten eine Mglichkeit, JavaScript-Funktionen innerhalb von Wasm-Modulen zu verwenden, ohne JavaScript-Zwischencode zu importieren, um eine Brcke zwischen JavaScript- und WebAssembly-Werten und Rufkonventionen bereitzustellen.

Dieser Artikel erklrt, wie Builtins funktionieren und welche verfgbar sind, und bietet dann ein Anwendungsbeispiel.

In diesem Artikel

Probleme beim Importieren von JavaScript-Funktionen

Fr viele JavaScript-Funktionen funktionieren regulre Importe gut. Das Importieren von Zwischencode fr Primitive wie String, ArrayBuffer und Map bringt jedoch erhebliche Leistungseinbuen mit sich. In solchen Fllen erwarten WebAssembly und die meisten darauf zielenden Sprachen eine enge Abfolge von Inline-Operationen anstelle eines indirekten Funktionsaufrufs, wie es bei regulren importierten Funktionen der Fall ist.

Insbesondere das Importieren von Funktionen aus JavaScript in WebAssembly-Module erzeugt Leistungsprobleme aus folgenden Grnden:

  • Bestehende APIs erfordern eine Konvertierung, um Unterschiede im Umgang mit dem this-Wert zu bewltigen, den WebAssembly-Funktionsimport-Aufrufe als undefined belassen.
  • Bestimmte Primitive verwenden JavaScript-Operatoren wie === und <, die nicht importiert werden knnen.
  • Die meisten JavaScript-Funktionen sind extrem grozgig in Bezug auf die Arten von Werten, die sie akzeptieren, und es ist wnschenswert, das Typsystem von WebAssembly zu nutzen, um diese berprfungen und Umwandlungen so weit wie mglich zu eliminieren.

Angesichts dieser Probleme ist es einfacher und besser fr die Leistung, eingebaute Definitionen zu erstellen, die bestehende JavaScript-Funktionalitten wie String-Primitive an WebAssembly anpassen, anstatt sie zu importieren und sich auf indirekte Funktionsaufrufe zu verlassen.

Verfgbare WebAssembly JavaScript Builtins

Die folgenden Abschnitte beschreiben die verfgbaren Builtins. Andere Builtins werden voraussichtlich in Zukunft untersttzt.

String-Operationen

Die verfgbaren String Builtins sind:

"wasm:js-string" "cast"

Wirft einen Fehler, wenn der bereitgestellte Wert kein String ist. Grob quivalent zu:

js
if (typeof obj !== "string") throw new WebAssembly.RuntimeError();
"wasm:js-string" "compare"

Vergleicht zwei String-Werte und bestimmt ihre Reihenfolge. Gibt -1 zurck, wenn der erste String kleiner als der zweite ist, 1, wenn der erste String grer als der zweite ist, und 0, wenn die Strings streng gleich sind.

"wasm:js-string" "concat"

Entspricht String.prototype.concat().

"wasm:js-string" "charCodeAt"

Entspricht String.prototype.charCodeAt().

"wasm:js-string" "codePointAt"

Entspricht String.prototype.codePointAt().

"wasm:js-string" "equals"

Vergleicht zwei String-Werte auf strikte Gleichheit, gibt 1 zurck, wenn sie gleich sind, und 0, wenn nicht.

Hinweis: Die "equals"-Funktion ist das einzige String-Builtin, das bei null-Eingaben keinen Fehler auslst, sodass Wasm-Module nicht auf null-Werte prfen mssen, bevor sie es aufrufen. Alle anderen Funktionen haben keine sinnvolle Mglichkeit, null-Eingaben zu verarbeiten und werfen daher bei ihnen einen Fehler.

"wasm:js-string" "fromCharCode"

Entspricht String.fromCharCode().

"wasm:js-string" "fromCharCodeArray"

Erzeugt einen String aus einem Wasm-Array von i16-Werten.

"wasm:js-string" "fromCodePoint"

Entspricht String.fromCodePoint().

"wasm:js-string" "intoCharCodeArray"

Schreibt die Zeichen-Codes eines Strings in ein Wasm-Array von i16-Werten.

"wasm:js-string" "length"

Entspricht String.prototype.length.

"wasm:js-string" "substring"

Entspricht String.prototype.substring().

"wasm:js-string" "test"

Gibt 0 zurck, wenn der bereitgestellte Wert kein String ist, oder 1, wenn er ein String ist. Grob quivalent zu:

js
typeof obj === "string";

Wie benutzt man Builtins?

Builtins funktionieren hnlich wie aus JavaScript importierte Funktionen, auer dass Sie Standard-Wasm-Funktionsquivalente verwenden, um JavaScript-Operationen auszufhren, die in einem reservierten Namensraum (wasm:) definiert sind. Da dies der Fall ist, knnen Browser optimalen Code fr sie vorhersagen und generieren. In diesem Abschnitt wird zusammengefasst, wie man sie verwendet.

JavaScript API

Builtins werden zur Kompilierzeit aktiviert, indem die Eigenschaft compileOptions.builtins als Argument angegeben wird, wenn Methoden zum Kompilieren und/oder Instanziieren eines Moduls aufgerufen werden. Ihr Wert ist ein Array von Strings, das die Sets von Builtins identifiziert, die Sie aktivieren mchten:

js
WebAssembly.compile(bytes, { builtins: ["js-string"] });

Das compileOptions-Objekt steht den folgenden Funktionen zur Verfgung:

WebAssembly-Modul-Features

In Ihrem WebAssembly-Modul knnen Sie jetzt Builtins wie im compileOptions-Objekt aus dem wasm:-Namensraum spezifiziert importieren (in diesem Fall die concat()-Funktion; siehe auch die quivalente eingebaute Definition):

wat
(func $concat (import "wasm:js-string" "concat")
    (param externref externref) (result (ref extern)))

Featureerkennung von Builtins

Beim Verwenden von Builtins sind Typberprfungen strenger als ohne bestimmte Regeln werden fr die Builtin-Importe auferlegt.

Daher knnen Sie zur Featureerkennung von Builtins ein Modul definieren, das ungltig mit vorhandenem Feature und gltig ohne es ist. Sie geben dann true zurck, wenn die Validierung fehlschlgt, um die Untersttzung anzuzeigen. Ein einfaches Modul, das dies erreicht, sieht wie folgt aus:

wat
(module
  (function (import "wasm:js-string" "cast")))

Ohne Builtins ist das Modul gltig, da Sie jede Funktion mit beliebiger Signatur importieren knnen (in diesem Fall: keine Parameter und keine Rckgabewerte). Mit Builtins ist das Modul ungltig, da die jetzt speziell behandelte "wasm:js-string" "cast"-Funktion eine bestimmte Signatur haben muss (ein externref-Parameter und ein nicht-nullbarer (ref extern)-Rckgabewert).

Sie knnen dann versuchen, dieses Modul mit der validate()-Methode zu validieren, beachten Sie jedoch, wie das Ergebnis mit dem !-Operator negiert wird denken Sie daran, dass Builtins untersttzt werden, wenn das Modul ungltig ist:

js
const compileOptions = {
  builtins: ["js-string"],
};

fetch("module.wasm")
  .then((response) => response.arrayBuffer())
  .then((bytes) => WebAssembly.validate(bytes, compileOptions))
  .then((result) => console.log(`Builtins available: ${!result}`));

Der obige Modulcode ist so kurz, dass Sie einfach die Literalbytes validieren knnen, anstatt das Modul herunterzuladen. Eine Featureerkennungsfunktion knnte folgendermaen aussehen:

js
function JsStringBuiltinsSupported() {
  let bytes = new Uint8Array([
    0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 2, 23, 1, 14, 119, 97, 115,
    109, 58, 106, 115, 45, 115, 116, 114, 105, 110, 103, 4, 99, 97, 115, 116, 0,
    0,
  ]);
  return !WebAssembly.validate(bytes, { builtins: ["js-string"] });
}

Hinweis: In vielen Fllen gibt es Alternativen zur Featureerkennung von Builtins. Eine andere Option knnte sein, regulre Importe neben den Builtins bereitzustellen, und untersttzende Browser ignorieren einfach die Rckfallebenen.

Builtins-Beispiel

Gehen wir ein einfaches, aber vollstndiges Beispiel durch, um zu zeigen, wie Builtins verwendet werden. Dieses Beispiel definiert eine Funktion in einem Wasm-Modul, die zwei Strings zusammenfgt und das Ergebnis in der Konsole ausgibt, dann exportiert. Wir werden dann die exportierte Funktion aus JavaScript aufrufen.

Das Beispiel, auf das wir uns beziehen, verwendet die Funktion WebAssembly.instantiate() auf der Webseite, um die Kompilierung und Instanziierung zu handhaben; Sie finden dieses und andere Beispiele in unserem webassembly-examples-Repo siehe js-builtin-examples.

Sie knnen das Beispiel aufbauen, indem Sie die folgenden Schritte befolgen. Zustzlich knnen Sie es live laufen sehen ffnen Sie die JavaScript-Konsole Ihres Browsers, um die Beispielausgabe zu sehen.

JavaScript

Das JavaScript fr das Beispiel ist unten gezeigt. Um dies lokal zu testen, fgen Sie es in eine HTML-Seite mit einer Methode Ihrer Wahl ein (zum Beispiel innerhalb von <script>-Tags oder in einer externen .js-Datei, die ber <script src=""> referenziert wird).

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());

Das JavaScript:

  • Definiert ein importObject, das eine Funktion "log" in einem Namespace "m" spezifiziert, die whrend der Instanziierung in das Wasm-Modul importiert wird. Es ist die console.log() Funktion.
  • Definiert ein compileOptions-Objekt, das Folgendes umfasst:
  • Verwendet fetch(), um das Wasm-Modul (log-concat.wasm) abzurufen, konvertiert die Antwort zu einem ArrayBuffer mit Response.arrayBuffer, und kompiliert und instanziiert dann das Wasm-Modul mit WebAssembly.instantiate().
  • Ruft die main()-Funktion auf, die aus dem Wasm-Modul exportiert wird.

Wasm-Modul

Die Textdarstellung unseres WebAssembly-Modulcodes sieht so aus:

wat
(module
  (global $h (import "string_constants" "hello ") externref)
  (global $w (import "string_constants" "world!") externref)
  (func $concat (import "wasm:js-string" "concat")
    (param externref externref) (result (ref extern)))
  (func $log (import "m" "log") (param externref))
  (func (export "main")
    (call $log (call $concat (global.get $h) (global.get $w))))
)

Dieser Code:

  • Importiert zwei globale String-Konstanten, "hello " und "world!", mit dem Namensraum "string_constants" wie im JavaScript angegeben. Sie erhalten die Namen $h und $w.
  • Importiert das concat Builtin aus dem wasm: Namensraum, gibt ihm den Namen $concat und legt fest, dass es zwei Parameter und einen Rckgabewert hat.
  • Importiert die importierte "log" Funktion aus dem "m" Namensraum, wie im JavaScript importObject Objekt angegeben, gibt ihr den Namen $log und legt fest, dass sie ein Parameter hat. Wir entschieden uns, ein regulres Import sowie ein Builtin im Beispiel einzuschlieen, um Ihnen zu zeigen, wie die beiden Anstze sich vergleichen.
  • Definiert eine Funktion, die unter dem Namen "main" exportiert wird. Diese Funktion ruft $log auf, wobei sie einen $concat-Aufruf als Parameter bergibt. Der $concat-Aufruf wird mit den $h und $w globalen Zeichenfolgenkonstanten als Parameter bergeben.

Um Ihr lokales Beispiel zum Laufen zu bringen:

  1. Speichern Sie den oben gezeigten WebAssembly-Modulcode in einer Textdatei mit dem Namen log-concat.wat im selben Verzeichnis wie Ihr HTML/JavaScript.

  2. Kompilieren Sie ihn in ein WebAssembly-Modul (log-concat.wasm) mit dem wasm-as-Werkzeug, das Teil der Binaryen-Bibliothek ist (siehe die Bauanleitungen). Sie mssen wasm-as mit aktivierten Referenztypen und Speicherbereinigung (GC) ausfhren, damit diese Beispiele erfolgreich kompiliert werden:

    sh
    wasm-as --enable-reference-types -enable-gc log-concat.wat
    

    Oder Sie knnen das -all-Flag anstelle von --enable-reference-types -enable-gc verwenden:

    sh
    wasm-as -all log-concat.wat
    
  3. Laden Sie Ihre Beispiel-HTML-Seite in einem untersttzenden Browser mit einem lokalen HTTP-Server.

Das Ergebnis sollte eine leere Webseite sein, mit "hello world!", das in der JavaScript-Konsole ausgegeben wird, generiert durch eine exportierte Wasm-Funktion. Das Protokollieren wurde mit einer aus JavaScript importierten Funktion durchgefhrt, whrend das Zusammenfgen der zwei ursprnglichen Strings durch ein Builtin erfolgte.


Web Proxy Viewer  |  New URL  |  Original Page