WebAssembly - Kurzanleitung
WebAssembly ist eine neue Computerprogrammiersprache für das Web. WebAssembly-Code ist ein einfaches Binärformat, das mit dem Web kompatibel ist und problemlos in modernen Webbrowsern ausgeführt werden kann. Die generierte Dateigröße ist klein und wird schneller geladen und ausgeführt. Sie können jetzt Sprachen wie C, C ++, Rust usw. im Binärformat kompilieren und es kann wie Javascript im Web ausgeführt werden.
Definition von WebAssembly
Gemäß der offiziellen Website von WebAssembly, die unter verfügbar ist https://webassembly.org/ist definiert als WebAssembly (abgekürzt als Wasm) ist ein binäres Befehlsformat für eine stapelbasierte virtuelle Maschine. Wasm wurde als portables Ziel für die Kompilierung von Hochsprachen wie C / C ++ / Rust entwickelt und ermöglicht die Bereitstellung im Web für Client- und Serveranwendungen.
Web Assembly muss ein Entwickler nicht schreiben, aber der Code ist in Sprachen wie C, C ++, Rust geschrieben und kann zu WebAssembly (wasm) kompiliert werden. Der gleiche Code kann in den Webbrowsern ausgeführt werden.
Web Assembly ist eine neue Sprache, der Code ist eine Assemblersprache auf niedriger Ebene, aber mit seiner Textformatfunktion ist der Code lesbar und das Debuggen ist bei Bedarf möglich.
Ziele von WebAssembly
Die offenen Standards für WebAssembly werden in einer W3C-Community-Gruppe entwickelt, der Vertreter aller gängigen Browser sowie einer W3C-Arbeitsgruppe angehören.
Die Hauptziele von WebAssembly sind unten aufgeführt:
Faster, Efficient and Portable - WebAssembly-Code soll auf verschiedenen Plattformen schneller ausgeführt werden und die verfügbare Hardware nutzen.
Easy to read and debug - WebAssembly ist eine einfache Assemblersprache und unterstützt das Textformat, mit dem Sie den Code bei Problemen debuggen und bei Bedarf auch neu schreiben können.
Security - WebAssembly kann sicher in den Webbrowsern ausgeführt werden, da Berechtigungen und Richtlinien mit demselben Ursprung berücksichtigt werden.
Vorteile von WebAssembly
Im Folgenden sind die Vorteile von WebAssembly aufgeführt:
Run is Modern Browsers - WebAssembly kann problemlos in den verfügbaren modernen Webbrowsern ausgeführt werden.
Multiple Language support- Sprachen wie C, C ++, Rust, Go können jetzt den Code in WebAssembly kompilieren und in Webbrowsern ausführen. Die Sprachen, die nicht in einem Browser ausgeführt werden konnten, können dies nun tun.
Faster, Efficient and Portable - Aufgrund der geringen Größe des Codes wird er schneller geladen und ausgeführt.
Easy to understand- Entwickler müssen beim Verständnis der WebAssembly-Codierung nicht viel Stress aufbringen, da sie den Code nicht in WebAssembly schreiben müssen. Kompilieren Sie stattdessen den Code in WebAssembly und führen Sie ihn im Web aus.
Easy to Debug - Obwohl der endgültige Code in einer Assemblersprache auf niedriger Ebene vorliegt, können Sie ihn auch im Textformat abrufen, das einfach zu lesen und zu debuggen ist.
Nachteile von WebAssembly
Im Folgenden sind die Nachteile von WebAssembly aufgeführt:
An WebAssembly wird noch gearbeitet, und es ist noch zu früh, um über die Zukunft zu entscheiden.
WebAssembly ist für die Interaktion mit dem Document Object Model (DOM) auf Javascript angewiesen.
WebAssembly wird auch als WASM bezeichnet, das erstmals im Jahr 2017 eingeführt wurde. Die großen Technologieunternehmen, die hinter der Entstehung von WebAssembly stehen, sind Google, Apple, Microsoft, Mozilla und W3C.
Das Gerücht ist, dass WebAssembly Javascript aufgrund seiner schnelleren Ausführung ersetzen wird, aber das ist nicht der Fall. WebAssembly und Javascript sollen zusammenarbeiten, um die komplexen Probleme zu lösen.
Notwendigkeit für WebAssembly
Bisher haben wir nur Javascript, das im Browser erfolgreich funktionieren kann. Es gibt sehr schwere Aufgaben, die in den Browsern mit Javascript schwer auszuführen sind.
Um nur einige zu nennen: Bilderkennung, CAD-Anwendungen (Computer Aided Design), Live-Videoerweiterung, VR und Augmented Reality, Musikanwendungen, wissenschaftliche Visualisierung und Simulation, Spiele, Bild- / Videobearbeitung usw.
WebAssembly ist eine neue Sprache mit binären Anweisungen, die schneller geladen und ausgeführt werden können. Die oben genannte Aufgabe kann problemlos in Hochsprachen wie C, C ++, Rust usw. ausgeführt werden. Wir benötigen eine Möglichkeit, den Code in C, C ++, Rust zu kompilieren und in Webbrowsern zu verwenden. Das gleiche ist mit WebAssembly möglich.
Wenn der WebAssembly-Code in den Browser geladen wird. Anschließend kümmert sich der Browser um die Konvertierung in ein Maschinenformat, das von den Prozessoren verstanden werden kann.
Für Javascript muss der Code heruntergeladen, analysiert und in das Maschinenformat konvertiert werden. Es wird viel Zeit investiert und für schwere Aufgaben wie die zuvor erwähnten kann es sehr langsam sein.
Funktionsweise von WebAssembly
Hochsprachen wie C, C ++ und Rust werden im Binärformat kompiliert, d. H. .wasm und Textformat .wat.
Der in C, C ++ und Rust geschriebene Quellcode wird kompiliert .wasmmit einem Compiler. Sie können das Emscripten SDK zum Kompilieren von C / C ++ verwenden.wasm.
Der Fluss ist wie folgt -
C / C ++ - Code kann kompiliert werden .wasmmit Emscripten SDK. Später wurde die.wasm Code kann mit Hilfe von Javascript in Ihrer HTML-Datei verwendet werden, um die Ausgabe anzuzeigen.
Schlüsselkonzepte von WebAssembly
Die Schlüsselkonzepte sind wie folgt erläutert -
Modul
Ein Modul ist ein Objekt, das vom Browser zu ausführbarem Maschinencode kompiliert wird. Ein Modul soll zustandslos sein und kann von Windows- und Web-Workern gemeinsam genutzt werden.
Erinnerung
Speicher in WebAssembly ist ein arraybufferdas hält die Daten. Sie können Speicher mithilfe der Javascript-API WebAssembly.memory () zuweisen.
Tabelle
Die Tabelle in WebAssembly ist ein typisiertes Array, das sich außerhalb des WebAssembly-Speichers befindet und hauptsächlich auf Funktionen verweist. Es speichert die Speicheradresse der Funktionen.
Beispiel
Instanz ist ein Objekt, das alle exportierten Funktionen enthält, die aus Javascript aufgerufen werden können, um im Browser ausgeführt zu werden.
WebAssembly wird auch als wasm bezeichnet, was eine Verbesserung von Javascript darstellt. Es wurde entwickelt, um in Browsern wie Javascript und auch mit NodeJS ausgeführt zu werden. Sie erhalten zufällig eine WASM-Ausgabe, wenn eine Hochsprache wie C, C ++, Rust kompiliert wird.
Betrachten Sie das folgende C-Programm -
int factorial(int n) {
if (n == 0)
return 1;
else
return n * factorial(n-1);
}
Nutzen Sie den WasmExplorer, der unter verfügbar isthttps://mbebenita.github.io/WasmExplorer/ um den kompilierten Code wie unten gezeigt zu erhalten -
Das WebAssembly-Textformat für das Fakultätsprogramm lautet wie folgt:
(module
(table 0 anyfunc)
(memory $0 1) (export "memory" (memory $0)) (export "factorial" (func $factorial)) (func $factorial (; 0 ;) (param $0 i32) (result i32) (local $1 i32)
(local $2 i32) (block $label$0 (br_if $label$0 (i32.eqz (get_local $0)
)
)
(set_local $2 (i32.const 1) ) (loop $label$1 (set_local $2
(i32.mul
(get_local $0) (get_local $2)
)
)
(set_local $0 (tee_local $1 (i32.add
(get_local $0) (i32.const -1) ) ) ) (br_if $label$1 (get_local $1)
)
)
(return
(get_local $2)
)
)
(i32.const 1)
)
)
Mit dem Wat2Wasm-Tool können Sie den WASM-Code wie unten beschrieben anzeigen.
Entwickler sollten keinen Code in wasm schreiben oder lernen, darin zu codieren, da dieser meistens beim Kompilieren von Hochsprachen generiert wird.
Stapelmaschinenmodell
In WASM werden alle Anweisungen auf den Stapel übertragen. Die Argumente werden gelöscht und das Ergebnis auf den Stapel zurückgeschoben.
Betrachten Sie das folgende WebAssembly-Textformat, das 2 Zahlen hinzufügt:
(module
(func $add (param $a i32) (param $b i32) (result i32)
get_local $a get_local $b
i32.add
)
(export "add" (func $add))
)
Der Name der Funktion lautet $addEs dauert 2 Parameter $a and $b. Das Ergebnis ist eine 32-Bit-Ganzzahl vom Typ. Auf die lokalen Variablen wird mit get_local zugegriffen, und die Add-Operation wird mit i32.add ausgeführt.
Die Stapeldarstellung zum Hinzufügen von 2 Zahlen während der Ausführung lautet wie folgt:
Im step 1 - Die Ausführung von get_local $a instruction, the first parameters i.e., $a wird auf den Stapel geschoben.
Im step 2 - Während der Ausführung von get_local $b instruction, the second parameters i.e., $b wird auf den Stapel geschoben.
Im step 3- Durch die Ausführung von i32.add werden die Elemente aus dem Stapel entfernt und das Ergebnis auf den Stapel zurückgeschoben. Der Wert, der am Ende im Stapel verbleibt, ist das Ergebnis der Funktion $ add.
In diesem Kapitel erfahren Sie, wie Sie das Emscripten SDK installieren, um C / C ++ zu kompilieren. Emscripten ist eine Low Level Virtual Machine (LLVM), die aus C / C ++ generierten Bytecode in JavaScript kompiliert, das problemlos im Browser ausgeführt werden kann.
Um C / C ++ zu WebAssembly zu kompilieren, müssen wir zuerst Emscripten sdk installieren.
Installieren Sie Emscripten sdk
Die Schritte zum Installieren von Emscripten sdk sind wie folgt:
Step 1 - Klonen Sie das emsdk repo: git clone https://github.com/emscripten-core/emsdk.git.
E:\wa>git clone https://github.com/emscripten-core/emsdk.git
Cloning into 'emsdk'...
remote: Enumerating objects: 14, done.
remote: Counting objects: 100% (14/14), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 1823 (delta 4), reused 4 (delta 2), pack-reused 1809 receiving obje
cts: 99% (1819/1823), 924.01 KiB | 257.00 KiB/s
Receiving objects: 100% (1823/1823), 1.01 MiB | 257.00 KiB/s, done.
Resolving deltas: 100% (1152/1152), done.
Step 2 - Geben Sie in das Verzeichnis emsdk ein.
cd emsdk
Step 3 - Für Windows: Führen Sie den folgenden Befehl aus.
emsdk install latest
For linuxDieser Befehl benötigt einige Zeit, um die erforderlichen Tools wie Java, Python usw. zu installieren. Befolgen Sie den unten angegebenen Code -
./emsdk install latest
Step 4 - Um das neueste SDK zu aktivieren, führen Sie den folgenden Befehl in Ihrem Terminal aus.
For windowsFühren Sie den folgenden Befehl aus:
emsdk activate latest
For linuxFühren Sie den folgenden Befehl aus -
./emsdk activate latest
Step 5 - Um PATH und andere Umgebungsvariablen zu aktivieren, führen Sie den folgenden Befehl in Ihrem Terminal aus.
For windows, führen Sie den Befehl aus -
emsdk_env.bat
For linuxFühren Sie den folgenden Befehl aus:
source ./emsdk_env.sh
Wir sind mit der Installation des emsdk fertig und können nun C- oder C ++ - Code kompilieren. Die Kompilierung von C / C ++ erfolgt in den nächsten Kapiteln.
So kompilieren Sie C- oder C ++ - Code wie folgt:
emcc source.c or source.cpp -s WASM=1 -o source.html
Die Ausgabe gibt Ihnen eine Datei source.html, source.js und source.wasm. Das js hat die API, die die source.wasm abruft, und Sie können die Ausgabe sehen, wenn Sie im Browser auf source.html klicken.
Um nur die WASM-Datei zu erhalten, können Sie den folgenden Befehl verwenden. Dieser Befehl gibt Ihnen nur die Datei source.wasm.
emcc source.c or source.cpp -s STANDALONE_WASM
In diesem Kapitel werden einige benutzerfreundliche Tools erläutert, die bei der Arbeit mit WebAssembly sehr hilfreich sind. Beginnen wir mit dem WebAssembly.studio-Tool.
WebAssembly.studio
Mit diesem Tool können Sie C, Rust, Wat to Wasm usw. kompilieren.
Zunächst können Sie auf C-Projekt leeren, Rostprojekt leeren, Wat-Projekt leeren klicken, um C und Rust to WASM zu kompilieren. 5.
Es verfügt über Build, Run, um den Code zu erstellen und die Ausgabe zu überprüfen. Über den Download-Button können Sie herunterladen.wasmDatei, die zum Testen im Browser verwendet werden kann. Dieses Tool ist sehr hilfreich, um C- und Rust-Code zu kompilieren und die Ausgabe zu überprüfen.
WebAssembly Explorer
Mit WebAssembly Explorer können Sie C- und C ++ - Code kompilieren. Siehe den Linkhttps://mbebenita.github.io/WasmExplorer/für mehr Details. Der Bildschirm, der nach dem Klicken auf den Link angezeigt wird, wird unten angezeigt -
Sie können die C- und C ++ - Version auswählen. Der Quellcode von C oder C ++ wird hier geschrieben -
Wenn Sie auf die Schaltfläche Kompilieren klicken, werden das WebAssembly-Textformat (WAT) und der Firefox x86-Assemblycode in den folgenden Blöcken angezeigt.
Sie können die herunterladen .wasm Code zum Testen im Browser.
WASMFiddle
Mit Wasmfiddle können Sie C-Code in WebAssembly kompilieren und die Ausgabe testen. Nach dem Klicken auf den Linkhttps://wasdk.github.io/WasmFiddle/, Sie sehen die folgende Seite -
Klicken Sie auf Erstellen, um den Code zu kompilieren. Sie können den Wat and Wasm-Code herunterladen, indem Sie auf Wat and Wasm klicken. Um die Ausgabe zu testen, klicken Sie auf die Schaltfläche Ausführen.
WASM zu WAT
Das Werkzeug wat2wasmSie erhalten einen WASM-Code, wenn Sie das WebAssembly-Textformat eingeben. Sie können auf den Link klickenhttps://webassembly.github.io/wabt/demo/wat2wasm/ für die Demo und der Bildschirm, der angezeigt wird, ist unten angegeben -
Sie können die Schaltfläche zum Hochladen verwenden, um .wasm hochzuladen. Im Textbereich wird das Textformat angezeigt.
WAT zu WASM
Das Tool wat2wasm gibt Ihnen Wasm-Code, wenn Sie das WebAssembly-Textformat eingeben. Sie können auf den Link klickenhttps://webassembly.github.io/wabt/demo/wat2wasm/ für die Demo und der Bildschirm, der angezeigt wird, ist unten angegeben -
Dieses Tool ist sehr hilfreich, da es hilft, die Ausgabe auch zu testen. Sie können den WAT-Code eingeben, den .wasm-Code anzeigen und den Code ausführen, um die Ausgabe anzuzeigen.
WebAssembly, auch WASM genannt, ist Low-Level-Code im Binärformat, der entwickelt wurde, um in Browsern auf die effizienteste Weise ausgeführt zu werden. Der WebAssembly-Code ist mit folgenden Konzepten strukturiert:
- Values
- Types
- Instructions
Lassen Sie uns sie jetzt im Detail lernen.
Werte
Werte in WebAssembly sollen komplexe Daten wie Text, Zeichenfolgen und Vektoren speichern. WebAssembly unterstützt Folgendes:
- Bytes
- Integers
- Gleitkomma
- Names
Bytes
Bytes ist die einfachste Form von Werten, die in WebAssembly unterstützt werden. Der Wert ist hexadezimal.
For exampleAls b dargestellte Bytes können auch natürliche Zahlen n annehmen, wobei n <256 ist.
byte ::= 0x00| .... |0xFF
Ganzzahlen
In WebAssembly werden folgende Ganzzahlen unterstützt:
- i32: 32-Bit-Ganzzahl
- i64: 64-Bit-Ganzzahl
Gleitkomma
In WebAssembly werden folgende Gleitkommazahlen unterstützt:
- f32: 32-Bit-Gleitkomma
- f64: 64-Bit-Gleitkomma
Namen
Namen sind Zeichenfolgen mit durch Unicode definierten Skalarwerten, die unter dem Link verfügbar sind http://www.unicode.org/versions/Unicode12.1.0/ hiermit gegeben.
Typen
Die Entitäten in WebAssembly werden als Typen klassifiziert. Die unterstützten Typen sind wie folgt:
- Werttypen
- Ergebnistypen
- Funktionstypen
- Limits
- Speichertypen
- Tabellentypen
- Globale Typen
- Externe Typen
Lassen Sie uns sie einzeln studieren.
Werttypen
Der von WebAssembly unterstützte Wertetyp lautet wie folgt:
- i32: 32-Bit-Ganzzahl
- i64: 64-Bit-Ganzzahl
- f32: 32-Bit-Gleitkomma
- f64: 64-Bit-Gleitkomma
valtype ::= i32|i64|f32|f64
Ergebnistypen
Die in Klammern geschriebenen Werte werden ausgeführt und in Ergebnistypen gespeichert. Der Ergebnistyp ist die Ausgabe der Ausführung eines aus Werten bestehenden Codeblocks.
resulttype::=[valtype?]
Funktionstypen
Ein Funktionstyp nimmt einen Vektor von Parametern auf und gibt einen Vektor von Ergebnissen zurück.
functype::=[vec(valtype)]--> [vec(valtype)]
Grenzen
Grenzwerte sind der Speicherbereich, der mit Speicher- und Tabellentypen verknüpft ist.
limits ::= {min u32, max u32}
Speichertypen
Speichertypen befassen sich mit linearen Speichern und dem Größenbereich.
memtype ::= limits
Tabellentypen
Tabellentypen werden nach dem ihr zugewiesenen Elementtyp klassifiziert.
tabletype ::= limits elemtype
elemtype ::= funcref
Der Tabellentyp hängt von der Grenze für die ihm zugewiesene minimale und maximale Größe ab.
Globale Typen
Globaler Typ enthält die globalen Variablen, die den Wert haben, der sich ändern oder gleich bleiben kann.
globaltype ::= mut valtype
mut ::= const|var
Externe Typen
Externe Typen befassen sich mit Importen und externen Werten.
externtype ::= func functype | table tabletype | mem memtype | global globaltype
Anleitung
Der WebAssembly-Code ist eine Folge von Anweisungen, die einem Stapelmaschinenmodell folgen. Da WebAssembly einem Stapelmaschinenmodell folgt, werden die Anweisungen auf den Stapel übertragen.
Die Argumentwerte für eine Funktion werden beispielsweise vom Stapel entfernt und das Ergebnis wird auf den Stapel zurückgeschoben. Am Ende gibt es nur einen Wert im Stapel und das ist das Ergebnis.
Einige der häufig verwendeten Anweisungen lauten wie folgt:
- Numerische Anweisungen
- Variable Anweisungen
Numerische Anweisungen
Numerische Anweisungen sind Operationen, die mit numerischen Werten ausgeführt werden.
For examplenn, mm ::= 32|64
ibinop ::= add|sub|mul|div_sx|rem_sx|and|or|xor
irelop ::= eq | ne | lt_sx | gt_sx | le_sx | ge_sx
frelop ::= eq | ne | lt | gt | le | ge
Variable Anweisungen
Bei Variablenanweisungen geht es um den Zugriff auf lokale und globale Variablen.
For example
So greifen Sie auf lokale Variablen zu -
get_local $a
get_local $b
Zu set lokale Variablen -
set_local $a
set_local $b
Zu access globale Variablen -
get_global $a
get_global $b
Zu set globale Variablen -
set_global $a
set_global $b
In diesem Kapitel wird der Vergleich zwischen WebAssembly und Javascript aufgeführt.
Javascript ist eine Sprache, die wir im Browser häufig verwendet haben. Mit der WebAssembly-Version können wir WebAssembly jetzt auch im Browser verwenden.
Der Grund für die Gründung von WebAssembly besteht nicht darin, Javascript zu ersetzen, sondern bestimmte Dinge zu erledigen, die mit Javascript schwer zu handhaben sind.
For example
Es ist schwierig, Aufgaben wie Bilderkennung, CAD-Anwendungen, Live-Video-Erweiterung, VR und Augmented Reality, Musikanwendungen, wissenschaftliche Visualisierung und Simulation, Spiele, Bild- / Videobearbeitung usw. mit Javascript zu erledigen.
Mit Hochsprachen wie C / C ++, Rust, die jetzt zu WebAssembly kompiliert werden können, ist es einfach, die oben genannte Aufgabe zu erledigen. WebAssembly generiert einen Binärcode, der einfach im Browser ausgeführt werden kann.
Hier ist die Liste der Vergleiche zwischen Javascript und WebAssembly.
Parameter | Javascript | WebAssembly |
---|---|---|
Codierung |
Sie können einfach Code in Javascript schreiben. Der geschriebene Code ist für Menschen lesbar und wird als .js gespeichert. Bei Verwendung im Browser müssen Sie ein <script> -Tag verwenden. |
Der Code kann in WebAssembly im Textformat geschrieben und als .wat gespeichert werden. Es ist schwierig, den Code im .wat-Format zu schreiben. Es ist am besten, den Code aus einer anderen Hochsprache zu kompilieren, anstatt von Anfang an in .wat zu schreiben. Sie können die .wat-Datei nicht im Browser ausführen und müssen sie mit den verfügbaren Compilern oder Online-Tools in .wasm konvertieren. |
Ausführung |
Der im Browser in Javascript geschriebene Code muss heruntergeladen, analysiert, kompiliert und optimiert werden. |
Wir haben WebAssembly-Code in .wasm bereits kompiliert und im Binärformat. |
Speicherverwaltung |
Javascript weist Speicher zu, wenn Variablen erstellt und der Speicher freigegeben wird, wenn er nicht verwendet wird, und wird zur Speicherbereinigung hinzugefügt. |
Der Speicher in WebAssembly ist ein Array-Puffer, der die Daten enthält. Sie können Speicher mithilfe der Javascript-API WebAssembly.memory () zuweisen. Der WebAssembly-Speicher wird in einem Array-Format gespeichert, dh einem flachen Speichermodell, das leicht zu verstehen ist und die Ausführung ausführt. Der Nachteil des Speichermodells in WebAssembly ist -
|
Ladezeit & Leistung |
Im Falle von Javascript muss beim Aufrufen im Browser die Javascript-Datei heruntergeladen und analysiert werden. Später konvertiert der Parser den Quellcode in Bytecode, den die Javascript-Engine im Browser ausführt. Die Javascript-Engine ist sehr leistungsfähig und daher ist die Ladezeit und Leistung von Javascript im Vergleich zu WebAssembly sehr schnell. |
Ein wichtiges Ziel von WebAssembly ist es, schneller als JavaScript zu sein. Wasm-Code, der aus Hochsprachen generiert wird, ist kleiner und daher die Ladezeit schneller. Aber Sprachen wie GO erzeugen, wenn sie zu wasm kompiliert werden, eine große Dateigröße für ein kleines Stück Code. WebAssembly ist so konzipiert, dass es schneller kompiliert werden kann und in allen gängigen Browsern ausgeführt werden kann. WebAssembly muss im Vergleich zu Javascript noch viele Leistungsverbesserungen hinzufügen. |
Debuggen |
Javascript ist für Menschen lesbar und kann leicht debuggt werden. Durch Hinzufügen von Haltepunkten zu Ihrem Javascript-Code im Browser können Sie den Code einfach debuggen. |
WebAssembly stellt den Code im Textformat bereit, das lesbar, aber immer noch sehr schwer zu debuggen ist. Mit Firefox können Sie den Wasm-Code im .wat-Format im Browser anzeigen. Sie können in .wat keine Haltepunkte hinzufügen, und das wird in Zukunft verfügbar sein. |
Browser-Unterstützung |
Javascript funktioniert gut in allen Browsern. |
Alle gängigen Webbrowser unterstützen WebAssembly. |
In diesem Kapitel erfahren Sie, wie Sie den Wasm-Code laden und mithilfe der Javascript-Webassembly-API im Browser ausführen.
Hier sind einige wichtige APIs, die wir im gesamten Tutorial verwenden werden, um Wasm-Code auszuführen.
- fetch () Browser API
- WebAssembly.compile
- WebAssembly.instance
- WebAssembly.instantiate
- WebAssembly.instantiateStreaming
Bevor wir die WebAssembly-Javascript-APIs diskutieren, verwenden wir zum Testen der API und der Ausgabe das folgende C-Programm und den aus dem c-Programm generierten .wasm-Code mit dem wasm explorer.
Ein Beispiel für das C-Programm lautet wie folgt:
#include<stdio.h>
int square(int n) {
return n*n;
}
Wir werden den WASM-Explorer verwenden, um den Wasm-Code zu erhalten -
Laden Sie den WASM-Code herunter und testen Sie damit die APIs.
fetch () Browser API
Die fetch () - API dient zum Laden der .wasm-Netzwerkressource.
<script>
var result = fetch("findsquare.wasm");
console.log(result);
</script>
Es gibt ein Versprechen zurück, wie unten gezeigt -
Sie können auch die XMLHttpRequest-Methode verwenden, um die wasm-Netzwerkressource abzurufen.
WebAssembly.compile ()
Die API-Verantwortung besteht darin, die Moduldetails zu kompilieren, die aus .wasm abgerufen werden.
Syntax
Die Syntax ist wie folgt -
WebAssembly.compile(buffer);
Parameter
Buffer - Dieser Code aus .wasm muss in ein typisiertes Array oder einen Array-Puffer konvertiert werden, bevor er als Eingabe zum Kompilieren angegeben wird.
Rückgabewert
Es wird ein Versprechen zurückgegeben, das das kompilierte Modul enthält.
Beispiel
Sehen wir uns ein Beispiel an, das die Ausgabe als kompiliertes Modul mit webAssembly.compile () liefert.
<script>
fetch("findsquare.wasm") .then(bytes => bytes.arrayBuffer())
.then(mod => {
var compiledmod = WebAssembly.compile(mod);
compiledmod.then(test=> {
console.log(test);
})
})
</script>
Ausgabe
Wenn die Datei console.log im Browser aktiviert ist, erhalten Sie die kompilierten Moduldetails.
Das Modul verfügt über ein Konstruktorobjekt mit Importen, Exporten und benutzerdefinierten Abschnitten. Sehen wir uns die nächste API an, um weitere Details des kompilierten Moduls zu erhalten.
WebAssembly.instance
Unter Verwendung der WebAssembly.instance gibt Ihnen die API die ausführbare Instanz des kompilierten Moduls, die weiter ausgeführt werden kann, um die Ausgabe abzurufen.
Syntax
Die Syntax ist wie folgt -
new WebAssembly.Instance(compiled module)
Rückgabewert
Der Rückgabewert ist ein Objekt mit der Array-Exportfunktion, die ausgeführt werden kann.
Beispiel
<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>
Ausgabe
Die Ausgabe gibt uns eine Reihe von Exportfunktionen, wie unten gezeigt -
Sie können die quadratische Funktion sehen, die wir aus dem kompilierten C-Code erhalten haben.
Um die Quadratfunktion auszuführen, können Sie Folgendes tun:
<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>
Die Ausgabe wird -
225
WebAssembly.instantiate
Diese API übernimmt das gemeinsame Kompilieren und Instanziieren des Moduls.
Syntax
Die Syntax lautet wie folgt:
WebAssembly.instantiate(arraybuffer, importObject)
Parameter
arraybuffer - Der Code aus .wasm muss in ein typisiertes Array oder einen Array-Puffer konvertiert werden, bevor er als Eingabe zur Instanziierung angegeben wird.
importObject- Das Importobjekt muss Details zum Speicher enthalten, importierte Funktionen, die im Modul verwendet werden sollen. Es kann sich um ein leeres Modulobjekt handeln, falls nichts gemeinsam genutzt werden kann.
Rückgabewert
Es wird ein Versprechen zurückgegeben, das Modul- und Instanzdetails enthält.
Beispiel
<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>
Ausgabe
Wenn Sie den Code ausführen, erhalten Sie die unten genannte Ausgabe.
WebAssembly.instantiateStreaming
Diese API übernimmt das Kompilieren und Instanziieren des WebAssembly-Moduls aus dem angegebenen WASM-Code.
Syntax
Die Syntax ist wie folgt -
WebAssembly.instantiateStreaming(wasmcode, importObject);
Parameter
wasmcode - Antwort von Fetch oder einer anderen API, die den Wasm-Code liefert und ein Versprechen zurückgibt.
importObject- Das Importobjekt muss Details zum Speicher enthalten, importierte Funktionen, die im Modul verwendet werden sollen. Es kann ein leeres Modulobjekt sein, falls nichts freigegeben werden soll.
Rückgabewert
Es wird ein Versprechen zurückgegeben, das Modul- und Instanzdetails enthält.
Beispiel
Ein Beispiel wird unten diskutiert -
<script type="text/javascript">
const importObj = {
module: {}
};
WebAssembly.instantiateStreaming(fetch("findsquare.wasm"), importObj).then(obj => {
console.log(obj);
});
</script>
Wenn Sie es im Browser testen, wird ein Fehler angezeigt -
Damit es auf Ihrem Server funktioniert, müssen Sie den MIME-Typ application / wasm hinzufügen oder WebAssembly.instantiate (arraybuffer, importObject) verwenden.
Die WebAssembly-Unterstützung wird allen neuesten Browsern wie Chrome und Firefox hinzugefügt, die Ihnen heute zur Verfügung stehen. Die Firefox-Version ab 54 bietet Ihnen eine spezielle Funktion zum Debuggen Ihres Wasm-Codes.
Führen Sie dazu Ihren Code in Firefox-Browsern aus, die wasm aufrufen. Betrachten Sie beispielsweise den folgenden C-Code, der das Quadrat der Zahl findet.
Ein Beispiel für das C-Programm lautet wie folgt:
#include<stdio.h>
int square(int n) {
return n*n;
}
Wir werden den WASM-Explorer verwenden, um den Wasm-Code zu erhalten -
Laden Sie den WASM-Code herunter und verwenden Sie ihn, um die Ausgabe im Browser anzuzeigen.
Die HTML-Datei, die den Wasm lädt, lautet wie folgt:
!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Square function</title>
<style>
div {
font-size : 30px; text-align : center; color:orange;
}
</style>
</head>
<body>
<div id="textcontent"></div>
<script>
let square;
fetch("findsquare.wasm").then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
.then(instance => {
square = instance.exports.square(13);
console.log("The square of 13 = " +square);
document.getElementById("textcontent").innerHTML = "The square of 13 = " +square;
});
</script>
</body>
</html>
Öffnen Sie Ihren Firefox-Browser, laden Sie die obige HTML-Datei und öffnen Sie das Debugger-Tool.
Sie sollten den Eintrag wasm: // im Debugger-Tool sehen. Klicken Sie auf wasm: // und es wird der Wasm-Code angezeigt, der wie oben gezeigt in das .wat-Format konvertiert wurde.
Sie können sich den Code der exportierten Funktion ansehen und den Code debuggen, wenn ein Problem auftritt. Firefox beabsichtigt auch, Haltepunkte hinzuzufügen, damit Sie den Code debuggen und den Ausführungsfluss überprüfen können.
In diesem Kapitel werden wir ein einfaches Programm in C schreiben und es in .wasm konvertieren und dasselbe im Browser ausführen, um den Text "Hello World" zu erhalten.
Verwendet das Wasm Explorer-Tool, das das C-Programm in .wasm konvertiert und den .wasm in unserer .html-Datei verwendet.
Das Wasm Explorer-Tool, das unter verfügbar ist https://mbebenita.github.io/WasmExplorer/ looks as follows −
Der C-Code, den wir verwenden werden, lautet wie folgt:
#include <stdio.h>
char *c_hello() {
return "Hello World";
}
Aktualisieren Sie den ersten Block im Wasm Explorer mit dem C-Code wie unten gezeigt -
Klicken Sie auf die Schaltfläche KOMPILIEREN, um wie unten gezeigt zu WASM und WAT und Firefox x86 Web Assembly zu kompilieren.
Verwenden Sie den DOWNLOAD, um die WASM-Datei abzurufen und unter zu speichern firstprog.wasm.
Erstellen Sie eine HTML-Datei mit dem Namen firstprog.html wie unten gezeigt -
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Hello World</title>
</head>
<body>
<div id="textcontent"></div>
<script type="text/javascript">
//Your code from webassembly here
</script>
</body>
</html>
Verwenden wir jetzt firstprog.wasm, um die Welt von der C-Funktion c_hello () zu lesen.
Schritt 1
Verwenden Sie die API fetch (), um den Code firstprog.wasm zu lesen.
Schritt 2
Der .wasm-Code muss mithilfe von in Arraybuffer konvertiert werden ArrayBuffer. Das ArrayBuffer-Objekt gibt Ihnen einen Binärdatenpuffer mit fester Länge zurück.
Der bisherige Code lautet wie folgt:
<script type="text/javascript">
fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer())
</script>
Schritt 3
Die Bytes von ArrayBuffer müssen mithilfe von zu einem Modul kompiliert werden WebAssembly.compile(buffer) Funktion.
Der Code sieht wie folgt aus:
<script type="text/javascript">
fetch("firstprog.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
</script>
Schritt 4
Um das Modul zu erhalten, müssen wir den Konstruktor webassembly.instance wie unten gezeigt aufrufen -
<script type="text/javascript">
fetch("firstprog.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
</script>
Schritt 5
Lassen Sie uns nun die Instanz trösten, um die Details im Browser anzuzeigen.
<script type="text/javascript">
fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod)) .then(module => {
return new WebAssembly.Instance(module)
})
.then(instance => {
console.log(instance);
});
</script>
Die console.log-Details werden unten angezeigt -
Um die Zeichenfolge "Hello World" von der Funktion c_hello () zu erhalten, müssen wir Code in Javascript hinzufügen.
Holen Sie sich zuerst die Speicherpuffer-Details wie unten gezeigt -
let buffer = instance.exports.memory.buffer;;
Der Pufferwert muss in ein typisiertes Array konvertiert werden, damit wir die Werte daraus lesen können. Der Puffer enthält die Zeichenfolge Hello World.
Um in typisiert zu konvertieren, rufen Sie den Konstruktor Uint8Array wie unten gezeigt auf -
let buffer = new Uint8Array(instance.exports.memory.buffer);
Jetzt können wir den Wert in einer for - Schleife aus dem Puffer lesen.
Lassen Sie uns nun den Startpunkt zum Lesen des Puffers erhalten, indem wir die Funktion aufrufen, die wir wie unten gezeigt geschrieben haben -
let test = instance.exports.c_hello();
Jetzt hat die Testvariable den Startpunkt zum Lesen unserer Zeichenfolge. WebAssembly hat nichts für Zeichenfolgenwerte, alles wird als Ganzzahl gespeichert.
Wenn wir also den Wert aus dem Puffer lesen, handelt es sich um einen ganzzahligen Wert, und wir müssen ihn mit fromCharCode () in Javascript in einen String konvertieren.
Der Code lautet wie folgt:
let mytext = "";
for (let i=test; buffer[i]; i++){
mytext += String.fromCharCode(buffer[i]);
}
Wenn Sie jetzt mytext trösten, sollte die Zeichenfolge "Hello World" angezeigt werden.
Beispiel
Der vollständige Code lautet wie folgt:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Add Function</title>
<style>
div {
font-size : 30px; text-align : center; color:orange;
}
</style>
</head>
<body>
<div id="textcontent"></div>
<script>
fetch("firstprog.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module)})
.then(instance => {
console.log(instance);
let buffer = new Uint8Array(instance.exports.memory.buffer);
let test = instance.exports.c_hello();
let mytext = "";
for (let i=test; buffer[i]; i++) {
mytext += String.fromCharCode(buffer[i]);
}
console.log(mytext); document.getElementById("textcontent").innerHTML = mytext;
});
</script>
</body>
</html>
Wir haben ein div hinzugefügt und der Inhalt wird dem div hinzugefügt, sodass die Zeichenfolge im Browser angezeigt wird.
Ausgabe
Die Ausgabe wird unten erwähnt -
Wir haben gesehen, wie man eine .wasm-Datei aus c / c ++ - Code erhält. In diesem Kapitel konvertieren wir den Wasm in ein WebAssembly-Modul und führen ihn im Browser aus.
Verwenden wir den C ++ Factorial-Code wie unten gezeigt -
int fact(int n) {
if ((n==0)||(n==1))
return 1;
else
return n*fact(n-1);
}
Öffnen Sie den Wasm Explorer, der unter verfügbar ist https://mbebenita.github.io/WasmExplorer/ as shown below −
Die erste Spalte hat die C ++ - Fakultätsfunktion, die zweite Spalte hat das WebAssembly-Textformat und die letzte Spalte hat den x86-Assemblycode.
Das WebAssembly-Textformat -
(module
(table 0 anyfunc)
(memory $0 1)
(export "memory" (memory $0)) (export "_Z4facti" (func $_Z4facti))
(func $_Z4facti (; 0 ;) (param $0 i32) (result i32)
(local $1 i32) (set_local $1
(i32.const 1)
)
(block $label$0
(br_if $label$0
(i32.eq
(i32.or
(get_local $0) (i32.const 1) ) (i32.const 1) ) ) (set_local $1
(i32.const 1)
)
(loop $label$1
(set_local $1 (i32.mul (get_local $0)
(get_local $1) ) ) (br_if $label$1 (i32.ne (i32.or (tee_local $0
(i32.add
(get_local $0) (i32.const -1) ) ) (i32.const 1) ) (i32.const 1) ) ) ) ) (get_local $1)
)
)
Die C ++ - Funktion fact wurde exportiert als “_Z4facti”Im WebAssembly-Textformat.
Klicken Sie auf den Download-Button, um den Wasm-Code herunterzuladen und die Datei als Fakultät zu speichern.
Um nun den .wasm-Code in das Modul zu konvertieren, müssen wir Folgendes tun:
Schritt 1
Konvertieren Sie den .wasm mithilfe von in Arraybuffer ArrayBuffer. Das ArrayBuffer-Objekt gibt Ihnen einen Binärdatenpuffer mit fester Länge zurück.
Schritt 2
Die Bytes von ArrayBuffer müssen mithilfe von zu einem Modul kompiliert werden WebAssembly.compile(buffer) Funktion.
Das WebAssembly.compile() Die Funktion kompiliert und gibt ein WebAssembly.Module aus den angegebenen Bytes zurück.
Hier ist der Javascript-Code, der in Schritt 1 und 2 erläutert wird.
<script type="text/javascript">
let factorial;
fetch("factorial.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
.then(instance => {
factorial = instance.exports._Z4facti;
console.log('Test the output in Brower Console by using factorial(n)');
});
</script>
Code Erklärung
Das Abrufen der Javascript-Browser-API wird verwendet, um den Inhalt von factorial.wasm abzurufen.
Der Inhalt wird mit arrayBuffer () in Bytes konvertiert.
Das Modul wird aus Bytes erstellt, indem WebAssembly.compile (mod) aufgerufen wird.
Die Instanz eines Moduls wird mit new erstellt
WebAssembly.Instance(module)
Die Fakultätsfunktion export _Z4facti wird mithilfe von WebAssembly.Module.exports () der Variablen Fakultät zugewiesen.
Beispiel
Hier ist die module.html zusammen mit dem Javascript-Code -
module.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Module</title>
</head>
<body>
<script>
let factorial;
fetch("factorial.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
.then(instance => {
factorial = instance.exports._Z4facti;
console.log('Test the output in Browser Console by using factorial(n)');
});
</script>
</body>
</html>
Ausgabe
Führen Sie module.html im Browser aus, um die Ausgabe anzuzeigen -
In diesem Kapitel werden wir die Funktion webassembly.validate () diskutieren, mit der die .wasm-Ausgabe überprüft wird. Der .wasm ist verfügbar, wenn wir C-, C ++ - oder Rostcode kompilieren.
Sie können die folgenden Tools verwenden, um den Wasm-Code abzurufen.
Wasm Fiddler, erhältlich bei https://wasdk.github.io/WasmFiddle/
WebAssembly Explorer, verfügbar unter https://mbebenita.github.io/WasmExplorer/.
Syntax
Die Syntax ist wie folgt -
WebAssembly.validate(bufferSource);
Parameter
bufferSource- Die bufferSource enthält den Binärcode, der entweder aus dem Programm C, C ++ oder Rust stammt. Es liegt in Form von typedarray oder ArrayBuffer vor.
Rückgabewert
Die Funktion gibt true zurück, wenn der .wasm-Code gültig ist, und false, wenn nicht.
Versuchen wir ein Beispiel. Gehen Sie zu Wasm Fiddler , das unter erhältlich isthttps://wasdk.github.io/WasmFiddle/, Geben Sie den C-Code Ihrer Wahl und den Wasm-Code ein.
Der rot markierte Block ist der C-Code. Klicken Sie in der Mitte auf die Schaltfläche Erstellen, um den Code auszuführen.
Klicken Sie auf die Schaltfläche Wasm, um den .wasm-Code herunterzuladen. Speichern Sie die .wasm an Ihrem Ende und lassen Sie uns diese zur Validierung verwenden.
Beispiel
Zum Beispiel: validate.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Testing WASM validate()</title>
</head>
<body>
<script>
fetch('program.wasm').then(res => res.arrayBuffer() ).then(function(testbytes) {
var valid = WebAssembly.validate(testbytes);
if (valid) {
console.log("Valid Wasm Bytes!");
} else {
console.log("Invalid Wasm Code!");
}
});
</script>
</body>
</html>
Ich habe die obige .html-Datei zusammen mit der .wasm-Download-Datei auf dem Wamp-Server gehostet. Hier ist die Ausgabe, wenn Sie es im Browser testen.
Ausgabe
Die Ausgabe ist die unten erwähnte -
WebAssembly hat den Code in einem Binärformat namens WASM. Sie können das Textformat auch in WebAssembly abrufen und es heißt WAT (WebAssembly Text Format). Als Entwickler sollten Sie keinen Code in WebAssembly schreiben, sondern müssen Hochsprachen wie C, C ++ und Rust in WebAssembly kompilieren.
WAT-Code
Schreiben wir den WAT-Code schrittweise.
Step 1 - Der Ausgangspunkt in einem WAT ist die Deklaration des Moduls.
(module)
Step 2 - Lassen Sie uns nun einige Funktionen in Form von Funktionen hinzufügen.
Die Funktion wird wie folgt deklariert -
(func <parameters/result> <local variables> <function body>)
Die Funktion beginnt mit dem Schlüsselwort func, auf das Parameter oder Ergebnisse folgen.
Parameter / Ergebnis
Die Parameter und der Rückgabewert als Ergebnis.
Die Parameter können den folgenden Typ haben, der von wasm unterstützt wird -
- i32: 32-Bit-Ganzzahl
- i64: 64-Bit-Ganzzahl
- f32: 32-Bit-Float
- f64: 64-Bit-Float
Die Parameter für die Funktionen sind wie folgt geschrieben:
- (param i32)
- (param i64)
- (param f32)
- (param f64)
Das Ergebnis wird wie folgt geschrieben:
- (Ergebnis i32)
- (Ergebnis i64)
- (Ergebnis f32)
- (Ergebnis f64)
Die Funktion mit Parametern und Rückgabewert wird wie folgt definiert:
(func (param i32) (param i32) (result i64) <function body>)
Lokale Variablen
Die lokalen Variablen sind diejenigen, die Sie in Ihrer Funktion benötigen. Ein lokaler Wert für die Funktion wird wie folgt definiert:
(func (param i32) (param i32) (local i32) (result i64) <function body>)
Funktionskörper
Funktionskörper ist die auszuführende Logik. Das endgültige Programm wird so aussehen -
(module (func (param i32) (param i32) (local i32) (result i64) <function body>) )
Step 3 - Zum Lesen und Einstellen von Parametern und lokalen Variablen.
Verwenden Sie zum Lesen der Parameter und lokalen Variablen get_local und set_local Befehl.
Example
(module
(func (param i32) (param i32) (local i32) (result i64) get_local 0
get_local 1
get_local 2
)
)
Gemäß der Funktionssignatur
get_local 0 wird das geben param i32
get_local 1 gibt den nächsten Parameter an param i32
get_local 2 wird geben local value i32
Anstatt mit numerischen Werten wie 0,1,2 auf die Parameter und Einheimischen zu verweisen, können Sie auch den Namen vor den Parametern verwenden und dem Namen ein Dollarzeichen voranstellen.
Das folgende Beispiel zeigt, wie der Name mit Parametern und Einheimischen verwendet wird.
Example
(module
(func
(param $a i32) (param $b i32)
(local $c i32) (result i64) get_local $a get_local $b get_local $c
)
)
Step 4 - Anweisung in Funktionskörper und Ausführung.
Die Ausführung in wasm folgt der Stack-Strategie. Die ausgeführten Anweisungen werden einzeln auf dem Stapel gesendet. Zum Beispiel wird der Befehl get_local $ a den Wert verschieben, den er auf dem Stapel liest.
Die Anweisung gefällt i32.add Dadurch werden die Elemente vom Stapel entfernt.
(func (param $a i32) (param $b i32) get_local $a
get_local $b
i32.add
)
Die Anweisung für i32.add ist ($a+$b). Der endgültige Wert von i32.add wird auf den Stapel verschoben und dem Ergebnis zugewiesen.
Wenn für die Funktionssignatur ein Ergebnis deklariert ist, sollte am Ende der Ausführung ein Wert im Stapel vorhanden sein. Wenn es keinen Ergebnisparameter gibt, muss der Stapel am Ende leer sein.
Der endgültige Code zusammen mit dem Funktionskörper lautet also wie folgt:
(module
(func (param $a i32) (param $b i32) (result i32) get_local $a
get_local $b
i32.add
)
)
Step 5 - Aufruf der Funktion.
Der endgültige Code mit dem Funktionskörper ist wie in Schritt 4 gezeigt. Um die Funktion aufzurufen, müssen wir sie exportieren.
Um die Funktion zu exportieren, können Indexwerte wie 0,1 verwendet werden, es können jedoch auch Namen angegeben werden. Dem Namen wird $ vorangestellt und nach dem Schlüsselwort func hinzugefügt.
Example
(module
(func $add (param $a i32) (param $b i32) (result i32) get_local $a
get_local $b i32.add
)
)
Die Funktion $ add muss mit dem unten gezeigten Schlüsselwort export exportiert werden -
(module
(func $add (param $a i32)
(param $b i32) (result i32) get_local $a get_local $b i32.add ) (export "add" (func $add))
)
Um den obigen Code im Browser zu testen, müssen Sie ihn in eine binäre Form (.wasm) konvertieren. Weitere Informationen zum Konvertieren finden Sie im nächsten Kapitel.WAT to .WASM.
Im vorherigen Kapitel haben wir gesehen, wie man Code schreibt .watdh WebAssembly-Textformat. Das WebAssembly-Textformat funktioniert nicht direkt im Browser, und Sie müssen es in das Binärformat konvertieren, dh WASM, damit es im Browser funktioniert.
WAT zu WASM
Lassen Sie uns .WAT in .WASM konvertieren.
Der Code, den wir verwenden werden, lautet wie folgt:
(module
(func $add (param $a i32) (param $b i32) (result i32) get_local $a
get_local $b i32.add ) (export "add" (func $add))
)
Jetzt geh zu WebAssembly Studio, die bei verfügbar ist https://webassembly.studio/.
Sie sollten so etwas sehen, wenn Sie auf den Link klicken -
Klicken Sie auf Leeres Wat-Projekt und unten auf die Schaltfläche Erstellen.
Sie gelangen zu einem leeren Projekt wie unten gezeigt -
Klicken Sie auf main.wat und ersetzen Sie den vorhandenen Code durch Ihren und klicken Sie auf die Schaltfläche Speichern.
Klicken Sie nach dem Speichern auf den Build, um ihn in .wasm - zu konvertieren.
Wenn der Build erfolgreich ist, sollte die WASM-Datei wie unten gezeigt erstellt werden.
Öffnen Sie die Datei main.wasm und verwenden Sie sie in Ihrer HTML-Datei, um die Ausgabe wie unten gezeigt anzuzeigen.
Zum Beispiel - add.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Add Function</title>
</head>
<body>
<script>
let sum;
fetch("main.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod)) .then(module => {
return new WebAssembly.Instance(module)
})
.then(instance => {
sum = instance.exports.add(10,40);
console.log("The sum of 10 and 40 = " +sum);
});
</script>
</body>
</html>
Die Funktion add wird wie im Code gezeigt exportiert. Die übergebenen Parameter sind 2 ganzzahlige Werte 10 und 40 und geben die Summe davon zurück.
Ausgabe
Die Ausgabe wird im Browser angezeigt.
Dynamische Verknüpfung ist der Prozess, bei dem zwei oder mehr Module zur Laufzeit miteinander verknüpft werden.
Um zu demonstrieren, wie dynamisches Verknüpfen funktioniert, verwenden wir das C-Programm und kompilieren es mit Ecmascript sdk zu wasm.
Also hier haben wir -
test1.c
int test1(){
return 100;
}
test2.c
int test2(){
return 200;
}
main.c
#include <stdio.h>
int test1();
int test2();
int main() {
int result = test1() + test2();
return result;
}
Im main.c-Code werden test1 () und test2 () verwendet, die in test1.c und test2.c definiert sind. Lassen Sie uns überprüfen, wie diese Module in WebAssembly verknüpft werden.
Der Befehl zum Kompilieren des obigen Codes lautet wie folgt: Verwenden Sie SIDE_MODULE = 1 für die dynamische Verknüpfung, wie im Befehl gezeigt.
emcc test1.c test2.c main.c -s SIDE_MODULE=1 -o maintest.wasm
Verwenden von WasmtoWat, verfügbar unter https://webassembly.github.io/wabt/demo/wasm2wat/, erhält das WebAssembly-Textformat von schedest.wasm.
(module
(type $t0 (func (result i32))) (type $t1 (func))
(type $t2 (func (param i32))) (type $t3 (func (param i32 i32) (result i32)))
(import "env" "stackSave" (func $env.stackSave (type $t0)))
(import "env" "stackRestore" (func $env.stackRestore (type $t2)))
(import "env" "__memory_base" (global $env.__memory_base i32)) (import "env" "__table_base" (global $env.__table_base i32))
(import "env" "memory" (memory $env.memory 0)) (import "env" "table" (table $env.table 0 funcref))
(func $f2 (type $t1)
(call $__wasm_apply_relocs) ) (func $__wasm_apply_relocs (export "__wasm_apply_relocs") (type $t1)) (func $test1 (export "test1") (type $t0) (result i32) (local $l0 i32)
(local.set $l0 (i32.const 100) ) (return (local.get $l0)
)
)
(func $test2 (export "test2") (type $t0) (result i32)
(local $l0 i32) (local.set $l0
(i32.const 200))
(return
(local.get $l0) ) ) (func $__original_main
(export "__original_main")
(type $t0) (result i32) (local $l0 i32)
(local $l1 i32) (local $l2 i32)
(local $l3 i32) (local $l4 i32)
(local $l5 i32) (local $l6 i32)
(local $l7 i32) (local $l8 i32)
(local $l9 i32) (local.set $l0(call $env.stackSave)) (local.set $l1 (i32.const 16))
(local.set $l2 (i32.sub (local.get $l0) (local.get $l1))) (call $env.stackRestore (local.get $l2) ) (local.set $l3(i32.const 0))
(i32.store offset=12 (local.get $l2) (local.get $l3))
(local.set $l4 (call $test1))
(local.set $l5 (call $test2))
(local.set $l6 (i32.add (local.get $l4) (local.get $l5))) (i32.store offset=8 (local.get $l2) (local.get $l6)) (local.set $l7 (i32.load offset=8 (local.get $l2))) (local.set $l8 (i32.const 16))
(local.set $l9 (i32.add (local.get $l2) (local.get $l8))) (call $env.stackRestore (local.get $l9)) (return(local.get $l7))
)
(func $main (export "main") (type $t3)
(param $p0 i32) (param $p1 i32)
(result i32)
(local $l2 i32) (local.set $l2
(call $__original_main)) (return (local.get $l2))
)
(func $__post_instantiate (export "__post_instantiate") (type $t1) (call $f2)) (global $__dso_handle (export "__dso_handle") i32 (i32.const 0))
)
Im WebAssembly-Textformat sind einige Importe wie unten gezeigt definiert.
(import "env" "stackSave" (func $env.stackSave (type $t0)))
(import "env" "stackRestore" (func $env.stackRestore (type $t2)))
(import "env" "__memory_base" (global $env.__memory_base i32)) (import "env" "__table_base" (global $env.__table_base i32))
(import "env" "memory" (memory $env.memory 0)) (import "env" "table" (table $env.table 0 funcref))
Dies wird beim Kompilieren von Code mit emcc (emscripten sdk) hinzugefügt und behandelt die Speicherverwaltung in WebAssembly.
Arbeiten mit Importen und Exporten
Um nun die Ausgabe zu sehen, müssen wir die Importe definieren, die Sie im .wat-Code sehen können -
(import "env" "stackSave" (func $env.stackSave (type $t0)))
(import "env" "stackRestore" (func $env.stackRestore (type $t2)))
(import "env" "__memory_base" (global $env.__memory_base i32)) (import "env" "__table_base" (global $env.__table_base i32))
(import "env" "memory" (memory $env.memory 0)) (import "env" "table" (table $env.table 0 funcref))
Die obigen Begriffe werden wie folgt erklärt:
env.stackSave - Es wird für die Stapelverwaltung verwendet, eine Funktionalität, die vom emscripten-kompilierten Code bereitgestellt wird.
env.stackRestore - Es wird für die Stapelverwaltung verwendet, eine Funktionalität, die vom emscripten-kompilierten Code bereitgestellt wird.
env.__memory_base- Es handelt sich um einen unveränderlichen globalen i32-Offset, der in env.memory verwendet und für das wasm-Modul reserviert wird. Das Modul kann dieses Global im Initialisierer seiner Datensegmente verwenden, so dass sie an der richtigen Adresse geladen werden.
env.__table_base- Es handelt sich um einen unveränderlichen globalen i32-Offset, der in env.table verwendet und für das wasm-Modul reserviert wird. Das Modul kann dieses Global im Initialisierer seiner Tabellenelementsegmente verwenden, sodass diese mit dem richtigen Versatz geladen werden.
env.memory - Hier finden Sie die Speicherdetails, die für die Wasm-Module freigegeben werden müssen.
env.table - Hier finden Sie die Tabellendetails, die von den Wasm-Modulen gemeinsam genutzt werden müssen.
Die Importe müssen wie folgt in Javascript definiert werden -
var wasmMemory = new WebAssembly.Memory({'initial': 256,'maximum': 65536});
const importObj = {
env: {
stackSave: n => 2, stackRestore: n => 3, //abortStackOverflow: () => {
throw new Error('overflow');
},
table: new WebAssembly.Table({
initial: 0, maximum: 65536, element: 'anyfunc'
}), __table_base: 0,
memory: wasmMemory, __memory_base: 256
}
};
Beispiel
Im Folgenden finden Sie den Javascript-Code, der den importObj in WebAssembly.instantiate verwendet.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
var wasmMemory = new WebAssembly.Memory({'initial': 256,'maximum': 65536});
const importObj = {
env: {
stackSave: n => 2, stackRestore: n => 3, //abortStackOverflow: () => {
throw new Error('overflow');
},
table: new WebAssembly.Table({
initial: 0, maximum: 65536, element: 'anyfunc'
}), __table_base: 0,
memory: wasmMemory, __memory_base: 256
}
};
fetch("maintest.wasm") .then(bytes => bytes.arrayBuffer()) .then(
module => WebAssembly.instantiate(module, importObj)
)
.then(finalcode => {
console.log(finalcode);
console.log(WebAssembly.Module.imports(finalcode.module));
console.log(finalcode.instance.exports.test1());
console.log(finalcode.instance.exports.test2());
console.log(finalcode.instance.exports.main());
});
</script>
</body>
</html>
Ausgabe
Die Ausgabe ist wie folgt -
Gemäß der offiziellen Website von WebAssembly.org, die unter verfügbar ist https://webassembly.org/docs/security/ Das Hauptziel von WebAssembly in Bezug auf die Sicherheit lautet wie folgt:
Das Sicherheitsmodell von WebAssembly hat zwei wichtige Ziele:
Schützen Sie Benutzer vor fehlerhaften oder bösartigen Modulen
Stellen Sie Entwicklern nützliche Grundelemente und Abhilfemaßnahmen für die Entwicklung sicherer Anwendungen im Rahmen von (1) zur Verfügung.
Der kompilierte Code, dh WASM aus C / C ++ / Rust, wird nicht direkt im Browser ausgeführt und verwendet Javascript-APIs. Der WASM-Code wird in einer Sandbox gespeichert, dh über den Javascript-API-Wrapper ausgeführt, und der Browser kommuniziert über die API mit WASM.
Hier ist ein Beispiel für die Verwendung einer .wasm-Datei im Browser.
Beispiel - C Program
#include<stdio.h>
int square(int n) {
return n*n;
}
Wir werden den WASM-Explorer verwenden, um den Wasm-Code zu erhalten -
Laden Sie den WASM-Code herunter und testen Sie damit die APIs.
Beispiel
<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>
Ausgabe
Sie erhalten folgende Ausgabe:
Die Exportobjekte haben einen Verweis auf die aufzurufende Funktion. Um das Funktionsquadrat aufzurufen, müssen Sie wie folgt vorgehen:
console.log(finalcode.instance.exports.square(25));
Probleme mit WASM-kompiliertem Code
Im Folgenden sind die Probleme mit WASM-kompiliertem Code aufgeführt:
Es ist schwierig zu überprüfen, ob schädlicher Code eingefügt wird, während der Code zu wasm kompiliert wird. Derzeit sind keine Tools zur Validierung des Codes verfügbar.
Wasm ist schwer zu analysieren und der fehlerhafte / bösartige Code kann einfach im Browser ausgeführt werden.
In diesem Kapitel werden wir ein einfaches C-Programm für Javascript kompilieren und im Browser ausführen.
Zum Beispiel - C Program
#include<stdio.h>
int square(int n) {
return n*n;
}
Wir haben die Installation von emsdk im Ordner wa / durchgeführt. Erstellen Sie im selben Ordner einen weiteren Ordner cprog / und speichern Sie den obigen Code als square.c.
Wir haben emsdk bereits im vorherigen Kapitel installiert. Hier werden wir emsdk verwenden, um den obigen c-Code zu kompilieren.
Kompilieren Sie test.c in Ihrer Eingabeaufforderung wie unten gezeigt -
emcc square.c -s STANDALONE_WASM –o findsquare.wasm
Der Befehl emcc kümmert sich um das Kompilieren des Codes und gibt Ihnen den .wasm-Code. Wir haben die Option STANDALONE_WASM verwendet, die nur die WASM-Datei enthält.
Beispiel - findsquare.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Square function</title>
<style>
div {
font-size : 30px; text-align : center; color:orange;
}
</style>
</head>
<body>
<div id="textcontent"></div>
<script>
let square; fetch("findsquare.wasm").then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod)) .then(module => {
return new WebAssembly.Instance(module)
})
.then(instance => {
square = instance.exports.square(13);
console.log("The square of 13 = " +square);
document.getElementById("textcontent").innerHTML = "The square of 13 = " +square;
});
</script>
</body>
</html>
Ausgabe
Die Ausgabe ist wie unten erwähnt -
In diesem Kapitel werden wir ein einfaches C ++ - Programm in Javascript kompilieren und im Browser ausführen.
Beispiel
C ++ - Programm - Umkehren einer bestimmten Nummer.
#include <iostream>
int reversenumber(int n) {
int reverse=0, rem;
while(n!=0) {
rem=n%10; reverse=reverse*10+rem; n/=10;
}
return reverse;
}
Wir haben die Installation von emsdk im Ordner wa / durchgeführt. Erstellen Sie im selben Ordner einen anderen Ordner cprog / und speichern Sie den obigen Code als reverse.cpp.
Wir haben emsdk bereits im vorherigen Kapitel installiert. Hier werden wir emsdk verwenden, um den obigen c-Code zu kompilieren.
Kompilieren Sie test.c in Ihrer Eingabeaufforderung wie unten gezeigt -
emcc reverse.cpp -s STANDALONE_WASM –o reverse.wasm
Der Befehl emcc kümmert sich um das Kompilieren des Codes und gibt Ihnen den .wasm-Code.
Beispiel - reversenumber.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Reverse Number</title>
<style>
div {
font-size : 30px; text-align : center; color:orange;
}
</style>
</head>
<body>
<div id="textcontent"></div>
<script>
let reverse;
fetch("reverse.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
.then(instance => {
console.log(instance);
reverse = instance.exports._Z13reversenumberi(1439898);
console.log("The reverse of 1439898 = " +reverse);
document.getElementById("textcontent")
.innerHTML = "The reverse of 1439898 = " +reverse;
});
</script>
</body>
</html>
Ausgabe
Die Ausgabe ist wie folgt -
Um RUST-Kompilierungscode zu erhalten, verwenden wir das Tool WebAssembly.studio.
Gehen Sie zu WebAssembly.studio, das unter Gehe zu verfügbar isthttps://webassembly.studio/ und es wird Ihr Bildschirm wie unten gezeigt angezeigt -
Klicken Sie auf Leeres Rostprojekt. Sobald Sie fertig sind, erhalten Sie drei Dateien in src / folder -
Öffnen Sie die Datei main.rs und ändern Sie den Code Ihrer Wahl.
Ich füge folgende Funktion hinzu, die zwei gegebene Zahlen hinzufügt -
fn add_ints(lhs: i32, rhs: i32) -> i32 {
lhs+rhs
}
Der in main.rs verfügbare Code lautet wie folgt:
#[no_mangle]
pub extern "C" fn add_one(x: i32) -> i32 {
x + 1
}
Ersetzen Sie das fn add_one durch Ihr fn wie unten gezeigt -
#[no_mangle]
pub extern "C" fn add_ints(lhs: i32, rhs: i32) -> i32 {
lhs+rhs
}
Ändern Sie in main.js den Funktionsnamen von add_one in add_ints
fetch('../out/main.wasm').then(
response =>
response.arrayBuffer()
).then(bytes => WebAssembly.instantiate(bytes)).then(results => {
instance = results.instance;
document.getElementById("container").textContent = instance.exports.add_one(41);
}).catch(console.error);
Ersetzen Sie instance.exports.add_one durch instance.exports.add_ints (100.100).
fetch('../out/main.wasm').then(
response =>
response.arrayBuffer()
).then(bytes => WebAssembly.instantiate(bytes)).then(results => {
instance = results.instance;
document.getElementById("container").textContent = instance.exports.add_ints(100,100)
}).catch(console.error);
Klicken Sie auf die Schaltfläche zum Erstellen auf der Benutzeroberfläche von webassembly.studio, um den Code zu erstellen.
Klicken Sie nach Abschluss des Builds auf die Schaltfläche Ausführen, die auf der Benutzeroberfläche verfügbar ist, um die Ausgabe anzuzeigen.
Wir erhalten die Ausgabe als 200, als wir instance.exports.add_ints (100,100) übergeben haben.
Ebenso können Sie ein anderes Programm für Rost schreiben und es in webassembly.studio kompilieren lassen.
Go hat die Unterstützung für WebAssembly ab Version 1.1 hinzugefügt. Um es beim ersten Download zu testen, gehen Sie.
Gehen Sie zur Golang-Site, die unter verfügbar ist https://golang.org/dl/und klicken Sie auf Download Go. Laden Sie gemäß Ihrem Betriebssystem Go herunter und installieren Sie es.
Wenn Sie fertig sind, schreiben Sie ein einfaches Programm, das zwei Zahlen in go hinzufügt.
testnum.go
package main
import "fmt"
func main() {
var a int = 100
var b int = 200
var ret int
ret = sum(a, b)
fmt.Printf( "Sum is : %d\n", ret )
}
/* function returning the max between two numbers */
func sum(num1, num2 int) int {
return num1+num2
}
Um den obigen Code zu wasm zu kompilieren, legen Sie zuerst die Umgebungsvariablen in Go fest.
Sie müssen den folgenden Befehl ausführen:
Set GOOS=js
GOARCH=wasm
Führen Sie anschließend den folgenden Befehl aus:
go build -o testnum.wasm testnum.go
Sie sollten die Datei testnum.wasm erhalten, sobald der Befehl ausgeführt wird.
Lassen Sie uns nun den Code im Browser testen. Dazu benötigen wir die Datei wasm_exec.js, die mit go installiert wird.
Die Datei wasm_exec.js ist im Ordner misc / wasm / in go verfügbar.
Beispiel
Hier ist der Code für testgo.html, der wasm_exec.js und testnum.wasm verwendet.
<html>
<head>
<meta charset="utf-8"/>
<script src="wasm_exec.js"></script>
</head>
<body>
<script type="text/javascript">
const importObj = {
module: {}
};
const go = new Go();
async function fetchAndInstantiate() {
const response = await fetch("testnum.wasm");
const buffer = await response.arrayBuffer();
const obj = await WebAssembly.instantiate(buffer, go.importObject);
console.log(obj);
go.run(obj.instance);
}
fetchAndInstantiate();
</script>
</body>
</html>
Ausgabe
Die Ausgabe ist wie folgt -
Javascript verfügt über eine Reihe von APIs, die mit Wasm-Code arbeiten können. Die API wird auch in nodejs unterstützt.
Installieren Sie NODEJS auf Ihrem System. Erstellen Sie eine Factorialtest.js-Datei.
Verwenden wir den C ++ Factorial-Code wie unten gezeigt -
int fact(int n) {
if ((n==0)||(n==1))
return 1;
else
return n*fact(n-1);
}
Öffnen Sie den Wasm Explorer, der unter verfügbar ist https://mbebenita.github.io/WasmExplorer/ wie unten gezeigt -
Die erste Spalte hat die C ++ - Fakultätsfunktion, die zweite Spalte hat das WebAssembly-Textformat und die letzte Spalte hat den x86-Assemblycode.
Das WebAssembly-Textformat lautet wie folgt:
(module
(table 0 anyfunc)
(memory $0 1) (export "memory" (memory $0))
(export "_Z4facti" (func $_Z4facti)) (func $_Z4facti (; 0 ;) (param $0 i32) (result i32) (local $1 i32)
(set_local $1(i32.const 1)) (block $label$0 (br_if $label$0 (i32.eq (i32.or (get_local $0)
(i32.const 1)
)
(i32.const 1)
)
)
(set_local $1 (i32.const 1) ) (loop $label$1 (set_local $1
(i32.mul
(get_local $0) (get_local $1)
)
)
(br_if $label$1
(i32.ne
(i32.or
(tee_local $0 (i32.add (get_local $0)
(i32.const -1)
)
)
(i32.const 1)
)
(i32.const 1)
)
)
)
)
(get_local $1)
)
)
Die C ++ - Funktion wurde als „_Z4facti”Im WebAssembly-Textformat.
Factorialtest.js
const fs = require('fs');
const buf = fs.readFileSync('./factorial.wasm');
const lib = WebAssembly.instantiate(new Uint8Array(buf)).
then(res => {
for (var i=1;i<=10;i++) {
console.log("The factorial of "+i+" = "+res.instance.exports._Z4facti(i))
}
}
);
Führen Sie in Ihrer Befehlszeile den Befehlsknoten factorialtest.js aus, und die Ausgabe lautet wie folgt:
C:\wasmnode>node factorialtest.js
The factorial of 1 = 1
The factorial of 2 = 2
The factorial of 3 = 6
The factorial of 4 = 24
The factorial of 5 = 120
The factorial of 6 = 720
The factorial of 7 = 5040
The factorial of 8 = 40320
The factorial of 9 = 362880
The factorial of 10 = 3628800
In diesem Kapitel werden die Beispiele für WebAssembly erläutert.
Beispiel 1
Es folgt das Beispiel eines C-Programms, um das maximale Element zu erhalten -
void displaylog(int n);
/* function returning the max between two numbers */
int max(int num1, int num2) {
/* local variable declaration */ int result;
if (num1 > num2)
result = num1;
else result = num2;
displaylog(result);
return result;
}
Kompilieren Sie den Code in wasm fiddle und laden Sie den .wasm- und .wat-Code herunter.
Wat code
Der Wat-Code lautet wie folgt:
(module
(type $FUNCSIG$vi (func (param i32))) (import "env" "displaylog" (func $displaylog (param i32)))
(table 0 anyfunc)
(memory $0 1) (export "memory" (memory $0))
(export "max" (func $max)) (func $max (; 1 ;) (param $0 i32) (param $1 i32) (result i32)
(call $displaylog (tee_local $0
(select
(get_local $0) (get_local $1)
(i32.gt_s (get_local $0) (get_local $1))
)
)
)
(get_local $0)
)
)
Laden Sie den WASM-Code herunter und lassen Sie ihn wie unten gezeigt in der HTML-Datei verwenden.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
const importObj = {
env: {
displaylog: n => alert("The max of (400, 130) is " +n)
}
};
fetch("testmax.wasm") .then(bytes => bytes.arrayBuffer())
.then(module => WebAssembly.instantiate(module, importObj))
.then(finalcode => {
console.log(finalcode);
console.log(finalcode.instance.exports.max(400,130));
});
</script>
</body>
</html>
Ausgabe
Die Ausgabe ist wie folgt -
Beispiel 2
Es folgt der C ++ - Code, um die Fibonacci-Reihe der angegebenen Nummer zu erhalten.
#include <iostream>>
void displaylog(int n);
int fibonacciSeries(int number) {
int n1=0,n2=1,n3,i;
for(i=2;i<number;++i) {
n3=n1+n2; displaylog(n); n1=n2; n2=n3;
}
return 0;
}
Ich benutze den Wasm Explorer, um den Code zu kompilieren. Laden Sie Wat and Wasm herunter und testen Sie es im Browser.
Sie können den unten genannten Code verwenden -
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
const importObj = {
env: { _Z10displaylogi: n => console.log(n) }
};
fetch("fib.wasm")
.then(bytes => bytes.arrayBuffer())
.then(module => WebAssembly.instantiate(module, importObj))
.then(finalcode => {
console.log(finalcode);
console.log(finalcode.instance.exports._Z15fibonacciSeriesi(10));
});
</script>
</body>
</html>
Ausgabe
Die Ausgabe ist wie folgt -
Beispiel 3
Im Folgenden finden Sie den Rust-Code zum Hinzufügen von Elementen zu einem bestimmten Array.
fn add_array(x: i32) -> i32 {
let mut sum = 0;
let mut numbers = [10,20,30]; for i in 0..3 {
sum += numbers[i];
}
sum
}
Wir werden WebAssembly Studio verwenden, um RUST to wasm zu kompilieren.
Erstellen Sie den Code, laden Sie die WASM-Datei herunter und führen Sie sie im Browser aus.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
const importObj = {
env: {
}
};
fetch("add_array.wasm") .then(bytes => bytes.arrayBuffer())
.then(module => WebAssembly.instantiate(module, importObj))
.then(finalcode => {
console.log(finalcode);
console.log(finalcode.instance.exports.add_array());
});
</script>
</body>
</html>
Output
The output will be as given below −