Как понять br_if в wasm?
Как работает br_if. Я читал документы, но ничего не нашел о результирующем значении br_if. Я использую https://webassembly.studio/. У меня есть этот код, и я не понимаю, почему он так работает.
(func $f (param $a i32) (result i32)
(block (result i32)
(br_if 0 (i32.const 5) (get_local $a))
))
Я предполагал, что br_if выполняется только тогда, когда условное значение не равно 0, но эта функция всегда возвращает 5, даже если параметр a равен 0. Я думал, что br_if является необязательным возвращаемым значением и пытается установить значение после блока, но оно не компилируется. Объясните, пожалуйста, как это работает.
(func $f (param $a i32) (result i32)
(block (result i32)
(br_if 0 (i32.const 5) (get_local $a))
)
(i32.const 10))
Также я хочу спросить о возврате значения из блоков или циклов, потому что в документах я не видел ни одного предложения об этом. Могу ли я опционально возвращать значение из цикла или блока, когда функция возвращает значение во всех ветвях?
1 ответ
В вашем примере используются свернутые инструкции , о которых я даже не знал, пока не посмотрел их прямо сейчас. Давайте перепишем его в более распространенном синтаксисе, и станет понятнее, что происходит:
(func $f (param $a i32) (result i32)
block (result i32)
i32.const 5
local.get $a
br_if 0
end)
Ваша функция принимает один i32 и возвращает один i32. Все тело функции представляет собой вложенный блок, который также «возвращает» i32, т. е. когда вы переходите к концу этого блока, одно значение будет сохранено на вершине стека (кроме 0 записей в стеке при входе). в этот блок).
Первые 5 нажаты. Затем вводится параметр функции. Тогда у нас есть филиал. Ветка делает то, что вы ожидаете - она потребляет
После выхода из блока возвращается единственное значение в стеке (5).
Это код, который, я думаю, вы ищете (один из возможных способов):
(func $f (param $a i32) (result i32)
local.get $a
if (result i32)
i32.const 5
else
i32.const 0
end)
Редактировать: Чтобы ответить на вторую часть, каждая инструкция (или последовательность инструкций) в WASM имеет статически известный эффект на стек, поэтому нет «необязательного возврата» из блока — если он возвращает значение по одному пути, он должен возвращать этот тип значения во всех путях. Вот почему скомпилированный код, как правило, вообще не возвращает значения для блоков, а вместо этого использует условную настройку локальных переменных.