Wie Online-Compiler funktionieren: Code im Browser ausführen

Browserbasierte Compiler führen Ihren Code direkt in der Webseite aus, und zwar mit WebAssembly: einem kompakten, abgeschotteten Binärformat, das Browser in schnellen Maschinencode übersetzen. Echte Compiler und Interpreter wie Clang, CPython, R und SQLite werden selbst zu WebAssembly kompiliert, einmal heruntergeladen und kompilieren oder starten Ihr Programm dann auf Ihrem eigenen Gerät, ohne dass etwas an einen Server gesendet wird. Herkömmliche Online-Compiler arbeiten genau umgekehrt: Sie laden Ihren Code auf einen Server hoch, der ihn ausführt und die Ausgabe zurückschickt.

Das Wichtigste in Kürze
  • WebAssembly ist ein portables Kompilierziel, das alle gängigen Browser mit nahezu nativer Geschwindigkeit ausführen, in derselben Sicherheits-Sandbox wie JavaScript.
  • Unsere C- und C++-Compiler führen Clang im Tab aus: Er wandelt Ihren Code in ein WebAssembly-Modul um, das anschließend mit einer kleinen WASI-Schicht für Ein- und Ausgabe ausgeführt wird.
  • Python, R, SQL, Ruby, PHP, Lua und Prolog laufen als WebAssembly-Builds ihrer offiziellen Interpreter; Sprachen der JavaScript-Familie nutzen die Engine des Browsers.
  • Lokale Ausführung bedeutet Datenschutz, keine Warteschlange auf dem Server und Offline-Nutzung, sobald die Laufzeitumgebung im Cache liegt.
  • Die Kehrseite sind ein einmaliger Download, keine Threads und keine Netzwerk-Sockets, ein temporäres Dateisystem im Arbeitsspeicher und in unserem C++-Build keine Exceptions.

Was ist WebAssembly?

WebAssembly (oft zu Wasm abgekürzt) ist ein maschinennahes Befehlsformat, das als Kompilierziel entworfen wurde. Man schreibt es in der Regel nicht von Hand. Stattdessen erzeugt ein Compiler wie Clang oder der Rust-Compiler aus gewöhnlichem Quellcode eine .wasm-Datei, genauso wie er eine ausführbare Datei für einen x86- oder ARM-Prozessor erzeugen würde. Das Format ist ein offener Standard des W3C, dokumentiert auf webassembly.org, und wird von Chrome, Edge, Firefox und Safari unterstützt.

Drei Eigenschaften machen es nützlich, um Code im Browser auszuführen:

  • Portabel. Dieselbe .wasm-Datei läuft unter Windows, macOS, Linux, Android und iOS, auf jedem Prozessor, weil der Browser sie in den lokalen Maschinencode übersetzt.
  • Schnell. WebAssembly ist typisiert und hardwarenah, daher können Browser-Engines es schon vor der Ausführung in effizienten Maschinencode übersetzen. Rechenintensiver Code läuft typischerweise deutlich schneller als vergleichbares JavaScript und liegt in etwa im selben Bereich wie nativer Code, ist aber meist etwas langsamer.
  • Abgeschottet. Ein WebAssembly-Modul erhält einen privaten Speicherblock und kann nur die Funktionen aufrufen, die ihm ausdrücklich bereitgestellt werden. Es kann Ihre Dateien nicht lesen, keine Netzwerkverbindungen öffnen und den Rest der Seite nicht anrühren, es sei denn, der Host-Code bietet dafür einen Weg.

WASI: eine Systemschnittstelle für WebAssembly

Ein C-Programm erwartet ein Betriebssystem: etwas, von dem es die Standardeingabe lesen, auf das es Ausgaben schreiben, Dateien öffnen und die Uhrzeit abfragen kann. WebAssembly bringt davon nichts mit. Das WebAssembly System Interface (WASI) definiert einen Standardsatz solcher Funktionen, die ein WebAssembly-Programm importieren kann. Außerhalb des Browsers setzen Laufzeitumgebungen wie Wasmtime WASI auf einem echten Betriebssystem um. Im Browser setzt eine kleine JavaScript-Bibliothek, ein sogenannter WASI-Shim, diese Funktionen auf Daten im Arbeitsspeicher um.

Wie herkömmliche Online-Compiler funktionieren

