Instructions

WebAssembly code consists of sequences of instructions. Its computational model is based on a stack machine in that instructions manipulate values on an implicit operand stack, consuming (popping) argument values and producing (pushing) result values.

Note

In the current version of WebAssembly, at most one result value can be pushed by a single instruction. This restriction may be lifted in future versions.

In addition to dynamic operands from the stack, some instructions also have static immediate arguments, typically indices or type annotations, which are part of the instruction itself.

Some instructions are structured in that they bracket nested sequences of instructions.

The following sections group instructions into a number of different categories.

Numeric Instructions

Numeric instructions provide basic operations over numeric values of specific type. These operations closely match respective operations available in hardware.

\[\begin{split}\begin{array}{llcl} \def\mathdef2022#1{{}}\mathdef2022{width} & \mathit{nn}, \mathit{mm} &::=& \mathsf{32} ~|~ \mathsf{64} \\ \def\mathdef2022#1{{}}\mathdef2022{signedness} & \href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} &::=& \mathsf{u} ~|~ \mathsf{s} \\ \def\mathdef2022#1{{}}\mathdef2022{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\href{../syntax/values.html#syntax-int}{\def\mathdef2079#1{{\mathit{i}#1}}\mathdef2079{\mathit{nn}}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\href{../syntax/values.html#syntax-float}{\def\mathdef2080#1{{\mathit{f}#1}}\mathdef2080{\mathit{nn}}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-iunop}{\mathit{iunop}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-funop}{\mathit{funop}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-ibinop}{\mathit{ibinop}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-fbinop}{\mathit{fbinop}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-itestop}{\mathit{itestop}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-irelop}{\mathit{irelop}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-frelop}{\mathit{frelop}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{8\_s} ~|~ \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{16\_s} ~|~ \mathsf{i64.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{32\_s} \\&&|& \mathsf{i32.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{wrap}}\mathsf{/i64} ~|~ \mathsf{i64.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}/\mathsf{i32} ~|~ \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{trunc}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}/\mathsf{f}\mathit{mm} \\&&|& \mathsf{f32.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{demote}}\mathsf{/f64} ~|~ \mathsf{f64.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{promote}}\mathsf{/f32} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{convert}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}/\mathsf{i}\mathit{mm} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{reinterpret}}\mathsf{/f}\mathit{nn} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{reinterpret}}\mathsf{/i}\mathit{nn} \\ \def\mathdef2022#1{{}}\mathdef2022{integer unary operator} & \href{../syntax/instructions.html#syntax-iunop}{\mathit{iunop}} &::=& \mathsf{clz} ~|~ \mathsf{ctz} ~|~ \mathsf{popcnt} \\ \def\mathdef2022#1{{}}\mathdef2022{integer binary operator} & \href{../syntax/instructions.html#syntax-ibinop}{\mathit{ibinop}} &::=& \mathsf{add} ~|~ \mathsf{sub} ~|~ \mathsf{mul} ~|~ \mathsf{div\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{rem\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \mathsf{and} ~|~ \mathsf{or} ~|~ \mathsf{xor} ~|~ \mathsf{shl} ~|~ \mathsf{shr\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{rotl} ~|~ \mathsf{rotr} \\ \def\mathdef2022#1{{}}\mathdef2022{floating-point unary operator} & \href{../syntax/instructions.html#syntax-funop}{\mathit{funop}} &::=& \mathsf{abs} ~|~ \mathsf{neg} ~|~ \mathsf{sqrt} ~|~ \mathsf{ceil} ~|~ \mathsf{floor} ~|~ \mathsf{trunc} ~|~ \mathsf{nearest} \\ \def\mathdef2022#1{{}}\mathdef2022{floating-point binary operator} & \href{../syntax/instructions.html#syntax-fbinop}{\mathit{fbinop}} &::=& \mathsf{add} ~|~ \mathsf{sub} ~|~ \mathsf{mul} ~|~ \mathsf{div} ~|~ \mathsf{min} ~|~ \mathsf{max} ~|~ \mathsf{copysign} \\ \def\mathdef2022#1{{}}\mathdef2022{integer test operator} & \href{../syntax/instructions.html#syntax-itestop}{\mathit{itestop}} &::=& \mathsf{eqz} \\ \def\mathdef2022#1{{}}\mathdef2022{integer relational operator} & \href{../syntax/instructions.html#syntax-irelop}{\mathit{irelop}} &::=& \mathsf{eq} ~|~ \mathsf{ne} ~|~ \mathsf{lt\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{gt\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{le\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{ge\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\ \def\mathdef2022#1{{}}\mathdef2022{floating-point relational operator} & \href{../syntax/instructions.html#syntax-frelop}{\mathit{frelop}} &::=& \mathsf{eq} ~|~ \mathsf{ne} ~|~ \mathsf{lt} ~|~ \mathsf{gt} ~|~ \mathsf{le} ~|~ \mathsf{ge} \\ \end{array}\end{split}\]

Numeric instructions are divided by value type. For each type, several subcategories can be distinguished:

  • Constants: return a static constant.
  • Unary Operators: consume one operand and produce one result of the respective type.
  • Binary Operators: consume two operands and produce one result of the respective type.
  • Tests: consume one operand of the respective type and produce a Boolean integer result.
  • Comparisons: consume two operands of the respective type and produce a Boolean integer result.
  • Conversions: consume a value of one type and produce a result of another (the source type of the conversion is the one after the “\(\mathsf{/}\)”).

Some integer instructions come in two flavours, where a signedness annotation \(\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\) distinguishes whether the operands are to be interpreted as unsigned or signed integers. For the other integer instructions, the use of two’s complement for the signed interpretation means that they behave the same regardless of signedness.

Conventions

Occasionally, it is convenient to group operators together according to the following grammar shorthands:

\[\begin{split}\begin{array}{llll} \def\mathdef2022#1{{}}\mathdef2022{unary operator} & \href{../syntax/instructions.html#syntax-unop}{\mathit{unop}} &::=& \href{../syntax/instructions.html#syntax-iunop}{\mathit{iunop}} ~|~ \href{../syntax/instructions.html#syntax-funop}{\mathit{funop}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}{N}\mathsf{\_s} ~|~ \\ \def\mathdef2022#1{{}}\mathdef2022{binary operator} & \href{../syntax/instructions.html#syntax-binop}{\mathit{binop}} &::=& \href{../syntax/instructions.html#syntax-ibinop}{\mathit{ibinop}} ~|~ \href{../syntax/instructions.html#syntax-fbinop}{\mathit{fbinop}} \\ \def\mathdef2022#1{{}}\mathdef2022{test operator} & \href{../syntax/instructions.html#syntax-testop}{\mathit{testop}} &::=& \href{../syntax/instructions.html#syntax-itestop}{\mathit{itestop}} \\ \def\mathdef2022#1{{}}\mathdef2022{relational operator} & \href{../syntax/instructions.html#syntax-relop}{\mathit{relop}} &::=& \href{../syntax/instructions.html#syntax-irelop}{\mathit{irelop}} ~|~ \href{../syntax/instructions.html#syntax-frelop}{\mathit{frelop}} \\ \def\mathdef2022#1{{}}\mathdef2022{conversion operator} & \href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}} &::=& \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{wrap}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{trunc}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{convert}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{demote}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{promote}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{reinterpret}} \\ \end{array}\end{split}\]

Parametric Instructions

Instructions in this group can operate on operands of any value type.

\[\begin{split}\begin{array}{llcl} \def\mathdef2022#1{{}}\mathdef2022{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{drop}} \\&&|& \href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}} \end{array}\end{split}\]

The \(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{drop}}\) operator simply throws away a single operand.

The \(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}\) operator selects one of its first two operands based on whether its third operand is zero or not.

Variable Instructions

Variable instructions are concerned with the access to local or global variables.

\[\begin{split}\begin{array}{llcl} \def\mathdef2022#1{{}}\mathdef2022{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{get\_local}}~\href{../syntax/modules.html#syntax-localidx}{\mathit{localidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{set\_local}}~\href{../syntax/modules.html#syntax-localidx}{\mathit{localidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{tee\_local}}~\href{../syntax/modules.html#syntax-localidx}{\mathit{localidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{get\_global}}~\href{../syntax/modules.html#syntax-globalidx}{\mathit{globalidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{set\_global}}~\href{../syntax/modules.html#syntax-globalidx}{\mathit{globalidx}} \\ \end{array}\end{split}\]

These instructions get or set the values of variables, respectively. The \(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{tee\_local}}\) instruction is like \(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{set\_local}}\) but also returns its argument.

Memory Instructions

Instructions in this group are concerned with linear memory.

\[\begin{split}\begin{array}{llcl} \def\mathdef2022#1{{}}\mathdef2022{memory immediate} & \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} &::=& \{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~\href{../syntax/values.html#syntax-int}{\def\mathdef2028#1{{\mathit{u}#1}}\mathdef2028{\mathit{32}}}, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~\href{../syntax/values.html#syntax-int}{\def\mathdef2028#1{{\mathit{u}#1}}\mathdef2028{\mathit{32}}} \} \\ \def\mathdef2022#1{{}}\mathdef2022{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{8\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{16\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{i64.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{32\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{16}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{i64.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{32}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{current\_memory}} \\&&|& \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{grow\_memory}} \\ \end{array}\end{split}\]

Memory is accessed with \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\) and \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\) instructions for the different value types. They all take a memory immediate \(\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\) that contains an address offset and an alignment hint (in base 2 logarithmic representation). Integer loads and stores can optionally specify a storage size that is smaller than the bit width of the respective value type. In the case of loads, a sign extension mode \(\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\) is then required to select appropriate behavior.

The static address offset is added to the dynamic address operand, yielding a 33 bit effective address that is the zero-based index at which the memory is accessed. All values are read and written in little endian byte order. A trap results if any of the accessed memory bytes lies outside the address range implied by the memory’s current size.

