WebAssembly - WASM

WebAssembly também é chamado de wasm, o que é um aprimoramento do Javascript. Ele é projetado para ser executado em navegadores como javascript e também com nodejs. Acontece que você obtém a saída wasm, quando qualquer linguagem de alto nível como C, C ++, Rust é compilada.

Considere o seguinte programa C -

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

Faça uso do WasmExplorer, que está disponível emhttps://mbebenita.github.io/WasmExplorer/ para obter o código compilado conforme mostrado abaixo -

O formato de texto WebAssembly para o programa fatorial é como indicado abaixo -

(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) 
   )
)

Usando a ferramenta Wat2Wasm, você pode visualizar o código WASM, assim como mencionado abaixo -

Os desenvolvedores não devem escrever código no wasm ou aprender a codificar nele, já que ele é gerado principalmente quando você compila linguagens de alto nível.

Stack Machine Model

No WASM, todas as instruções são colocadas na pilha. Os argumentos são removidos e o resultado retornado à pilha.

Considere o seguinte formato de WebAssembly Text que adiciona 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))
)

O nome da função é $add, leva 2 parâmetros $ a e $ b. O resultado é um tipo inteiro de 32 bits. As variáveis ​​locais são acessadas usando get_local e a operação add é executada usando i32.add.

A representação da pilha para adicionar 2 números durante a execução será a seguinte -

Dentro step 1 - A execução da instrução get_local $ a, os primeiros parâmetros, isto é, $ a são colocados na pilha.

Dentro step 2 - Durante a execução da instrução get_local $ b, os segundos parâmetros, isto é, $ b são colocados na pilha.

Dentro step 3- A execução de i32.add irá retirar os elementos da pilha e colocar o resultado de volta na pilha. O valor que fica no final dentro da pilha é o resultado da função $ add.