Компиляторы
WebAssembly: компиляция для веба
Figma рендерит вектор в 60 fps прямо в браузере. AutoCAD открывает 3D-чертежи без установки. Google Earth крутит планету в Chrome. Секрет - WebAssembly: код на Rust и C++ компилируется в портативный байткод, который браузер превращает в нативный ARM или x86 за миллисекунды. Wasm быстрее JS в 10-50 раз для вычислительных задач - это меняет, что вообще возможно в вебе.
- **Figma** перенесла рендеринг с JavaScript на Wasm (C++ через Emscripten) - Canvas-операции ускорились в 3x, а потребление памяти снизилось на 30%
- **Cloudflare Workers** запускает Wasm-модули на 300+ edge-узлах с cold start ~5ms - в 10x быстрее Docker-контейнеров
- **Pyodide** компилирует CPython в Wasm: NumPy, Pandas, scikit-learn работают прямо в браузере без сервера - это основа JupyterLite
Wasm Binary Format
WebAssembly - это бинарный формат инструкций для стековой виртуальной машины. Файл `.wasm` состоит из секций: type, import, function, table, memory, export, code. Каждая секция имеет числовой ID и LEB128-закодированную длину. Браузерный движок (V8, SpiderMonkey, JavaScriptCore) читает `.wasm` и компилирует его в нативный машинный код быстрее, чем парсит JavaScript.
Clang/LLVM компилирует C/C++ в Wasm за один проход: `clang --target=wasm32 -O2 -o add.wasm add.c`. Rust использует `wasm32-unknown-unknown` target. V8 запускает Wasm-модуль за ~5-10 мс (включая компиляцию) против ~100-500 мс для парсинга эквивалентного JS.
Что записано в первых 4 байтах любого валидного .wasm файла?
Linear Memory
Wasm-модуль видит один непрерывный массив байт - linear memory. Это не куча в обычном смысле: адресация всегда от 0, размер задаётся в страницах по 64 KB, максимум 4 GB (для wasm32). JS-код может читать и писать в эту память через `WebAssembly.Memory` и `TypedArray`. Именно так C-строки и структуры данных пробрасываются между JS и Wasm.
Изоляция памяти - ключевое свойство безопасности Wasm. Модуль не может прочитать arbitrary память браузера; он видит только свой буфер. Wasm64 (работа ведётся в 2024-2025) расширяет адресное пространство до 64-бит и снимает лимит 4 GB.
Размер одной страницы WebAssembly linear memory?
WASI: WebAssembly System Interface
WASI (WebAssembly System Interface) - стандарт системных вызовов для Wasm вне браузера. Вместо прямых syscall (как в Linux) модуль импортирует функции из пространства имён `wasi_snapshot_preview1`: `fd_write`, `path_open`, `clock_time_get` и ещё ~50 функций. Среда исполнения (Wasmtime, WasmEdge, Wasmer) предоставляет эти функции и управляет возможностями через capability-based security.
Главная идея WASI - portability без JVM. Один .wasm файл работает на Linux x86_64, macOS ARM, Windows, embedded RISC-V. Docker-образ с Wasm весит ~5 MB против ~50-500 MB для контейнера на основе Alpine Linux. Поэтому Solomon Hykes (создатель Docker) написал: 'If Wasm+WASI existed in 2008, we wouldn't have needed to create Docker'.
Что такое capability-based security в контексте WASI?
Component Model
Wasm Component Model (2023-2024) - следующий уровень над core Wasm. Компонент описывает свой интерфейс через WIT (WebAssembly Interface Types): типизированные функции, записи, перечисления, ресурсы. Это позволяет компонентам на разных языках (Rust, Go, Python, C++) взаимодействовать без ручного кодирования данных через linear memory.
Wasmtime 14+ (Bytecode Alliance, 2023) полностью поддерживает Component Model. Компоненты можно компоновать через `wac` tool: взять Rust-компонент для криптографии и Python-компонент для бизнес-логики и связать их без общего runtime. Это fundamentally меняет микросервисную архитектуру - компонент холоднее, чем функция в AWS Lambda.
WebAssembly заменяет JavaScript в браузере
Wasm дополняет JS: берёт на себя CPU-интенсивные вычисления, JS управляет DOM и координирует работу
Wasm не имеет прямого доступа к DOM. Любое взаимодействие с браузерным API идёт через JS-биндинги (wasm-bindgen в Rust, Emscripten в C++). Figma, AutoCAD Web, Google Earth - везде JS и Wasm работают вместе
Что описывает WIT (WebAssembly Interface Types) файл?
Итоги
- Wasm - бинарный формат для стековой VM; браузер компилирует .wasm в нативный код быстрее, чем парсит JS
- Linear memory - изолированный буфер байт; JS и Wasm обмениваются данными через TypedArray-вью на этот буфер
- WASI переносит Wasm за пределы браузера с capability-based security; Component Model добавляет типизированные интерфейсы между компонентами
Связанные темы
Wasm опирается на компиляторную инфраструктуру и связан с управлением памятью:
- LLVM — Clang использует LLVM backend wasm32 для компиляции C/C++/Rust в .wasm
- Cranelift — Wasmtime использует Cranelift как JIT/AOT backend для компиляции Wasm в нативный код
- GC и управление памятью — Wasm не имеет встроенного GC для managed-языков; Wasm GC proposal (2023) добавляет поддержку
Вопросы для размышления
- Если Wasm быстрее JS для вычислений, почему не всё переписать на Wasm? Какие задачи останутся на JS?
- WASI позиционируется как замена Docker для некоторых use cases. Где эта замена работает, а где нет?
- Component Model решает проблему интеграции разноязычных компонентов. Какие архитектурные паттерны это открывает?