WebAssembly

Présenté par Brendan Eich, le créateur de JavaScript et en partie d'Asm.js, WebAssembly ou wasm, est un nouveau langage de représentation intermédiaire (IRL) compatible avec tous les navigateurs. Il permettra à différents langages de haut niveau, de fonctionner dans les navigateurs en étant compilés en wasm. Le but initial est de compiler des programmes et bibliothèques de C et C++ en WebAssembly. Puis d'autres langages devront suivre.

 

 

PARTIE 1 | C’EST QUOI WEBASSEMBLY ?

WebAssembly, ou wasm, est un nouveau type de code qui peut être exécuté dans un navigateur web moderne. C'est un langage bas niveau semblable à l'assembleur, permettant d'atteindre des performances proches des applications natives (par exemple écrites en C/C++) tout en fonctionnant sur le Web. WebAssembly est conçu pour fonctionner en lien avec JavaScript et, en passe de devenir une norme dans l'industrie, il donne aux développeurs web un certain nombre d'options qu'ils n'avaient pas auparavant. Il leur permet par exemple de :

  • Profiter du format compact wasm pour transmettre des fichiers rapidement sur le réseau et les charger en tant que modules JavaScript
  • Obtenir des performances quasi natives sans utiliser de plug-in
  • Écrire un code à la fois performant et sécurisé, car il s'exécute dans le sandbox de sécurité du navigateur
  • Avoir un choix de langages en dehors de JavaScript. Il permet par exemple aux développeurs d'écrire du code en C ou C++, puis de compiler directement en wasm, sans devoir compiler le code en JavaScript d'abord. En dehors de C/C++, des langages supplémentaires seront supportés à l'avenir

Cela a d'énormes implications pour la plate-forme web, il fournit un moyen d'exécuter un code écrit dans divers langages sur le web à une vitesse proche du natif, avec des applications clientes exécutées sur le web qui auparavant n'auraient pas pu être réalisées.

 

Les modules WebAssembly peuvent être importés dans une application web (ou Node.js) en exposant les fonctions WebAssembly à utiliser via JavaScript. Les frameworks JavaScript pourraient utiliser WebAssembly pour conférer des avantages massifs de performance et de nouvelles fonctionnalités tout en rendant la fonctionnalité facilement accessible aux développeurs web.

 

WebAssembly est en cours de création en tant que standard ouvert au sein du W3C WebAssembly Community Group avec les objectifs suivants :

  • Être rapide, efficace et portable : Le code WebAssembly peut être exécuté à une vitesse proche du natif sur plusieurs plateformes en profitant des capacités matérielles communes
  • Être lisible et débuggable: WebAssembly est un langage d'assemblage de bas niveau, mais son format de texte est lisible par l'homme (la spécification pour laquelle il est encore en cours de finalisation) et permet au code d'être écrit, lu et débuggé à la main
  • Conserver la sécurité : WebAssembly est conçu pour être exécuté dans un environnement sûr, en sandbox. Comme d'autres codes web, il imposera les règles de même origine du navigateur, ainsi que ses politiques d'autorisations
  • Ne pas casser le web : WebAssembly est conçu de manière à facilement s'associer aux autres technologies web et à maintenir une rétrocompatibilité

 

 

La plateforme web peut s'imaginer comme composé de deux parties :

  • Une machine virtuelle (VM) qui exécute le code de la Web app, e.g le code Javascript qui fait tourner vos applications
  • Un ensemble de Web APIs que la Web app peut appeler pour contrôler les fonctionnalités des navigateurs/appareils et réaliser des actions (DOM, CSSOM, WebGL, IndexedDB, Web Audio API, etc.)

 

 

Historiquement, la VM était seulement capable de charger le Javascript. Cela fonctionnait bien vu que le Javascript est assez puissant pour résoudre la majeure partie des problèmes que les gens rencontrent sur Internet.

Cependant, certains problèmes de performances ont eu lieu, notamment lors de l'utilisation de Javascript pour des cas d'utilisations plus avancés comme les jeux 3D, la réalité virtuelle et augmentée, la vision artificielle, l'édition d'image/vidéo, et un nombre de domaines qui demandent des performances natives.

 

De plus, le coût du téléchargement et de la compilation de très grosses applications JavaScript peut être prohibitif. L'utilisation de mobiles ou d'autres plateformes à puissance réduite accentue d'autant plus l'effet de goulet d'étranglement des performances.

