На этой странице

WebAssembly — это высокопроизводительный язык, похожий на ассемблер, в который можно компилировать код из различных языков, включая C/C++, Rust и AssemblyScript. На данный момент он поддерживается в Chrome, Firefox, Safari, Edge и Node.js!

Спецификация WebAssembly описывает два формата файлов: бинарный формат — WebAssembly-модуль с расширением .wasm — и соответствующее текстовое представление, называемое WebAssembly Text format, с расширением .wat.

  • Module (модуль) — скомпилированный бинарник WebAssembly, то есть файл .wasm.
  • Memory (память) — ArrayBuffer с изменяемым размером.
  • Table (таблица) — типизированный массив ссылок с изменяемым размером, не хранящийся в Memory.
  • Instance (экземпляр) — инстанцирование модуля вместе с его Memory, Table и переменными.

Чтобы использовать WebAssembly, нужны бинарный файл .wasm и набор API для взаимодействия с WebAssembly. Node.js предоставляет необходимые API через глобальный объект WebAssembly.

console.log(WebAssembly);
/*
Object [WebAssembly] {
  compile: [Function: compile],
  validate: [Function: validate],
  instantiate: [Function: instantiate]
}
*/

Есть несколько способов сгенерировать бинарные файлы WebAssembly, в том числе:

  • Написать WebAssembly (.wat) вручную и преобразовать в бинарный формат инструментами вроде wabt
  • Использовать emscripten с приложением на C/C++
  • Использовать wasm-pack с приложением на Rust
  • Использовать AssemblyScript, если вам ближе опыт, похожий на TypeScript

Некоторые из этих инструментов генерируют не только бинарный файл, но и «связующий» (glue) JavaScript-код и соответствующие HTML-файлы для запуска в браузере.

Как только у вас есть WebAssembly-модуль, вы можете инстанцировать его с помощью объекта WebAssembly в Node.js.

// Предположим, существует файл add.wasm, содержащий единственную функцию, которая складывает 2 переданных аргумента
const fs = require('node:fs');

// Используем функцию readFileSync, чтобы прочитать содержимое файла "add.wasm"
const wasmBuffer = fs.readFileSync('/path/to/add.wasm');

// Используем метод WebAssembly.instantiate, чтобы инстанцировать WebAssembly-модуль
WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
  // Экспортируемая функция находится в объекте instance.exports
  const { add } = wasmModule.instance.exports;
  const sum = add(5, 6);
  console.log(sum); // Выведет: 11
});

WebAssembly-модули не могут самостоятельно напрямую обращаться к функциональности ОС. Для доступа к ней можно использовать сторонний инструмент Wasmtime. Wasmtime использует API WASI для доступа к функциональности ОС.