WebAssembly - Módulos
Hemos visto cómo obtener un archivo .wasm desde el código c / c ++. En este capítulo, convertiremos el wasm en un módulo WebAssembly y lo ejecutaremos en el navegador.
Usemos el código factorial de C ++ como se muestra a continuación:
int fact(int n) {
if ((n==0)||(n==1))
return 1;
else
return n*fact(n-1);
}
Abra Wasm Explorer que está disponible en https://mbebenita.github.io/WasmExplorer/ as shown below −
La primera columna tiene la función factorial C ++, la segunda columna tiene el formato de texto de WebAssembly y la última columna tiene el código de ensamblaje x86.
El formato de texto de WebAssembly -
(module
(table 0 anyfunc)
(memory $0 1)
(export "memory" (memory $0))
(export "_Z4facti" (func $_Z4facti))
(func $_Z4facti (; 0 ;) (param $0 i32) (result i32)
(local $1 i32)
(set_local $1
(i32.const 1)
)
(block $label$0
(br_if $label$0
(i32.eq
(i32.or
(get_local $0)
(i32.const 1)
)
(i32.const 1)
)
)
(set_local $1
(i32.const 1)
)
(loop $label$1
(set_local $1
(i32.mul
(get_local $0)
(get_local $1)
)
)
(br_if $label$1
(i32.ne
(i32.or
(tee_local $0
(i32.add
(get_local $0)
(i32.const -1)
)
)
(i32.const 1)
)
(i32.const 1)
)
)
)
)
(get_local $1)
)
)
La función C ++ fact se ha exportado como "_Z4facti”En formato de texto de WebAssembly.
Haga clic en el botón de descarga para descargar el código wasm y guardar el archivo como factorial.wasm.
Ahora para convertir el código .wasm al módulo, tenemos que hacer lo siguiente:
Paso 1
Convierta el .wasm en arraybuffer usando ArrayBuffer. El objeto ArrayBuffer le devolverá un búfer de datos binarios de longitud fija.
Paso 2
Los bytes de ArrayBuffer deben compilarse en un módulo usando WebAssembly.compile(buffer) función.
los WebAssembly.compile() La función compila y devuelve un WebAssembly.Module a partir de los bytes dados.
Aquí está el código Javascript que se analiza en los pasos 1 y 2.
<script type="text/javascript">
let factorial;
fetch("factorial.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
.then(instance => {
factorial = instance.exports._Z4facti;
console.log('Test the output in Brower Console by using factorial(n)');
});
</script>
Explicación del código
La recuperación de la API del navegador Javascript se utiliza para obtener el contenido de factorial.wasm.
El contenido se convierte a bytes usando arrayBuffer ().
El módulo se crea a partir de bytes llamando a WebAssembly.compile (mod).
La instancia de un módulo se crea usando new
WebAssembly.Instance(module)
La función factorial export _Z4facti se asigna a la variable factorial utilizando WebAssembly.Module.exports ().
Ejemplo
Aquí está el module.html junto con el código javascript -
module.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Module</title>
</head>
<body>
<script>
let factorial;
fetch("factorial.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
.then(instance => {
factorial = instance.exports._Z4facti;
console.log('Test the output in Browser Console by using factorial(n)');
});
</script>
</body>
</html>
Salida
Ejecute module.html en el navegador para ver el resultado: