vak: (Default)
[personal profile] vak
На виртуальные машины я пожаловался, теперь глянем на дело конструктивно. Предположим, мы хотим сделать софт, которому суждена долгая жизнь. Скажем, декодер звука MP3, или отрисовщик документов в формате DJVU, или парсер санскрита. Лет через сто какой-нибудь марсианин захочет прослушать или прочитать древний файл из архива землян. Понятно, что бинарники за сто лет устареют. А виртуальные машины выживут (не все), и могут спасти ситуацию. Тут я задумался. Какие из современных вариантов имеют лучшие шансы? И сдаётся мне, что самая распространённая нынче и живучая виртуальная машина это JavaScript. В каждом компьютере установлен как минимум один браузер, и в нём эта машина. Можно было бы на неё положиться.

Возникает вопрос: каким образом можно разрабатывать софт для запуска на VM внутри браузеров? Ответ состоит в магическом слове WebAssembly. Это стандарт, Draft Release 2.0 на настоящее время, определяющий бинарный формат и софтверные интерфейсы. Существующие компиляторы Си/Cи++ (clang) и Rust умеют генерить бинарный код для Wasm.

Отлично! С чего же начать? В сети есть куча примеров, как скомпилировать Си-код, вычисляющий функцию Фибоначчи, и вызвать её из браузера. Но этот не то, чего хочется. Вот есть у меня симулятор древней ЭВМ БЭСМ-6. Как скомпилировать его для Wasm, и вызывать как обычно, из командной строки? Ведь виртуальная машина браузера изолирует ваш код от окружения и мало чего ему позволяет. Оказывается, умные люди об этом уже позаботились. Встречайте проект WASI: интерфейс из WebAssembly к сервисам локальной операционной системы.

Компилируем

Меньше слов, больше дела. Устанавливаем компилятор Си/Си++ для WASI отсюда: wasi-sdk-16

Компилируем простейший код:
$ cat hello.c
#include <stdio.h>
int main()
{
printf("Hello, WebAssembly!\n");
}

$ /opt/wasi-sdk-16.0/bin/clang hello.c -o hello.wasm

$ file hello.wasm
hello.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

$ /opt/wasi-sdk-16.0/bin/size hello.wasm
text data bss dec hex filename
14817 2651 0 17468 443c hello.wasm

Выполняем

Теперь выполним этот бинарник. Необязательно звать весь браузер, есть решение попроще. Устанавливаем утилиту wasmtime, по сути независимую реализацию виртуальной машины WebAssembly. На маке она ставится так:
brew install wasmtime
Установка на Линуксе:
curl https://wasmtime.dev/install.sh -sSf | bash
Теперь запускаем наш пример:
$ wasmtime hello.wasm 
Hello, WebAssembly!
В следующий раз попробую запустить бенчмарк Dhrystone.

Date: 2022-08-08 00:23 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Классно! Бум знать. Вообще линки на твои посты хоть все записывай в wowiki.

Date: 2022-08-08 03:31 (UTC)
x86128: (Default)
From: [personal profile] x86128
Когда стандартизуют еще иинтерфейс Garbage Collector будет вообще сказка - можно будет эффективно писать WASM на языках с GC.

Date: 2022-08-08 11:43 (UTC)
dmytrish: (Default)
From: [personal profile] dmytrish
Ох, с GC тут ситуация «и хочется, и колется».

С одной стороны, сегодняшний WASM это хорошо изолированный от внешнего мира автомат с собственным состоянием. Слишком много зависимости от внешней VM с ее собственным GC (особенно если это какая-то конкретная машина вроде v8) нарушит эту изолированность, отвязанность от внешних платформ. Но понимаю, неприятно, когда приходится в каждой WASM-памяти держать ее собственный memory allocator.

Но вот interface types, component model, witx, вообще любой способ обеспечить Interface Definition Language, нужны немедленно, конечно. Печально, когда даже два wasm-модуля не могут найти общий язык для структурированных данных.

Date: 2022-08-09 08:17 (UTC)
dimorlus: (Default)
From: [personal profile] dimorlus
А под винду? Я поставил компилятор, поставил wasmtime, сделал hello.wasm, но

C:\Test>wasmtime hello.wasm

не пишет ничего. Как я понимаю, проблема именно в wasmtime, потому что hello.wasm под WLS получается такой же точно (там и wasmtime работает).

А если этот hello.wasm браузером запускать, то как?

Date: 2022-08-10 12:13 (UTC)
dimorlus: (Default)
From: [personal profile] dimorlus
В браузере пока не попробовал, а с wasmtime выяснилось, что на машине с Win11 (где у меня и WLS стоит) и в нем, и просто в винде wasmtime работает, а вот на машине с win7 wasmtime.exe hello.wasm ничего не пишет.