Как выглядит секция элементов модуля wasm в бинарном формате?

Я читаю эту документацию, чтобы изучить двоичный формат 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.

Видно, что некоторые из этих форматов перекрываются, но спецификация развивается, и из соображений обратной совместимости с самыми ранними версиями формат сегодня такой.

Другие вопросы по тегам