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 -