WebAssembly est un langage diffèrent de JavaScript, mais n'a pas pour but de le remplacer. Il faut plutôt l'envisager comme complément, travaillant "main dans la main" avec JavaScript, permettant ainsi aux développeurs WEB de prendre avantage des points forts de chacun des deux langages :

  • JavaScript est un langage haut niveau, flexible et suffisamment expressif pour écrire des applications web.  Il possède beaucoup d'avantages : il est dynamiquement typé, ne nécessite aucune étape de compilation, et a un écosystème foisonnant qui lui fournit de puissants frameworks, bibliothèques, et autres outils
  • WebAssembly est un langage bas niveau, de style assembleur, avec un format binaire compact qui tourne avec des performances proches du natif et fourni au langage une gestion bas niveau de la mémoire tout comme le C++ et Rust comme cible de compilation afin de pouvoir tourner sur le web. (Notez qu'une priorité de WebAssembly est de supporter les langages avec modèles de mémoire à garbage-collector dans le futur)

 

Avec l'apparition du WebAssembly dans les navigateurs, la machine virtuelle dont nous parlions précédemment charge et exécute deux types de code - JavaScript ET WebAssembly.

Les deux différents types de code peuvent s'appeler si nécessaire : l'API WebAssembly JavaScript enveloppe le code exporté avec des fonctions JavaScript qui peuvent être appelées normalement et le code WebAssembly peut importer et appeler normalement de manière synchrone les fonctions JavaScript. En fait, l'unité de base de code WebAssembly est appelée module et est similaire par de nombreux aspects aux modules ES2015.

Il y a différents concepts clefs nécessaires pour comprendre comment fonctionne WebAssembly dans le navigateur. Tous ces concepts se retrouvent totalement dans l'API WebAssembly JavaScript.

  • Module : Représente un binaire WebAssembly qui a été compilé en code exécutable par le navigateur.  Un module est sans état et - comme un Blob - peut donc être explicitement mis en cache dans IndexedDB ou partagé entre le contexte fenêtre et les workers (via postMessage()).  Un module déclare des imports et exports au même titre qu'un module ES2015
  • Mémoire : Représente un ArrayBuffer redimensionnable qui contient un tableau d'octets contiguë accessible en lecture/écriture par les instructions bas niveau d'accès mémoire du WebAssembly
  • Table : Représente un tableau typé de référence (comme par exemple des fonctions) qui ne peut pas être stocké de manière brute en mémoire (pour des raisons de sécurité et de portabilité)
  • Instance : Représente un module associé avec tous les états qu'il utilise à l'exécution à savoir la mémoire, la table précédemment citée et un ensemble de données importés. Une instance est comme un module ES2015 qui e été chargé dans un contexte global avec un ensemble d'imports

L'API Javascript fournit aux développeurs la capacité de créer des modules,de la mémoire, des tables et instances. Pour une instance WebAssembly donnée, le code JavaScript peut appeler - de manière synchrone - ses exports qui sont accessibles comme des fonctions JavaScript normales. De façon arbitraire, toute fonction JavaScript peut aussi être appelée, de manière synchrone, par du code WebAssembly en passant ces fonctions JavaScript comme des imports à une instance WebAssembly.

 

Vu que JavaScript a un contrôle total sur la façon de charger, compiler et exécuter du code WebAssembly, les développeurs peuvent voir le WebAssembly comme une fonctionnalité JavaScript pour générer efficacement des fonctions très rapides.

Dans le futur, les modules WebAssembly seront chargeables comme des module ES2015 (en utilisant <script type='module'>), ce qui veut dire que JavaScript sera capable de récupérer, compiler et importer un module WebAssembly aussi facilement qu'un module ES2015.

PARTIE 2 | COMMENT UTILISER WEBASSEMBLY

D'autres outils verront sans aucun doute le jour à l'avenir. Pour le moment, il y a deux points d'entrée principaux:

  • Porter une application C/C++ avec Emscripten
  • Ecrire ou générer WebAssembly directement au niveau assembleur
  • Ecrire une application Rust et cibler WebAssembly en sortie

 

L'outil Emscripten est capable de prendre du code source C/C++ et de le compiler dans un module.wasm, de générer le code "glue" Javascript nécessaire pour charger et exécuter le module et de créer un document HTML capable d'afficher les résultats d'exécution du code.

 

En résume, le principe de fonctionnement est le suivant :

  1. D'abord, Emscripten alimente clang+LLVM - une chaine de compilation open source mature empruntée par exemple à XCode sur OSX - avec le code C/C++
  2. Emscripten transforme ensuite le résultat compilé par clang+LLVM en binaire .wasm
  3. Par lui-même WebAssembly ne peut pour l'instant pas accéder directement au DOM; Il peut seulement appeler JavaScript avec des données de type primitif entier ou flottant. Ainsi, pour accéder à toute API Web, WebAssembly a besoin d'appeler du JavaScript qui ensuite effectuera l'appel à l'API Web. C'est pourquoi Emscripten crée le document HTML et le code "passe-plat" JavaScript nécessaire pour atteindre cet objectif

 

 

 

 

Pour le moment, Emscripten implemente des librairies C/C++ populaire comme SDL, OpenGL, OpenAL, et une partie de POSIX. Ces libraires sont implémentées sous forme d'API Web et donc chacune d'entre elles requiert un peu de code JavaScript "passe-plat" pour relier WebAssembly à l'API Web sous-jacente.

Ainsi le code "passe-plat" implémente les fonctionnalités de chaque librairie utilisée par le C/C++. Le code "passe-plat" contient aussi la logique pour appeler l'API JavaScript WebAssembly pour chercher, charger et exécuter le fichier .wasm.

 

Il y a des prérequis qui ont besoin d'être installé sur l’ordinateur:

  • Git : Sur Linux and OS X, il est en principe déjà présent.
  • CMake : Sur Linux et OS X, l'installer en utilisant un gestionnaire de package comme apt-get ou brew pour être sûr que les dépendances et les paths soient correct. Sur Windows, utiliser l'installeur CMake.
  • Un compilateur du système hôte : Sur Linux, installée GCC. Sur OS X, installer Xcode. On Windows, installer Visual Studio Community 2015 avec l'update 3 ou plus récent. A noter que les releases récentes VS 2017 ne fonctionneront pas : Elles ne sont pas encore supportées par Emscripten.
  • Python 2.7.x : Sur Linux et OS X, il est le plus souvent fournit par défaut.

 

Ensuite, il faut compiler Emscripten à partir des sources. Exécuter les commandes suivantes pour l'automatiser en utilisant l'Emscripten SDK:

 

Maintenant, à partir du répertoire emsdk, entrer la commande suivante pour initialiser l'environnement du compilateur Emscripten à partir duquel il sera possible de compiler les exemples C en asm.js/wasm:

 

CREER UN DOCUMENT HTML ET LA « GLUE » JAVASCRIPT :

C'est le cas le plus simple que nous allons voir, pour lequel vous utiliserez Emscripten pour générer tout ce dont vous avez besoin pour exécuter votre code en WebAssembly dans le navigateur.

  1. D'abord nous avons besoin d'un exemple à compiler. Prenez une copie du simple programme C suivant et sauvez le dans un fichier nommé hello.c dans un nouveau répertoire de votre disque dur :

  1. Maintenant, en utilisant la fenêtre terminale qui vous a servi pour entrer dans l'environnement du compilateur Emscripten, naviguez jusqu'au répertoire dans lequel se trouve votre fichier hello.c et exécuter la commande suivante :

 

 

Les options passées avec la commande sont les suivantes :

  • -s WASM=1 — Spécifie que nous voulons du wasm en sortie. Si nous ne spécifions pas cela, Emscripten génèrera juste en sortie du asm.js comme il fait le par défaut.
  • -o hello.html — Spécifie que nous voulons qu'Emscripten génère une page HTML (dont le nom de fichier est spécifié), le module wasm et le code "glue" en JavaScript pour une exécution dans un contexte web.

 

Maintenant dans le répertoire source il devrait y avoir :

  • Le code du module binaire wasm (hello.wasm)
  • Un fichier JavaScript contenant du code de collage à traduire entre les fonctions C natives et JavaScript / wasm (hello.js)
  • Un fichier HTML pour charger, compiler et instancier votre code wasm, et afficher sa sortie dans le navigateur (hello.html)

 

Il ne reste plus qu'à charger le hello.html dans un navigateur prenant en charge WebAssembly. Si tout a fonctionné comme prévu, il devrait y avoir la sortie "Hello world" dans la console Emscripten apparaissant sur la page web, et la console JavaScript de votre navigateur.

 

UTILISER UNE TEMPLATE HTML

  1. Tout d'abord, il faut enregistrer le code C suivant dans un fichier appelé hello2.c, dans un nouveau répertoire :

  1. Rechercher le fichier shell_minimal.html dans le répertoire emsdk. Copier dans un sous-répertoire appelé html_template dans le nouveau répertoire.

 

  1. Maintenant il faut ouvrir le nouveau répertoire (encore une fois, dans la fenêtre de terminal de l'environnement de compilation Emscripten), et exécuter la commande suivante :

Les options que nous avons passées sont légèrement différentes cette fois-ci:

  • Nous avons spécifié -o hello2.html, ce qui signifie que le compilateur affichera toujours le code JavaScript et .html.
  • Nous avons également spécifié --shell-file html_template / shell_minimal.html, ceci fournit le chemin vers le modèle HTML que vous voulez utiliser pour créer le code HTML dans lequel vous allez exécuter votre exemple.

 

Maintenant, il ne reste plus qu’à exécuter cet exemple. La commande ci-dessus aura généré hello2.html, qui aura plus ou moins le même contenu que le modèle avec du code ajouté pour charger le wasm généré. Ouvrez-le dans votre navigateur et vous verrez la même sortie comme le dernier exemple.

 

APPELER UNE FONCTION EN C

Si vous avez une fonction définie dans votre code C que vous voulez appeler à partir de JavaScript, vous pouvez le faire en utilisant la fonction Emscripten ccall () et la déclaration EMSCRIPTEN_KEEPALIVE (qui ajoute vos fonctions à la liste des fonctions exportées).

  1. Pour commencer, enregistrez le code suivant en tant que hello3.c dans un nouveau répertoire :

Par défaut, le code généré par Emscripten appelle toujours la fonction main () et les autres fonctions sont éliminées en tant que code mort. Mettre EMSCRIPTEN_KEEPALIVE avant un nom de fonction empêche que cela se produise. Vous devez également importer la bibliothèque emscripten.h pour utiliser EMSCRIPTEN_KEEPALIVE.

 

  1. Maintenant, ajoutez aussi html_template / shell_minimal.html dans ce nouveau répertoire, juste pour plus de facilité (vous le placerez évidemment au centre de votre environnement de développement réel).

 

  1. Passons maintenant à l'étape de compilation. Depuis votre dernier répertoire (et à l'intérieur de votre fenêtre de terminal d'environnement de compilation Emscripten), compilez votre code C avec la commande suivante.

  1. Si vous chargez à nouveau l'exemple dans votre navigateur, vous verrez la même chose qu'avant.

 

  1. Maintenant, nous devons lancer notre nouvelle fonction myFunction () à partir de JavaScript. Tout d'abord, ajoutons un <button> comme indiqué ci-dessous, juste au-dessus de la première balise d'ouverture <script type = 'text / javascript'>.

 

  1. Maintenant, ajoutez le code suivant dans le dernier élément <script> (juste au-dessus de la balise de fermeture </script>) :

 

 

 

 

 

 

PARTIE 3 | WEBASSEMBLY EN APPLICATION

 

WebAssembly ou Wasm représente une avancée fondamentale de la plateforme web. Il permet d'exécuter du code (éventuellement écrit depuis différents langages) sur le Web avec des performances similaires aux applications natives.

WebAssembly est conçu pour être utilisé de pair avec JavaScript. Grâce à l'API JavaScript WebAssembly, on peut charger des modules WebAssembly au sein d'une application JavaScript et partager des fonctionnalités entre les deux. Cela permet de tirer parti des performances de WebAssembly et de la flexibilité de JavaScript, même si on ne sait pas écrire du code WebAssembly.

Wasm est conçu comme un standard web par le groupe communautaire du W3C pour Wasm auquel participe les différents éditeurs de navigateur.

 

Avec les avantages qu’il présente, il n’a fallu que deux ans à tous les principaux fournisseurs de navigateurs pour prendre en charge le nouveau standard. Dans un billet de blog, Mozilla a en effet annoncé que le support WebAssembly est disponible dans tous les principaux navigateurs. Apple et Microsoft ont fourni de nouvelles versions de Safari et Edge, avec le support de WebAssembly. Étant donné que Mozilla Firefox et Google Chrome prenaient déjà en charge WebAssembly, cela veut dire que les quatre principaux navigateurs sont désormais capables de générer du code compilé dans le format wasm sur le Web. « Google, Apple et Microsoft s'étaient tous engagés à prendre en charge WebAssembly dans leurs navigateurs. Avoir ce support sur le marché aujourd'hui est un développement vraiment passionnant », a déclaré Luke Wagner, l'ingénieur de Mozilla qui a créé le précurseur de WebAssembly, asm.js, et qui a dirigé le travail sur la spécification WebAssembly.

Pour les développeurs, la prise en charge du nouveau standard par les principaux navigateurs signifie qu'ils peuvent tirer parti de WebAssembly avec l'assurance que la plupart des utilisateurs seront en mesure d'exécuter des modules wasm par défaut.

WebAssembly apporte des performances sur le Web qu'il est extrêmement difficile d'atteindre avec JavaScript seul, notamment pour l'industrie du jeu. « Asm.js et WebAssembly étaient sans l'ombre d'un doute pour les entreprises de l'industrie du jeu, car elles avaient d'énormes investissements dans des programmes en C ++ qu'elles ne voulaient pas réécrire pour le Web », a déclaré Wagner. Raison pour laquelle cette industrie a été la première à adopter WebAssembly et asm.js. D’après l’ingénieur de Mozilla, Epic et Unity ont devancé les autres en étant les premiers à mettre en ligne leurs moteurs de jeu à l'échelle industrielle sans réécrire les bases de code C++ en JavaScript.
Mais aujourd'hui, les cas d'utilisation de WebAssembly et asm.js se sont développés au-delà des jeux en ligne. À mesure que les utilisateurs expérimentent le processus d'utilisation du format WebAssembly, et du compilateur Emscripten, ils trouvent des moyens de transférer des applications de plus en plus sophistiquées vers le Web. D'après Luke Wagner, les applications portées sur le Web grâce à WebAssembly couvrent divers domaines, y compris la vision par ordinateur, la cartographie 3D, le traitement des signaux numériques, l'imagerie médicale, la simulation physique, le chiffrement, la compression, etc. « Nous voyons maintenant des gens utiliser WebAssembly pour toutes sortes de nouveaux projets », dit-il. Pour lui, cela promet que nous serons un jour capables de faire tourner n'importe quelle application sur le Web et de la faire fonctionner comme si elle fonctionnait localement sur un PC.

WebAssembly, or wasm, is the most significant new technology to come to the web platform in a decade.  Technically speaking, it is a new, low-level, assembly-like language that runs efficiently on the existing web platform and is backward-compatible with its precursor, asm.js. Most people, however, will use the wasm format as a compiler target, translating their applications into web-ready modules that can run in modern web browsers at near-native speeds.

 

WebAssembly delivers significant performance gains because modern browser engines can parse and execute its binary format an order of magnitude faster than JavaScript. So you can take C/C++ code, translate it into wasm using a compiler tool like Emscripten, and load the generated wasm module into a JavaScript app, where it will be safely and efficiently executed by the browser.

 

The wasm format makes it possible to support graphics-heavy games in a browser without plug-ins. It can be used to port scientific simulation and other compute-intensive applications to the web platform. It also has non-web applications such as the Internet of Things, mobile apps and JavaScript virtual machines.

 

What does it replace or change ?

  • The wasm format removes the need for browser plug-ins to support online gaming.
  • It works alongside JavaScript, replacing asm.js as the compilation target for C/C++ applications.
  • It allows programmers to put large C/C++ applications on the web without rewriting them.

 

WebAssembly is an emerging standard, with ongoing work on the specification. The browser vendors have reached consensus on the design of the initial wasm API and binary format, and there is an active W3C Community Group with members from Mozilla, Microsoft, Google and Apple.

 

Firefox and Chrome browsers currently support the wasm format on Linux, MacOS, Windows and Android. The latest versions of Edge and Safari now include WebAssembly support as well. Autodesk plans to support wasm and WebGL 2 in its Stingray v1.8 game engine. Other game engines and projects like the Rust language are adding experimental support.

 

 

Sources:

https://www.developpez.com/actu/123097/WebAssembly-a-t-il-pour-vocation-de-remplacer-a-long-terme-JavaScript-Le-standard-est-au-centre-des-discussions-des-developpeurs-web/

http://webassembly.org/community/feedback/

https://www.scriptol.fr/programmation/wasm.php

https://www.synbioz.com/blog/webassembly_vers_un_web_compile

 

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *