Заранее прошу простить, но конкретный исходник по вопросу к посту подготовить не успеваю, но в конце пара ссылок на суть дела от других производителей…
Пытался сделать максимально компактную .wasm хрень на C
с помощью emcc
, задача которой просто байтики молотить - картинку обработать. Исходник оставил на другом компе, но дело не столько в нём, сколько в понимании модели памяти вебасма. Сделать-то компактно ополучилось: ноль инклудов, пара функций, пара глобальных переменных, экспорт всего наружу, всего 50 строк, ~400 байт на выходе.
Компилируется, в JS инициализируется, как надо не работает, но и не падает.
Вопросы:
-
А правда, что wasm-инстанс (ну, «запущенная wasm программа») имеет модель памяти вида «плоский шмат» и любой указатель - это оффсет в этом шмате? То есть, если я хочу выделить память без планов её освобождать, я могу просто отступить куда-нибудь вперёд килобайт на 100 (при наличии Memory достаточного размера) и спокойно туда записывать? То есть, правда ли то, что в wasm-инстансе нет ничего подобного вызовам mmap/brk в линуксе, когда тебе могут надавать вообще разных адресов? В wasm у тебя только один шмат, просто можно как-то нарастить размер.
-
А во что превратится глобальный
static int[1024 * 1024];
написанный в сишном коде в webassembly? А можно я буду выделять себе свой единственно нужный буфер именно так? Пробовал взять на него указатель - дают некое число небольшое число типа1050
- ну типа прямо как offset в пункте (1). Попробовал туда записывать - причём циклом по всему массиву - нормально, ничего не упало.
Пока вот два таких наводящих вопроса, конкретнее пока смысла нет, да и исходник провтыкал, найду запощу. Проблема просто в том, что я в память на webassembly пишу, а попытка посмотреть на тот же буфер со стороны JS выглядит так, что туда не пишется и там чисто - нолики лежат в той области, на которую пытаюсь смотреть. Может не туда смотрю, а может запись не происходит вообще. Странно, что в консоли хрома при этом ничего красного нет, ну вдруг я за границы массива пытался бы срать - так нет же.
Про исходник: в принципе все технические детали сп***ны отсюда: https://github.com/quin2/fast-paint
На что обратить внимание:
-
Шмат памяти, в котором вся
сишная
часть этого проекта ковыряется, была «выделена» вот тут: https://github.com/quin2/fast-paint/blob/main/buffer.c#L63 - но, как мы знаем, в webassembly модель памяти - просто один шмат, поэтому этот malloc был скомпилён скорее всего в итоге во что-то, что вернуло uint32 с оффсетом на память. -
Далее со значением этого указателя
screen
имеют дело уже вот тут https://github.com/quin2/fast-paint/blob/main/script.js#L35 в виде обычного числа. -
Ну и основной цимес: как чуваки апдейтят canvas context: https://github.com/quin2/fast-paint/blob/main/script.js#L421 - вот просто хоба и скопировали прямо из буфера, в который инстанцировали webassembly с оффсетом
pointer
шмат памяти и закинули наctx
. Тащемта всё! В этой простоте и вся трагедия - попытка это повторить БЕЗ ВЫЗОВАmalloc
в сишной части, а просто отступив сколько-то памяти - это какой-то провал и непонятно почему, хоть и незаконно.