WebAssembly - Módulos

Vimos como obter um arquivo .wasm do código c / c ++. Neste capítulo, vamos converter o wasm em um módulo WebAssembly e executar o mesmo no navegador.

Vamos usar o código fatorial C ++ conforme mostrado abaixo -

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

Abra o Wasm Explorer que está disponível em https://mbebenita.github.io/WasmExplorer/ as shown below −

A primeira coluna possui a função fatorial C ++, a 2ª coluna possui o formato de texto WebAssembly e a última coluna possui o código Assembly x86.

O formato de texto 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)
   )
)

A função C ++ fact foi exportado como “_Z4facti”No formato WebAssembly Text.

Clique no botão de download para baixar o código wasm e salve o arquivo como factorial.wasm.

Agora, para converter o código .wasm para o módulo, temos que fazer o seguinte -

Passo 1

Converta o .wasm em arraybuffer usando ArrayBuffer. O objeto ArrayBuffer retornará um buffer de dados binários de comprimento fixo.

Passo 2

Os bytes do ArrayBuffer devem ser compilados em um módulo usando WebAssembly.compile(buffer) função.

o WebAssembly.compile() função compila e retorna um WebAssembly.Module a partir dos bytes fornecidos.

Aqui está o código Javascript discutido nas etapas 1 e 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>

Explicação do código

  • A busca da API do navegador Javascript é usada para obter o conteúdo de factorial.wasm.

  • O conteúdo é convertido em bytes usando arrayBuffer ().

  • O módulo é criado a partir de bytes chamando WebAssembly.compile (mod).

  • A instância de um módulo é criada usando novos

    WebAssembly.Instance(module)

  • A função fatorial export _Z4facti é atribuída à variável fatorial usando WebAssembly.Module.exports ().

Exemplo

Aqui está o module.html junto com o 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>

Resultado

Execute module.html no navegador para ver a saída -