2 Punkte von GN⁺ 2024-11-11 | 1 Kommentare | Auf WhatsApp teilen
  • Ein Tool zum Kompilieren von JavaScript nach WebAssembly, ähnlich wie porffor, da es eigenständige WASM-Binärdateien erzeugt. Geschrieben in Rust
  • Ein experimentelles Tool, das noch nicht für den Produktionseinsatz bereit ist; viele Sprachfunktionen und eingebaute Typen fehlen noch oder sind unvollständig
  • Das Ziel ist es, 100 % der Sprache zu unterstützen.

Warum Jawsm?

  • Das Projekt Jawsm begann während der Arbeit an Crowst, einem Stresstest-Tool zum Ausführen von WebAssembly-Szenarien.
  • Es unterstützt nur Code, der aus Rust nach WASM kompiliert wurde, aber Rust ist keine weit verbreitete Sprache.
  • Skriptsprachen auf WASM auszuführen ist derzeit nicht ideal. Man muss entweder einen Interpreter einbinden oder eine Abwandlung der Zielsprache verwenden.
  • Es wird davon ausgegangen, dass mit modernen WASM-Vorschlägen eine 100%ige Implementierung der JavaScript-Funktionen ohne kompilierten Interpreter möglich ist.

Was funktioniert

  • Das Ziel ist eine 100%ige Implementierung der Sprache, mit Fokus auf der Umsetzung der Semantik.
  • Vier Punkte sind schwer umzusetzen: Scopes/Closures, try/catch, async/await, Generatoren.
  • Aktuell implementiert Jawsm die Kompilierung von Code mit Closures, try/catch sowie eine eingeschränkte Promise-API und async.
  • Funktionierende Features: Variablendeklaration und -zuweisung, while, String-Literale, Zahlen und grundlegende Operatoren, Booleans und grundlegende Boolesche Operatoren, Array-Literale, Objekt-Literale, das Schlüsselwort new.

Anforderungen an den Host

  • Jawsm basiert auf aktuellen WASM-Vorschlägen, daher sind die erzeugten Binärdateien zwischen Laufzeitumgebungen nur eingeschränkt portabel.
  • Die Implementierung erfolgt mit Blick auf WASIp2; für die WASIp2-Funktionen wird V8 zusammen mit JavaScript-Polyfills verwendet.
  • Es gibt ein Skript run.js, das von Jawsm erzeugte Binärdateien ausführen kann.

Verwendung

  • Es wird empfohlen, es nicht zu verwenden, es sei denn, man möchte dazu beitragen.
  • Nach dem Klonen des Repositorys kann mit dem Skript execute.sh eine WAT-Datei erzeugt, in eine Binärdatei kompiliert und anschließend mit Node.js ausgeführt werden.
  • Erforderlich sind Rusts cargo, die neueste Version von wasm-tools und Node.js v23.0.0 oder neuer.

Nächste Schritte

  • Zuerst sollen die schwer umzusetzenden Funktionen fertiggestellt werden; als Nächstes sind Generatoren und die Unterstützung des Schlüsselworts await geplant.
  • Eigentlich soll der Vorschlag für Stack Switching genutzt werden, derzeit wird jedoch CPS-Transformation verwendet, um Continuations zu simulieren.
  • Danach sollen Syntax sowie eingebaute Typen und APIs implementiert werden.

Wie es funktioniert

  • Das Projekt wandelt JavaScript-Syntax in WASM-Instruktionen um und nutzt dabei die WASM-Vorschläge für GC, Exception Handling und Tail-Call-Optimierung.
  • Um Scopes und Closures von JavaScript in WASM zu simulieren, wird zusätzlicher WASM-Code erzeugt.

1 Kommentare

 
GN⁺ 2024-11-11
Hacker-News-Kommentare
  • Das ist eine clevere Nutzung des neuen WASM-GC-Vorschlags. Frühere JS->WASM-Compiler haben eine vollständige JS-Engine eingebettet, aber dieses Projekt versucht, JS-Strukturen direkt auf WASM-Primitiven abzubilden.

    • Ich habe früher einen ARM-Embedded-Compiler gebaut, der fast schon nahe an TypeScript war. Einige der Techniken könnten nützlich sein.
  • Ich schreibe gerne Rust, aber es ist keine weit verbreitete Sprache. Rust bekommt derzeit viel Aufmerksamkeit und scheint an vielen Stellen eingesetzt zu werden.

  • Ich bin zuversichtlich, dass man 100 % der JavaScript-Spezifikation abdecken kann. Ideen, Fragen oder Kritik sind willkommen.

    • Ich frage mich, ob es Ergebnisse von test262_runner.rb gibt. Es wäre gut, diesen Fortschritt im README zu zeigen. Großartiges Projekt.
  • Ich habe die README.md des Projekts gelesen, bin mir aber nicht sicher, wie die vorgesehene Nutzung aussieht. Ich frage mich, wie der erzeugte WASM-Code mit der Laufzeit interagiert. Ist das als Werkzeug gedacht, das mit Browsern und anderen WASM-Laufzeiten kompatibel ist, oder nur mit der an das Projekt gekoppelten Laufzeit?

    • Ich frage mich, wie es reagiert, wenn es im JavaScript-Code auf Web-APIs oder globale Bezeichner trifft, die nur in bestimmten Umgebungen definiert sind. Falls es nicht für diese Umgebung gedacht ist, frage ich mich, wie I/O bei der Nutzung funktionieren soll.
  • „JS ohne Browser-Laufzeit ausführen“ rückt näher. perforr, jaws oder ein anderes Projekt werden am Ende erfolgreich sein.

  • Ich frage mich, wie mit Inkonsistenzen bei der Zeichenkodierung und den damit verbundenen Utilities umgegangen wird. WASM unterstützt UTF-8 und JS unterstützt UTF-16 (potenziell fehlerhaft).

  • Ich mag diesen Ansatz sehr. Direkt für WASM zu bauen, statt zu versuchen, unmittelbar Binärdateien zu erzeugen, bedeutet, dass man sich auf WASM GC und die als Teil von WASI 0.3 erwartete Async-Unterstützung verlassen kann.

  • Manche Leute nennen das einen Compiler. Großartige Arbeit.

  • Ich frage mich, ob dieser Code schneller läuft als die Ausführung desselben Codes in JS oder ob es eher um Interoperabilität mit anderen Sprachen geht.