Die meisten lange etablierten Online-Compiler und Seiten für Programmieraufgaben führen Ihren Code auf ihren Servern aus:

  1. Ihr Browser sendet den Quellcode (und alle Eingaben) an den Server der Website.
  2. Der Server legt ihn in einer isolierten Umgebung ab, typischerweise einem Container oder einer leichtgewichtigen virtuellen Maschine, mit Grenzen für Zeit, Arbeitsspeicher und Prozesse.
  3. Der dort installierte echte Compiler oder Interpreter baut und startet das Programm.
  4. Die Ausgabe wird aufgefangen und an Ihren Browser zurückgeschickt, danach wird die Umgebung verworfen.

Dieses Modell hat echte Vorteile. Der Server kann fast jede Sprache und Version anbieten, dazu volle Betriebssystemfunktionen wie Threads und Prozesse und teils auch Netzwerkzugriff und große Bibliotheken. Aber Ihr Code verlässt Ihr Gerät, stark ausgelastete Dienste lassen Anfragen warten, jeder Lauf hängt von einem Netzwerk-Roundtrip ab, und der Betreiber muss für jede Ausführung Rechenleistung bezahlen, weshalb viele die Läufe begrenzen oder ein Konto verlangen.

Wie unsere Compiler im Browser funktionieren

Bei unseren Online-Compilern wird die Laufzeitumgebung jeder Sprache in Ihren Browser geladen und in einem Web Worker ausgeführt, einem Hintergrund-Thread, der die Seite während der Programmausführung bedienbar hält. Ein Zeitlimit und eine Stopp-Schaltfläche erlauben es der Seite, den Worker zu beenden, wenn ein Programm zu lange läuft, zum Beispiel wegen einer Endlosschleife. Die Laufzeitdateien sind auf exakte Versionen festgelegt, und die meisten werden vor der Ausführung anhand eines kryptografischen Hashs geprüft.

C und C++: ein echter Compiler im Tab

Der C-Compiler und der C++-Compiler nutzen Clang 21, den LLVM-basierten Compiler, vom Projekt YoWASP als WebAssembly verpackt. Jeder Lauf besteht aus zwei Stufen:

  1. Kompilieren. Clang, selbst als WebAssembly ausgeführt, kompiliert Ihre main.c oder main.cpp mit aktivierter Optimierung und aktivierten Warnungen (C17 oder C++20). Die Ausgabe ist keine x86- oder ARM-Programmdatei, sondern ein neues WebAssembly-Modul für WASI. Compiler-Warnungen und -Fehler werden genau so angezeigt, wie Clang sie ausgibt.
  2. Ausführen. Der Browser kompiliert dieses Modul zu Maschinencode und startet es mit einem WASI-Shim. Der Shim verbindet die Standardeingabe mit dem Text im Eingabefeld und leitet Standardausgabe und Standardfehlerausgabe in den Ausgabebereich.

Mit anderen Worten: Ein zu WebAssembly kompilierter Compiler erzeugt Ihr zu WebAssembly kompiliertes Programm, und beide laufen im selben Tab.

Interpreter, die zu WebAssembly kompiliert wurden

SpracheLaufzeitumgebungWas es ist
PythonPyodideCPython, der Referenz-Interpreter von Python, zu WebAssembly kompiliert. Pakete wie NumPy und pandas sind dafür ebenfalls vorgebaut.
RwebRDer offizielle WebAssembly-Build von R, einschließlich der Basisgrafik.
SQLsql.jsDie Datenbank-Engine SQLite, zu WebAssembly kompiliert, mit der Datenbank im Arbeitsspeicher.
Rubyruby.wasmDer offizielle CRuby-Interpreter für WASI, mit seiner Standardbibliothek.
PHPphp-wasmDer PHP-Interpreter, zu WebAssembly kompiliert.
LuawasmoonDer Lua-5.4-Referenz-Interpreter, zu WebAssembly kompiliert.
Prologswipl-wasmSWI-Prolog, zu WebAssembly kompiliert.

Da es dieselben Interpreter sind, die man auf dem eigenen Rechner installiert, entsprechen Verhalten und Fehlermeldungen weitgehend den Desktop-Versionen. Probieren Sie sie im Python-Compiler, im R-Compiler und im SQL-Compiler aus.

Sprachen, die die Engine des Browsers nutzen

Manche Sprachen brauchen überhaupt kein WebAssembly. Der JavaScript-Compiler führt Code direkt in der JavaScript-Engine des Browsers aus. TypeScript und CoffeeScript werden von ihren offiziellen Compilern, die als JavaScript ausgeliefert werden, in JavaScript übersetzt, und das Ergebnis wird dann auf dieselbe Weise ausgeführt. Scheme nutzt BiwaScheme und Clojure nutzt SCI (den Small Clojure Interpreter), beides Interpreter, die selbst als JavaScript laufen.

Vorteile der Code-Ausführung im Browser

  • Datenschutz. Ihr Quellcode und Ihre Eingaben bleiben auf Ihrem Gerät. Sie werden von unserem Server weder hochgeladen noch gespeichert oder protokolliert, weil der Server sie nie erhält.
  • Keine Warteschlange und kein Konto. Jeder Besucher nutzt seinen eigenen Prozessor, daher gibt es keine gemeinsame Ausführungswarteschlange und keinen Grund, Läufe zu rationieren.
  • Funktioniert nach dem Laden offline. Sobald Seite und Laufzeitumgebung heruntergeladen und zwischengespeichert sind, können Sie bei abbrechender Verbindung weiter Code bearbeiten und ausführen, solange der Tab geöffnet bleibt. Zusatzpakete, die bei Bedarf nachgeladen werden, etwa manche Python-Bibliotheken, brauchen beim ersten Mal weiterhin eine Verbindung.
  • Schnelle Wiederholungsläufe. Nach dem ersten Laden starten interpretierte Sprachen fast sofort, und zwischen dem Klick auf „Ausführen“ und der Ausgabe liegt kein Netzwerk-Roundtrip.

Grenzen und Kompromisse

GrenzeWarum es sie gibtWas das in der Praxis bedeutet
Download-GrößeDer gesamte Compiler oder Interpreter muss in Ihren Browser gelangen.Clang, R und Ruby umfassen mehrere Dutzend Megabyte; Lua und SQLite unter einem Megabyte. Spätere Besuche nutzen den Browser-Cache.
Keine ThreadsUnsere Laufzeitumgebungen laufen einthreadig; WebAssembly-Threads brauchen zusätzliche Isolationseinstellungen im Browser und Unterstützung in der Laufzeitumgebung.pthread, std::thread oder Pythons threading für echte Parallelität funktionieren nicht wie auf einem Desktop.
Keine Netzwerk-SocketsDie Sandbox gibt Programmen keine Möglichkeit, rohe Netzwerkverbindungen zu öffnen.Code, der aus C, Python oder R Sockets öffnet oder HTTP-Anfragen stellt, schlägt fehl. JavaScript im Browser kann weiterhin fetch nutzen.
Kein echtes DateisystemLaufzeitumgebungen erhalten höchstens ein virtuelles Dateisystem im Arbeitsspeicher, nie Ihre Festplatte.Python und einige andere Laufzeitumgebungen können während einer Sitzung Dateien anlegen, die aber beim Schließen der Seite verschwinden; unsere C- und C++-Programme erhalten nur Standardeingabe und -ausgabe.
Keine C++-ExceptionsUnser C++-Build wird mit deaktivierten Exceptions kompiliert (-fno-exceptions).Code mit try, catch oder throw lässt sich nicht kompilieren; verwenden Sie stattdessen Rückgabewerte oder Fehlercodes.
Arbeitsspeicher32-Bit-WebAssembly kann höchstens 4 GiB adressieren, und Browser oder Geräte erlauben womöglich weniger.Sehr große Arrays oder Datensätze können zu Speicherfehlern führen, besonders auf Smartphones.
Eingabe ist nicht interaktivDie Standardeingabe wird bereitgestellt, bevor das Programm startet.Geben Sie zuerst die gesamte Eingabe in das Eingabefeld ein; Abfragen können nicht mitten im Lauf auf Sie warten.

Zum Lernen, Testen von Algorithmen und für Studienaufgaben spielen diese Grenzen selten eine Rolle. Für Programme, die Netzwerk, mehrere Prozesse oder viel Arbeitsspeicher brauchen, nutzen Sie eine lokale Installation oder eine serverbasierte Umgebung.

Das Sicherheitsmodell

