WebAssembly - "Hello World"

In questo capitolo scriveremo un semplice programma in C e lo convertiremo in .wasm ed eseguiremo lo stesso nel browser per ottenere il testo "Hello World".

Utilizzerà lo strumento di esplorazione di wasm che convertirà il programma C in .wasm e utilizzerà il .wasm all'interno del nostro file .html.

Lo strumento di esplorazione di Wasm, disponibile all'indirizzo https://mbebenita.github.io/WasmExplorer/ looks as follows −

Il codice C che useremo è il seguente:

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

Aggiorna il primo blocco in wasm explorer con il codice C come mostrato di seguito -

Fare clic sul pulsante COMPILA per compilare in WASM e WAT e Firefox x86 Web Assembly come mostrato di seguito -

Utilizzare il DOWNLOAD per ottenere il file .wasm e salvarlo come firstprog.wasm.

Crea un file .html chiamato firstprog.html come mostrato di seguito -

<!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>

Usiamo ora firstprog.wasm per leggere helloworld dalla funzione C c_hello ().

Passo 1

Usa fetch () api per leggere il codice firstprog.wasm.

Passo 2

Il codice .wasm deve essere convertito in arraybuffer utilizzando ArrayBuffer. L'oggetto ArrayBuffer restituirà un buffer di dati binari di lunghezza fissa.

Il codice finora sarà il seguente:

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

Passaggio 3

I byte da ArrayBuffer devono essere compilati in un modulo utilizzando WebAssembly.compile(buffer) funzione.

Il codice apparirà come di seguito:

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

Passaggio 4

Per ottenere il modulo dobbiamo chiamare il costruttore webassembly.instance come mostrato di seguito -

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

Passaggio 5

Consolliamo ora l'istanza per vedere i dettagli nel browser.

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

I dettagli di console.log sono mostrati di seguito:

Per ottenere la stringa "Hello World" dalla funzione c_hello (), dobbiamo aggiungere del codice in javascript.

Per prima cosa, ottieni i dettagli del buffer di memoria come mostrato di seguito:

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

Il valore del buffer deve essere convertito in un array digitato in modo che possiamo leggere i valori da esso. Il buffer contiene la stringa Hello World.

Per convertire in digitato chiama il costruttore Uint8Array come mostrato di seguito -

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

Ora possiamo leggere il valore dal buffer in un ciclo for.

Otteniamo ora il punto di inizio per leggere il buffer, chiamando la funzione che abbiamo scritto come mostrato di seguito -

let test = instance.exports.c_hello();

Ora, la variabile di test ha il punto di inizio per leggere la nostra stringa. WebAssembly non ha nulla per i valori stringa, tutto viene memorizzato come numeri interi.

Quindi, quando leggiamo il valore dal buffer, sarà un valore intero e dobbiamo convertirlo in una stringa usando fromCharCode () in javascript.

Il codice è il seguente:

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

Ora, quando consoli mytext dovresti vedere la stringa "Hello World".

Esempio

Il codice completo è il seguente:

<!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>

Abbiamo aggiunto un div e il contenuto viene aggiunto al div, quindi la stringa viene visualizzata nel browser.

Produzione

L'output è menzionato di seguito: