Bytecode im Browser: Mit WebAssembly und Rust zur Web-Anwendung

Am Beispiel eines Chatsystems demonstrieren die Autoren die Programmierung eines browserbasierten Chatclients und -servers mit Rust und Wasm.

In Pocket speichern vorlesen Druckansicht 76 Kommentare lesen

(Bild: Lightspring/Shutterstock.com)

Lesezeit: 11 Min.
Von
  • Dr. Jens Breitbart
  • Dr. Stefan Lankes
Inhaltsverzeichnis

WebAssembly (Wasm) ist ein offener Standard für Bytecode, der das Ausführen von Programmen im Webbrowser ermöglicht. Die gängigen Browser wie Firefox, Chrome, Safari und Edge unterstützen Wasm bereits. Das WebAssembly-Projekt geht aus Mozillas asm.js und dem Portable Native Client (PNaCl) hervor. Beide Projekte schufen die Voraussetzungen, um vorkompilierten C/C++-Code durch den Browser für das Host-System zu kompilieren und anschließend nativ im Browser auszuführen. Im Vergleich zu JavaScript lässt sich dadurch eine höhere Performance erzielen, während gleichzeitig wichtige Security-Funktionen des Browsers wie das Sandboxing aktiv bleiben – und Nutzer von potenziell höherer Sicherheit profitieren.

Mehr zur Rust

Die Idee, vorkompilierten Bytecode auszuliefern, ist nicht neu. Sie kam schon in den Neunzehnneunziger Jahren mit Java zum Einsatz. Vorkompilierter Java-Code stand Nutzern damals als Java-Bytecode zur Verfügung. Beim Programmstart musste dieser interpretiert oder durch einen Just-in-Time-(JIT)-Compiler übersetzt werden und ließ sich anschließend ausführen.

Java- und WebAssembly-Bytecode unterscheiden sich allerdings deutlich. Java-Bytecode bietet eine höhere Abstraktionsebene und enthält unter anderen Typinformationen – verlangt aber Garbage Collection, da Objekte nicht explizit freigegeben werden. WebAssembly hingegen lässt sich eher mit klassischem Assembler vergleichen und enthält keine Informationen über Objekte. Es verwundert daher kaum, dass eine typische Java-VM deutlich komplexer ausfällt als das entsprechende WebAssembly-Gegenstück.

WebAssembly lässt sich aufgrund seiner Ähnlichkeit mit Assembler recht einfach als weiteres Backend in einen Compiler integrieren. Beispielsweise kann die Compiler-Infrastruktur LLVM WebAssembly erzeugen. Daher lässt sich mit clang aus C/C++ oder mit rustc aus Rust WebAssembly generieren. Auch mit dem Compiler Emscripten lässt sich C-Code über das LLVM-Backend im Browser zur Ausführung bringen.

Alle weiteren Beispiele im Rahmen dieses Artikels verwenden Rust. Die Programmiersprache geht ursprünglich auf Mozilla zurück, daher sind unter anderen Teile des Firefox-Browsers in Rust geschrieben. Da Mozilla auch nach dem Wechsel von Teilen des Wasm-Teams zu Fastly zu den engagierten Förderern von WebAssembly gehört, fällt die WebAssembly-Unterstützung von Rust umfangreich aus.

Bytecode bezeichnet eine Menge an Instruktionen für eine virtuelle Maschine. Sie sind im Allgemeinen unabhängig von konkreter Hardware und dem verwendeten Betriebssystem. Bytecode lässt sich durch das Kompilieren des Quellcodes erzeugen. Prominentes Beispiel ist Java-Bytecode, der sich mit einer Java Virtual Machine (JVM) auf verschiedenen Betriebssystemen und unterschiedlicher Hardware ausführen lässt. Dabei unterscheiden sich je nach Plattform zwar die JVMs, der Code hingegen ist immer gleich. Als Vorteil gegenüber der Interpretation des Quellcodes zur Laufzeit verspricht Bytecode eine schnellere Ausführung.

Die Abbildung zeigt den geplanten Aufbau des beispielhaften Chatsystems für den Browser (Abb. 1).