Beliebigen Code auszuführen klingt riskant, doch Compiler im Browser stützen sich auf Schutzmechanismen, die Browser ohnehin bei jeder Website anwenden.

  • WebAssembly-Isolation. Ein Modul kann nur seinen eigenen linearen Speicher lesen und beschreiben, der auf Grenzverletzungen geprüft wird, und nur Funktionen aufrufen, die ausdrücklich in das Modul importiert wurden. Ein C-Programm mit einem Pufferüberlauf kann seinen eigenen Speicher beschädigen, aber nicht in den Browser oder das Betriebssystem ausbrechen.
  • Die Browser-Sandbox. Der gesamte Seitencode, einschließlich WebAssembly und Web Workers, läuft innerhalb der Prozess-Sandbox des Browsers und der Same-Origin-Regeln, kann also weder Daten anderer Websites noch Ihre Dateien lesen.
  • Worker und Zeitlimits. Die Ausführung in einem Worker bedeutet, dass ein außer Kontrolle geratenes Programm beendet werden kann, ohne die Seite einzufrieren oder neu zu laden.
  • Geprüfte Laufzeitumgebungen. Das Festlegen exakter Laufzeitversionen und die Prüfung von Hashes, wo die Lademethode es zulässt, schützt davor, dass ein Content Delivery Network unbemerkt eine andere oder veränderte Datei ausliefert.

Ein Vorbehalt: JavaScript, das Sie im JavaScript-Compiler ausführen, hat dieselben Fähigkeiten wie jedes Skript auf einer Webseite, einschließlich Netzwerkanfragen. Wie bei jedem Code gilt: Führen Sie nur Code-Schnipsel aus, die Sie verstehen, besonders solche, die von Fremden kopiert wurden.

Wann welche Art von Online-Compiler sinnvoll ist

  1. Wenn Ihr Code privat ist, zum Beispiel Studien- oder Arbeitscode, bevorzugen Sie einen Compiler im Browser, damit er Ihr Gerät nie verlässt.
  2. Wenn Sie Threads, Sockets, eine bestimmte Systembibliothek oder eine Sprache ohne WebAssembly-Build brauchen, nutzen Sie einen serverbasierten Dienst oder eine lokale Installation.
  3. Wenn Sie eine langsame oder volumenbegrenzte Verbindung haben, beginnen Sie mit den leichteren Laufzeitumgebungen; das erste Laden einer großen Laufzeitumgebung kostet am meisten.

Häufig gestellte Fragen

Wird mein Code an einen Server gesendet, wenn ich Ihre Online-Compiler nutze?

Nein. Die Seite lädt den Compiler oder Interpreter herunter, und Ihr Code und Ihre Eingaben werden auf Ihrem eigenen Gerät kompiliert und ausgeführt. Der Server liefert nur die Seite und die Laufzeitdateien aus.

Ist WebAssembly so schnell wie nativer Code?

Meist liegt es nah dran, ist aber etwas langsamer, und der Abstand hängt von der Aufgabe und vom Browser ab. Bei typischen Übungen und Algorithmen fällt der Unterschied nicht auf; der Download beim ersten Mal ist die größere Verzögerung.

Warum dauert der erste Lauf länger?

Beim ersten Lauf wird die Laufzeitumgebung heruntergeladen und initialisiert, was bei Clang, R oder Ruby mehrere Dutzend Megabyte bedeutet. Der Browser speichert diese Dateien zwischen, sodass spätere Besuche deutlich schneller starten.

Warum lässt sich mein C++-Code mit try und catch nicht kompilieren?

Unser C++-Build wird mit deaktivierten Exceptions kompiliert, weil die Ausnahmebehandlung in WebAssembly zusätzliche Unterstützung von Toolchain und Laufzeitumgebung braucht, die dieses Setup nicht nutzt. Schreiben Sie die Fehlerbehandlung auf Rückgabewerte, std::optional oder Fehlercodes um oder kompilieren Sie lokal, wenn Sie Exceptions brauchen.

Kann ein Programm in einem Online-Compiler meinem Computer schaden?

Code, der als WebAssembly im Browser läuft, ist auf seinen eigenen Speicher und die von der Seite bereitgestellten Funktionen beschränkt, und die Browser-Sandbox fügt eine weitere Schutzschicht hinzu. Er kann weder Ihre Dateien lesen noch Software installieren. JavaScript-Code kann dennoch wie jedes Seitenskript Webanfragen stellen; führen Sie daher keinen Code aus, dem Sie nicht vertrauen.

Selbst ausprobieren

Setzen Sie diesen Leitfaden mit unseren kostenlosen Tools in die Praxis um.

Weiterlesen

In die Zwischenablage kopiert