Les compilateurs en ligne dans le navigateur exécutent votre code dans la page web elle-même grâce à WebAssembly, un format binaire compact et isolé (« sandbox ») que les navigateurs traduisent en code machine rapide. De vrais compilateurs et interpréteurs comme Clang, CPython, R et SQLite sont eux-mêmes compilés en WebAssembly, téléchargés une seule fois, puis compilent ou exécutent votre programme sur votre propre appareil, sans rien envoyer à un serveur. Les compilateurs en ligne traditionnels fonctionnent à l'inverse : ils envoient votre code à un serveur qui l'exécute et vous renvoie le résultat.
- WebAssembly est une cible de compilation portable que tous les grands navigateurs exécutent à une vitesse proche du code natif, dans le même bac à sable de sécurité que JavaScript.
- Nos compilateurs C et C++ font tourner Clang dans l'onglet : il transforme votre code en module WebAssembly, ensuite exécuté avec une petite couche WASI qui gère l'entrée et la sortie.
- Python, R, SQL, Ruby, PHP, Lua et Prolog tournent sous forme de versions WebAssembly de leurs interpréteurs officiels ; les langages de la famille JavaScript utilisent le moteur du navigateur.
- Une exécution locale signifie confidentialité, pas de file d'attente côté serveur et utilisation hors ligne une fois l'environnement d'exécution en cache.
- En contrepartie : un téléchargement initial, pas de threads ni de sockets réseau, un système de fichiers temporaire en mémoire et, dans notre version de C++, pas d'exceptions.
Qu'est-ce que WebAssembly ?
WebAssembly (souvent abrégé en Wasm) est un format d'instructions de bas niveau conçu comme cible de compilation. On ne l'écrit généralement pas à la main. Un compilateur comme Clang ou celui de Rust produit un fichier .wasm à partir d'un code source ordinaire, comme il produirait un exécutable pour un processeur x86 ou ARM. Ce format est un standard ouvert développé au W3C, documenté sur webassembly.org, et pris en charge par Chrome, Edge, Firefox et Safari.
Trois propriétés le rendent utile pour exécuter du code dans un navigateur :
- Portable. Le même fichier
.wasmfonctionne sous Windows, macOS, Linux, Android et iOS, sur n'importe quel processeur, car le navigateur le traduit en code machine local. - Rapide. WebAssembly est typé et proche du matériel, si bien que les moteurs des navigateurs peuvent le compiler avant l'exécution en code machine efficace. Le code gourmand en calcul s'exécute généralement bien plus vite que le JavaScript équivalent, dans la même fourchette que le code natif, même si c'est en général un peu plus lent.
- Isolé. Un module WebAssembly reçoit un bloc de mémoire privé et ne peut appeler que les fonctions qu'on lui fournit explicitement. Il ne peut pas lire vos fichiers, ouvrir de connexions réseau ni toucher au reste de la page, sauf si le code hôte lui en donne le moyen.
WASI : une interface système pour WebAssembly
Un programme C attend un système d'exploitation : de quoi lire l'entrée standard, écrire une sortie, ouvrir des fichiers et obtenir l'heure. WebAssembly n'intègre rien de tout cela. La WebAssembly System Interface (WASI) définit un ensemble standard de fonctions de ce type qu'un programme WebAssembly peut importer. En dehors du navigateur, des environnements d'exécution comme Wasmtime implémentent WASI au-dessus d'un vrai système d'exploitation. Dans un navigateur, une petite bibliothèque JavaScript appelée WASI shim implémente ces fonctions au-dessus de données en mémoire.
Comment fonctionnent les compilateurs en ligne traditionnels
La plupart des compilateurs en ligne établis de longue date et des sites d'exercices de programmation exécutent votre code sur leurs serveurs :
- Votre navigateur envoie le code source (et les éventuelles données d'entrée) au serveur du site.
- Le serveur le place dans un environnement isolé, généralement un conteneur ou une machine virtuelle légère, avec des limites de temps, de mémoire et de processus.
- Le vrai compilateur ou interpréteur installé sur place construit et exécute le programme.
- La sortie est récupérée et renvoyée à votre navigateur, puis l'environnement est supprimé.
Ce modèle a de vrais avantages. Le serveur peut proposer presque n'importe quel langage et version, toutes les fonctions du système d'exploitation comme les threads et les processus, et parfois l'accès au réseau et de grandes bibliothèques. Mais votre code quitte votre appareil, les services très sollicités peuvent mettre les requêtes en file d'attente, chaque exécution dépend d'un aller-retour réseau, et l'exploitant doit payer la puissance de calcul de chaque exécution, ce qui explique pourquoi beaucoup limitent les exécutions ou exigent un compte.
Comment fonctionnent nos compilateurs dans le navigateur
Sur nos compilateurs en ligne, l'environnement d'exécution de chaque langage est téléchargé dans votre navigateur et exécuté dans un Web Worker, un thread en arrière-plan qui garde la page réactive pendant l'exécution de votre programme. Une limite de temps et un bouton Arrêter permettent à la page d'interrompre le worker si un programme tourne trop longtemps, par exemple à cause d'une boucle infinie. Les fichiers d'exécution sont figés sur des versions précises, et la plupart sont vérifiés par empreinte cryptographique avant d'être exécutés.
C et C++ : un vrai compilateur dans l'onglet
Le compilateur C et le compilateur C++ utilisent Clang 21, le compilateur basé sur LLVM, empaqueté en WebAssembly par le projet YoWASP. Chaque exécution se déroule en deux étapes :
- Compilation. Clang, lui-même exécuté en WebAssembly, compile votre
main.coumain.cppavec optimisation et avertissements activés (C17 ou C++20). Sa sortie n'est pas un exécutable x86 ou ARM mais un nouveau module WebAssembly ciblant WASI. Les avertissements et erreurs du compilateur s'affichent exactement comme Clang les imprime. - Exécution. Le navigateur compile ce module en code machine et le lance avec un WASI shim. Le shim relie l'entrée standard au texte de la zone de saisie et envoie la sortie standard et la sortie d'erreur standard vers le panneau de sortie.
Autrement dit, un compilateur compilé en WebAssembly produit votre programme compilé en WebAssembly, et les deux s'exécutent dans le même onglet.
Des interpréteurs compilés en WebAssembly
| Langage | Environnement d'exécution | De quoi s'agit-il |
|---|---|---|
| Python | Pyodide | CPython, l'interpréteur Python de référence, compilé en WebAssembly. Des paquets comme NumPy et pandas sont aussi précompilés pour lui. |
| R | webR | La version WebAssembly officielle de R, y compris les graphiques de base. |
| SQL | sql.js | Le moteur de base de données SQLite compilé en WebAssembly, avec la base conservée en mémoire. |
| Ruby | ruby.wasm | L'interpréteur CRuby officiel construit pour WASI, avec sa bibliothèque standard. |
| PHP | php-wasm | L'interpréteur PHP compilé en WebAssembly. |
| Lua | wasmoon | L'interpréteur Lua 5.4 de référence compilé en WebAssembly. |
| Prolog | swipl-wasm | SWI-Prolog compilé en WebAssembly. |
Comme ce sont les mêmes interpréteurs que ceux que l'on installe sur son ordinateur, le comportement et les messages d'erreur correspondent de près aux versions de bureau. Vous pouvez les essayer sur le compilateur Python, le compilateur R et le compilateur SQL.
Les langages qui utilisent le moteur du navigateur
Certains langages n'ont pas besoin de WebAssembly. Le compilateur JavaScript exécute le code directement dans le moteur JavaScript du navigateur. TypeScript et CoffeeScript sont traduits en JavaScript par leurs compilateurs officiels, distribués en JavaScript, puis le résultat est exécuté de la même façon. Scheme utilise BiwaScheme et Clojure utilise SCI (le Small Clojure Interpreter), deux interpréteurs qui tournent eux-mêmes en JavaScript.
Avantages d'exécuter du code dans le navigateur
- Confidentialité. Votre code source et vos données d'entrée restent sur votre appareil. Ils ne sont ni envoyés, ni stockés, ni journalisés par notre serveur, puisqu'il ne les reçoit jamais.
- Pas de file d'attente, pas de compte. Chaque visiteur utilise son propre processeur : il n'y a donc pas de file d'exécution partagée ni besoin de rationner les exécutions.
- Fonctionne hors ligne après le chargement. Une fois la page et l'environnement d'exécution téléchargés et mis en cache, vous pouvez continuer à modifier et exécuter du code si votre connexion tombe, tant que l'onglet reste ouvert. Les paquets supplémentaires chargés à la demande, comme certaines bibliothèques Python, exigent quand même une connexion la première fois.
- Exécutions répétées rapides. Après le premier chargement, les langages interprétés démarrent presque instantanément, et il n'y a pas d'aller-retour réseau entre le clic sur Exécuter et l'affichage de la sortie.
Limites et compromis
| Limite | Pourquoi elle existe | Ce que cela signifie en pratique |
|---|---|---|
| Taille du téléchargement | Le compilateur ou l'interpréteur complet doit parvenir jusqu'à votre navigateur. | Clang, R et Ruby pèsent des dizaines de mégaoctets ; Lua et SQLite moins d'un. Les visites suivantes utilisent le cache du navigateur. |
| Pas de threads | Nos environnements d'exécution sont mono-thread ; les threads WebAssembly nécessitent des réglages d'isolation supplémentaires du navigateur et une prise en charge côté environnement d'exécution. | pthread, std::thread ou le threading de Python pour un vrai parallélisme ne fonctionneront pas comme sur un poste de bureau. |
| Pas de sockets réseau | Le bac à sable ne donne aucun moyen aux programmes d'ouvrir des connexions réseau brutes. | Le code qui ouvre des sockets ou envoie des requêtes HTTP depuis C, Python ou R échouera. Le JavaScript du navigateur peut toujours utiliser fetch. |
| Pas de vrai système de fichiers | Les environnements d'exécution disposent au mieux d'un système de fichiers virtuel en mémoire, jamais de votre disque. | Python et quelques autres environnements peuvent créer des fichiers pendant une session, mais ils disparaissent à la fermeture de la page ; nos programmes C et C++ n'ont que l'entrée et la sortie standard. |
| Pas d'exceptions C++ | Notre version de C++ est compilée avec les exceptions désactivées (-fno-exceptions). | Le code utilisant try, catch ou throw ne compilera pas ; utilisez plutôt des valeurs de retour ou des codes d'erreur. |
| Mémoire | WebAssembly 32 bits ne peut adresser que 4 Gio au maximum, et les navigateurs ou appareils peuvent en autoriser moins. | De très grands tableaux ou jeux de données peuvent provoquer des erreurs de mémoire insuffisante, surtout sur téléphone. |
| Saisie non interactive | L'entrée standard est fournie avant le démarrage du programme. | Saisissez d'abord toutes les données dans la zone de saisie ; les invites ne peuvent pas vous attendre en cours d'exécution. |
Pour apprendre, tester des algorithmes ou faire des exercices de cours, ces limites comptent rarement. Pour les programmes qui ont besoin du réseau, de plusieurs processus ou de beaucoup de mémoire, utilisez une installation locale ou un environnement côté serveur.
Le modèle de sécurité
Exécuter du code arbitraire semble risqué, mais les compilateurs dans le navigateur s'appuient sur des protections que les navigateurs appliquent déjà à chaque site web.
- Isolation WebAssembly. Un module ne peut lire et écrire que sa propre mémoire linéaire, dont les bornes sont contrôlées, et ne peut appeler que les fonctions qui lui sont explicitement importées. Un programme C avec un dépassement de tampon peut corrompre sa propre mémoire, mais il ne peut pas s'échapper vers le navigateur ou le système d'exploitation.
- Le bac à sable du navigateur. Tout le code de la page, y compris WebAssembly et les Web Workers, s'exécute dans le bac à sable de processus du navigateur et sous les règles de même origine : il ne peut donc pas lire les données d'autres sites ni vos fichiers.
- Workers et limites de temps. Exécuter dans un worker permet d'interrompre un programme qui s'emballe sans figer ni recharger la page.
- Environnements d'exécution vérifiés. Figer les versions exactes des environnements d'exécution, et vérifier les empreintes lorsque la méthode de chargement le permet, évite qu'un réseau de diffusion de contenu serve discrètement un fichier différent ou modifié.
Une réserve : le JavaScript que vous exécutez dans le compilateur JavaScript dispose des mêmes capacités que n'importe quel script d'une page web, y compris envoyer des requêtes réseau. Comme pour tout code, n'exécutez que des extraits que vous comprenez, surtout ceux copiés auprès d'inconnus.
Quel type de compilateur en ligne choisir ?
- Si votre code est privé, par exemple un devoir ou du code professionnel, préférez un compilateur dans le navigateur pour qu'il ne quitte jamais votre appareil.
- Si vous avez besoin de threads, de sockets, d'une bibliothèque système précise ou d'un langage sans version WebAssembly, utilisez un service côté serveur ou une installation locale.
- Si votre connexion est lente ou limitée en volume, commencez par les environnements d'exécution les plus légers ; le premier chargement d'un environnement volumineux est le principal coût.
Questions fréquentes
Mon code est-il envoyé à un serveur quand j'utilise vos compilateurs en ligne ?
Non. La page télécharge le compilateur ou l'interpréteur, et votre code et vos données d'entrée sont compilés et exécutés sur votre propre appareil. Le serveur ne fait que livrer la page et les fichiers d'exécution.
WebAssembly est-il aussi rapide que le code natif ?
Il en est généralement proche mais un peu plus lent, et l'écart dépend de la charge de travail et du navigateur. Pour des exercices et algorithmes classiques, la différence ne se remarque pas ; le téléchargement initial est le délai le plus long.
Pourquoi la première exécution est-elle plus longue ?
La première exécution télécharge et initialise l'environnement d'exécution, ce qui représente des dizaines de mégaoctets pour Clang, R ou Ruby. Le navigateur met ces fichiers en cache, et les visites suivantes démarrent beaucoup plus vite.
Pourquoi mon code C++ avec try et catch ne compile-t-il pas ?
Notre version de C++ est compilée avec les exceptions désactivées, car la gestion des exceptions en WebAssembly demande à la chaîne d'outils et à l'environnement d'exécution une prise en charge supplémentaire que cette configuration n'utilise pas. Réécrivez la gestion d'erreurs avec des valeurs de retour, std::optional ou des codes d'erreur, ou compilez en local si vous avez besoin des exceptions.
Un programme exécuté dans un compilateur en ligne peut-il endommager mon ordinateur ?
Le code exécuté en WebAssembly dans le navigateur est confiné à sa propre mémoire et aux fonctions que la page lui fournit, et le bac à sable du navigateur ajoute une couche de protection. Il ne peut pas lire vos fichiers ni installer de logiciel. Le code JavaScript peut en revanche envoyer des requêtes web comme n'importe quel script de page : évitez donc d'exécuter du code auquel vous ne faites pas confiance.
Commentaires
Connectez-vous pour noter cet outil.
Partagez une astuce, posez une question ou racontez comment l’outil a fonctionné pour vous.
Aucun commentaire pour l’instant. Soyez le premier à raconter votre expérience.