Trabalhando com WebAssembly e JavaScript no Node.js: técnicas avançadas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução ao trabalho avançado com WebAssembly e JavaScript no Node.js

\n\n

O WebAssembly (Wasm) já deixou de ser uma tecnologia exótica para navegadores. No ecossistema Node.js, ele abre possibilidades únicas para executar computações de alto desempenho, escritas em C/C++, Rust ou Go, com sobrecarga mínima. Em nível avançado, trabalhar com Wasm no Node.js exige um profundo entendimento do gerenciamento de memória, chamadas assíncronas e otimização da transferência de dados entre ambientes de execução. Neste artigo, analisaremos exemplos práticos de integração do WebAssembly com JavaScript, usando Node.js.

\n\n

1. Compilação e carregamento de módulos Wasm no Node.js

\n\n

Preparação do arquivo Wasm

\n

Para começar, precisaremos de um módulo Wasm compilado. Suponha que temos uma função simples em C que soma dois números:

\n\n
// sum.c\nint add(int a, int b) {\n    return a + b;\n}
\n\n

Compilamos usando Emscripten ou wasm-pack:

\n
emcc sum.c -O3 -o sum.wasm --no-entry -s EXPORTED_FUNCTIONS="['_add']"
\n\n

Carregando o módulo no Node.js

\n

No Node.js, podemos carregar um módulo Wasm de duas maneiras: através do síncrono readFileSync ou do assíncrono WebAssembly.instantiate. Vamos considerar a variante assíncrona avançada com importação:

\n\n
const fs = require('fs');\nconst path = require('path');\n\nasync function loadWasmModule(filePath, imports = {}) {\n    const wasmBuffer = fs.readFileSync(path.resolve(filePath));\n    const result = await WebAssembly.instantiate(wasmBuffer, imports);\n    return result.instance;\n}\n\n(async () => {\n    const instance = await loadWasmModule('./sum.wasm');\n    const { add } = instance.exports;\n    console.log('Resultado:', add(5, 7)); // 12\n})();
\n\n

Aqui, imports é um objeto que pode conter funções JavaScript chamadas a partir do Wasm (por exemplo, para registro ou trabalho com memória).

\n\n

2. Gerenciamento de memória: trabalhando com a memória linear do Wasm

\n\n

Uma das principais complexidades do trabalho avançado com Wasm é o gerenciamento da memória linear. Os módulos Wasm têm sua própria memória isolada (ArrayBuffer), à qual o JavaScript pode acessar diretamente através de instance.exports.memory. Vamos considerar um exemplo onde passamos um array de números do JS para o Wasm, o processamos e retornamos o resultado.

\n\n

Exemplo: soma de array em C

\n
// sum_array.c\nint sum_array(int* arr, int len) {\n    int sum = 0;\n    for(int i = 0; i < len; i++) {\n        sum += arr[i];\n    }\n    return sum;\n}
\n\n

Compilamos com exportação de memória:

\n
emcc sum_array.c -O3 -o sum_array.wasm --no-entry \\\n  -s EXPORTED_FUNCTIONS="['_sum_array']" \\\n  -s EXPORTED_RUNTIME_METHODS="['cwrap', 'getValue']"
\n\n

Código JavaScript para transferência de dados

\n
async function sumArrayWithWasm(numbers) {\n    const instance = await loadWasmModule('./sum_array.wasm');\n    const memory = instance.exports.memory;\n    const sumArray = instance.exports.sum_array;\n\n    // Alocar memória para o array (4 bytes por int)\n    const bytesPerElement = 4;\n    const offset = instance.exports.malloc ? \n                   instance.exports.malloc(numbers.length * bytesPerElement) : \n                   0; // Se não houver malloc, usar endereço fixo\n\n    // Criar Uint32Array para escrever os dados\n    const buffer = new Uint32Array(memory.buffer, offset, numbers.length);\n    buffer.set(numbers);\n\n    // Chamar a função Wasm\n    const result = sumArray(offset, numbers.length);\n\n    // Liberar memória (se houver free)\n    if (instance.exports.free) {\n        instance.exports.free(offset);\n    }\n\n    return result;\n}\n\n(async () => {\n    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    const sum = await sumArrayWithWasm(arr);\n    console.log('Soma do array:', sum); // 55\                

Blogs

Book Recommendations