WebAssembly - "Hola mundo"
En este capítulo vamos a escribir un programa simple en C y convertirlo a .wasm y ejecutar el mismo en el navegador para obtener el texto "Hello World".
Hará uso de la herramienta de exploración wasm que convertirá el programa C a .wasm y hará uso del .wasm dentro de nuestro archivo .html.
La herramienta de exploración Wasm que está disponible en https://mbebenita.github.io/WasmExplorer/ looks as follows −
El código C que vamos a utilizar es el siguiente:
#include <stdio.h>
char *c_hello() {
return "Hello World";
}
Actualice el primer bloque en wasm Explorer con el código C como se muestra a continuación:
Haga clic en el botón COMPILAR para compilar en WASM y WAT y Firefox x86 Web Assembly como se muestra a continuación:
Use DESCARGAR para obtener el archivo .wasm y guárdelo como firstprog.wasm.
Cree un archivo .html llamado firstprog.html como se muestra a continuación:
<!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>
Usemos ahora firstprog.wasm para leer el helloworld de la función C c_hello ().
Paso 1
Use fetch () api para leer el código firstprog.wasm.
Paso 2
El código .wasm debe convertirse en arraybuffer usando ArrayBuffer. El objeto ArrayBuffer le devolverá un búfer de datos binarios de longitud fija.
El código hasta ahora será el siguiente:
<script type="text/javascript">
fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer())
</script>
Paso 3
Los bytes de ArrayBuffer deben compilarse en un módulo usando WebAssembly.compile(buffer) función.
El código se verá a continuación:
<script type="text/javascript">
fetch("firstprog.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
</script>
Etapa 4
Para obtener el módulo, debemos llamar al constructor webassembly.instance como se muestra a continuación:
<script type="text/javascript">
fetch("firstprog.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
</script>
Paso 5
Consuelemos ahora la instancia para ver los detalles en el 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>
Los detalles de console.log se muestran a continuación:
Para obtener la cadena "Hola mundo" de la función c_hello (), necesitamos agregar algo de código en javascript.
Primero, obtenga los detalles del búfer de memoria como se muestra a continuación:
let buffer = instance.exports.memory.buffer;;
El valor del búfer tiene que convertirse en una matriz con tipo para que podamos leer los valores. El búfer tiene la cadena Hello World.
Para convertir a tipeado, llame al constructor Uint8Array como se muestra a continuación:
let buffer = new Uint8Array(instance.exports.memory.buffer);
Ahora, podemos leer el valor del búfer en un bucle for.
Obtengamos ahora el punto de inicio para leer el búfer, llamando a la función que escribimos como se muestra a continuación:
let test = instance.exports.c_hello();
Ahora, la variable de prueba tiene el punto de inicio para leer nuestra cadena. WebAssembly no tiene nada para los valores de cadena, todo se almacena como números enteros.
Entonces, cuando leemos el valor del búfer, será un valor entero y necesitamos convertirlo en una cadena usando fromCharCode () en javascript.
El código es el siguiente:
let mytext = "";
for (let i=test; buffer[i]; i++){
mytext += String.fromCharCode(buffer[i]);
}
Ahora, cuando consueles mytext, debería ver la cadena "Hello World".
Ejemplo
El código completo es el siguiente:
<!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>
Hemos agregado un div y el contenido se agrega al div, por lo que la cadena se muestra en el navegador.
Salida
La salida se menciona a continuación: