Creando un módulo de WebAssembly con JavaScript

20 enero, 2018 11:45 por

Esta es una traducción del artículo original publicado en el blog de Mozilla Hacks.

WebAssembly es una nueva forma de ejecutar código en la web. Con ello, puedes escribir módulos en lenguajes como C o C++ y ejecutarlos desde el navegador.

Actualmente los módulos no pueden ejecutarse por si mismos. Esto va a cambiar apenas llegue a los navegadores el soporte a módulos ES. Una vez que ocurra, los módulos de WebAssembly serán cargados tal como cualquier módulo de ES usando <script type="module">.

Pero por ahora, necesitas usar JavaScript para iniciar el módulo de WebAssembly. Esto crea una instancia del módulo. Entonces tu código JavaScript puede llamar a funciones de la instancia del módulo WebAssembly.

Por ejemplo, miremos como React iniciaría un módulo de WebAssembly. (Puedes aprender más sobre ello en este artículo en inglés sobre cómo React puede usar WebAssembly.)

Cuando el usuario carga la página, esta iniciaría de la misma forma.

El navegador descargará todos los archivos JS. Adicionalmente, un archivo .wasm se descargará. Esto contendrá el código WebAssembly que será binario.

Necesitaremos cargar el código en estos archivos para ejecutarlo. Primero se usa el archivo .js que cargará la parte de JavaScript de React. Luego este código instanciará un módulo de WebAssembly… el reconciliador.

Para hacerlo, se llama a WebAssembly.instantiate.


Ahora veamos más de cerca. Lo primero que le pasamos a WebAssembly.instantiate será el código binario contenido en un archivo .wasm. Ese es el código del  módulo. Así que extraemos el binario a un buffer y lo pasamos dentro de él:

El motor empezará a compilar el código del módulo al código que la máquina entiende.

Pero no queremos que esto suceda en el hilo principal. En artículos anteriores se ha hecho la comparación de que el hilo principal es como un desarrollador full stack, porque maneja JavaScript, el DOM y la apariencia. No queremos que bloquee el hilo principal de ejecución cuando se compile el módulo, por eso es que WebAssembly.instantiate retorna una promesa (promise).

Esto permite al hilo principal trabajar en otras cosas y una vez que el compilador finalice la compilación del módulo, será notificado a través de la promesa. La promesa dará la instancia.

Pero el módulo compilado no es la única cosa que se necesita para crear la instancia. Yo veo el módulo como un libro de instrucciones.

La instancia es como una persona que está intentando hacer algo con el libro de instrucciones, pero para ello necesita materiales, cosas con las cuales trabajar.

Aquí es donde el segundo parámetro de WebAssembly.instantiate toma sentido. Es el objeto a importar:


Imagina los objetos importados como una caja de ingredientes o piezas. La instancia usa estos materiales para construir cosas, siguiendo el conjunto de instrucciones. Al igual que un manual requiere un conjunto de materiales, cada módulo espera un conjunto de importaciones

Así que cuando instancias un módulo, le pasas un objeto importado que tiene todas las dependencias. Cada objeto puede tener uno de los siguiente 4 tipos de importación:

  • Valores
  • Funciones de cierre (function closures)
  • Memoria
  • Tablas

Valores

Puede tener valores, los cuales básicamente son variables globales. Los únicos tipos que WASM soporta por los momentos son enteros y flotantes, así que los valores tienen que ser de uno de esos dos tipos. Esto cambiará a medida que se agreguen más tipos a las especificaciones de WebAssembly.

Funciones de cierre

También puede tener funciones de cierre. Esto significa que puedes pasar funciones de JavaScript las cuales pueden ser llamadas desde WebAssembly.

Esto es particularmente muy útil porque en la versión actual de WebAssembly no puedes llamar directamente a métodos del DOM. El acceso directo al DOM está planificado pero por ahora no es parte de la especificación.

Lo que puedes hacer mientras tanto es pasar una función de JavaScript que interactúe con el DOM de la forma que desees. Entonces WebAssembly solo llamará la función de JS.

Memoria

Otra tipo de importación es el objeto de memoria. Este objeto permite a WebAssembly emular la gestión de memoria. El concepto del objeto de memoria suele confundir a las personas, por eso te recomendamos leer este artículo para comprenderlo.

Tablas

El tipo final de importación también está relacionado con la seguridad. Se llama tabla. Es posible para ti usar algo llamado funciones de puntero, lo cual se explicará mas adelante.

Estas son las diferentes formas de importación que puedes utilizar en tu instancia.

Para retornar la instancia, la promesa retornada desde WebAssembly.instantiate se resuelve. Ésta contiene dos cosas: la instancia y el módulo compilado por separado.

Lo bueno es que teniendo compilado el módulo puedes generar rápidamente otras instancias del mismo módulo. Solo debes pasar el módulo en el parámetro source. El módulo como tal no tiene ningún estado. Esto significa que la instancias pueden compartir el código del módulo compilado.

Tu instancia ahora esta equipada y lista para ejecutarse. Tiene un manual de instrucciones que es el código compilado, y eso es todo sobre las importaciones. Puedes ahora llamar a sus respectivos métodos.

The following two tabs change content below.
Colaborador de Mozilla Venezuela e Hispano en las áreas de desarrollo y medios sociales, entre otros. También soy desarrollador Web, Skateboarder, Profesor universitario, jugador de Playstation y PC, usuario Linux, Blogger, Geek, entre otros.

Compartir artículo:

Start the discussion at foro.mozilla-hispano.org

cc-by-sa