WebAssembly - "Hello World"

Neste capítulo, vamos escrever um programa simples em C, convertê-lo em .wasm e executá-lo no navegador para obter o texto "Hello World".

Fará uso da ferramenta wasm explorer que irá converter o programa C para .wasm e fará uso do .wasm dentro do nosso arquivo .html.

A ferramenta Wasm explorer que está disponível em https://mbebenita.github.io/WasmExplorer/ looks as follows −

O código C que vamos usar é o seguinte -

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

Atualize o primeiro bloco no wasm explorer com o código C conforme mostrado abaixo -

Clique no botão COMPILAR para compilar para WASM e WAT e Firefox x86 Web Assembly conforme mostrado abaixo -

Use o DOWNLOAD para obter o arquivo .wasm e salve-o como firstprog.wasm.

Crie um arquivo .html chamado firstprog.html como mostrado abaixo -

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

Vamos agora usar firstprog.wasm para ler o helloworld da função C c_hello ().

Passo 1

Use a api fetch () para ler o código firstprog.wasm.

Passo 2

O código .wasm deve ser convertido em arraybuffer usando ArrayBuffer. O objeto ArrayBuffer retornará a você um buffer de dados binários de comprimento fixo.

O código até agora será o seguinte -

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

etapa 3

Os bytes do ArrayBuffer devem ser compilados em um módulo usando WebAssembly.compile(buffer) função.

O código será semelhante a abaixo -

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

Passo 4

Para obter o módulo, temos que chamar o construtor webassembly.instance conforme mostrado abaixo -

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

Etapa 5

Vamos agora consolar a instância para ver os detalhes no navegador.

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

Os detalhes do console.log são mostrados abaixo -

Para obter a string “Hello World” da função c_hello (), precisamos adicionar algum código em javascript.

Primeiro, obtenha os detalhes do buffer de memória conforme mostrado abaixo -

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

O valor do buffer deve ser convertido em um array digitado para que possamos ler os valores dele. O buffer contém a string Hello World.

Para converter para digitado, chame o construtor Uint8Array conforme mostrado abaixo -

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

Agora, podemos ler o valor do buffer em um loop for.

Vamos agora obter o ponto de partida para ler o buffer, chamando a função que escrevemos conforme mostrado abaixo -

let test = instance.exports.c_hello();

Agora, a variável de teste tem o ponto de partida para ler nossa string. WebAssembly não tem nada para valores de string, tudo é armazenado como números inteiros.

Então, quando lemos o valor do buffer, ele será um valor inteiro e precisamos convertê-lo em uma string usando fromCharCode () em javascript.

O código é o seguinte -

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

Agora, ao consolar meu texto, você verá a string “Hello World”.

Exemplo

O código completo é o seguinte -

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

Adicionamos um div e o conteúdo é adicionado ao div, de modo que a string é exibida no navegador.

Resultado

O resultado é mencionado abaixo -