WebAssembly (сокр. wasm) – это эффективный низкоуровневый язык программирования. Главное его предназначение заключается в повышении производительности JavaScript.

WebAssembly построен на подмножестве JavaScript – asm.js. Он также хранится в текстовом формате. Может возникнуть вопрос: как код может быть эффективнее если он также проходит интерпретатор, а затем компилируется? Для этого используется пролог директива, благодаря которой компилятор сразу переводит код на язык ассемблера, пропуская этап интерпретации.

Код wasm представлен как помеченное, ориентированное дерево, в котором внутренние вершины сопоставлены с операторами языка, а листья с соответствующими операндами. И это дерево хранится в двоичном формате. Благодаря этому мы получаем небольшой размер модуля, быстрое декодирование, и меньшее использование памяти. Если удастся приблизиться к скорости выполнения машинного кода, то произойдет настоящая революция в развитии веб-приложений.

Процесс компиляции webassembly

После появления этого стандарта появилась возможность компилировать языки верхнего уровня в код wasm или asm.js. На данный момент доступно для языков C и C++.

Для примера скомпилируем код С:

#include<stdio.h>
int main() {
  printf("hello, world!\n");
  return 0;
}

Для этого воспользуемся компилятором Emscripten, способный преобразовывать бит код LLVM (Low Level Virtual Machine) в представление на языке JavaScript и Binaryen который имеет инструментарий для компиляции wasm. Чтобы скомпилировать, выполним следующую команду:

emcc file.cpp -o file.js -s ‘BINARYEN=”путь для двоичного файла”’

Примерно так выглядит уже транслированный код C в wasm:

(module
  (memory 16777216 16777216)
  (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
  (type $FUNCSIG$ii (func (param i32) (result i32)))
  (type $FUNCSIG$vi (func (param i32)))
  (import $abort "env" "abort" (param i32))
  (export "add" $add)
  (func $add (param $x i32) (param $y i32) (result i32)
    (local $i2 i32)
    (local $i3 i32)

    (i32.add
      (get_local $x)
      (get_local $y)
    )
  )
)

При переводе в бинарный формат производится несколько этапов сжатия:

  • Сырой формат – стандартный бинарный формат;
  • Специальное сжатие бинарного формата;
  • Общая компрессия

Еще одним плюсом wasm является непосредственный доступ к машинному коду. Так как зачастую в машинном языке новый функционал представляется в виде SDK, к которому нет доступа с клиентской части веб-приложений. И для того, чтобы иметь возможность использовать этот SDK нужно время, когда браузеры будут поддерживать новые возможности и предоставят соответствующий API. Но, даже при этих условиях JavaScript будет работать слишком медленно.

Использование API машинного кода средствами WebAssembly становится гораздо проще и появляется возможность обращаться к нему на более низком уровне. Это дает возможности, которые были недостижимы ранее. API предоставляет всего лишь доступ к сырым данным, которые обрабатывал SDK, теперь можно оперировать при помощи wasm. Это открывает широкий простор для операций с данными, благодаря подгружаемым библиотекам из Интернет, не заботясь о продолжительной стандартизации SDK. В будущем у WebAssembly ожидаются такие нововведения как:

  • Полная поддержка многопоточности;
  • Интеграция с DOM;
  • Оптимизация хвостовой рекурсии;
  • Мультипроцессорная поддержка;
  • Интеграция со сборщиком мусора;

Этот функционал достаточно сложно воспроизвести на JavaScript. Wasm разрабатывается для того, чтобы служить отличной платформой для поддержки языков с похожими характеристиками. Wasm позволит воплотить в жизнь создание новых продуктов работающих в браузере, в таких направлениях как:

  • Продвинутые редакторы музыки/изображений/видео;
  • Системы автоматизированного проектирования;
  • Высокопроизводительные игры;
  • Средства разработки;

WebAssembly эта та технология к которой бы рано или поздно дошла эволюция. Технология, которая безусловно изменит web, открыв возможности для построения более технологичных web-приложений.

Опубликовано в МЦИИ Omega Science от 23.07.2016