Note

Future version of WebAssembly might provide memory instructions with 64 bit address ranges.

The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{current\_memory}}\) instruction returns the current size of a memory. The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{grow\_memory}}\) instruction grows memory by a given delta and returns the previous size, or \(-1\) if enough memory cannot be allocated. Both instructions operate in units of page size.

Note

In the current version of WebAssembly, all memory instructions implicitly operate on memory index \(0\). This restriction may be lifted in future versions.

Control Instructions

Instructions in this group affect the flow of control.

\[\begin{split}\begin{array}{llcl} \def\mathdef2022#1{{}}\mathdef2022{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{nop}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{unreachable}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}~\href{../syntax/types.html#syntax-resulttype}{\mathit{resulttype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}~\href{../syntax/types.html#syntax-resulttype}{\mathit{resulttype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}~\href{../syntax/types.html#syntax-resulttype}{\mathit{resulttype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{else}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_if}}~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_table}}~\href{../syntax/conventions.html#syntax-vec}{\mathit{vec}}(\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}})~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call}}~\href{../syntax/modules.html#syntax-funcidx}{\mathit{funcidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\ \end{array}\end{split}\]

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{nop}}\) instruction does nothing.

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{unreachable}}\) instruction causes an unconditional trap.

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}\), \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}\) and \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}\) instructions are structured instructions. They bracket nested sequences of instructions, called blocks, terminated with, or separated by, \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) or \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{else}}\) pseudo-instructions. As the grammar prescribes, they must be well-nested. A structured instruction can produce a value as described by the annotated result type.

Each structured control instruction introduces an implicit label. Labels are targets for branch instructions that reference them with label indices. Unlike with other index spaces, indexing of labels is relative by nesting depth, that is, label \(0\) refers to the innermost structured control instruction enclosing the referring branch instruction, while increasing indices refer to those farther out. Consequently, labels can only be referenced from within the associated structured control instruction. This also implies that branches can only be directed outwards, “breaking” from the block of the control construct they target. The exact effect depends on that control construct. In case of \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}\) or \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}\) it is a forward jump, resuming execution after the matching \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\). In case of \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}\) it is a backward jump to the beginning of the loop.

Note

This enforces structured control flow. Intuitively, a branch targeting a \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}\) or \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}\) behaves like a \(\mathsf{break}\) statement, while a branch targeting a \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}\) behaves like a \(\mathsf{continue}\) statement.

Branch instructions come in several flavors: \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}\) performs an unconditional branch, \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_if}}\) performs a conditional branch, and \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_table}}\) performs an indirect branch through an operand indexing into the label vector that is an immediate to the instruction, or to a default target if the operand is out of bounds. The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return}}\) instruction is a shortcut for an unconditional branch to the outermost block, which implicitly is the body of the current function. Taking a branch unwinds the operand stack up to the height where the targeted structured control instruction was entered. However, forward branches that target a control instruction with a non-empty result type consume matching operands first and push them back on the operand stack after unwinding, as a result for the terminated structured instruction.

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call}}\) instruction invokes another function, consuming the necessary arguments from the stack and returning the result values of the call. The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}\) instruction calls a function indirectly through an operand indexing into a table. Since tables may contain function elements of heterogeneous type \(\href{../syntax/types.html#syntax-elemtype}{\mathsf{anyfunc}}\), the callee is dynamically checked against the function type indexed by the instruction’s immediate, and the call aborted with a trap if it does not match.

Note

In the current version of WebAssembly, \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}\) implicitly operates on table index \(0\). This restriction may be lifted in future versions.

Expressions

Function bodies, initialization values for globals, and offsets of element or data segments are given as expressions, which are sequences of instructions terminated by an \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) marker.

\[\begin{split}\begin{array}{llll} \def\mathdef2022#1{{}}\mathdef2022{expression} & \href{../syntax/instructions.html#syntax-expr}{\mathit{expr}} &::=& \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\ \end{array}\end{split}\]

In some places, validation restricts expressions to be constant, which limits the set of allowable instructions.