WebAssembly - WASM

WebAssembly también se llama wasm, que es una mejora de Javascript. Está diseñado para ejecutarse dentro de navegadores como javascript y también con nodejs. Se obtiene una salida wasm cuando se compila cualquier lenguaje de alto nivel como C, C ++, Rust.

Considere el siguiente programa en C:

int factorial(int n) {
   if (n == 0) 
      return 1; 
   else 
      return n * factorial(n-1); 
}

Utilice WasmExplorer, que está disponible enhttps://mbebenita.github.io/WasmExplorer/ para obtener el código compilado como se muestra a continuación -

El formato de texto de WebAssembly para el programa factorial es el siguiente:

(module 
   (table 0 anyfunc) 
   (memory $0 1) 
   (export "memory" (memory $0)) (export "factorial" (func $factorial)) 
   (func $factorial (; 0 ;) (param $0 i32) (result i32)
      (local $1 i32) 
      (local $2 i32) 
      (block $label$0 
         (br_if $label$0 
            (i32.eqz 
               (get_local $0) 
            )
         )
         (set_local $2 
            (i32.const 1) 
         ) 
         (loop $label$1 
            (set_local $2 
               (i32.mul 
                  (get_local $0) (get_local $2) 
               ) 
            ) 
            (set_local $0 
               (tee_local $1        (i32.add 
                  (get_local $0) (i32.const -1) 
               ) 
               ) 
            ) 
            (br_if $label$1      (get_local $1) 
            ) 
         ) 
         (return 
            (get_local $2)
         ) 
      ) 
      (i32.const 1) 
   )
)

Con la herramienta Wat2Wasm, puede ver el código WASM, tal como se menciona a continuación:

Se supone que los desarrolladores no deben escribir código en wasm ni aprender a codificar en él, ya que se genera principalmente cuando compila lenguajes de alto nivel.

Modelo de máquina apilable

En WASM, todas las instrucciones se insertan en la pila. Los argumentos se abren y el resultado se devuelve a la pila.

Considere el siguiente formato de texto de WebAssembly que agrega 2 números:

(module
   (func $add (param $a i32) (param $b i32) (result i32) 
      get_local $a 
      get_local $b 
      i32.add
   )
   (export "add" (func $add))
)

El nombre de la función es $add, toma 2 parámetros $ ay $ b. El resultado es un tipo entero de 32 bits. Se accede a las variables locales mediante get_local y la operación de adición se realiza mediante i32.add.

La representación de la pila para sumar 2 números durante la ejecución será la siguiente:

En step 1 - La ejecución de la instrucción get_local $ a, los primeros parámetros, es decir, $ a se insertan en la pila.

En step 2 - Durante la ejecución de la instrucción get_local $ b, los segundos parámetros, es decir, $ b se introducen en la pila.

En step 3- La ejecución de i32.add sacará los elementos de la pila y enviará el resultado a la pila. El valor que queda al final dentro de la pila es el resultado de la función $ add.