---
# System prepended metadata

title: Intro a WebAssembly (wasm).
tags: [DAW, daw, ' wasm']

---

---
title: Intro a WebAssembly (wasm).
tags: DAW, wasm
---

<div style="width: 30%; margin-left: auto;">
    
![](https://hackmd.io/_uploads/HJiR4eGJT.png)    
    
</div>


<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Llicència de Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />Aquesta obra està subjecta a una llicència de <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Reconeixement-CompartirIgual 4.0 Internacional de Creative Commons</a>

# Intro a Web Assembly.
![imagen](https://hackmd.io/_uploads/HkX3zO2nT.png)
Segons la pròpia [pàgina oficial](https://webassembly.org), WebAssembly es pot definir com:
> WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.

## Corolaris que s'extreuen directament de la definició:
1. WebAssembly **no** es javascript, és un format binari totalment diferent.
2. WebAssembly corre sobre una màquina virtual basada en pila.
3. WebAssembly està dissenyat per a poderse compilar a partir de diferents llenguatges i facilitar el desplegament a través de la web.

## Principis de disseny de WebAssembly:
1. Efficient i ràpid: L'objectiu de la màquina de pila Wasm, és apropar-se a la velocitat nativa.
2. Segur: L'execució de WebAssembly es produeix dins d'un 'sand box' i en el cas de la web, reforça les polítiques d'origen comú: 'same origin' i polítiques de seguretat del navegador.
3. Oberta i depurable: WebAssembly està dissenyada per a poder representar-se en forma de text agradablement formatat per motius de depuració, proves, optimització, aprenentatge o inclús per a poder escriure programes a ma en format wasm.
4. Part de la plataforma web: Els mòduls de WebAssembly són capaços de fer crides al context de JavaScrip i accedir a la funcionalitat del navegador a través de la mateixa API a la que accedeix JavaScript.

## [Conceptes clau](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts#webassembly_key_concepts):

1. Module: Represents a WebAssembly binary that has been compiled by the browser into executable machine code. A Module is stateless and thus, like a Blob, can be explicitly shared between windows and workers (via postMessage()). A Module declares imports and exports just like an ES module.
2. Memory: A resizable ArrayBuffer that contains the linear array of bytes read and written by WebAssembly's low-level memory access instructions.
3. Table: A resizable typed array of references (e.g. to functions) that could not otherwise be stored as raw bytes in Memory (for safety and portability reasons).
4. Instance: A Module paired with all the state it uses at runtime including a Memory, Table, and set of imported values. An Instance is like an ES module that has been loaded into a particular global with a particular set of imports.

## Diferents maneres d'utilitzar WebAssembly:
1. Portar una aplicació C/C++ amb Emscripten.
2. Escriure o generar WebAssembly directament a nivel d'ensamblador.
3. Escriure una aplicació en Rust i compilar a WebAssembly.
4. Utilitzar AssemblyScript que s'assembla a TypeScript es compila a un binari de WebAssembly.

## Generant mòduls wasm a partir de codi C/C++.
### Instal·lació d'Emscripten.
Les passes necessàries per instal·lar el SDK d'Emscripten les podeu trobar a la [pàgina oficial](https://emscripten.org/docs/getting_started/downloads.html), però us aconsello que comenceu fent ús de la [imatge Docker](https://hub.docker.com/r/emscripten/emsdk#!) preparada a tal efecte. Amb la següent comanda, obtindreu accés a la terminal del contenidor amb la carpeta on heu executat l'ordre montada com a un volum Docker a la ruta '/src' del contenidor.

```bash=
docker run  -it -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk bash
```

```bash=
xavi@portatil:~/Documentos/wasm$ docker run  -it -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk bash
groups: cannot find name for group ID 131
emscripten@4fa4fc854c38:/src$ ls    
favicon.ico  hello.html  hello.js  hello.wasm  hello_wasm.html  helloworld.cpp  helloworld.js  helloworld.wasm
emscripten@4fa4fc854c38:/src$
```
### Generació i compilació del codi C++ d'exemple.
Partirem d'un fitxer helloworld.cpp típic:
```cpp=
#include <iostream>

int main() {
    std::cout << "Hello World!\n";
    return 0;
}
```
I el compilarem amb l'eina emcc que tenim preparada al contenidor:
```bash=
emscripten@4fa4fc854c38:/src$ emcc helloworld.cpp -o helloworld.js
cache:INFO: generating system asset: symbol_lists/27772d71a5153dd93f16df2df7cc5d46369da5ac.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/27772d71a5153dd93f16df2df7cc5d46369da5ac.json" for subsequent builds)
cache:INFO:  - ok
```
Ara ja tenim el nostre mòdul .wasm i el _codi adhesiu_ ('glue code'):
```bash=
emscripten@4fa4fc854c38:/src$ ls -l
total 360
-rw-rw-r-- 1 emscripten emscripten  16655 Feb 28 07:16 favicon.ico
-rw-rw-r-- 1 emscripten        131    246 Feb 28 08:19 hello_wasm.html
-rw-rw-r-- 1 emscripten        131     85 Feb 28 08:15 helloworld.cpp
-rw-r--r-- 1 emscripten        131 175276 Feb 28 09:40 helloworld.js
-rwxr-xr-x 1 emscripten        131 161689 Feb 28 09:40 helloworld.wasm
```
El fitxer hello_wasm.html ha estat creat a ma. També és possible que el propi compilador emcc ens generi un fitxer html, però no és tant instructiu com aquest codi minimalista escrit a ma:
```htmlembedded=
<!DOCTYPE html>
<html lang="ca">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello wasm!</title>
</head>
<body>
    <script src="helloworld.js"></script>
</body>

```
El resultat el podem veure a la següent imatge:
![imagen](https://hackmd.io/_uploads/SyhigKnhT.png)

### Integració del codi C al navegador.
#### ccall i cwrap
Utilitzarem els seguents fitxers:
1. Un programa en c: wrapping.c
2. Un document html: wrapping.html

```clike=
// wrapping.c
#include <stdio.h>
#include "emscripten.h"

EMSCRIPTEN_KEEPALIVE int suma(int a, int b) {
    return a + b;
}


EMSCRIPTEN_KEEPALIVE int main() {
    printf("Hello World!, %d\n", suma(4, 6));
    return 0;
}

```


```htmlembedded=
<!DOCTYPE html>
<html lang="ca">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>wrapping.html</title>
    <script src="wrapping.js"></script>
    <script>
        function run_wasm() {
            var suma = Module.cwrap("suma", "number", ["number","number"]);

            var result = Module.ccall(
                "main",
                "number",
                null,
                null
            );
            console.log(result);

            var a = document.querySelector("#a").value;
            var b = document.querySelector("#b").value;

            var result = Module.ccall(
                "suma",
                "number",
                ["number","number"],
                [a, b]
            );
            console.log(result);

            console.log(suma(a,b));
        }
    </script>
</head>
<body>
    <input type="number" id="a">
    <input type="number" id="b">    
    <button onclick="run_wasm()">Run Wasm</button>
</body>
</html>
```

I compilarem el codi amb el següent modificador:

```bash=
emcc wrapping.c -o wrapping.js -sEXPORTED_RUNTIME_METHODS=ccall,cwrap
```

![imagen](https://hackmd.io/_uploads/r11yu932T.png)
