Article de reference

WebAssembly

{{Cite web|title=WebAssembly/design/Semantics.md|url=https://github.com/WebAssembly/design/blob/376bcc4b9cba79280d79be023d71e30d0b00ba47/Semantics.md|access-date=2021-02-23|webs...

de code binaire portable et un format texte correspondant pour les programmes exécutables ainsi que des interfaces logicielles facilitant la communication entre ces programmes et leur environnement hôte.

L'objectif principal de WebAssembly est de faciliter le développement d'applications performantes sur les pages web , mais il est également conçu pour être utilisable dans des environnements non web. Il s'agit d'une norme ouverte destinée à prendre en charge n'importe quel langage sur n'importe quel système d'exploitation, et en pratique, bon nombre des langages les plus populaires bénéficient déjà d'une prise en charge, même partielle.

Annoncé en World Wide Web Consortium (W3C) le 5 décembre 2019 et a reçu le prix du meilleur logiciel de langage de programmation décerné par l' Association for Computing Machinery (ACM) SIGPLAN en 2021. Le W3C maintient la norme grâce aux contributions de Mozilla , Microsoft , Google , Apple , Fastly , Intel et Red Hat . ( 2015 )

en langage assembleur sur le Web , où elle sera exécutée côté client , par l'ordinateur de l'utilisateur via son navigateur . Pour ce faire, WebAssembly doit être beaucoup plus indépendant du matériel qu'un véritable langage assembleur.

WebAssembly a été annoncé pour la première fois en 2015 et sa première démonstration a consisté à exécuter Angry Bots d' Unity dans Firefox , Google Chrome [ et Microsoft Edge (ancienne version) . Les technologies précurseurs étaient asm.js de Mozilla et Google Native Client [ , et l'implémentation initiale était basée sur les fonctionnalités d'asm.js

En mars 2017, la conception du produit minimum viable (MVP) a été déclarée terminée et la phase de prévisualisation s'est achevée. Fin septembre 2017, Safari 11 a été publié avec la prise en charge de WebAssembly. En février 2018, le groupe de travail WebAssembly a publié trois versions préliminaires publiques pour la spécification de base, l'interface JavaScript et l'API Web.

Le MVP était axé sur les langages de bas niveau tels que C et C++ , avec l'intention d'ajouter des fonctionnalités utiles pour les langages de haut niveau dans une version future.

Le multithreading est actuellement à l'état de brouillon, mais il est pris en charge par Chrome depuis la version 75 en juin 2019, Firefox version 79 et Safari version 14.1

La spécification WebAssembly 2.0 a été finalisée en 2022 et est devenue une norme W3C en décembre 2024. Elle ajoute de nombreuses instructions liées à l'instruction SIMD ( Single Instruction, Multiple Data ) et un nouveau type de données v128, avec la possibilité pour les fonctions de renvoyer plusieurs valeurs, des instructions d'initialisation/copie de mémoire en masse et des types de référence, qui sont des pointeurs opaques vers des objets situés en dehors de la mémoire linéaire.

WebAssembly 3.0 a été publié en septembre 2025. Parmi ses nouvelles fonctionnalités figurent un espace d'adressage 64 bits , la prise en charge de plusieurs espaces d'adressage, la gestion des exceptions et le ramasse-miettes pour les types struct et array. La prise en charge du ramasse-miettes permet une compilation plus efficace pour les langages de haut niveau, mais WasmGC de WebAssembly 3.0 ne possède pas les fonctionnalités requises par le runtime .NET .

Mises en œuvre

Bien que WebAssembly ait été initialement conçu pour permettre une vitesse d'exécution de code quasi native dans le navigateur web, son utilité s'est avérée précieuse en dehors de ce cadre, dans des contextes plus généraux. Un environnement d'exécution WebAssembly est une machine virtuelle de bas niveau , semblable à la JVM ou à la Flash VM ; il peut être intégré à n'importe quelle application hôte, et des environnements d'exécution WebAssembly autonomes ont ainsi été créés, tels que serveurs d'applications pour héberger des applications WebAssembly « côté serveur » et à d'autres applications pour prendre en charge les architectures d'extension logicielle basées sur des plugins , comme WebAssembly for Proxies (Proxy-Wasm), qui spécifie une interface binaire d'application (ABI) basée sur WebAssembly pour étendre les serveurs proxy .

navigateurs Web

En novembre 2017, Mozilla a annoncé la prise en charge de WebAssembly « dans tous les principaux navigateurs » , après son activation par défaut dans Edge [Legacy] 16 Cette prise en charge inclut également les navigateurs web mobiles pour iOS et Android. asm.js. 46 Pour certaines extensions de la norme préliminaire 2.0, la prise en charge peut être moindre, mais plus de 90 % des navigateurs web les prennent déjà en charge, par exemple l'extension des types de référence

Environnements d'exécution hors navigateur

Les environnements d'exécution WebAssembly hors navigateur incluent Wasmer, Wasmtime, WAMR, WAVM, wasm3 et d'autres. Ces systèmes exécutent des modules Wasm précompilés et fournissent souvent des API supplémentaires pour l'intégration de WebAssembly dans différents environnements. Parmi les cas d'utilisation de wasm hors navigateur, on peut citer les interfaces de plug-ins et la virtualisation légère.

Compilateurs

Les implémentations WebAssembly utilisent généralement la compilation AOT ( Ahead-of-Time ) ou la compilation JIT ( Just-in-Time ), bien que certaines puissent également recourir à un interpréteur . Si les premières implémentations sont apparues dans les navigateurs web, il existe désormais de nombreuses implémentations hors navigateur pour une utilisation plus générale.

chaînes d'outils de compilation

Étant donné que les exécutables WebAssembly sont précompilés, une variété de langages de programmation peuvent cibler Wasm. La compilation se fait soit par sortie directe vers Wasm, soit via des machines virtuelles intermédiaires implémentées dans Wasm.

Parmi les chaînes d'outils notables, on peut citer :

  • Emscripten , qui compile le C et le C++ en Wasm en utilisant Clang comme interface, Binaryen comme optimiseur, et peut également cibler n'importe quel langage pris en charge par LLVM.
  • Clang autonome (version 8 et ultérieures), qui prend en charge la compilation directe en Wasm.
  • Flux de travail basés sur LLVM pour des langages tels que Rust et AssemblyScript.

Soutien linguistique

En 2021, une quarantaine de langages de programmation prenaient en charge WebAssembly comme cible de compilation. Exemples :

Limites

Les navigateurs Web empêchent le code WebAssembly de manipuler directement le modèle objet de document (DOM ). Le code Wasm doit donc faire appel à JavaScript pour cela.

Spectre et Meltdown , une fois la prise en charge des threads à mémoire partagée ajoutée. Face à cette préoccupation, les développeurs de WebAssembly ont suspendu le développement de cette fonctionnalité. Toutefois, afin d'explorer ces futures extensions du langage, Google Chrome a ajouté une prise en charge expérimentale de la proposition de threads WebAssembly en octobre 2018.

WebAssembly a été critiqué pour sa capacité à faciliter la dissimulation de preuves pour les auteurs de logiciels malveillants , les escrocs et les auteurs d'attaques par hameçonnage ; WebAssembly n'est présent sur la machine de l'utilisateur que sous sa forme compilée, ce qui « rend la détection des logiciels malveillants difficile » . La rapidité et la facilité de dissimulation offertes par WebAssembly ont conduit à son utilisation pour le minage de cryptomonnaies à l'insu des utilisateurs . Coinhive, un service désormais disparu qui facilitait le minage de cryptomonnaies dans les navigateurs web, affirmait que son « mineur utilise WebAssembly et offre environ 65 % des performances d'un mineur natif ». Une étude de juin 2019 de l' Université technique de Brunswick a analysé l'utilisation de WebAssembly sur le million de sites web les plus populaires selon Alexa et a constaté que son utilisation prédominante était le minage malveillant de cryptomonnaies, et que les logiciels malveillants représentaient plus de la moitié des sites web utilisant WebAssembly étudiés. Une étude de l'Université de Stuttgart datant d'avril 2021 a révélé que, depuis lors, le minage de cryptomonnaies a été marginalisé, tombant à moins de 1 % de tous les modules WebAssembly collectés à partir d'un large éventail de sources, y compris le million de sites Web les plus populaires selon Alexa.

Comme WebAssembly ne prend en charge que le flux de contrôle structuré , il est compatible avec les techniques de vérification de sécurité, y compris l'exécution symbolique .

Performance

Au début, la vitesse d'exécution d'un programme Wasm était estimée à environ 91 % (soit environ 10 % plus lente) de celle d'un programme natif comparable, sans compter le temps de chargement/d'instanciation ; cependant, divers tests ultérieurs indiquent une large gamme de performances, allant de 33 % à 200 % de la vitesse d'exécution du code natif, selon la tâche.Université du Massachusetts à Amherst a présenté une analyse approfondie des performances de WebAssembly par rapport au code natif . Cette étude a utilisé la suite de benchmarks SPEC CPU et un système appelé « Browsix-Wasm » pour exécuter des applications Unix non modifiées dans le navigateur, permettant ainsi de tester des applications réelles. Elle a révélé un écart de performances significatif entre l'exécution de WebAssembly et l'exécution native ; en particulier, les programmes WebAssembly ont affiché un ralentissement moyen de 45 % dans Firefox et de 55 % dans Chrome lors des tests en conditions réelles. Lors des ralentissements les plus importants, un programme WebAssembly pouvait mettre 2,08 fois plus de temps à s'exécuter dans Firefox et 2,5 fois plus de temps dans Chrome. L'article a identifié plusieurs raisons à cette différence de performances, notamment des optimisations manquantes, des problèmes de génération de code dans les compilateurs WebAssembly et les limitations inhérentes à la plateforme WebAssembly.

Une étude de 2021 suggère que WebAssembly est beaucoup plus rapide que JavaScript dans certains cas, comme l'exécution d'une fonction complexe sur un petit fichier ( par exemple , le traitement d'un fichier graphique) ; cependant, à l'époque, l'interpréteur JavaScript disposait de certaines optimisations dont les implémentations WebAssembly ne disposaient pas ( par exemple , la compilation à la volée ).

En 2022, des chercheurs ont déterminé qu'un programme Wasm s'exécute à environ 120 % (soit 20 % plus rapidement) de la vitesse d'un programme JavaScript comparable. Ces résultats concordent avec l'expérience de la startup Zaplib, dont les fondateurs ont expliqué dans un article de blog sa fermeture en raison des performances insuffisantes de WebAssembly. Leur objectif était d'améliorer significativement les performances des applications web existantes en les portant progressivement vers Rust /Wasm ; cependant, la migration du simulateur d'un client depuis JavaScript n'a permis qu'une amélioration de 5 % des performances. De même, concernant Figma , ils ont déclaré ce qui suit :

Après un examen plus approfondi, il apparaît que l'utilisation de WebAssembly par Figma relève davantage d'un concours de circonstances historiques — la volonté de développer en C++ pour assurer la compatibilité avec leur application native — que d'impératifs de performance critiques. Les fichiers Figma sont traités en C++/WebAssembly, ce qui représente sans doute un gain de vitesse considérable, mais l'essentiel des performances exceptionnelles de Figma est dû à son moteur de rendu WebGL .

En 2023, une étude des performances de WebAssembly pour les tâches cryptographiques a indiqué que « lorsqu’il utilisait l’environnement d’exécution le plus rapide, WebAssembly était seulement environ 2,32 fois plus lent (en médiane) que le code natif avec des optimisations spécifiques à l’architecture ». Ce résultat excluait deux tests où le code natif bénéficiait d’instructions spéciales implémentées directement dans le processeur de la plateforme cible ; pour ces tests particuliers, les programmes WebAssembly étaient « 80 fois plus lents que le code natif ».

Les tests de performance ont révélé plusieurs autres points faibles de WebAssembly, tels que des performances médiocres dues à l'absence d'accès direct au DOM, un problème qui est en cours de résolution.

WASI

interface binaire d'application (ABI) et interface de programmation d'application (API)) conçue par Mozilla , destinée à être portable sur n'importe quelle plateforme. Elle offre des fonctionnalités similaires à l'interface de système d'exploitation portable ( POSIX ), telles que les entrées/sorties de fichiers (E/S) limitées par une sécurité basée sur les capacités . D'autres ABI/API ont été proposées.

WASI est influencé par CloudABI et Capsicum .

Docker , a écrit en 2019 : « Si WASM+WASI avait existé en 2008, nous n’aurions pas eu besoin de créer Docker. C’est dire son importance. WebAssembly côté serveur est l’avenir de l’informatique. »

WASI 0.1 propose quelques API de type POSIX, telles que les entrées/sorties de fichiers, la lecture des variables d'environnement et la génération de nombres aléatoires, mais offre une prise en charge réseau très limitée. WASI 0.2 est repensé selon le modèle de composants WebAssembly. WASI 0.3 ajoutera la prise en charge des fonctions asynchrones ; l'hôte assure la traduction entre les appels de fonctions bloquantes et asynchrones, de sorte qu'une fonction exportée bloquante peut être appelée comme une fonction asynchrone, et inversement.

À partir de la version 0.2, WASI est défini selon le modèle de composants. Les interfaces de ce modèle sont spécifiées dans un IDL appelé WIT (WebAssembly Interface Types). Alors que le langage WebAssembly de base ne prend en charge que les entiers et les nombres à virgule flottante, les interfaces WIT peuvent exprimer des types tels que des chaînes de caractères, des listes, ainsi que des types d'enregistrements et de variantes définis par l'utilisateur, et sont indépendantes du langage. Les composants ne peuvent pas accéder à la mémoire des autres et interagissent donc uniquement via des fonctions importées et exportées. Le modèle de composants est conçu autour de la composition : deux composants peuvent être composés en un seul lorsque les exportations de l'un correspondent aux importations de l'autre, ce qui permet de virtualiser n'importe quelle interface. Les interfaces WIT sont regroupées en un « monde ». WASI 0.2 définit un monde d'interface en ligne de commande (CLI) similaire à l'API de type POSIX de WASI 0.1, et un monde de proxy HTTP pour les serveurs web.

Le modèle de composants n'est actuellement pas pris en charge par les navigateurs.

Spécification

Environnement hôte

La norme générale fournit les spécifications de base de l'API JavaScript et des détails sur l'intégration.

machine virtuelle

Le code Wasm (code binaire, c'est-à-dire bytecode) est conçu pour être exécuté sur une machine virtuelle portable . Cette machine virtuelle est conçue pour être plus rapide à analyser et à exécuter que JavaScript et pour offrir une représentation compacte du code. La norme ne stipule aucune fonctionnalité externe (comme les appels système ) que pourrait attendre le code binaire Wasm ; elle spécifie plutôt comment l'environnement hôte peut fournir une telle interface via un « module ».

Programme Wasm

Un programme Wasm est conçu comme un module distinct contenant des ensembles de valeurs et de définitions de types de programmes définis par Wasm. Ces éléments sont fournis au format binaire ou textuel (voir ci-dessous) et possèdent une structure commune. Un tel module peut fournir une fonction de démarrage exécutée lors de l'instanciation d'un binaire Wasm.

Jeu d'instructions

La norme de base pour le format binaire d'un programme Wasm définit une architecture de jeu d'instructions (ISA) ; chaque opération exécutable par la machine virtuelle se voit attribuer un codage binaire spécifique (un « opcode »), mais la manière exacte dont l'opération est implémentée n'est pas spécifiée, ce qui permet une grande flexibilité dans la construction d'une machine virtuelle. La liste des types d'instructions comprend celles pour les chargements/stockages mémoire standard, les instructions numériques, paramétriques, de contrôle de flux et les variables spécifiques à Wasm.

Le nombre d'opcodes utilisés dans la norme d'origine ( SIMD de WebAssembly (pour le traitement parallèle) introduit un préfixe d'opcode alternatif (0xfd) pour les instructions SIMD de 128 bits ; la concaténation de ce préfixe SIMD, suivie d'un opcode valide après celui-ci, forme chaque opcode SIMD. Les opcodes SIMD ajoutent 236 instructions aux capacités SIMD du MVP (pour un total d'environ 436 instructions) Cet ensemble d'instructions est activé par défaut dans plusieurs implémentations importantes :

  1. V8 de Google (dans Google Chrome)
  2. Le moteur SpiderMonkey dans Mozilla Firefox
  3. Le moteur JavaScriptCore de Safari d'Apple

Ces opcodes SIMD sont à la fois portables et conçus pour être directement mappés sur des jeux d'instructions natifs tels que x86-64 et ARM . En revanche, les instructions SIMD ne sont pas directement prises en charge par la JVM de Java ni par le CIL de .NET ; toutefois, ces deux technologies proposent des API pour le traitement parallèle, qui offrent des gains de performance grâce aux instructions SIMD. Un ensemble plus récent d'instructions « SIMD relâchées » autorise un comportement limité, défini par l'implémentation, afin d'améliorer les performances.

Représentation du code

En mars 2017, le groupe de travail WebAssembly a adopté un consensus sur le format binaire initial (« MVP »), l’API JavaScript et l’interpréteur de référence. Ce consensus définit un format binaire WebAssembly les expressions S et les langages assembleur traditionnels. Le format binaire est simple et conçu pour permettre la compilation en flux continu : la compilation peut ainsi commencer avant la fin du téléchargement du module, et les fonctions peuvent être compilées en parallèle.

Le tableau ci-dessous présente un exemple de fonction factorielle écrite en C et son code WebAssembly correspondant après compilation, affiché à la fois au format texte .wat (une représentation textuelle lisible par l'homme de WebAssembly) et au format binaire .wasm (le bytecode brut , exprimé ci-dessous en hexadécimal ), exécuté par un navigateur Web ou un environnement d'exécution prenant en charge WebAssembly.

Code source C et WebAssembly correspondant
Code source CFormat de texte WebAssembly .watToutes les constantes entières sont codées à l'aide d'un codage LEB128 à longueur variable et à faible encombrement.

Le format texte WebAssembly est généralement écrit sous forme condensée à l'aide d'expressions S. Pour les instructions et les expressions, ce format est une simplification syntaxique et ne présente aucune différence de comportement avec le format linéaire. Grâce à pile d'appels et du code du module WebAssembly, ainsi que de la mémoire du moteur. Cela permet d'exécuter du code WebAssembly dans le même processus que la machine virtuelle JavaScript dans laquelle il est intégré, sans compromettre la sécurité de la mémoire.

Un module contient une liste de variables globales, distinctes de la mémoire linéaire, qui peuvent être mutables ou immuables. Les fonctions déclarent une liste de variables locales. Les paramètres d'une fonction sont également des variables locales.

Les instructions opèrent sur une pile de valeurs . La structure de la pile est fixe (les branchements doivent empiler et dépiler le même nombre d'opérandes), ce qui permet aux moteurs WebAssembly de compiler en supprimant la pile et en produisant des opérations en code machine efficaces sur les registres, plutôt que de gérer une pile à l'exécution. Une architecture de machine à pile a été choisie car elle permet une densité de code plus élevée qu'une machine à registres .

Flux de contrôle

Contrairement aux langages assembleur classiques, WebAssembly utilise un flux de contrôle structuré similaire à celui des langages de haut niveau. L'absence volontaire de prise en charge des instructions de saut simplifie la validation et la compilation du code WebAssembly en une seule passe , et facilite la lecture du code désassemblé au format texte.

Les blocs sont délimités par les constructions block`\`, loop`\` et if`/` else. Les instructions de branchement contiennent une étiquette qui identifie la profondeur du bloc dans lequel elles sont imbriquées : br 0`\` branche vers le bloc dans lequel l’instruction est contenue, ` br 1\` branche vers le bloc dans lequel ce bloc est contenu, et ainsi de suite. Les branchements vers `\` blockou `\ if` sautent à la fin du bloc comme une instruction `break`, tandis que les branchements vers `\` loopretournent au début de la boucle, comme une instruction `continue`. L’ br_tableinstruction prend un index en entrée et saute vers une cible à partir d’une liste d’étiquettes. Une instruction `switch` de style C peut être exprimée avec un `switch` br_tableà l’intérieur d’une série de blocs imbriqués.

Les compilateurs ciblant wasm convertissent le flux de contrôle non structuré en boucles de haut niveau à l'aide de l'algorithme Relooper d'Emscripten, conçu à l'origine pour cibler JavaScript.

Fonctions

Les déclarations de fonctions sont listées dans une section distincte, avant celle contenant le corps des fonctions. Les pointeurs de fonctions sont émulés à l'aide d'un index dans la table des fonctions globales, car le code n'est pas stocké dans la mémoire linéaire. Les fonctions peuvent également être importées et exportées, fournissant ainsi l' interface de fonctions externes pour communiquer avec JavaScript ou d'autres systèmes embarqués.

Plus d articles de Worldlex Wiki

Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

Explorer l index