From 2e1dfbf08988f2256199562020f6b3ef96cf9a45 Mon Sep 17 00:00:00 2001 From: julieng Date: Thu, 11 Nov 2021 07:39:19 +0100 Subject: convert content to md --- files/fr/webassembly/c_to_wasm/index.md | 243 ++++++------- files/fr/webassembly/concepts/index.md | 146 ++++---- files/fr/webassembly/exported_functions/index.md | 68 ++-- files/fr/webassembly/index.md | 168 ++++----- files/fr/webassembly/loading_and_running/index.md | 104 +++--- .../webassembly/using_the_javascript_api/index.md | 377 ++++++++++----------- 6 files changed, 506 insertions(+), 600 deletions(-) (limited to 'files') diff --git a/files/fr/webassembly/c_to_wasm/index.md b/files/fr/webassembly/c_to_wasm/index.md index b55618c1de..2353bba4b4 100644 --- a/files/fr/webassembly/c_to_wasm/index.md +++ b/files/fr/webassembly/c_to_wasm/index.md @@ -10,178 +10,159 @@ tags: - wasm translation_of: WebAssembly/C_to_wasm --- -
{{WebAssemblySidebar}}
+{{WebAssemblySidebar}} -

Quand vous avez écrit un module de code dans un langage comme le C/C++, vous pouvez ensuite le compiler en WebAssembly en utilisant un outil comme Emscripten. Regardons comment cela fonctionne.

+Quand vous avez écrit un module de code dans un langage comme le C/C++, vous pouvez ensuite le compiler en WebAssembly en utilisant un outil comme [Emscripten](/fr/docs/Mozilla/Projects/Emscripten). Regardons comment cela fonctionne. -

Mise en place de l'environnement Emscripten

+## Mise en place de l'environnement Emscripten -

D'abord, mettons en place l'environnement requis pour le développement.

+D'abord, mettons en place l'environnement requis pour le développement. -

Prérequis

+### Prérequis -

Recuperer le SDK de Emscripten en utilisant les instructions suivantes: https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html

+Recuperer le SDK de Emscripten en utilisant les instructions suivantes:  -

Compiler un exemple

+## Compiler un exemple -

Une fois l'environnement mis en place, regardons comment l'utiliser pour compiler un exemple en C via Emscripten. Il existe un certain nombre d'options disponibles quand on compile avec Emscripten, mais nous allons couvrir seulement les deux principaux scénarios:

+Une fois l'environnement mis en place, regardons comment l'utiliser pour compiler un exemple en C via Emscripten. Il existe un certain nombre d'options disponibles quand on compile avec Emscripten, mais nous allons couvrir seulement les deux principaux scénarios: - +- Compiler vers du wasm et créer du HTML pour exécuter notre code plus toute la "glue" Javascript nécessaire à l'exécution du wasm dans l'environnement Web. +- Compiler vers du wasm et juste créer le Javascript. -

Nous verrons les deux par la suite.

+Nous verrons les deux par la suite. -

Créer le document HTML et la "glue" JavaScript

+### Créer le 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. 

+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. 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: -
    #include <stdio.h>
    +    ```cpp
    +    #include 
     
    -int main(int argc, char ** argv) {
    -  printf("Hello World\n");
    -}
    -
  2. -
  3. Maintenant, en utilisant la fenêtre terminal 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écutez la commande suivante : -
    emcc hello.c -s WASM=1 -o hello.html
    -
  4. -
+ int main(int argc, char ** argv) { + printf("Hello World\n"); + } + ``` -

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

+2. Maintenant, en utilisant la fenêtre terminal 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écutez la commande suivante : - + ```bash + emcc hello.c -s WASM=1 -o hello.html + ``` -

À ce stade votre dossier source devrait contenir :

+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](http://asmjs.org/) comme il le fait 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 execution dans un contexte web. -

Exécuter votre exemple

+À ce stade votre dossier source devrait contenir : -

Maintenant, tout ce qui vous reste à faire est de charger le fichier hello.html dans un navigateur qui supporte WebAssembly. Il est activé par défaut dans Firefox 52+, Chrome 57+ et dans la derniere version d'Opera (vous pouvez aussi executer du code wasm dans Firefox 47+ en activant le flag javascript.options.wasm dans about:config, ou dans Chrome (51+) et Opera (38+) en allant dans chrome://flags and en activant le flag Experimental WebAssembly.)

+- Un fichier de code binaire wasm (`hello.wasm`) +- Un fichier JavaScript contenant du code "glue" à traduire entre les fonctions natives C, et Java/wasm (`hello.js`) +- Un fichier HTML pour charger, compiler et instancier votre code wasm, et l'afficher dans votre navigateur (`hello.html`) -

Si tout a fonctionné comme prévu, vous devriez voir la sortie "Hello World" dans la console Emscripten apparaissant dans la page web et dans la console Javascript de votre navigateur. Bravo, vous venez de compiler un programme C en WebAssembly puis d'executer ce programme dans votre navigateur!   

+### Exécuter votre exemple -

Utiliser un template HTML personnalisé

+Maintenant, tout ce qui vous reste à faire est de charger le fichier `hello.html` dans un navigateur qui supporte WebAssembly. Il est activé par défaut dans Firefox 52+, Chrome 57+ et dans la derniere version d'Opera (vous pouvez aussi executer du code wasm dans Firefox 47+ en activant le flag `javascript.options.wasm` dans *about:config*, ou dans Chrome (51+) et Opera (38+) en allant dans *chrome://flags* and en activant le flag *Experimental WebAssembly*.) -

Vous souhaiterez parfois utiliser un template HTML personnalisé. Voyons comment faire :

+Si tout a fonctionné comme prévu, vous devriez voir la sortie "Hello World" dans la console Emscripten apparaissant dans la page web et dans la console Javascript de votre navigateur. Bravo, vous venez de compiler un programme C en WebAssembly puis d'executer ce programme dans votre navigateur! -
    -
  1. -

    Tout d'abord, sauvegarder le code C suivant dans un fichier nommé hello2.c, au sein d'un nouveau dossier (vide) :

    +### Utiliser un template HTML personnalisé -
    #include <stdio.h>
    +Vous souhaiterez parfois utiliser un template HTML personnalisé. Voyons comment faire :
     
    -int main(int argc, char ** argv) {
    -    printf("Hello World\n");
    +1.  Tout d'abord, sauvegarder le code C suivant dans un fichier nommé `hello2.c`, au sein d'un nouveau dossier (vide) :
     
    -}
    -
  2. -
  3. -

    Cherchez le fichier shell_minimal.html dans le dépôt emsdk. Copiez-le dans un sous-dossier nommé html_template dans votre précédent nouveau dossier.

    -
  4. -
  5. -

    Naviguez maintenant jusqu'au nouveau dossier (toujours dans votre terminal disposant de l'environnement Emscripten), et exécutez la commande suivante :

    + ```cpp + #include -
    emcc -o hello2.html hello2.c -O3 -s WASM=1 --shell-file html_template/shell_minimal.html
    + int main(int argc, char ** argv) { + printf("Hello World\n"); -

    Les options que nous avons donné sont un peu différentes cette fois :

    + } + ``` -
      -
    • Nous avons spécifié -o hello2.html, ce qui signifie que le compilateur va générer du code JavaScript "glue" ainsi qu'un .html.
    • -
    • Nous avons également spécifié --shell-file html_template/shell_minimal.html — cela fournit le chemin vers le template HTML que vous souhaitez utiliser pour créer le HTML qui vous permettra d'exécuter l'exemple.
    • -
    -
  6. -
  7. -

    Maintenant, lançons l'exemple. La commande ci-dessus aura généré hello2.html, qui aura à peu près le même contenu que le template avec un peu de code "glue" pour charger le code wasm généré, l'exéuter, etc. Ouvrez-le dans votre navigateur et vous verrez quasiment la même chose qu'avec notre dernier exemple.

    -
  8. -
