WebAssembly - "Hello World"

Dans ce chapitre, nous allons écrire un programme simple en C et le convertir en .wasm et l'exécuter dans le navigateur pour obtenir le texte "Hello World".

Utilisera l'outil d'exploration wasm qui convertira le programme C en .wasm et utilisera le .wasm dans notre fichier .html.

L'outil d'exploration Wasm disponible sur https://mbebenita.github.io/WasmExplorer/ looks as follows −

Le code C que nous allons utiliser est le suivant -

#include <stdio.h>
char *c_hello() {
   return "Hello World"; 
}

Mettez à jour le premier bloc dans wasm explorer avec le code C comme indiqué ci-dessous -

Cliquez sur le bouton COMPILER pour compiler vers WASM et WAT et Firefox x86 Web Assembly comme indiqué ci-dessous -

Utilisez le TÉLÉCHARGEMENT pour obtenir le fichier .wasm et l'enregistrer sous firstprog.wasm.

Créez un fichier .html appelé firstprog.html comme indiqué ci-dessous -

<!doctype html>
<html>
   <head>
      <meta charset="utf-8"> 
      <title>WebAssembly Hello World</title> 
   </head> 
   <body>
      <div id="textcontent"></div>     
      <script type="text/javascript"> 
         //Your code from webassembly here
      </script> 
   </body>
</html>

Utilisons maintenant firstprog.wasm pour lire le monde hellow à partir de la fonction C c_hello ().

Étape 1

Utilisez l'api fetch () pour lire le code firstprog.wasm.

Étape 2

Le code .wasm doit être converti en arraybuffer en utilisant ArrayBuffer. L'objet ArrayBuffer vous renverra un tampon de données binaires de longueur fixe.

Le code jusqu'à présent sera le suivant -

<script type="text/javascript"> 
   fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer()) 
</script>

Étape 3

Les octets de ArrayBuffer doivent être compilés dans un module en utilisant WebAssembly.compile(buffer) fonction.

Le code ressemblera à ci-dessous -

<script type="text/javascript">
   fetch("firstprog.wasm")
   .then(bytes => bytes.arrayBuffer())
   .then(mod => WebAssembly.compile(mod))
</script>

Étape 4

Pour obtenir le module, nous devons appeler le constructeur webassembly.instance comme indiqué ci-dessous -

<script type="text/javascript">     
   fetch("firstprog.wasm") 
   .then(bytes => bytes.arrayBuffer())
   .then(mod => WebAssembly.compile(mod))
   .then(module => {return new WebAssembly.Instance(module) }) 
</script>

Étape 5

Consolons maintenant l'instance pour voir les détails dans le navigateur.

<script type="text/javascript"> 
   fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer()) 
   .then(mod => WebAssembly.compile(mod)) .then(module => {
      return new WebAssembly.Instance(module) 
   }) 
   .then(instance => {
      console.log(instance);
   }); 
</script>

Les détails de console.log sont affichés ci-dessous -

Pour obtenir la chaîne «Hello World» de la fonction c_hello (), nous devons ajouter du code en javascript.

Tout d'abord, obtenez les détails de la mémoire tampon comme indiqué ci-dessous -

let buffer = instance.exports.memory.buffer;;

La valeur du tampon doit être convertie en un tableau typé afin que nous puissions en lire les valeurs. Le tampon contient la chaîne Hello World.

Pour convertir en typé, appelez le constructeur Uint8Array comme indiqué ci-dessous -

let buffer = new Uint8Array(instance.exports.memory.buffer);

Maintenant, nous pouvons lire la valeur du tampon dans une boucle for.

Obtenons maintenant le point de départ pour lire le tampon, en appelant la fonction que nous avons écrite comme indiqué ci-dessous -

let test = instance.exports.c_hello();

Maintenant, la variable de test a le point de départ pour lire notre chaîne. WebAssembly n'a rien pour les valeurs de chaîne, tout est stocké sous forme d'entiers.

Ainsi, lorsque nous lirons la valeur du tampon, ce sera une valeur entière et nous devons la convertir en une chaîne en utilisant fromCharCode () en javascript.

Le code est le suivant -

let mytext = ""; 
for (let i=test; buffer[i]; i++){ 
   mytext += String.fromCharCode(buffer[i]);
}

Maintenant, lorsque vous console mytext, vous devriez voir la chaîne «Hello World».

Exemple

Le code complet est le suivant -

<!doctype html> 
<html> 
   <head> 
      <meta charset="utf-8"> 
      <title>WebAssembly Add Function</title>
      <style>
         div { 
            font-size : 30px; text-align : center; color:orange; 
         } 
      </style>
   </head>
   <body>
      <div id="textcontent"></div>
      <script> 
         fetch("firstprog.wasm")
         .then(bytes => bytes.arrayBuffer())
         .then(mod => WebAssembly.compile(mod))
         .then(module => {return new WebAssembly.Instance(module)})
         .then(instance => {   
            console.log(instance); 
            let buffer = new Uint8Array(instance.exports.memory.buffer); 
            let test = instance.exports.c_hello(); 
            let mytext = ""; 
            for (let i=test; buffer[i]; i++) {
               mytext += String.fromCharCode(buffer[i]);
            }
            console.log(mytext); document.getElementById("textcontent").innerHTML = mytext; 
         });
      </script>
   </body>
</html>

Nous avons ajouté un div et le contenu est ajouté au div, donc la chaîne est affichée sur le navigateur.

Production

La sortie est mentionnée ci-dessous -