Ferris Talk #8: Wasm loves Rust – WebAssembly und Rust jenseits des Browsers

Wasm ist mehr als ein JavaScript-Konkurrent im Browser: Serverseitig hat es das Potenzial, fundamentale Probleme verteilter Systeme zu lösen, und zwar mit Rust.

In Pocket speichern vorlesen Druckansicht 52 Kommentare lesen
Ferris Talk – Neuigkeiten zu Rust. Eine Heise-Kolumne von Rainer Stropek und Stefan Baumgartner für Rustaceans
Lesezeit: 12 Min.
Von
  • Rainer Stropek
Inhaltsverzeichnis

Wenn heute von WebAssembly (Wasm) die Rede ist, denken die meisten sofort an Webentwicklung. Wasm kann aber viel mehr, als JavaScript für die Client-seitige Programmierung herauszufordern. Auf der Serverseite hat durch Wasm eine kleine Revolution begonnen, die das Potenzial hat, innovative Lösungen für heutzutage noch nicht oder schlecht gelöste, fundamentale Probleme im Bereich verteilter Systeme hervorzubringen.

Ferris Talks – die Kolumne für Rustaceans

Wasm bricht zurzeit das Monopol von JavaScript im Browser auf, und Firmen bringen große bestehende Codeteile in C/C++ mithilfe dieser Technologie in den Browser. Sprachen wie C# mit dem Blazor-Framework oder Rust mit Yew versuchen, erste Schritte zur Eroberung des Web-Clients zu gehen. Viele Entwicklerinnen und Entwickler sind begeistert, ihre Lieblingssprache, ihr bestehendes Wissen und bereits vorhandene Codeteile in den Browser bringen zu können, ohne gezwungen zu sein, tief in die JavaScript-Welt einzutauchen. Dadurch bekommt Wasm als neuer W3C-Standard eine Menge Aufmerksamkeit.

In dieser Ausgabe der Rust-Kolumne werfen wir einen Blick auf aktuelle Entwicklungen im Bereich WebAssembly und sehen uns an, welche Auswirkungen sie abseits des Webbrowsers auf zukünftige Softwarearchitekturen haben. Schließlich gibt es trotz der Plattform- und Programmiersprachenunabhängigkeit von Wasm eine enge Bindung zu Rust. Was Go für die Entwicklung von Containertechnologie war, ist Rust für Wasm.

Beginnen wir mit der Frage, wozu es auf dem Server überhaupt Wasm braucht. Im Zentrum des offenen Standards steht die Idee, ein portables (also nicht betriebssystem- oder architekturspezifisches), speicher- und laufzeiteffizientes Binärformat zu definieren, das als Compile-Ziel für beliebige Programmiersprachen dient. Wasm-Code lässt sich vor der Ausführung performant in systemspezifische Maschinensprache übersetzen und während der Ausführung bietet er die Vorteile der jeweiligen Zielplattform wie unter anderem spezifische Hardwarefunktionen. Dabei läuft Wasm-Code in einer Sandbox und die Zuständigen können kontrollieren, wie er mit der Außenwelt (Dateisystem, Netzwerk) kommuniziert.

Bevor wir tiefer in die Materie einsteigen, sehen wir uns an, wie einfach es ist, ein "Hello World"-Programm mit Rust und Wasm zu erstellen:

Eine Voraussetzung ist das Installieren des wasm32-wasi Compilation Target für Rust mit rustup durch folgenden Befehl: rustup target add wasm32-wasi. Ist dieser Schritt erledigt, lassen sich Rust-Programme bereits in Wasm-Module kompilieren: cargo build --target wasm32-wasi

Zum Ausführen außerhalb des Browsers ist eine Wasm-Runtime nötig. Verschiedene Laufzeitumgebungen stehen zur Auswahl, beispielsweise Wasmer und Wasmtime. In diesem Artikel ist Wasmtime zum Zuge gekommen, daher lässt sich ein Wasm-Programm mit folgender Kommandozeile starten:

wasmtime target/wasm32-wasi/debug/hello_wasm.wasm

Wer die Checkliste durchgeht, stößt beim Versuch, eine Datei im Rust-Programm zu lesen, auf einen Fehler. Der folgende Code führt zur Fehlermeldung "Error: failed to find a pre-opened file descriptor through which "./text.txt" could be opened":

vuse std::fs;
use anyhow::Result;

fn main() -> Result<()> {
    let content = fs::read_to_string("./text.txt")?;
    println!("{}", content);

    Ok(())
}

Listing: Wasm "Hello World"

Erst, wenn der Aufruf von wasmtime explizit den Zugriff auf ein Verzeichnis erlaubt (wasmtime --dir=. target/wasm32-wasi/debug/hello_wasm.wasm, man beachte den dir-Parameter), kann das Programm den Inhalt der referenzierten Datei ./text.txt einlesen. Hinter dem kontrollierten Zugriff auf Betriebssystem-APIs steckt das WebAssembly System Interface (WASI).

Wasm-Laufzeitumgebungen wie wasmtime können aber mehr als nur Wasm-Module in der Kommandozeile ausführen. Sie bieten auch Bibliotheken, mit denen sich Wasm-Module in Anwendungen einbetten lassen. Dabei spielt es keine Rolle, ob beide Seiten – Host und eingebettete Komponente – in Rust geschrieben sind oder nicht. Programmiersprachen, die Wasm und verbundene Technologien unterstützen, lassen sich mischen. Einen Einstieg in das Einbetten von Wasm-Modulen in eine Rust-Anwendung findet sich in der Wasm-Dokumentation unter "Using WebAssembly from Rust".