+2. Cherchez le fichier `shell_minimal.html` dans le dépôt emsdk. Copiez-le dans un sous-dossier nommé `html_template` dans votre précédent nouveau dossier. +3. Naviguez maintenant jusqu'au nouveau dossier (toujours dans votre terminal disposant de l'environnement Emscripten), et exécutez la commande suivante : -
-

Note : Vous pouvez spécifier, comme sortie, juste le fichier* JavaScript "glue" au lieu de la sortie HTML en specifiant un fichier .js au lieu d'un fichier HTML dans le flag-o . Par exemple: emcc -o hello2.js hello2.c -O3 -s WASM=1. Vous pouevz ensuite votre propre fichier HTML à partir de rien bien que ce soit une approche plus compliquée. Il est généralement plus simple d'utiliser le template HTML fournit.

+ ```bash + emcc -o hello2.html hello2.c -O3 -s WASM=1 --shell-file html_template/shell_minimal.html + ``` -

* Emscripten necessite une grande variété de code Javascript "glue" pour gérer les allocations memoire, les fuites memoires et bien d'autres problèmes.

-
+ Les options que nous avons donné sont un peu différentes cette fois : -

Appeler une fonction personnalisée définie en C

+ - Nous avons spécifié `-o hello2.html`, ce qui signifie que le compilateur va générer du code JavaScript "glue" ainsi qu'un `.html`. + - Nous avons également spécifié `--shell-file html_template/shell_minimal.html` — cela fournit le chemin vers le template HTML que vous souhaitez utiliser pour créer le HTML qui vous permettra d'exécuter l'exemple. -

Si vous avez une fonction définie dans votre code C et que vous souhaitez l'appeler de Javascript, vous pouvez le faire en utilisant la fonction Emscripten ccall() et la déclaration EMSCRIPTEN_KEEPALIVE (qui ajoute vos fonctions dans la liste des fonctions exportées) . Voir Why do functions in my C/C++ source code vanish when I compile to JavaScript, and/or I get No functions to process?. Regardons comment cela fonctionne.

+4. Maintenant, lançons l'exemple. La commande ci-dessus aura généré hello2.html, qui aura à peu près le même contenu que le template avec un peu de code "glue" pour charger le code wasm généré, l'exéuter, etc. Ouvrez-le dans votre navigateur et vous verrez quasiment la même chose qu'avec notre dernier exemple. -
    -
  1. -

    Pour démarrer, sauvegardez le code suivante dans un fichier nommé hello3.c dans un nouveau répertoire:

    +> **Note :** Vous pouvez spécifier, comme sortie, juste le fichier\* JavaScript "glue" au lieu de la sortie HTML en specifiant un fichier .js au lieu d'un fichier HTML dans le flag`-o` . Par exemple: `emcc -o hello2.js hello2.c -O3 -s WASM=1`. Vous pouevz ensuite votre propre fichier HTML à partir de rien bien que ce soit une approche plus compliquée. Il est généralement plus simple d'utiliser le template HTML fournit. +> +> \* Emscripten necessite une grande variété de code Javascript "glue" pour gérer les allocations memoire, les fuites memoires et bien d'autres problèmes. -
    #include <stdio.h>
    -#include <emscripten/emscripten.h>
    +### Appeler une fonction personnalisée définie en C
     
    -int main(int argc, char ** argv) {
    -    printf("Hello World\n");
    -}
    +Si vous avez une fonction définie dans votre code C et que vous souhaitez l'appeler de Javascript, vous pouvez le faire en utilisant la fonction Emscripten `ccall()` et la déclaration `EMSCRIPTEN_KEEPALIVE` (qui ajoute vos fonctions dans la liste des fonctions exportées) . Voir [Why do functions in my C/C++ source code vanish when I compile to JavaScript, and/or I get No functions to process?](https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html#why-do-functions-in-my-c-c-source-code-vanish-when-i-compile-to-javascript-and-or-i-get-no-functions-to-process). Regardons comment cela fonctionne.
     
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    +1.  Pour démarrer, sauvegardez le code suivante dans un fichier nommé `hello3.c` dans un nouveau répertoire:
     
    -void EMSCRIPTEN_KEEPALIVE myFunction(int argc, char ** argv) {
    -  printf("MyFunction Called\n");
    -}
    +    ```cpp
    +    #include 
    +    #include 
     
    -#ifdef __cplusplus
    -}
    -#endif
    + int main(int argc, char ** argv) { + printf("Hello World\n"); + } -

    By default, Emscripten-generated code always just calls the main() function, and other functions are eliminated as dead code. Putting EMSCRIPTEN_KEEPALIVE before a function name stops this from happening. You also need to import the emscripten.h library to use EMSCRIPTEN_KEEPALIVE.

    - -
    -

    Note : We are including the #ifdef blocks so that if you are trying to include this in C++ code, the example will still work. Due to C versus C++ name mangling rules, this would otherwise break, but here we are setting it so that it treats it as an external C function if you are using C++.

    -
    -
  2. -
  3. -

    Now add html_template/shell_minimal.html into this new directory too, just for convenience (you'd obviously put this in a central place in your real dev environment).

    -
  4. -
  5. -

    Now let's run the compilation step again. From inside your latest directory (and while inside your Emscripten compiler environment terminal window), compile your C code with the following command. (Note that we need to compile with NO_EXIT_RUNTIME, which is necessary as otherwise when main() exits the runtime would be shut down - necessary for proper C emulation, e.g., atexits are called - and it wouldn't be valid to call compiled code.)

    + #ifdef __cplusplus + extern "C" { + #endif -
    emcc -o hello3.html hello3.c -O3 -s WASM=1 --shell-file html_template/shell_minimal.html -s NO_EXIT_RUNTIME=1  -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall"]'
    -
  6. -
  7. -

    If you load the example in your browser again, you'll see the same thing as before!

    -
  8. -
  9. -

    Now we need to run our new myFunction() function from JavaScript. First of all, let's add a {{htmlelement("button")}} as shown below, just above the first opening <script type='text/javascript'> tag.

    + void EMSCRIPTEN_KEEPALIVE myFunction(int argc, char ** argv) { + printf("MyFunction Called\n"); + } -
    <button class="mybutton">Run myFunction</button>
    -
  10. -
  11. -

    Now add the following code inside the last {{htmlelement("script")}} element (just above the closing </script> tag):

    + #ifdef __cplusplus + } + #endif + ``` -
    document.querySelector('.mybutton').addEventListener('click', function(){
    -  alert('check console');
    -  var result = Module.ccall('myFunction', // name of C function
    -                             null, // return type
    -                             null, // argument types
    -                             null); // arguments
    -});
    -
  12. -
- -

This illustrates how ccall() is used to call the exported function.

- -

Voir aussi

- - + By default, Emscripten-generated code always just calls the `main()` function, and other functions are eliminated as dead code. Putting `EMSCRIPTEN_KEEPALIVE` before a function name stops this from happening. You also need to import the `emscripten.h` library to use `EMSCRIPTEN_KEEPALIVE`. + + > **Note :** We are including the `#ifdef` blocks so that if you are trying to include this in C++ code, the example will still work. Due to C versus C++ name mangling rules, this would otherwise break, but here we are setting it so that it treats it as an external C function if you are using C++. + +2. Now add `html_template/shell_minimal.html` into this new directory too, just for convenience (you'd obviously put this in a central place in your real dev environment). +3. Now let's run the compilation step again. From inside your latest directory (and while inside your Emscripten compiler environment terminal window), compile your C code with the following command. (Note that we need to compile with NO_EXIT_RUNTIME, which is necessary as otherwise when main() exits the runtime would be shut down - necessary for proper C emulation, e.g., atexits are called - and it wouldn't be valid to call compiled code.) + + ```bash + emcc -o hello3.html hello3.c -O3 -s WASM=1 --shell-file html_template/shell_minimal.html -s NO_EXIT_RUNTIME=1  -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall"]' + ``` + +4. If you load the example in your browser again, you'll see the same thing as before! +5. Now we need to run our new `myFunction()` function from JavaScript. First of all, let's add a {{htmlelement("button")}} as shown below, just above the first opening `` tag): + + ```js + document.querySelector('.mybutton').addEventListener('click', function(){ + alert('check console'); + var result = Module.ccall('myFunction', // name of C function + null, // return type + null, // argument types + null); // arguments + }); + ``` + +This illustrates how `ccall()` is used to call the exported function. + +## Voir aussi + +- [emscripten.org](http://emscripten.org/) — pour en apprendre plus sur Emscripten et sa large palette d'options +- [Appeler des fonctions C compilées depuis JavaScript grâce à ccall/cwrap](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#calling-compiled-c-functions-from-javascript-using-ccall-cwrap) +- [Pourquoi les fonctions dans mon code source C/C++ disparaissent quand je le compile dans JavaScript, et/ou je reçois une erreur "No functions to process" ?](https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html#why-do-functions-in-my-c-c-source-code-vanish-when-i-compile-to-javascript-and-or-i-get-no-functions-to-process) +- [WebAssembly sur Mozilla Research](https://research.mozilla.org/webassembly/) diff --git a/files/fr/webassembly/concepts/index.md b/files/fr/webassembly/concepts/index.md index 2d770e0eea..6dc2801da0 100644 --- a/files/fr/webassembly/concepts/index.md +++ b/files/fr/webassembly/concepts/index.md @@ -3,133 +3,115 @@ title: Concepts de WebAssembly slug: WebAssembly/Concepts translation_of: WebAssembly/Concepts --- -
{{WebAssemblySidebar}}
+{{WebAssemblySidebar}} -

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.

+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 ?

+## 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.

+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.

+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.

+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

+## 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 :

+WebAssembly est en cours de création en tant que standard ouvert au sein du [W3C WebAssembly Community Group](https://www.w3.org/community/webassembly/) avec les objectif 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](http://webassembly.org/docs/portability/#assumptions-for-efficient-execution). +- Ê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é. -
-

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

-
+> **Note :** WebAssembly aura également des usages en dehors du web et des environnements JavaScript (voir [Non-web embeddings](http://webassembly.org/docs/non-web/)). -

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

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

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

+La plateforme web peut s'imaginer comme composée 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](/fr/docs/Web/API) que la Web app peut appeler pour contrôler les fonctionnalités des navigateurs/appareils et réaliser des actions ([DOM](/fr/docs/Web/API/Document_Object_Model), [CSSOM](/fr/docs/Web/API/CSS_Object_Model), [WebGL](/fr/docs/Web/API/WebGL_API), [IndexedDB](/fr/docs/Web/API/IndexedDB_API), [Web Audio API](/fr/docs/Web/API/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).

+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](http://webassembly.org/docs/use-cases/) pour plus d'informations). -

De plus, le coût du téléchargement, du parsing 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.

+De plus, le coût du téléchargement, du parsing 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 :

+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 fourni 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é](http://webassembly.org/docs/high-level-goals/) 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 type de code - JavaScript ET WebAssembly.

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

Les deux différents type 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.

+Les deux différents type 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. -

Les concepts clefs du WebAssembly 

+### Les concepts clefs du WebAssembly  -

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.

+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](/fr/docs/Web/API/Blob) - peut donc être explicitement[ mis en cache dans IndexedDB](/fr/WebAssembly/Caching_modules) ou partagé entre le contexte fenêtre et les workers (via [`postMessage()`](/fr/docs/Web/API/MessagePort/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ées. Une instance est comme un module ES2015 qui a été chargée 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.

+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.

+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.

+Dans le futur, les modules WebAssembly seront chargeables comme des module ES2015 (en utilisant `` dans votre fichier HTML, puis ajoutez le code suivant: -

Streaming de notre module webassembly

+ ```js + var importObject = { + imports: { + imported_func: function(arg) { + console.log(arg); + } + } + }; + ``` -

Il est dorénavant possible dans Firefox 58 de compiler et instancier les modules Webassembly directement à partir des ressources initiales. Il est nécessaire dans ce cas d'utiliser les méthodes {{jsxref("WebAssembly.compileStreaming()")}} et {{jsxref("WebAssembly.instantiateStreaming()")}}. Ces méthodes en streaming sont plus facile d'utilisation que leurs contreparties synchrones, car elles traduisent directement le bytecode en instances de type Module/Instance, sans nécessiter la manipulation d'une réponse intermédiaire {{domxref("Response")}} en un {{domxref("ArrayBuffer")}}.

+### Streaming de notre module webassembly -

Cet exemple (voir notre démo sur GitHub instantiate-streaming.html, et également view it live) montre comment utiliser  instantiateStreaming() pour récupérer un module wasm, le compiler, l'instancier afin d'avoir accès aux fonctions exportées qu'il contient et d'y importer des fonctions Javascript, le tout en une seule et même étape.  

+Il est dorénavant possible dans Firefox 58 de compiler et instancier les modules Webassembly directement à partir des ressources initiales. Il est nécessaire dans ce cas d'utiliser les méthodes {{jsxref("WebAssembly.compileStreaming()")}} et {{jsxref("WebAssembly.instantiateStreaming()")}}. Ces méthodes en streaming sont plus facile d'utilisation que leurs contreparties synchrones, car elles traduisent directement le bytecode en instances de type `Module`/`Instance`, sans nécessiter la manipulation d'une réponse intermédiaire {{domxref("Response")}} en un {{domxref("ArrayBuffer")}}. -

Ajoutez le code suivant à votre script, en dessous du premier bloc:

+Cet exemple (voir notre démo sur GitHub [instantiate-streaming.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/instantiate-streaming.html), et également [view it live](https://mdn.github.io/webassembly-examples/js-api-examples/instantiate-streaming.html)) montre comment utiliser  `instantiateStreaming()` pour récupérer un module wasm, le compiler, l'instancier afin d'avoir accès aux fonctions exportées qu'il contient et d'y importer des fonctions Javascript, le tout en une seule et même étape. -
WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject)
-.then(obj => obj.instance.exports.exported_func());
+Ajoutez le code suivant à votre script, en dessous du premier bloc: -

Le résultat net de l'ensemble du code est que l'appel à exported_func, notre fonction exportée Webassembly, entraîne à son tour l'appel à imported_func notre fonction importée Javscript, qui logue la valeur 42 fournie à l'instance WebAssembly dans la console. Si vous sauvegardez l'exemple et chargez le code dans un navigateur qui supporte WebAssembly, vous pourrez le voir en action.

+ WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject) + .then(obj => obj.instance.exports.exported_func()); -

Note: Cet exemple interminable et tarabiscoté semble aboutir à un résultat de faible importance, il permet néanmoins d'illustrer les possibilités offertes par l'utilisation conjointe d'un code WebAssembly et d'un code Javscript dans une application web. Comme il est précisé ailleurs, l'objectif de WebAssembly n'est pas de remplacer Javascript; à vrai dire les deux sont conçus pour fonctionner de concert, chacun tirant parti des forces de l'autre.

+Le résultat net de l'ensemble du code est que l'appel à `exported_func`, notre fonction exportée Webassembly, entraîne à son tour l'appel à `imported_func` notre fonction importée Javscript, qui logue la valeur 42 fournie à l'instance WebAssembly dans la console. Si vous sauvegardez l'exemple et chargez le code dans un navigateur qui supporte WebAssembly, vous pourrez le voir en action. -

Chargement de notre module wasm sans streaming

+**Note**: Cet exemple interminable et tarabiscoté semble aboutir à un résultat de faible importance, il permet néanmoins d'illustrer les possibilités offertes par l'utilisation conjointe d'un code WebAssembly et d'un code Javscript dans une application web. Comme il est précisé ailleurs, l'objectif de WebAssembly n'est pas de remplacer Javascript; à vrai dire les deux sont conçus pour fonctionner de concert, chacun tirant parti des forces de l'autre. -

Si vous ne pouvez pas ou ne souhaitez pas utiliser les méthodes en streaming décrites ci-dessus, vous pouvez utiliser à la place les méthodes synchrones {{jsxref("WebAssembly.compile")}} / {{jsxref("WebAssembly.instantiate")}}.

+### Chargement de notre module wasm sans streaming -

Ces méthodes n'accèdent pas directement au bytecode, elles requièrent une étape supplémentaire afin de transformer la réponse en un {{domxref("ArrayBuffer")}} , et cela avant les étapes de compilation/instanciation du module wasm.

+Si vous ne pouvez pas ou ne souhaitez pas utiliser les méthodes en streaming décrites ci-dessus, vous pouvez utiliser à la place les méthodes synchrones {{jsxref("WebAssembly.compile")}} / {{jsxref("WebAssembly.instantiate")}}. -

Le code équivalent à l'exemple précédent prend la forme suivante:

+Ces méthodes n'accèdent pas directement au bytecode, elles requièrent une étape supplémentaire afin de transformer la réponse en un {{domxref("ArrayBuffer")}} , et cela avant les étapes de compilation/instanciation du module wasm. -
fetch('simple.wasm').then(response =>
-  response.arrayBuffer()
-).then(bytes =>
-  WebAssembly.instantiate(bytes, importObject)
-).then(results => {
-  results.instance.exports.exported_func();
-});
+Le code équivalent à l'exemple précédent prend la forme suivante: -

Visualiser wasm dans l'outil de développement 

+ fetch('simple.wasm').then(response => + response.arrayBuffer() + ).then(bytes => + WebAssembly.instantiate(bytes, importObject) + ).then(results => { + results.instance.exports.exported_func(); + }); -

In Firefox 54+, the Developer Tool Debugger Panel has functionality to expose the text representation of any wasm code included in a web page. To view it, you can go to the Debugger Panel and click on the “wasm://” entry.

+### Visualiser wasm dans l'outil de développement  -

+In Firefox 54+, the Developer Tool Debugger Panel has functionality to expose the text representation of any wasm code included in a web page. To view it, you can go to the Debugger Panel and click on the “wasm://” entry. -

Starting soon in Firefox, in addition to viewing WebAssembly as text, developers will be able to debug (place breakpoints, inspect the callstack, single-step, etc.) WebAssembly using the text format. See WebAssembly debugging with Firefox DevTools for a video preview.

+![](wasm-debug.png) -

Memory

+Starting soon in Firefox, in addition to viewing WebAssembly as text, developers will be able to debug (place breakpoints, inspect the callstack, single-step, etc.) WebAssembly using the text format. See [WebAssembly debugging with Firefox DevTools](https://www.youtube.com/watch?v=R1WtBkMeGds) for a video preview. -

Dans le modèle mémoire bas niveau de WebAssembly, la mémoire est représentée comme une suite continue de bytes non typés appelée Linear Memory. Cette mémoire linéaire est accessible en écriture et  en lecture par des instructions load et store à l'intérieur du module. Dans ce modèle de mémoire, les instructions load et store peuvent accéder à n'importe quel byte de la mémoire linéaire, ce qui est nécessaire à une réprésentation fidèle de concepts C/C++ comme les pointeurs.

+## Memory -

Cependant contrairement à une implémentation native d'un programe C/C++ dans laquelle l'espace de mémoire disponible recouvre celle de l'ensemble du processus, la mémoire accessible par une instance particulière de WebAssembly est un espace mémoire spécifique  — potentiellement très réduit — contenu dans une objet mémoire WebAssembly. Ceci permet à une application web unique d'utiliser des librairies indépendantes — Chacune d'entre elles pouvant utiliser en interne WebAssembly— avec des espaces mémoires séparés qui sont complètement isolés les uns des autres.

+Dans le modèle mémoire bas niveau de WebAssembly, la mémoire est représentée comme une suite continue de bytes non typés appelée [Linear Memory](http://webassembly.org/docs/semantics/#linear-memory). Cette mémoire linéaire est accessible en écriture et  en lecture par des instructions [load et store ](http://webassembly.org/docs/semantics/#linear-memory-accesses)à l'intérieur du module. Dans ce modèle de mémoire, les instructions load et store peuvent accéder à n'importe quel byte de la mémoire linéaire, ce qui est nécessaire à une réprésentation fidèle de concepts C/C++ comme les pointeurs. -

Dans Javascript, une instance Memory peut être pensée comme un ArrayBuffer redimensionnable. De la même manière que pour les ArrayBuffers, une application web peut créer de nombreux objets Memory indépendants. Vous pouvez en créer un en utilisant le constructeur {{jsxref("WebAssembly.Memory()")}}, qui prend comme arguments la taille initiale ainsi que la taille maximale de l'espace mémoire à créer.

+Cependant contrairement à une implémentation native d'un programe C/C++ dans laquelle l'espace de mémoire disponible recouvre celle de l'ensemble du processus, la mémoire accessible par une instance particulière de WebAssembly est un espace mémoire spécifique  — potentiellement très réduit — contenu dans une objet mémoire WebAssembly. Ceci permet à une application web unique d'utiliser des librairies indépendantes — Chacune d'entre elles pouvant utiliser en interne WebAssembly— avec des espaces mémoires séparés qui sont complètement isolés les uns des autres. -

Explorons ces concepts à travers un exemple rapide.

+Dans Javascript, une instance Memory peut être pensée comme un ArrayBuffer redimensionnable. De la même manière que pour les ArrayBuffers, une application web peut créer de nombreux objets Memory indépendants. Vous pouvez en créer un en utilisant le constructeur {{jsxref("WebAssembly.Memory()")}}, qui prend comme arguments la taille initiale ainsi que la taille maximale de l'espace mémoire à créer. -
    -
  1. -

    Créez une autre page HTML (copiez pour cela notre simple template) et appelez la memory.html. Ajoutez un élement <script></script> à la page.

    -
  2. -
  3. -

    Maintenant ajoutez la ligne suivante en haut de votre script, afin de créer une instance mémoire:

    +Explorons ces concepts à travers un exemple rapide. -
    var memory = new WebAssembly.Memory({initial:10, maximum:100});
    +1. Créez une autre page HTML (copiez pour cela notre [simple template](https://github.com/mdn/webassembly-examples/blob/master/template/template.html)) et appelez la `memory.html`. Ajoutez un élement `` à la page. +2. Maintenant ajoutez la ligne suivante en haut de votre script, afin de créer une instance mémoire: -

    L'unité pour initial et maximum correspond à une page WebAssembly — soit une taille fixe de 64 KB. Cela signifie que l'instance mémoire ci-dessus à une taille initiale de 64 KB, et une taille maximum de 6.4 MB.

    + var memory = new WebAssembly.Memory({initial:10, maximum:100}); -

    WebAssembly memory expose ses bytes par l'intermédiaire d'un tampon getter/setter qui retourne un ArrayBuffer. Par exemple, pour écrire  42 directement dans l'espace du premier mot de la mémoire linéaire, vous pouvez faire cela:

    + L'unité pour `initial` et `maximum` correspond à une page WebAssembly — soit une taille fixe de 64 KB. Cela signifie que l'instance mémoire ci-dessus à une taille initiale de 64 KB, et une taille maximum de 6.4 MB. -
    new Uint32Array(memory.buffer)[0] = 42;
    + WebAssembly memory expose ses bytes par l'intermédiaire d'un tampon getter/setter qui retourne un ArrayBuffer. Par exemple, pour écrire  42 directement dans l'espace du premier mot de la mémoire linéaire, vous pouvez faire cela: -

    Vous pouvez retourner cette même valeur en utilisant:

    + new Uint32Array(memory.buffer)[0] = 42; -
    new Uint32Array(memory.buffer)[0]
    -
  4. -
  5. -

    À vous d'essayer — Enregistrez ce que vous avez rédigé jusqu'à maintenant, chargez-le dans votre navigateur, puis essayez d'entrer les deux lignes ci-dessus dans votre Javscript console.

    -
  6. -
+ Vous pouvez retourner cette même valeur en utilisant: -

Redimensionner la mémoire

+ new Uint32Array(memory.buffer)[0] -

Une instance de mémoire peut être agrandie par appel à la méthode {{jsxref("Memory.prototype.grow()")}}, qui prend comme argument la taille de mémoire à ajouter (en unité de page WebAssembly).

+3. À vous d'essayer — Enregistrez ce que vous avez rédigé jusqu'à maintenant, chargez-le dans votre navigateur, puis essayez d'entrer les deux lignes ci-dessus dans votre Javscript console. -
memory.grow(1);
+### Redimensionner la mémoire -

Si une valeur maximum a été fournie à la création de l'instance mémoire, les tentatives d'augmenter l'espace mémoire au delà de cette valeur maximum aboutiront à une exception de type  {{jsxref("WebAssembly.RangeError")}}. Le moteur Javsacript utilise cette valeur limite supérieure pour réserver d'avance un espace mémoire suffisant, ce qui permet de rendre les redimensionnements mémoires plus efficaces.

+Une instance de mémoire peut être agrandie par appel à la méthode {{jsxref("Memory.prototype.grow()")}}, qui prend comme argument la taille de mémoire à ajouter (en unité de page WebAssembly). -

Note: En raison du caractère immuable de la longueur de byte d'un {{domxref("ArrayBuffer")}}, après une opération {{jsxref("Memory.prototype.grow()")}} réussie, le buffer getter retourne un nouvel objet ArrayBuffer (avec la nouvelle longeur de byte du buffer) et tous les objets ArrayBuffer précédents se retrouve en état "dissocié", ou déconnectés de l'espace mémoire dont ils étaient issus initialement.

+ memory.grow(1); -

Tout comme les fonctions, les espaces mémoires linéaires peuvent être définis à l'intérieur du module, ou bien importés. De manière similaire aux fonctions, un module peut également exporter sa mémoire. Cela signifie que Javascript peut accéder à la mémoire d'une instance WebAssembly soit en créant un nouveau WebAssembly.Memory afin de le passer en import à cette instance, soit en recevant un export Memory (via Instance.prototype.exports).

+Si une valeur maximum a été fournie à la création de l'instance mémoire, les tentatives d'augmenter l'espace mémoire au delà de cette valeur maximum aboutiront à une exception de type  {{jsxref("WebAssembly.RangeError")}}. Le moteur Javsacript utilise cette valeur limite supérieure pour réserver d'avance un espace mémoire suffisant, ce qui permet de rendre les redimensionnements mémoires plus efficaces. -

Exemple avancé pour l'utilisation mémoire

+Note: En raison du caractère immuable de la longueur de byte d'un {{domxref("ArrayBuffer")}}, après une opération {{jsxref("Memory.prototype.grow()")}} réussie, le buffer getter retourne un nouvel objet ArrayBuffer (avec la nouvelle longeur de byte du buffer) et tous les objets ArrayBuffer précédents se retrouve en état "dissocié", ou déconnectés de l'espace mémoire dont ils étaient issus initialement. -

Essayons de clarifier les affirmations ci-dessus à l'aide d'un exemple plus abouti —  à savoir un module WebAssembly qui importe une instance mémoire telle que définie plus tôt, et qui l'alimente d'un tableau d'entiers, pour en faire la somme totale. Vous pouvez trouver cela dans ce fichier memory.wasm.

+Tout comme les fonctions, les espaces mémoires linéaires peuvent être définis à l'intérieur du module, ou bien importés. De manière similaire aux fonctions, un module peut également exporter sa mémoire. Cela signifie que Javascript peut accéder à la mémoire d'une instance WebAssembly soit en créant un nouveau `WebAssembly.Memory` afin de le passer en import à cette instance, soit en recevant un export Memory (via [`Instance.prototype.exports`](/fr/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance/exports)). -
    -
  1. -

    Faites une copie locale de memory.wasm dans le même dossier que précédement.

    +### Exemple avancé pour l'utilisation mémoire -

    Note: Vous pouvez trouver la représentation textuelle du module sur memory.wat.

    -
  2. -
  3. -

    Retournez à votre fichier memory.html, et récupérez, compilez, et instancier votre module wasm comme précédement — Ajoutez à la fin de votre script les lignes suivantes:

    +Essayons de clarifier les affirmations ci-dessus à l'aide d'un exemple plus abouti —  à savoir un module WebAssembly qui importe une instance mémoire telle que définie plus tôt, et qui l'alimente d'un tableau d'entiers, pour en faire la somme totale. Vous pouvez trouver cela dans ce fichier [memory.wasm.](https://github.com/mdn/webassembly-examples/raw/master/js-api-examples/memory.wasm) -
    WebAssembly.instantiateStreaming(fetch('memory.wasm'), { js: { mem: memory } })
    -.then(results => {
    -  // add code here
    -});
    -
  4. -
  5. -

    Puisque ce module exporte sa mémoire, nous pouvons utiliser la fonction exportée accumulate() à partir du champ instance (de type Instance) de la valeur de retour results du module pour créer et alimenter l'instance mémoire du module (mem) avec un tableau. Ajoutez les lignes suivantes à votre code à l'emplacement indiqué dans le snippet précédent.

    +1. Faites une copie locale de `memory.wasm` dans le même dossier que précédement. -
    var i32 = new Uint32Array(memory.buffer);
    +    **Note**: Vous pouvez trouver la représentation textuelle du module sur [memory.wat](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/memory.wat).
     
    -for (var i = 0; i < 10; i++) {
    -  i32[i] = i;
    -}
    +2.  Retournez à votre fichier `memory.html`, et récupérez, compilez, et instancier votre module wasm comme précédement — Ajoutez à la fin de votre script les lignes suivantes:
     
    -var sum = results.instance.exports.accumulate(0, 10);
    -console.log(sum);
    -
  6. -
+ WebAssembly.instantiateStreaming(fetch('memory.wasm'), { js: { mem: memory } }) + .then(results => { + // add code here + }); -

Note: vous pouvez remarquer que nous avons créé la vue {{domxref("Uint32Array")}} sur le champ buffer de l'objet Memory (Memory.prototype.buffer), et pas sur l'objet Memory lui même.

+3. Puisque ce module exporte sa mémoire, nous pouvons utiliser la fonction exportée `accumulate()` à partir du champ instance (de type Instance) de la valeur de retour results du module pour créer et alimenter l'instance mémoire du module (`mem`) avec un tableau. Ajoutez les lignes suivantes à votre code à l'emplacement indiqué dans le snippet précédent. -

Les imports Memory fonctionnent de la même manière que les imports fonctions, à la différence prés que les objets Memory véhiculent des valeurs au lieu de fonctions Javscripts. Les imports Memory sont utiles pour deux raisons:

+ var i32 = new Uint32Array(memory.buffer); - + for (var i = 0; i < 10; i++) { + i32[i] = i; + } -

Note: Vous pouvez trouver une démo complete à memory.html (à voir également live) .

+ var sum = results.instance.exports.accumulate(0, 10); + console.log(sum); -

Tables

+Note: vous pouvez remarquer que nous avons créé la vue {{domxref("Uint32Array")}} sur le champ buffer de l'objet Memory ([`Memory.prototype.buffer`](/fr/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory/buffer)), et pas sur l'objet Memory lui même. -

Une Table WebAssembly est un tableau de références typées redimensionnable qui peut être accédé à la fois par du code Javscript et par du code WebAssembly. Memory fournit un tableau de bytes bruts redimensionnable, mais il n'est pas prudent d'y stocker des références, car une référence est une valeur considérée comme sûre par le moteur Javascript, valeur dont les bytes ne doivent être accessibles ni en lecture, ni en écriture par le contenu pour des raisons de sécurité, de portabilité, et de stabilité.

+Les imports Memory fonctionnent de la même manière que les imports fonctions, à la différence prés que les objets Memory véhiculent des valeurs au lieu de fonctions Javscripts. Les imports Memory sont utiles pour deux raisons: -

Les Tables possèdent un type, qui limite les types de références qui peuvent être contenues dans la table. Dans la version actuelle de WebAssembly, il n'existe qu'un seul type de références — functions — et de fait seul ce type de références est donc valide. Dans de prochaines versions, d'autres types de références seront ajoutés.  

+- Ils permettent de récupérer et créer le contenu mémoire initial avant ou en parrallèle de la compilation du module. +- Ils permettent qu'un objet mémoire unique soit importé par des instances de modules multiples, ce qui est une fonctionnalité clef dans l'objectif d'une implémentation d'une connexion dynamique dans WebAssembly. -

Les références de type fonction sont nécessaires afin de compiler des languages comme C/C++ qui permettent l'implémentation de pointeurs sur fonctions. Dans une implémentation native en C/C++, un pointeur sur fonction est représenté par une adresse brute associée au code de la fonction contenue dans l'espace d'adressage virtuel du processus. Pour les raisons de sécurités mentionnées plus haut, cette référence dans WebAssembly ne peut être stockée directement en mémoire linéaire. Les références de fonctions sont stockées dans une table et leurs index, qui sont des entiers, peuvent être placés en mémoire linéaire et véhiculés de manière sûre. 

+**Note**: Vous pouvez trouver une démo complete à [memory.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/memory.html) (à voir également [live](https://mdn.github.io/webassembly-examples/js-api-examples/memory.html)) . -

Lorsque l'appel à un pointeur sur fonction est nécessaire, le caller WebAssembly fournit l'index de la référence à appeler. La valeur de cet index est controlée par rapport au valeurs limites données à l'instantiation de la table (safety bounds checked), et cela avant que l'appel par référence à la fonction soit effectué. Autrement dit, les tables sont actuellement des primitives bas niveau utilisées pour compiler des fonctionnalités de language de programmation bas niveau, de manière sûre et portable.

+## Tables -

Les Tables peuvent être modifiées via Table.prototype.set(), which updates one of the values in a table, and Table.prototype.grow(), which increases the number of values that can be stored in a table.  This allows the indirectly-callable set of functions to change over time, which is necessary for dynamic linking techniques.  The mutations are immediately accessible via Table.prototype.get() in JavaScript, and to wasm modules.

+Une Table WebAssembly est un tableau de [références]() typées redimensionnable qui peut être accédé à la fois par du code Javscript et par du code WebAssembly. Memory fournit un tableau de bytes bruts redimensionnable, mais il n'est pas prudent d'y stocker des références, car une référence est une valeur considérée comme sûre par le moteur Javascript, valeur dont les bytes ne doivent être accessibles ni en lecture, ni en écriture par le contenu pour des raisons de sécurité, de portabilité, et de stabilité. -

Un exemple de table

+Les Tables possèdent un type, qui limite les types de références qui peuvent être contenues dans la table. Dans la version actuelle de WebAssembly, il n'existe qu'un seul type de références — functions — et de fait seul ce type de références est donc valide. Dans de prochaines versions, d'autres types de références seront ajoutés. -

Envisageons un exemple basique d'utilisation d'une table — un module WebAssembly qui crée et exporte une table contenant 2 éléments: l'élement 0 retourne 13 et l'élément 1 retourne 42. Vous retrouvez cela dans le fichier table.wasm.

+Les références de type fonction sont nécessaires afin de compiler des languages comme C/C++ qui permettent l'implémentation de pointeurs sur fonctions. Dans une implémentation native en C/C++, un pointeur sur fonction est représenté par une adresse brute associée au code de la fonction contenue dans l'espace d'adressage virtuel du processus. Pour les raisons de sécurités mentionnées plus haut, cette référence dans WebAssembly ne peut être stockée directement en mémoire linéaire. Les références de fonctions sont stockées dans une table et leurs index, qui sont des entiers, peuvent être placés en mémoire linéaire et véhiculés de manière sûre. -
    -
  1. -

    Faites une copie locale de table.wasm dans un nouveau dossier.

    +Lorsque l'appel à un pointeur sur fonction est nécessaire, le caller WebAssembly fournit l'index de la référence à appeler. La valeur de cet index est controlée par rapport au valeurs limites données à l'instantiation de la table (safety bounds checked), et cela avant que l'appel par référence à la fonction soit effectué. Autrement dit, les tables sont actuellement des primitives bas niveau utilisées pour compiler des fonctionnalités de language de programmation bas niveau, de manière sûre et portable. -

    Note: vous pouvez voir une réprésentation textuelle du module sur table.wat.

    -
  2. -
  3. -

    Créez une nouvelle copie du template HTML dans le même dossier et nommez le table.html.

    -
  4. -
  5. -

    Comme précédement, récupérez, compilez, et instanciez le module wasm — ajoutez les lignes suivantes à l'intérieur d'un élement {{htmlelement("script")}} au bas du body html:

    +Les Tables peuvent être modifiées via [`Table.prototype.set()`](/fr/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/set), which updates one of the values in a table, and [`Table.prototype.grow()`](/fr/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/grow), which increases the number of values that can be stored in a table.  This allows the indirectly-callable set of functions to change over time, which is necessary for [dynamic linking techniques](http://webassembly.org/docs/dynamic-linking/).  The mutations are immediately accessible via [`Table.prototype.get()`](/fr/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/get) in JavaScript, and to wasm modules. -
    WebAssembly.instantiateStreaming(fetch('table.wasm'))
    -.then(function(results) {
    -  // add code here
    -});
    -
  6. -
  7. -

    Maintenant accédez aux données contenues dans la table — ajoutez les lignes suivantes dans votre code à la place indiquée dans le snippet précédent:

    +### Un exemple de table -
    var tbl = results.instance.exports.tbl;
    -console.log(tbl.get(0)());  // 13
    -console.log(tbl.get(1)());  // 42
    -
  8. -
+Envisageons un exemple basique d'utilisation d'une table — un module WebAssembly qui crée et exporte une table contenant 2 éléments: l'élement 0 retourne 13 et l'élément 1 retourne 42. Vous retrouvez cela dans le fichier [table.wasm](https://github.com/mdn/webassembly-examples/raw/master/js-api-examples/table.wasm). -

Ce code accède à chaque fonction référencée contenue dans la table, et l' instancie afin d'imprimer sa valeur de retour dans la console — à noter que chaque référence de fonction est obtenue à l'aide de la méthode Table.prototype.get(), suivie d'une paire suplémentaire de parenthèses pour finaliser l'invocation de la fonction.

+1. Faites une copie locale de `table.wasm` dans un nouveau dossier. -

Note: Vous pouvez retoruver la démo complète sur table.html (voir également live).

+ **Note**: vous pouvez voir une réprésentation textuelle du module sur [table.wat](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/table.wat). -

Globals

+2. Créez une nouvelle copie du template [HTML](https://github.com/mdn/webassembly-examples/blob/master/template/template.html) dans le même dossier et nommez le `table.html`. +3. Comme précédement, récupérez, compilez, et instanciez le module wasm — ajoutez les lignes suivantes à l'intérieur d'un élement {{htmlelement("script")}} au bas du body html: -

WebAssembly fournit la capacité de créer des instances de variables globales, depuis Javascript et importable/exportable à partir d'une ou plusieurs instances de {{jsxref("WebAssembly.Module")}}. C'est très utile, car cela rend possible la mise en place d'un lien dynamique entre de multiple modules WebAssembly.  

+ WebAssembly.instantiateStreaming(fetch('table.wasm')) + .then(function(results) { + // add code here + }); -

Pour créer une instance globale WebAssembly à partir de Javascript, vous pouvez utiliser le constructeur {{jsxref("WebAssembly.Global()")}}, de la manière suivante:

+4. Maintenant accédez aux données contenues dans la table — ajoutez les lignes suivantes dans votre code à la place indiquée dans le snippet précédent: -
const global = new WebAssembly.Global({value:'i32', mutable:true}, 0);
+ var tbl = results.instance.exports.tbl; + console.log(tbl.get(0)()); // 13 + console.log(tbl.get(1)()); // 42 -

Vous pouvez remarquer que ce constructeur prend deux paramètres:

+Ce code accède à chaque fonction référencée contenue dans la table, et l' instancie afin d'imprimer sa valeur de retour dans la console — à noter que chaque référence de fonction est obtenue à l'aide de la méthode [`Table.prototype.get()`](/fr/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/get), suivie d'une paire suplémentaire de parenthèses pour finaliser l'invocation de la fonction. -
    -
  • Un objet qui comprend deux propriétés décrivant la variable globale: -
      -
    • value: correspond au type de donnée de la variable globale instanciée. Type de donnée qui peut être n'importe quel type compatible avec les modules WebAssembly modules — i32i64f32, ou f64.
    • -
    • mutable: un booléen definissant si la valeur est "mutable" ou non.
    • -
    -
  • -
  • Une valeur correspondant à la valeur prise par la variable. Cela peut être n'importe quelle valeur à condition qu'elle soit compatible avec le type de donnée spécifié.
  • -
+**Note**: Vous pouvez retoruver la démo complète sur [table.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/table.html) (voir également [live](https://mdn.github.io/webassembly-examples/js-api-examples/table.html)). -

Finalement comment tout cela fonctionne? Dans l'exemple suivant nous définissons une variable globale "mutable" de type i32, avec une valeur de 0.

+## Globals -

La valeur de la variable globale est ensuite changée en 42 en utilisant la propriété Global.value, puis en 43 en utilisant cette fois la fonction exportée de l'instance du module global.wasm  incGlobal() (cette fonction ajoute 1 à la valeur qui lui est donnée et retourne la nouvelle valeur).

+WebAssembly fournit la capacité de créer des instances de variables globales, depuis Javascript et importable/exportable à partir d'une ou plusieurs instances de {{jsxref("WebAssembly.Module")}}. C'est très utile, car cela rend possible la mise en place d'un lien dynamique entre de multiple modules WebAssembly. -
const output = document.getElementById('output');
+Pour créer une instance globale WebAssembly à partir de Javascript, vous pouvez utiliser le constructeur {{jsxref("WebAssembly.Global()")}}, de la manière suivante:
 
-function assertEq(msg, got, expected) {
-    output.innerHTML += `Testing ${msg}: `;
-    if (got !== expected)
-        output.innerHTML += `FAIL!<br>Got: ${got}<br>Expected: ${expected}<br>`;
-    else
-        output.innerHTML += `SUCCESS! Got: ${got}<br>`;
-}
+    const global = new WebAssembly.Global({value:'i32', mutable:true}, 0);
+
+Vous pouvez remarquer que ce constructeur prend deux paramètres:
+
+- Un objet qui comprend deux propriétés décrivant la variable globale:
+
+  - `value`: correspond au type de donnée de la variable globale instanciée. Type de donnée qui peut être n'importe quel type compatible avec les modules WebAssembly modules — `i32`, `i64`, `f32`, ou `f64`.
+  - `mutable`: un booléen definissant si la valeur est "mutable" ou non.
+
+- Une valeur correspondant à la valeur prise par la variable. Cela peut être n'importe quelle valeur à condition qu'elle soit compatible avec le type de donnée spécifié.
+
+Finalement comment tout cela fonctionne? Dans l'exemple suivant nous définissons une variable globale "mutable" de type `i32`, avec une valeur de 0.
+
+La valeur de la variable globale est ensuite changée en `42` en utilisant la propriété `Global.value`, puis en `43` en utilisant cette fois la fonction exportée de l'instance du module global.wasm  `incGlobal()` (cette fonction ajoute 1 à la valeur qui lui est donnée et retourne la nouvelle valeur).
+
+    const output = document.getElementById('output');
+
+    function assertEq(msg, got, expected) {
+        output.innerHTML += `Testing ${msg}: `;
+        if (got !== expected)
+            output.innerHTML += `FAIL!
Got: ${got}
Expected: ${expected}
`; + else + output.innerHTML += `SUCCESS! Got: ${got}
`; + } -assertEq("WebAssembly.Global exists", typeof WebAssembly.Global, "function"); + assertEq("WebAssembly.Global exists", typeof WebAssembly.Global, "function"); -const global = new WebAssembly.Global({value:'i32', mutable:true}, 0); + const global = new WebAssembly.Global({value:'i32', mutable:true}, 0); -WebAssembly.instantiateStreaming(fetch('global.wasm'), { js: { global } }) -.then(({instance}) => { - assertEq("getting initial value from wasm", instance.exports.getGlobal(), 0); - global.value = 42; - assertEq("getting JS-updated value from wasm", instance.exports.getGlobal(), 42); - instance.exports.incGlobal(); - assertEq("getting wasm-updated value from JS", global.value, 43); -});
+ WebAssembly.instantiateStreaming(fetch('global.wasm'), { js: { global } }) + .then(({instance}) => { + assertEq("getting initial value from wasm", instance.exports.getGlobal(), 0); + global.value = 42; + assertEq("getting JS-updated value from wasm", instance.exports.getGlobal(), 42); + instance.exports.incGlobal(); + assertEq("getting wasm-updated value from JS", global.value, 43); + }); -

Note: Vous pouvez voir cet exemple en live sur GitHub; voir également le code source.

+**Note**: Vous pouvez voir cet exemple en [live sur GitHub](https://mdn.github.io/webassembly-examples/js-api-examples/global.html); voir également le code [source](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/global.html). -

Multiplicité

+## Multiplicité -

Maintenant que nous avons présenté l'utilisation des principaux composants de WebAssembly, il est temps de dire quelques mots sur le concept de multiplicité. Ce dernier donne à WebAssembly un certains nombre d'avantages en terme d'efficience architecturale:

+Maintenant que nous avons présenté l'utilisation des principaux composants de WebAssembly, il est temps de dire quelques mots sur le concept de multiplicité. Ce dernier donne à WebAssembly un certains nombre d'avantages en terme d'efficience architecturale: -
    -
  • Un seul et unique module peut avoir N instances, de la même manière qu'une fonction littérale peut fournir N valeurs de closure.
  • -
  • Une seule et unique instance de module peut utiliser 0-1 instance de mémoire, qui elles-mêmes fournissent "l'espace d'adressage" de l'instance. Les versions futures de WebAssembly pourraient autoriser 0-N instances de mémoire par module instancié (voir Multiple Tables and Memories).
  • -
  • Une seule et unique instance de module peut utiliser 0-1 instance de tables — cela constitue "l'espace d'adressage de fonction" de l'instance, utilisé pour des pointeurs de fonction de type C. Des versions futures de WebAssembly pourraient autoriser 0–N instance de table par module instancié.
  • -
  • Une instance mémoire ou table peut être utilisée par 0-N instances de module — ces instances partagent toutes le même espace d'adressage, rendant possible l'implémentation d'un lien dynamique.
  • -
+- Un seul et unique module peut avoir N instances, de la même manière qu'une fonction littérale peut fournir N valeurs de closure. +- Une seule et unique instance de module peut utiliser 0-1 instance de mémoire, qui elles-mêmes fournissent "l'espace d'adressage" de l'instance. Les versions futures de WebAssembly pourraient autoriser 0-N instances de mémoire par module instancié (voir [Multiple Tables and Memories](http://webassembly.org/docs/future-features/#multiple-tables-and-memories)). +- Une seule et unique instance de module peut utiliser 0-1 instance de tables — cela constitue "l'espace d'adressage de fonction" de l'instance, utilisé pour des pointeurs de fonction de type C. Des versions futures de WebAssembly pourraient autoriser 0–N instance de table par module instancié. +- Une instance mémoire ou table peut être utilisée par 0-N instances de module — ces instances partagent toutes le même espace d'adressage, rendant possible l'implémentation d'un lien dynamique. -

Vous pouvez voir la mise en application du concept de multiplicité dans notre article Understanding text format — voir en particulier la section Mutating tables and dynamic linking.

+Vous pouvez voir la mise en application du concept de multiplicité dans notre article Understanding text format — voir en particulier la section [Mutating tables and dynamic linking](/fr/docs/WebAssembly/Understanding_the_text_format#Mutating_tables_and_dynamic_linking). -

Résumé

+## Résumé -

Cet article  a couvert les bases de l'utilisation de l'API WebAssembly Javascript nécessaires à l'inclusion d'un module WebAssembly dans un contexte javascript, afin d'utiliser les fonctions du module dans ce contexte,  et de se familiairiser avec la manipulation de la mémoire et des tables WebAssembly. Nous avons terminé en évoquant le concept de multiplicité.

+Cet article  a couvert les bases de l'utilisation de l'API WebAssembly Javascript nécessaires à l'inclusion d'un module WebAssembly dans un contexte javascript, afin d'utiliser les fonctions du module dans ce contexte,  et de se familiairiser avec la manipulation de la mémoire et des tables WebAssembly. Nous avons terminé en évoquant le concept de multiplicité. -

A voir également

+## A voir également - +- [webassembly.org](http://webassembly.org/) +- [WebAssembly concepts](/fr/docs/WebAssembly/Concepts) +- [WebAssembly on Mozilla Research](https://research.mozilla.org/webassembly/) -- cgit v1.2.3-54-g00ecf