Как выглядит секция элементов модуля wasm в бинарном формате?
1 ответ
Раздел сегментов элементов
Идея этого раздела заключается в том, чтобы заполнитьWebAssembly.Table
объекты с содержимым. Изначально была только одна таблица, и ее единственным возможным содержимым были индексы/идентификаторы функций. Вы можете написать:
(elem 0 (offset (i32.const 1)) 2)
Это означает: при создании экземпляра заполните индекс таблицы значением, напримерtables[0][1] = 2;
. Вот индекс функции, которую будет хранить таблица.
Тип сегмента элемента выше называетсяactive
в настоящее время, и после создания экземпляра он больше не будет доступен приложению (они «отброшены»). Из спецификаций:
Сегмент активного элемента копирует свои элементы в таблицу во время создания экземпляра, как указано индексом таблицы и постоянным выражением, определяющим смещение в этой таблице.
Все идет нормально. Но было признано, что есть потребность в более мощной секции сегмента элемента. Введены сегменты пассивного и декларативного элементов.
Пассивный сегмент не используется во время создания экземпляра и всегда доступен во время выполнения (пока не будет удален самим приложением сelem.drop
). Есть инструкция (отBulk memory and table instructions
предложение, уже интегрированное в стандарт), которые можно использовать для операций с таблицами и сегментами элементов.
Сегмент декларативного элемента недоступен во время выполнения, а просто служит для прямого объявления ссылок, которые формируются в коде с такими инструкциями, как ref.func.
Вот набор тестов, где вы можете увидеть множество примеров сегментов элементов (в текстовом формате).
Двоичный формат
Предполагая, что вы анализируете код, вы читаете один , и на основе его значения вы ожидаете формат из спецификации:
- означает активный сегмент, как указано выше, для неявного табличного индекса
0
, и вектор . -
1
означает пассивный сегмент, ( for в настоящее время), за которым следует вектор соответствующих элементов (func.refs
). - является активным сегментом.
-
3
означает декларативный сегмент. -
4
является активным сегментом, где значения в векторе являются выражениями, а не просто индексами (так что вы могли бы иметь(i32.const 2)
в приведенном выше примере вместо2
). -
5
пассив с выражениями -
6
активен с индексом таблицы и выражениями -
7
декларативный с выражениями
По этой причине в спецификациях сказано, что от этогоu32
[0..7] вы можете использовать его три младших бита, чтобы определить, какой формат вам нужно проанализировать. Например, 3-й бит означает «вектор состоит из выражений?».
Теперь, все сказанное, кажется, что предложение ссылочных типов (пока) не полностью интегрировано в двоичный формат спецификации (но, похоже, в текстовый). Когда это произойдет, вы сможете иметь другое, чем0x00
(func.ref
) дляelemkind
.
Видно, что некоторые из этих форматов перекрываются, но спецификация развивается, и из соображений обратной совместимости с самыми ранними версиями формат сегодня такой.