MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/d6d7ff2e2f9c

Concepts de WebAssembly

Cette traduction est incomplète. Aidez à traduire cet article depuis l'anglais.

Cet article explique les concepts de fonctionnement de WebAssembly, y compris ses objectifs, les problèmes qu'il résout et la manière dont il s'exécute dans le moteur de rendu du navigateur.

Qu'est-ce que WebAssembly ?

WebAssembly est un nouveau type de code pouvant être exécuté dans les navigateurs modernes et fournissant de nouvelles fonctionnalités ainsi que des gains majeurs en performance. Il n'est pas particulièrement destiné à être écrit à la main, mais il est plutôt conçu pour être une cible de compilation efficace pour les langages source de bas niveau tels C, C ++, Rust, etc.

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.

De plus, vous ne devez même pas savoir comment créer du code WebAssembly pour en profiter. 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.

Objectifs de WebAssembly

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

  • Être rapide, efficace et portable — Le code WebAssembly peut être exécuté à une vitesse proche du natif sur plusieurs platformes 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, ansi 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é.

Note : WebAssembly aura également des usages en dehors du web et des environments JavaScript (voir Non-web embeddings).

Comment WebAssembly s'intègre dans la plateforme web?

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.
  • Une 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 pour nous comme le Javascript est assez puissant pour résoudre la majeure partie des problèmes que les gens rencontrent sur Internet. Nous nous sommes, cependant, confrontés à des problèmes de performances 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 ( voir Cas d'utilisations WebAssembly pour plus d'informations).

Additionally, the cost of downloading, parsing, and compiling very large JavaScript applications can be prohibitive.  Mobile and other resource-constrained platforms can further amplify these performance bottlenecks.

WebAssembly is a different language from JavaScript, but it is not intended as a replacement. Instead, it is designed to complement and work alongside JavaScript, allowing web developers to take advantage of both language's strong points:

  • JavaScript is a high-level language, flexible and expressive enough to write web applications.  It has many advantages — it is dynamically typed, requires no compile step, and has a huge ecosystem that provides powerful frameworks, libraries, and other tools.
  • WebAssembly is a low-level assembly-like language with a compact binary format that runs with near-native performance and provides languages with low-level memory models such as C++ and Rust a compilation target so that they can run on the web. (Note that WebAssembly has the high-level goal of supporting languages with garbage-collected memory models in the future.)

With the advent of WebAssembly appearing in browsers, the virtual machine that we talked about earlier will now load and run two types of code — JavaScript AND WebAssembly.

The different code types can call each other as required — the WebAssembly JavaScript API wraps exported WebAssembly code with JavaScript functions that can be called normally, and WebAssembly code can import and synchronously call normal JavaScript functions.  In fact, the basic unit of WebAssembly code is called a module and WebAssembly modules are symmetric in many ways to ES2015 modules.

WebAssembly key concepts

There are several key concepts needed to understand how WebAssembly runs in the browser.  All of these concepts are reflected 1:1 in the WebAssembly JavaScript API.

  • Module: Represents a WebAssembly binary that has been compiled by the browser into executable machine code.  A Module is stateless and thus, like a Blob, can be explicitly cached in IndexedDB or shared between windows and workers (via postMessage()).  A Module declares imports and exports just like an ES2015 module.
  • Memory: A resizable ArrayBuffer that contains the linear array of bytes read and written by WebAssembly’s low-level memory access instructions.
  • Table: A resizable typed array of references (e.g. to functions) that could not otherwise be stored as raw bytes in Memory (for safety and portability reasons).
  • Instance: A Module paired with all the state it uses at runtime including a Memory, Table, and set of imported values.  An Instance is like an ES2015 module that has been loaded into a particular global with a particular set of imports.

The JavaScript API provides developers with the ability to create modules, memories, tables, and instances.  Given a WebAssembly instance, JavaScript code can synchronously call its exports, which are exposed as normal JavaScript functions.  Arbitrary JavaScript functions can also be synchronously called by WebAssembly code by passing in those JavaScript functions as the imports to a WebAssembly instance.

Since JavaScript has complete control over how WebAssembly code is downloaded, compiled and run, JavaScript developers could even think of WebAssembly as just a JavaScript feature for efficiently generating high-performance functions.

In the future, WebAssembly modules will be loadable just like ES2015 modules (using <script type='module'>), meaning that JavaScript will be able to fetch, compile, and import a WebAssembly module as easily as an ES2015 module.

How do I use WebAssembly in my app?

Above we talked about the raw primitives that WebAssembly adds to the Web platform: a binary format for code and APIs for loading and running this binary code.  Now let’s talk about how we can use these primitives in practice.

The WebAssembly ecosystem is at a nascent stage; more tools will undoubtedly emerge going forward. Right now, there are two main entry points:

  • Porting a C/C++ application with Emscripten.
  • Writing or generating WebAssembly directly at the assembly level.

Let’s talk about these options:

Porting from C/C++

The Emscripten tool is able to take C/C++ source code and compile it into a .wasm module, plus the necessary JavaScript "glue" code for loading and running the module, and an HTML document to display the results of the code.

In a nutshell, the process works as follows:

  1. Emscripten first feeds the C/C++ into clang+LLVM — a mature open-source C/C++ compiler toolchain, shipped as part of XCode on OSX for example.
  2. Emscripten transforms the compiled result of clang+LLVM into a .wasm binary.
  3. By itself, WebAssembly cannot currently directly access the DOM; it can only call JavaScript, passing in integer and floating point primitive data types. Thus, to access any Web API, WebAssembly needs to call out to JavaScript, which then makes the Web API call. Emscripten therefore creates the HTML and JavaScript glue code needed to achieve this.

Note: There are future plans to allow WebAssembly to call Web APIs directly.

The JavaScript glue code is not as simple as you might imagine. For a start, Emscripten implements popular C/C++ libraries like SDL, OpenGL, OpenAL, and parts of POSIX. These libraries are implemented in terms of Web APIs and thus each one requires some JavaScript glue code to connect WebAssembly to the underlying Web API.

So part of the glue code is implementing the functionality of each respective library used by the C/C++ code. The glue code also contains the logic for calling the abovementioned WebAssembly JavaScript APIs to fetch, load and run the .wasm file.

The generated HTML document loads the JavaScript glue file and writes stdout to a <textarea>. If the application uses OpenGL, the HTML also contains a <canvas> element that is used as the rendering target. It’s very easy to modify the Emscripten output and turn it into whatever web app you require.

You can find full documentation on Emscripten at emscripten.org, and a guide to implementing the toolchain and compiling your own C/C++ app across to wasm at Compiling from C/C++ to WebAssembly.

Writing WebAssembly directly

Do you want to build your own compiler, or your own tools, or make a JavaScript library that generates WebAssembly at runtime?

In the same fashion as physical assembly languages, the WebAssembly binary format has a text representation — the two have a 1:1 correspondence. You can write or generate this format by hand and then convert it into the binary format with any of several WebAssemby text-to-binary tools.

For a simple guide on how to do this, see our Converting WebAssembly text format to wasm article.

Summary

This article has given you an explanation of what WebAssembly is, why it is so useful, how it fits into the web, and how you can make use of it.

See also

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : Mo-la-machette, arthurwhite
 Dernière mise à jour par : Mo-la-machette,