Zurück in die Zukunft mit WebAssembly

Hallo Habr! Ich präsentiere Ihnen die Übersetzung des Artikels "Zurück in die Zukunft mit WebAssembly" von Attila Vágó.

Dieser Beitrag ist eine Übersetzung eines Artikels, der sich mit den Eigenschaften von WebAssemly und Emscripten befasst. Originalartikel in Englisch.


Der Autor des Artikels, Attila Vago, ist ein leitender Softwareentwickler bei HMH. Schreibt Code, Blogs und andere Dinge im Internet. Eine Vielzahl von Programmiersprachen, eine pragmatische Figur mit einer Leidenschaft für JavaScript und einfachem Zugriff. Leicht inspirierte und inspirierende Person mit einer starken Sucht nach Dingen für Nerds, großartiges Essen, Craft Beer und Lego. Wird vom Mac verwendet. Er trainiert um 6 Uhr morgens.

2011 schrieb ich meine erste unabhängige Zeile mit Nicht-HTML-Code (ich habe 2007 damit gearbeitet) und sie wurde in dem sehr guten alten C geschrieben, das von Professor David J. Malan von der Harvard University unterrichtet wurde. Er wird für immer meine Inspiration bleiben, nicht nur für das Studium der Programmierung, sondern auch für das programmatische Denken. Ich erinnerte mich auch daran, dass die Herstellung eines Erdnussbuttersandwichs nur für mich ist, aber es ist eine unglaublich schwierige Aufgabe für einen Computer und ebenso schwierig für eine Person, die vorgibt, ein Computer zu sein.



Wenn Sie das Video mindestens die ersten 18 Minuten gesehen haben (ich weiß, dass es lange dauert, aber das Programmieren Zeit braucht), werden Sie verstehen, warum mir C bis heute am Herzen liegt. Zu meiner Enttäuschung habe ich es nicht gelernt, denn für einen Webentwickler ist C die geringste Priorität. Ich hatte nie einen wirklichen Grund, tief in diese Sprache einzutauchen, obwohl ich unzählige Udemy-Kurse und C-Bücher gekauft habe. Ich habe sie nie berührt (behalten Sie Ihr Urteilsvermögen für sich, das haben Sie auch getan) oder mich selbst belogen, wenn ich kaufe Smart Watch Pebble, die in C funktionieren, schreiben Sie dann unbedingt einen Code für sie. Ja, genau! Keiner dieser Gründe war gut genug.


Was ist WebAssembly und wie überholt es JS?


WebAssembly (kurz Wasm) ist ein binäres Befehlsformat für eine gestapelte virtuelle Maschine.

„Wasm wurde als tragbare Plattform zum Kompilieren von Hochsprachen wie C / C ++ / Rust entwickelt, mit der Sie Client- und Serveranwendungen im Internet bereitstellen können.“
- erklärt freundlicherweise webassembly.org


Mit anderen Worten bedeutet dies, dass Sie Module schreiben können, die im Internet in einem Browser / Server funktionieren, aber in Sprachen wie C geschrieben, in eine Binärdatei kompiliert und daher unglaublich schnell sind, da sie direkt auf der Hardware des Computers funktionieren. Im Vergleich dazu weisen Skriptsprachen wie JavaScript mehrere Abstraktionsebenen zwischen Code und Hardware auf, was sie unter anderem verlangsamt. Dies spielt natürlich nicht immer eine Rolle, und jeder von ihnen hat seinen eigenen Platz im Programm oder sogar im Web-Ökosystem.


Auf dieser Grundlage unterstützt Wasm by Structure (anfangs) nur Ganzzahlen und Gleitkommazahlen, was eine hohe Rechenleistung bietet und daher häufig für Implementierungen vom Canvas-Typ verwendet wird. Es ist wichtig zu verstehen, dass WebAssembly keine Bedrohung für JavaScript darstellt - zumindest noch nicht - und wie Sie später in diesem Artikel sehen werden, können C und JavaScript tatsächlich sehr glücklich im selben Projekt leben und den Code des anderen ausführen. Ja, so etwas.



Emscripten "klebt" C und JS


Jetzt warte! Ich weiß was ich sage. Sie können keine Dinge wie "C in JS ausführen und umgekehrt" sagen und erwarten, dass die Welt nicht reagiert. Egal wie seltsam es klingt, ich täusche mich nicht. Es stellt sich heraus, dass Emscripten eine Kette von Tools zum Kompilieren in asm.js und WebAssembly ist. Entwickelt mit LLVM (mein Gott, ich habe die Hälfte dieser Dinge beim Schreiben des Textes des Artikels gelernt), mit dem Sie C und C ++ im Internet mit fast nativer Geschwindigkeit ohne Plug-Ins ausführen können.


Nun, hier ist, was Sie daraus für sich selbst hervorheben müssen. Emscripten hilft Ihnen beim Kompilieren von C-Code in WebAssembly und bietet zusätzliche Tools, um den Entwickler bei der Kommunikation zwischen den beiden Sprachen zu entlasten, und hilft beim Starten von Wasm in Ihrem Webprojekt. Der grundlegende Kompilierungsbefehl für Emscripten lautet wie folgt:


emcc lib/strings.c -s WASM=1 -o public/strings.js 

Während ein nicht grundlegender Befehl wie folgt ausgeführt wird:

 emcc lib/imports.c -s WASM=1 -s EXPORTED_FUNCTIONS="['_getNum', '_main', '_getDoubleNum', '_greet']" -o public/imports.js 

Emscripten einzurichten ist nicht die einfachste Sache, aber keine Rakete zu starten. Das einzige, was das Setup kompliziert, ist, dass es viele Abhängigkeiten wie Python, Node, xCode, Git und cMake hat. Alle Anweisungen finden Sie auf der Installationsseite und sind leicht zu befolgen.
Deshalb Emscripten:

  • ist ein großartiges Tool für die Portierung, mit dem Sie vorhandene Projekte, die in C oder C ++ geschrieben wurden, kompilieren und in allen modernen Browsern ausführen können. Verschwinde von hier, Internet Explorer!
  • Ideal für APIs, da OpenGL in WebGL konvertiert wird und Sie vertraute APIs wie SDL oder direkt HTML5 verwenden können. Oh ja!
  • Und es ist verdammt schnell: Dank LLVM, Emscripten, asm.js und WebAssembly läuft der Code fast mit seiner eigenen Geschwindigkeit. Lauf, Hase, lauf!


Hinweis: Sie benötigen Emscripten nicht, um Wasm zu generieren, da alle neuen Browser eine API zur Unterstützung von Wasm im selben Fenster haben, in der Emscripten als oberste Ebene ausgeführt wird, was das Leben des Entwicklers erheblich erleichtert. Zum Beispiel passt Emscripten die Speichermenge für Sie an, was durch C mühsam sein kann.


Beispiele ... Beispiele gibt es überall!


Sie wissen, wie sie sagen: "Eine Codezeile sagt mehr als tausend Worte." - OK, dies ist das Vorrecht des Erzählers und all das. Schauen wir uns also ohne weiteres einen echten Code an. Off-Topic-Kommentar: An diesem Tag konnte ich die C-Syntax nicht überwinden. Sie wurde nicht die Hälfte der Zeit kompiliert, da mein Code wackelig wäre. Und nach acht Jahren bin ich so: "Ja, es sieht aus wie JavaScript . "


Leute, wenn jemand anfängt, C-Code in meinem React zu sehen, bringt mich einfach zurück in die Realität, okay?


Ein wenig abseits des Themas, hier ist der aktuelle C-Code:


Bild

Und dementsprechend in JavaScript:


Bild

OK, was genau passiert in diesen Dateien? Eigentlich ziemlich viel, also werde ich auflisten.

  1. Es ist wichtig zu verstehen, dass main () , sofern nicht anders angegeben, immer zuerst startet und standardmäßig auch kompiliert wird. Wenn Sie eine andere Funktion kompilieren möchten, müssen Sie sie speziell im Flag des Arrays EXPORTED_FUNCTIONS setzen , wie im vorherigen Abschnitt gezeigt.
  2. Sie schreiben Ihren C-Code wie gewohnt und importieren seine regulären Bibliotheken. Darüber hinaus erhalten Sie den syntaktischen Zucker Emscripten sowie mehr Methoden / Funktionen als mit jedem anderen Tool.
  3. Die von HTML referenzierte Datei imports.js (der Name ist willkürlich, aber immer derselbe wie die C-Datei) ist nichts anderes als der Emscripten-Kleber, der beim Kompilieren automatisch generiert wird. Sie müssen sich keine Sorgen machen, stellen Sie nur sicher, dass wirklich darauf verwiesen wird.
  4. Printf ist nur eine gewöhnliche C-Anweisung, die eine Zeichenfolge auf der Konsole registriert. Nichts besonderes, mach weiter.
  5. Die Zeilen 14 und 17 sind ein Anti-Pattern, aber ein gutes Beispiel für die Ausführung von JS in Ihrem C-Code. Der einzige wirkliche Unterschied zwischen emscripten_run_script und emscripten_async_run_script besteht darin, dass Sie JS in C asynchron ausführen können. Meistens mit setTimeout () . Der Grund, warum ich sagte, dass dies ein Anti-Muster ist, ist, dass es so ist. Die ganze Idee von WebAssembly besteht darin, C in JS auszuführen, nicht JS in C, und daher ...
  6. Die Zeilen 20 und 24 und die zugehörigen JS-Funktionen in der Datei index.html stellen die richtige Vorlage dar, nämlich das Deklarieren Ihres JS in Ihrem JS und das Zurückgeben von etwas für C.
  7. EM_JS , das dann jsFunction startet, ist einfach ein einfacher Weg - um das gleiche Ziel wie in den Punkten 4 und 5 zu erreichen.

Das vorhergesagte Ergebnis des Obigen ist wie folgt:


Bild

Ladies Ahead!


Wie bei jedem Code hat auch WebAssembly eine laufende Reihenfolge. Leg dich nicht mit der Warteschlange an! Die Bestellung ist in diesem Fall Standard für die C-Bestellung. Alles beginnt in Main () und wann immer main () bereit ist, ist Wasm bereit. Was passiert jedoch, wenn Sie zur Laufzeit eine statische Funktion zum Aufrufen benötigen? Nun, nur ein wenig Emscripten syntaktischer Zucker, und alles läuft wie am Schnürchen:


Bild

Wir sammeln Fliegen vom Kuchen


Dies ist gut geschriebener Code, insbesondere die einfachen Dinge, die in den vorherigen Abschnitten dargestellt wurden, aber wir alle wissen, dass die reale Welt viel größer als "Hallo Welt" ist und die Hälfte der Zeit jedes Entwicklers damit verbracht wird, herauszufinden, warum der Code nicht was tut sollte. Fehler sind einfach unvermeidlich und in gewissem Sinne Teil des Lebens.


Wenn Sie C in JS oder einem Wasm ausführen, kann alles noch deprimierender werden. Glücklicherweise hilft Emscripten erneut mit zwei sehr nützlichen Debugging-Methoden:


 // browser debugger gets triggered emscripten_debugger(); // browser console warning with stack-trace emscripten_log(EM_LOG_WARN, “'param' your message”); 

Schnell beeilt sich Gonzalez, um zu helfen


Ob Sie es glauben oder nicht, die Schöpfer von Emscripten haben an alles gedacht. Ein großes Feature - und das letzte, das ich in diesem Artikel erwähnen werde, da es zu viele gibt, um sie alle in einem zu vereinen - ist die Grundlage für eine schnelle Entwicklung und Erprobung. Sie können Ihren Wasm kompilieren, ein Projekt erstellen und den Server auf einen Schlag starten:


 emrun --port 7777 --no_browser public/index.html Now listening at http://localhost:7777/ 

Die von Ihnen ausgeführte HTML-Seite ist nicht emrun-fähig. Die Erfassung von Stdout, stderr und exit (Rückkehrcode) funktioniert nicht. Kompilieren Sie die Anwendung mit dem Linker-Flag --emrun neu, um dies zu aktivieren, oder übergeben Sie --no_emrun_detect an emrun, um diese Prüfung auszublenden.

Okay, in zwei Fällen ... das obige Beispiel funktioniert, aber das nächste funktioniert besser, was den angezeigten Fehler erklärt.


 <b>// compile as emrun project emcc lib/strings.c -s WASM=1 --emrun -o public/index.html // run the emrun server again emrun --port 7777 --no_browser public/index.html</b> 

Ich lasse es einfach so. Als ich WebAssembly studierte, feierte ich den St. Patrick's Day und den nächsten Tag. Ich bin mir nicht ganz sicher, was als nächstes passieren wird, aber es hat mich genug begeistert, zwei Tage vor dem Monitor zu sitzen und zu versuchen, die Grundlagen von WebAssebly zu erlernen, und das sollte etwas bedeuten, oder? Dies ist genau der C-Code, den ich seit 2011 geschrieben habe, und er fühlt sich großartig an. Ich denke, WebAssembly hat eine echte Zukunft, aber ich bin mir nicht sicher, ob es das Netzwerk vollständig übernehmen und JS töten wird, wie einige predigen. Was denkst du?


Bild

Source: https://habr.com/ru/post/de453008/


All Articles