Instructions

WebAssembly computation is performed by executing individual instructions.

Numeric Instructions

Numeric instructions are defined in terms of the generic numeric operators. The mapping of numeric instructions to their underlying operators is expressed by the following definition:

\[\begin{split}\begin{array}{lll@{\qquad}l} \mathit{op}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}}(i_1,\dots,i_k) &=& \mathrm{i}\mathit{op}_N(i_1,\dots,i_k) \\ \mathit{op}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{f}N}}(z_1,\dots,z_k) &=& \mathrm{f}\mathit{op}_N(z_1,\dots,z_k) \\ \mathit{op}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v}N}}(i_1,\dots,i_k) &=& \mathrm{i}\mathit{op}_N(i_1,\dots,i_k) \\ \end{array}\end{split}\]

And for conversion operators:

\[\begin{split}\begin{array}{lll@{\qquad}l} \mathit{cvtop}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{t_1,t_2}(c) &=& \mathit{cvtop}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{|t_1|,|t_2|}(c) \\ \end{array}\end{split}\]

Where the underlying operators are partial, the corresponding instruction will trap when the result is not defined. Where the underlying operators are non-deterministic, because they may return one of multiple possible NaN values, so are the corresponding instructions.

Note

For example, the result of instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}\) applied to operands \(i_1, i_2\) invokes \(\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}}(i_1, i_2)\), which maps to the generic \(\href{../exec/numerics.html#op-iadd}{\mathrm{iadd}}_{32}(i_1, i_2)\) via the above definition. Similarly, \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i64}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{trunc}}\mathsf{\_}\href{../syntax/types.html#syntax-valtype}{\mathsf{f32}}\mathsf{\_s}\) applied to \(z\) invokes \(\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{trunc}}^{\mathsf{s}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{f32}},\href{../syntax/types.html#syntax-valtype}{\mathsf{i64}}}(z)\), which maps to the generic \(\href{../exec/numerics.html#op-trunc-s}{\mathrm{trunc}^{\mathsf{s}}}_{32,64}(z)\).

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)

  1. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

Note

No formal reduction rule is required for this instruction, since \(\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}\) instructions already are values.

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-unop}{\mathit{unop}}\)

  1. Assert: due to validation, a value of value type \(t\) is on the top of the stack.

  2. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\) from the stack.

  3. If \(\href{../syntax/instructions.html#syntax-unop}{\mathit{unop}}_t(c_1)\) is defined, then:

    1. Let \(c\) be a possible result of computing \(\href{../syntax/instructions.html#syntax-unop}{\mathit{unop}}_t(c_1)\).

    2. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

  4. Else:

    1. Trap.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~t\mathsf{.}\href{../syntax/instructions.html#syntax-unop}{\mathit{unop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c \in \href{../syntax/instructions.html#syntax-unop}{\mathit{unop}}_t(c_1)) \\ (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~t\mathsf{.}\href{../syntax/instructions.html#syntax-unop}{\mathit{unop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} & (\mathrel{\mbox{if}} \href{../syntax/instructions.html#syntax-unop}{\mathit{unop}}_{t}(c_1) = \{\}) \end{array}\end{split}\]

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-binop}{\mathit{binop}}\)

  1. Assert: due to validation, two values of value type \(t\) are on the top of the stack.

  2. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\) from the stack.

  3. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\) from the stack.

  4. If \(\href{../syntax/instructions.html#syntax-binop}{\mathit{binop}}_t(c_1, c_2)\) is defined, then:

    1. Let \(c\) be a possible result of computing \(\href{../syntax/instructions.html#syntax-binop}{\mathit{binop}}_t(c_1, c_2)\).

    2. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

  5. Else:

    1. Trap.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~t\mathsf{.}\href{../syntax/instructions.html#syntax-binop}{\mathit{binop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c \in \href{../syntax/instructions.html#syntax-binop}{\mathit{binop}}_t(c_1,c_2)) \\ (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~t\mathsf{.}\href{../syntax/instructions.html#syntax-binop}{\mathit{binop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} & (\mathrel{\mbox{if}} \href{../syntax/instructions.html#syntax-binop}{\mathit{binop}}_{t}(c_1,c_2) = \{\}) \end{array}\end{split}\]

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-testop}{\mathit{testop}}\)

  1. Assert: due to validation, a value of value type \(t\) is on the top of the stack.

  2. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\) from the stack.

  3. Let \(c\) be the result of computing \(\href{../syntax/instructions.html#syntax-testop}{\mathit{testop}}_t(c_1)\).

  4. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~t\mathsf{.}\href{../syntax/instructions.html#syntax-testop}{\mathit{testop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c = \href{../syntax/instructions.html#syntax-testop}{\mathit{testop}}_t(c_1)) \\ \end{array}\end{split}\]

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-relop}{\mathit{relop}}\)

  1. Assert: due to validation, two values of value type \(t\) are on the top of the stack.

  2. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\) from the stack.

  3. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(c\) be the result of computing \(\href{../syntax/instructions.html#syntax-relop}{\mathit{relop}}_t(c_1, c_2)\).

  5. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~t\mathsf{.}\href{../syntax/instructions.html#syntax-relop}{\mathit{relop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c = \href{../syntax/instructions.html#syntax-relop}{\mathit{relop}}_t(c_1,c_2)) \\ \end{array}\end{split}\]

\(t_2\mathsf{.}\href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}\mathsf{\_}t_1\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?\)

  1. Assert: due to validation, a value of value type \(t_1\) is on the top of the stack.

  2. Pop the value \(t_1.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\) from the stack.

  3. If \(\href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{t_1,t_2}(c_1)\) is defined:

    1. Let \(c_2\) be a possible result of computing \(\href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{t_1,t_2}(c_1)\).

    2. Push the value \(t_2.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\) to the stack.

  4. Else:

    1. Trap.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (t_1\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~t_2\mathsf{.}\href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}\mathsf{\_}t_1\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^? &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (t_2\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2) & (\mathrel{\mbox{if}} c_2 \in \href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{t_1,t_2}(c_1)) \\ (t_1\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~t_2\mathsf{.}\href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}\mathsf{\_}t_1\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^? &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} & (\mathrel{\mbox{if}} \href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{t_1,t_2}(c_1) = \{\}) \end{array}\end{split}\]

Reference Instructions

\(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t\)

  1. Push the value \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t\) to the stack.

Note

No formal reduction rule is required for this instruction, since the \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}\) instruction is already a value.

\(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}is\_null}}\)

  1. Assert: due to validation, a reference value is on the top of the stack.

  2. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

  3. If \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) is \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t\), then:

    1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~1\) to the stack.

  4. Else:

    1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-val}{\mathit{val}}~\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}is\_null}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~1) & (\mathrel{\mbox{if}} \href{../exec/runtime.html#syntax-val}{\mathit{val}} = \href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t) \\ \href{../exec/runtime.html#syntax-val}{\mathit{val}}~\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}is\_null}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0) & (\mathrel{\mbox{otherwise}}) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}func}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]\) exists.

  3. Let \(a\) be the function address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]\).

  4. Push the value \(\href{../exec/runtime.html#syntax-ref}{\mathsf{ref}}~a\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} F; (\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}func}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& F; (\href{../exec/runtime.html#syntax-ref}{\mathsf{ref}}~a) & (\mathrel{\mbox{if}} a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]) \\ \end{array}\end{split}\]

Vector Instructions

Most vector instructions are defined in terms of generic numeric operators applied lane-wise based on the shape.

\[\begin{array}{lll@{\qquad}l} \mathit{op}_{t\mathsf{x}N}(n_1,\dots,n_k) &=& \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t\mathsf{x}N}(op_t(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(n_1) ~\dots~ \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(n_k)) \end{array}\]

Note

For example, the result of instruction \(\mathsf{i32x4}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}\) applied to operands \(i_1, i_2\) invokes \(\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}_{\mathsf{i32x4}}(i_1, i_2)\), which maps to \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\mathsf{i32x4}}(\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}}(i_1^+, i_2^+))\), where \(i_1^+\) and \(i_2^+\) are sequences resulting from invoking \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\mathsf{i32x4}}(i_1)\) and \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\mathsf{i32x4}}(i_2)\) respectively.

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\)

  1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

Note

No formal reduction rule is required for this instruction, since \(\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}\) instructions coincide with values.

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-vvunop}{\mathit{vvunop}}\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  3. Let \(c\) be the result of computing \(\href{../syntax/instructions.html#syntax-vvunop}{\mathit{vvunop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1)\).

  4. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-vvunop}{\mathit{vvunop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c = \href{../syntax/instructions.html#syntax-vvunop}{\mathit{vvunop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1)) \\ \end{array}\end{split}\]

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-vvbinop}{\mathit{vvbinop}}\)

  1. Assert: due to validation, two values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(c\) be the result of computing \(\href{../syntax/instructions.html#syntax-vvbinop}{\mathit{vvbinop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1, c_2)\).

  5. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-vvbinop}{\mathit{vvbinop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c = \href{../syntax/instructions.html#syntax-vvbinop}{\mathit{vvbinop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1, c_2)) \\ \end{array}\end{split}\]

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-vvternop}{\mathit{vvternop}}\)

  1. Assert: due to validation, three values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_3\) from the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  4. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  5. Let \(c\) be the result of computing \(\href{../syntax/instructions.html#syntax-vvternop}{\mathit{vvternop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1, c_2, c_3)\).

  6. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_3)~\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-vvternop}{\mathit{vvternop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c = \href{../syntax/instructions.html#syntax-vvternop}{\mathit{vvternop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1, c_2, c_3)) \\ \end{array}\end{split}\]

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{any\_true}}\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  3. Let \(i\) be the result of computing \(\href{../exec/numerics.html#op-ine}{\mathrm{ine}}_{128}(c_1, 0)\).

  4. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) onto the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{any\_true}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i) & (\mathrel{\mbox{if}} i = \href{../exec/numerics.html#op-ine}{\mathrm{ine}}_{128}(c_1, 0)) \\ \end{array}\end{split}\]

\(\mathsf{i8x16.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{swizzle}}\)

  1. Assert: due to validation, two values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  3. Let \(i^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_2)\).

  4. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  5. Let \(j^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_1)\).

  6. Let \(c^\ast\) be the concatenation of the two sequences \(j^\ast\) and \(0^{240}\).

  7. Let \(c'\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c^\ast[ i^\ast[0] ] \dots c^\ast[ i^\ast[15] ])\).

  8. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c'\) onto the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{swizzle}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c') \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & i^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_2) \\ \wedge & c^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_1)~0^{240} \\ \wedge & c' = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c^\ast[ i^\ast[0] ] \dots c^\ast[ i^\ast[15] ])) \end{array} \end{array}\end{split}\]

\(\mathsf{i8x16.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{shuffle}}~x^\ast\)

  1. Assert: due to validation, two values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  2. Assert: due to validation, for all \(x_i\) in \(x^\ast\) it holds that \(x_i < 32\).

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  4. Let \(i_2^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_2)\).

  5. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  6. Let \(i_1^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_1)\).

  7. Let \(i^\ast\) be the concatenation of the two sequences \(i_1^\ast\) and \(i_2^\ast\).

  8. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(i^\ast[x^\ast[0]] \dots i^\ast[x^\ast[15]])\).

  9. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) onto the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{shuffle}}~x^\ast) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & i^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_1)~\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_2) \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(i^\ast[x^\ast[0]] \dots i^\ast[x^\ast[15]])) \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{splat}}\)

  1. Let \(t\) be the type \(\href{../valid/instructions.html#aux-unpacked}{\mathrm{unpacked}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})\).

  2. Assert: due to validation, a value of value type \(t\) is on the top of the stack.

  3. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(N\) be the integer \(\href{../valid/instructions.html#aux-dim}{\mathrm{dim}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})\).

  5. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1^N)\).

  6. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{splat}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} t = \href{../valid/instructions.html#aux-unpacked}{\mathrm{unpacked}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}) \wedge c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1^{\href{../valid/instructions.html#aux-dim}{\mathrm{dim}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})})) \\ \end{array}\end{split}\]

\(t_1\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extract\_lane}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?~x\)

  1. Assert: due to validation, \(x < N\).

  2. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(i^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}N}(c_1)\).

  5. Let \(t_2\) be the type \(\href{../valid/instructions.html#aux-unpacked}{\mathrm{unpacked}}(t_1\mathsf{x}N)\).

  6. Let \(c_2\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{sx^?}_{t_1,t_2}(i^\ast[x])\).

  7. Push the value \(t_2.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(t_1\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extract\_lane}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (t_2\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & t_2 = \href{../valid/instructions.html#aux-unpacked}{\mathrm{unpacked}}(t_1\mathsf{x}N) \\ \wedge & c_2 = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{sx^?}_{t_1,t_2}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}N}(c_1)[x])) \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{replace\_lane}}~x\)

  1. Assert: due to validation, \(x < \href{../valid/instructions.html#aux-dim}{\mathrm{dim}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})\).

  2. Let \(t_1\) be the type \(\href{../valid/instructions.html#aux-unpacked}{\mathrm{unpacked}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})\).

  3. Assert: due to validation, a value of value type \(t_1\) is on the top of the stack.

  4. Pop the value \(t_1.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\) from the stack.

  5. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  6. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  7. Let \(i^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_2)\).

  8. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(i^\ast \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} [x] = c_1)\).

  9. Push \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) on the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (t_1\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{replace\_lane}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & i^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_2) \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(i^\ast \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} [x] = c_1)) \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vunop}{\mathit{vunop}}\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  3. Let \(c\) be the result of computing \(\href{../syntax/instructions.html#syntax-vunop}{\mathit{vunop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1)\).

  4. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

\[\begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-vunop}{\mathit{vunop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c = \href{../syntax/instructions.html#syntax-vunop}{\mathit{vunop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1)) \end{array}\]

\(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}}\)

  1. Assert: due to validation, two values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. If \(\href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1, c_2)\) is defined:

    1. Let \(c\) be a possible result of computing \(\href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1, c_2)\).

    2. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

  5. Else:

    1. Trap.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c \in \href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1, c_2)) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} & (\mathrel{\mbox{if}} \href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1, c_2) = \{\}) \end{array}\end{split}\]

\(t\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vrelop}{\mathit{vrelop}}\)

  1. Assert: due to validation, two values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(i_1^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_1)\).

  5. Let \(i_2^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_2)\).

  6. Let \(i^\ast\) be the result of computing \(\href{../syntax/instructions.html#syntax-vrelop}{\mathit{vrelop}}_t(i_1^\ast, i_2^\ast)\).

  7. Let \(j^\ast\) be the result of computing \(\href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{1,|t|}(i^\ast)\).

  8. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t\mathsf{x}N}(j^\ast)\).

  9. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~t\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vrelop}{\mathit{vrelop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t\mathsf{x}N}(\href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{1,|t|}(\href{../syntax/instructions.html#syntax-vrelop}{\mathit{vrelop}}_t(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_1), \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_2))))) \end{array} \end{array}\end{split}\]

\(t\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vishiftop}{\mathit{vishiftop}}\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) from the stack.

  3. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  4. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  5. Let \(i^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_1)\).

  6. Let \(j^\ast\) be the result of computing \(\href{../syntax/instructions.html#syntax-vishiftop}{\mathit{vishiftop}}_{t}(i^\ast, s^N)\).

  7. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t\mathsf{x}N}(j^\ast)\).

  8. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~t\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vishiftop}{\mathit{vishiftop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & i^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_1) \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t\mathsf{x}N}(\href{../syntax/instructions.html#syntax-vishiftop}{\mathit{vishiftop}}_{t}(i^\ast, s^N))) \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{all\_true}}\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  3. Let \(i_1^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1)\).

  4. Let \(i\) be the result of computing \(\href{../exec/numerics.html#aux-bool}{\mathrm{bool}}(\bigwedge(i_1 \neq 0)^\ast)\).

  5. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) onto the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{all\_true}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & i_1^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c) \\ \wedge & i = \href{../exec/numerics.html#aux-bool}{\mathrm{bool}}(\bigwedge(i_1 \neq 0)^\ast)) \end{array} \end{array}\end{split}\]

\(t\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{bitmask}}\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  3. Let \(i_1^N\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c)\).

  4. Let \(B\) be the bit width \(|t|\) of value type \(t\).

  5. Let \(i_2^N\) be the result of computing \(\href{../exec/numerics.html#op-ilt-s}{\mathrm{ilt\_s}}_{B}(i_1^N, 0^N)\).

  6. Let \(j^\ast\) be the concatenation of the two sequences \(i_2^N\) and \(0^{32-N}\).

  7. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-ibits}{\mathrm{ibits}}_{32}^{-1}(j^\ast)\).

  8. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) onto the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~t\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{bitmask}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c = \href{../exec/numerics.html#aux-ibits}{\mathrm{ibits}}_{32}^{-1}(\href{../exec/numerics.html#op-ilt-s}{\mathrm{ilt\_s}}_{|t|}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c), 0^N))) \\ \end{array}\end{split}\]

\(t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{narrow}}\mathsf{\_}t_1\mathsf{x}M\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\)

  1. Assert: due to syntax, \(N = 2\cdot M\).

  2. Assert: due to validation, two values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  4. Let \(i_2^M\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_2)\).

  5. Let \(d_2^M\) be the result of computing \(\href{../exec/numerics.html#op-narrow-u}{\mathrm{narrow}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(i_2^M)\).

  6. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  7. Let \(i_1^M\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\).

  8. Let \(d_1^M\) be the result of computing \(\href{../exec/numerics.html#op-narrow-u}{\mathrm{narrow}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(i_1^M)\).

  9. Let \(j^N\) be the concatenation of the two sequences \(d_1^M\) and \(d_2^M\).

  10. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(j^N)\).

  11. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) onto the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{narrow}}\_t_1\mathsf{x}M\_\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & d_1^M = \href{../exec/numerics.html#op-narrow-u}{\mathrm{narrow}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}( \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)) \\ \wedge & d_2^M = \href{../exec/numerics.html#op-narrow-u}{\mathrm{narrow}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}( \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_2)) \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(d_1^M~d_2^M)) \end{array} \end{array}\end{split}\]

\(t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}\mathsf{\_}t_1\mathsf{x}M\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\)

  1. Assert: due to syntax, \(N = M\).

  2. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(i^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\).

  5. Let \(j^\ast\) be the result of computing \(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(i^\ast)\).

  6. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(j^\ast)\).

  7. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) onto the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}\mathsf{\_}t_1\mathsf{x}M\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \\ \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)))) \end{array} \end{array}\end{split}\]

\(t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_}t_1\mathsf{x}M\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?\)

  1. Assert: due to syntax, \(N = M / 2\).

  2. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(i^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\).

  5. If \(\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\) is \(\mathsf{low}\), then:

    1. Let \(j^\ast\) be the sequence \(i^\ast[0 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\).

  6. Else:

    1. Let \(j^\ast\) be the sequence \(i^\ast[N \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\).

  7. Let \(k^\ast\) be the result of computing \(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{|t_1|,|t_2|}(j^\ast)\).

  8. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(k^\ast)\).

  9. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) onto the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_}t_1\mathsf{x}M\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^? &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \\ \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{|t_1|,|t_2|}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)[\href{../syntax/instructions.html#syntax-half}{\mathit{half}}(0, N) \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]))) \end{array} \end{array}\end{split}\]

where:

\[\begin{split}\begin{array}{lcl} \mathsf{low}(x, y) &=& x \\ \mathsf{high}(x, y) &=& y \\ \end{array}\end{split}\]

\(t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}\mathsf{\_}t_1\mathsf{x}M\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\mathsf{\_zero}\)

  1. Assert: due to syntax, \(N = 2 \cdot M\).

  2. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(i^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\).

  5. Let \(j^\ast\) be the result of computing \(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(i^\ast)\).

  6. Let \(k^\ast\) be the concatenation of the two sequences \(j^\ast\) and \(0^M\).

  7. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(k^\ast)\).

  8. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) onto the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}\mathsf{\_}t_1\mathsf{x}M\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\mathsf{\_zero} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \\ \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1))~0^M)) \end{array} \end{array}\end{split}\]

\(\mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{dot}}\mathsf{\_i16x8\_s}\)

  1. Assert: due to validation, two values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(i_1^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i16x8}}}(c_1)\).

  5. Let \(j_1^\ast\) be the result of computing \(\href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{16,32}(i_1^\ast)\).

  6. Let \(i_2^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i16x8}}}(c_2)\).

  7. Let \(j_2^\ast\) be the result of computing \(\href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{16,32}(i_2^\ast)\).

  8. Let \((k_1~k_2)^\ast\) be the result of computing \(\href{../exec/numerics.html#op-imul}{\mathrm{imul}}_{32}(j_1^\ast, j_2^\ast)\).

  9. Let \(k^\ast\) be the result of computing \(\href{../exec/numerics.html#op-iadd}{\mathrm{iadd}}_{32}(k_1, k_2)^\ast\).

  10. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i32x4}}}(k^\ast)\).

  11. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) onto the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~\mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{dot}}\mathsf{\_i16x8\_s} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \\ \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & (i_1~i_2)^\ast = \href{../exec/numerics.html#op-imul}{\mathrm{imul}}_{32}(\href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{16,32}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i16x8}}}(c_1)), \href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{16,32}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i16x8}}}(c_2))) \\ \wedge & j^\ast = \href{../exec/numerics.html#op-iadd}{\mathrm{iadd}}_{32}(i_1, i_2)^\ast \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i32x4}}}(j^\ast)) \end{array} \end{array}\end{split}\]

\(t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extmul}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_}t_1\mathsf{x}M\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\)

  1. Assert: due to syntax, \(N = M / 2\).

  2. Assert: due to validation, two values of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) are on the top of the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\) from the stack.

  4. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  5. Let \(i_1^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\).

  6. Let \(i_2^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_2)\).

  7. If \(\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\) is \(\mathsf{low}\), then:

    1. Let \(j_1^\ast\) be the sequence \(i_1^\ast[0 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\).

    2. Let \(j_2^\ast\) be the sequence \(i_2^\ast[0 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\).

  8. Else:

    1. Let \(j_1^\ast\) be the sequence \(i_1^\ast[N \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\).

    2. Let \(j_2^\ast\) be the sequence \(i_2^\ast[N \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\).

  9. Let \(k_1^\ast\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(j_1^\ast)\).

  10. Let \(k_2^\ast\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(j_2^\ast)\).

  11. Let \(k^\ast\) be the result of computing \(\href{../exec/numerics.html#op-imul}{\mathrm{imul}}_{t_2\mathsf{x}N}(k_1^\ast, k_2^\ast)\).

  12. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(k^\ast)\).

  13. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) onto the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2)~t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extmul}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_}t_1\mathsf{x}M\_\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \\ \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & i^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)[\href{../syntax/instructions.html#syntax-half}{\mathit{half}}(0, N) \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N] \\ \wedge & j^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_2)[\href{../syntax/instructions.html#syntax-half}{\mathit{half}}(0, N) \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N] \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(\href{../exec/numerics.html#op-imul}{\mathrm{imul}}_{t_2\mathsf{x}N}(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(i^\ast), \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(j^\ast)))) \end{array}\end{split}\]

where:

\[\begin{split}\begin{array}{lcl} \mathsf{low}(x, y) &=& x \\ \mathsf{high}(x, y) &=& y \\ \end{array}\end{split}\]

\(t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extadd\_pairwise}}\_t_1\mathsf{x}M\_\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\)

  1. Assert: due to syntax, \(N = M / 2\).

  2. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\) from the stack.

  4. Let \(i^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\).

  5. Let \((j_1~j_2)^\ast\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(i^\ast)\).

  6. Let \(k^\ast\) be the result of computing \(\href{../exec/numerics.html#op-iadd}{\mathrm{iadd}}_{N}(j_1, j_2)^\ast\).

  7. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(k^\ast)\).

  8. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1)~t_2\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extadd\_pairwise}}\_t_1\mathsf{x}M\_\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) \\ \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & (i_1~i_2)^\ast = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)) \\ \wedge & j^\ast = \href{../exec/numerics.html#op-iadd}{\mathrm{iadd}}_{N}(i_1, i_2)^\ast \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(j^\ast)) \end{array} \end{array}\end{split}\]

Parametric Instructions

\(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{drop}}\)

  1. Assert: due to validation, a value is on the top of the stack.

  2. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

\[\begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-val}{\mathit{val}}~~\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{drop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \epsilon \end{array}\]

\(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}~(t^\ast)^?\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) from the stack.

  3. Assert: due to validation, two more values (of the same value type) are on the top of the stack.

  4. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_2\) from the stack.

  5. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_1\) from the stack.

  6. If \(c\) is not \(0\), then:

    1. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_1\) back to the stack.

  7. Else:

    1. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_2\) back to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-val}{\mathit{val}}_1~\href{../exec/runtime.html#syntax-val}{\mathit{val}}_2~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}~t^?) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}_1 & (\mathrel{\mbox{if}} c \neq 0) \\ \href{../exec/runtime.html#syntax-val}{\mathit{val}}_1~\href{../exec/runtime.html#syntax-val}{\mathit{val}}_2~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}~t^?) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}_2 & (\mathrel{\mbox{if}} c = 0) \\ \end{array}\end{split}\]

Note

In future versions of WebAssembly, \(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}\) may allow more than one value per choice.

Variable Instructions

\(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.get}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x]\) exists.

  3. Let \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) be the value \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x]\).

  4. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

\[\begin{split}\begin{array}{lcl@{\qquad}l} F; (\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.get}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& F; \href{../exec/runtime.html#syntax-val}{\mathit{val}} & (\mathrel{\mbox{if}} F.\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x] = \href{../exec/runtime.html#syntax-val}{\mathit{val}}) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.set}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x]\) exists.

  3. Assert: due to validation, a value is on the top of the stack.

  4. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

  5. Replace \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x]\) with the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\).

\[\begin{split}\begin{array}{lcl@{\qquad}l} F; \href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.set}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& F'; \epsilon & (\mathrel{\mbox{if}} F' = F \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x] = \href{../exec/runtime.html#syntax-val}{\mathit{val}}) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.tee}}~x\)

  1. Assert: due to validation, a value is on the top of the stack.

  2. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

  3. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

  4. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

  5. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.set}}~x\).

\[\begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.tee}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.set}}~x) \end{array}\]

\(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{global.get}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]\) exists.

  3. Let \(a\) be the global address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\) exists.

  5. Let \(\mathit{glob}\) be the global instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\).

  6. Let \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) be the value \(\mathit{glob}.\href{../exec/runtime.html#syntax-globalinst}{\mathsf{value}}\).

  7. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{global.get}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-val}{\mathit{val}} \end{array} \\ \qquad (\mathrel{\mbox{if}} S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]].\href{../exec/runtime.html#syntax-globalinst}{\mathsf{value}} = \href{../exec/runtime.html#syntax-val}{\mathit{val}}) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{global.set}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]\) exists.

  3. Let \(a\) be the global address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\) exists.

  5. Let \(\mathit{glob}\) be the global instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\).

  6. Assert: due to validation, a value is on the top of the stack.

  7. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

  8. Replace \(\mathit{glob}.\href{../exec/runtime.html#syntax-globalinst}{\mathsf{value}}\) with the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\).

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; \href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{global.set}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad (\mathrel{\mbox{if}} S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]].\href{../exec/runtime.html#syntax-globalinst}{\mathsf{value}} = \href{../exec/runtime.html#syntax-val}{\mathit{val}}) \\ \end{array}\end{split}\]

Note

Validation ensures that the global is, in fact, marked as mutable.

Table Instructions

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) exists.

  3. Let \(a\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) exists.

  5. Let \(\mathit{tab}\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\).

  6. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  7. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  8. If \(i\) is not smaller than the length of \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\), then:

    1. Trap.

  9. Let \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) be the value \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[i]\).

  10. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-val}{\mathit{val}} \end{array} \\ \qquad (\mathrel{\mbox{if}} S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[i] = \href{../exec/runtime.html#syntax-val}{\mathit{val}}) \\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) exists.

  3. Let \(a\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) exists.

  5. Let \(\mathit{tab}\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\).

  6. Assert: due to validation, a reference value is on the top of the stack.

  7. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

  8. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  9. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  10. If \(i\) is not smaller than the length of \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\), then:

    1. Trap.

  11. Replace the element \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[i]\) with \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\).

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad (\mathrel{\mbox{if}} S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[i] = \href{../exec/runtime.html#syntax-val}{\mathit{val}}) \\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.size}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) exists.

  3. Let \(a\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) exists.

  5. Let \(\mathit{tab}\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\).

  6. Let \(\mathit{sz}\) be the length of \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\).

  7. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.size}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}) \end{array} \\ \qquad (\mathrel{\mbox{if}} |S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}| = \mathit{sz}) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.grow}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) exists.

  3. Let \(a\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) exists.

  5. Let \(\mathit{tab}\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\).

  6. Let \(\mathit{sz}\) be the length of \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\).

  7. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  8. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) from the stack.

  9. Assert: due to validation, a reference value is on the top of the stack.

  10. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

  11. Let \(\mathit{err}\) be the \(\href{../syntax/values.html#syntax-int}{\mathit{i32}}\) value \(2^{32}-1\), for which \(\href{../exec/numerics.html#aux-signed}{\mathrm{signed}}_{32}(\mathit{err})\) is \(-1\).

  12. Either:

  1. If growing \(\mathit{tab}\) by \(n\) entries with initialization value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) succeeds, then:

    1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) to the stack.

  2. Else:

    1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) to the stack.

  1. Or:

  1. push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) to the stack.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; \href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.grow}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x] = a \\ \wedge & \mathit{sz} = |S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}| \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a] = \href{../exec/modules.html#grow-table}{\mathrm{growtable}}(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a], n, \href{../exec/runtime.html#syntax-val}{\mathit{val}})) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; \href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.grow}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\href{../exec/numerics.html#aux-signed}{\mathrm{signed}}_{32}^{-1}(-1)) \end{array} \end{array}\end{split}\]

Note

The \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.grow}}\) instruction is non-deterministic. It may either succeed, returning the old table size \(\mathit{sz}\), or fail, returning \({-1}\). Failure must occur if the referenced table instance has a maximum size defined that would be exceeded. However, failure can occur in other cases as well. In practice, the choice depends on the resources available to the embedder.

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.fill}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) exists.

  3. Let \(\mathit{ta}\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\) exists.

  5. Let \(\mathit{tab}\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\).

  6. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  7. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) from the stack.

  8. Assert: due to validation, a reference value is on the top of the stack.

  9. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

  10. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  11. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  12. If \(i + n\) is larger than the length of \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\), then:

    1. Trap.

  1. If \(n\) is \(0\), then:

    1. Return.

  2. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) to the stack.

  3. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

  4. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\).

  5. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(i+1)\) to the stack.

  6. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

  7. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) to the stack.

  8. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.fill}}~x\).

\[\begin{split}\begin{array}{l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.fill}}~x) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & i + n > |S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}|) \\[1ex] \end{array} \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.fill}}~x) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{otherwise}}) \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n+1)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.fill}}~x) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow} \\ \qquad S; F; \begin{array}[t]{@{}l@{}} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i+1)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.fill}}~x) \\ \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~x~y\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) exists.

  3. Let \(\mathit{ta}_x\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}_x]\) exists.

  5. Let \(\mathit{tab}_x\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}_x]\).

  6. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[y]\) exists.

  7. Let \(\mathit{ta}_y\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[y]\).

  8. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}_y]\) exists.

  9. Let \(\mathit{tab}_y\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}_y]\).

  10. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  11. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) from the stack.

  12. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  13. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) from the stack.

  14. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  15. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) from the stack.

  16. If \(s + n\) is larger than the length of \(\mathit{tab}_y.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\) or \(d + n\) is larger than the length of \(\mathit{tab}_x.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\), then:

    1. Trap.

  17. If \(n = 0\), then:

  1. Return.

  1. If \(d \leq s\), then:

  1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) to the stack.

  2. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) to the stack.

  3. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~y\).

  4. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\).

  5. Assert: due to the earlier check against the table size, \(d+1 < 2^{32}\).

  6. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\) to the stack.

  7. Assert: due to the earlier check against the table size, \(s+1 < 2^{32}\).

  8. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+1)\) to the stack.

  1. Else:

  1. Assert: due to the earlier check against the table size, \(d+n-1 < 2^{32}\).

  2. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+n-1)\) to the stack.

  3. Assert: due to the earlier check against the table size, \(s+n-1 < 2^{32}\).

  4. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+n-1)\) to the stack.

  1. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~y\).

  1. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\).

  2. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) to the stack.

  3. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) to the stack.

  1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) to the stack.

  2. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~x~y\).

\[\begin{split}~\\[-1ex] \begin{array}{l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~x~y) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & s + n > |S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[y]].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}| \\ \vee & d + n > |S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}|) \\[1ex] \end{array} \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~x~y) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{otherwise}}) \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n+1)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~x~y) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow} \\ \qquad S; F; \begin{array}[t]{@{}l@{}} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~y)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d+1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s+1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~x~y) \\ \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} d \leq s) \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n+1)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~x~y) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow} \\ \qquad S; F; \begin{array}[t]{@{}l@{}} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d+n)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s+n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~y)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~x~y) \\ \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} d > s) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}~x~y\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) exists.

  3. Let \(\mathit{ta}\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\) exists.

  5. Let \(\mathit{tab}\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\).

  6. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[y]\) exists.

  7. Let \(\mathit{ea}\) be the element address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[y]\).

  8. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[\mathit{ea}]\) exists.

  9. Let \(\mathit{elem}\) be the element instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[\mathit{ea}]\).

  10. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  11. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) from the stack.

  12. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  13. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) from the stack.

  14. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  15. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) from the stack.

  16. If \(s + n\) is larger than the length of \(\mathit{elem}.\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}\) or \(d + n\) is larger than the length of \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\), then:

    1. Trap.

  17. If \(n = 0\), then:

    1. Return.

  18. Let \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) be the reference value \(\mathit{elem}.\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}[s]\).

  19. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) to the stack.

  20. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

  21. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\).

  22. Assert: due to the earlier check against the table size, \(d+1 < 2^{32}\).

  23. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\) to the stack.

  24. Assert: due to the earlier check against the segment size, \(s+1 < 2^{32}\).

  25. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+1)\) to the stack.

  26. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) to the stack.

  27. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}~x~y\).

\[\begin{split}~\\[-1ex] \begin{array}{l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}~x~y) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & s + n > |S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[y]].\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}| \\ \vee & d + n > |S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}|) \\[1ex] \end{array} \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}~x~y) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{otherwise}}) \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n+1)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}~x~y) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow} \\ \qquad S; F; \begin{array}[t]{@{}l@{}} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d+1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s+1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}~x~y) \\ \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} \href{../exec/runtime.html#syntax-val}{\mathit{val}} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[y]].\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}[s]) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{elem.drop}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[x]\) exists.

  3. Let \(a\) be the element address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[a]\) exists.

  5. Replace \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[a].\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}\) with \(\epsilon\).

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{elem.drop}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad (\mathrel{\mbox{if}} S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[x]].\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}} = \epsilon) \\ \end{array}\end{split}\]

Memory Instructions

Note

The alignment \(\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}\) in load and store instructions does not affect the semantics. It is an indication that the offset \(\mathit{ea}\) at which the memory is accessed is intended to satisfy the property \(\mathit{ea} \mathbin{\mathrm{mod}} 2^{\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}} = 0\). A WebAssembly implementation can use this hint to optimize for the intended use. Unaligned access violating that property is still allowed and must succeed regardless of the annotation. However, it may be substantially slower on some hardware.

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\) and \(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) be \(\href{../exec/runtime.html#syntax-ord}{\mathsf{unord}}\).

  2. Let \(F\) be the current frame.

  3. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  4. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  5. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  6. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  7. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  8. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  9. Let \(\mathit{ea}\) be the integer \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  10. If \(N\) is not part of the instruction, then:

  1. Let \(N\) be the bit width \(|t|\) of number type \(t\).

  1. If both \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) is \(\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}\) and \(\mathit{ea}\) modulo \(N/8\) is not equal to \(0\), then:

  1. Trap.

  1. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

    2. Let \(b^\ast\) be the byte sequence \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\).

  2. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{notears}}^?\) be \(\href{../exec/relaxed.html#syntax-ord}{\mathrm{tearing}}(t, N, \mathit{ea})\).

    4. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast~\href{../exec/runtime.html#syntax-ord}{\mathit{notears}}^?)\) to read \(N/8\) bytes \(b^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

  3. Let \(c_{N}\) be the integer for which \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast\).

  4. Let \(c\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{N,|t|}(c_{N})\).

  5. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}({N}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}})^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & (\href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \vee \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0) \\ \wedge & c = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{N,|t|}(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}^{-1}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}({N}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}})^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}({N}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}})?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast~\href{../exec/runtime.html#syntax-ord}{\mathit{notears}}^?)}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & (\href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \vee \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0) \\ \wedge & c = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{N,|t|}(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}^{-1}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(b^\ast))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}({N}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}})^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + N/8 > n \vee \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}} \wedge \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0)) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \\ \wedge & N = |t| \mathrel{\mbox{if}} N~\mbox{not present} \\ \wedge & \mathit{sx} = \mathsf{u} \mathrel{\mbox{if}} \mathit{sx}~\mbox{not present} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \href{../exec/runtime.html#syntax-ord}{\mathit{notears}}^? = \href{../exec/relaxed.html#syntax-ord}{\mathrm{tearing}}(t, N, \mathit{ea})) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{M}\mathsf{x}N\_\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) be \(\href{../exec/runtime.html#syntax-ord}{\mathsf{unord}}\).

  2. Let \(F\) be the current frame.

  3. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  4. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  5. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  6. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  7. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  8. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  9. Let \(\mathit{ea}\) be the integer \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  10. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

  1. If \(\mathit{ea} + M \cdot N /8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

    1. Trap.

  2. Let \(b^\ast\) be the byte sequence \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} M \cdot N /8]\).

  1. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + M \cdot N/8\) is larger than \(n\), then:

      1. Trap.

    3. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)\) to read \(M \cdot N/8\) bytes \(b^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

  2. Let \(m_k\) be the integer for which \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}M}}(m_k) = b^\ast[k \cdot M/8 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} M/8]\).

  3. Let \(W\) be the integer \(M \cdot 2\).

  4. Let \(n_k\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{M,W}(m_k)\).

  5. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\mathsf{i}W\mathsf{x}N}(n_0 \dots n_{N-1})\).

  6. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{M}\mathsf{x}N\_\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + M \cdot N / 8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}M}}(m_k) = \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} + k \cdot M/8 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} M/8] \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\mathsf{i}W\mathsf{x}N}(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{M,W}(m_0) \dots \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{M,W}(m_{N-1}))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{M}\mathsf{x}N\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{M}\mathsf{x}N\_\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + M \cdot N / 8 \leq n \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}M}}(m_k) = b^\ast[k \cdot M/8 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} M/8] \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\mathsf{i}W\mathsf{x}N}(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{M,W}(m_0) \dots \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{M,W}(m_{N-1}))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{M}\mathsf{x}N\_\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + M \cdot N/8 > n) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & W = M \cdot 2) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_splat}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) be \(\href{../exec/runtime.html#syntax-ord}{\mathsf{unord}}\).

  2. Let \(F\) be the current frame.

  3. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  4. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  5. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  6. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  7. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  8. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  9. Let \(\mathit{ea}\) be the integer \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  10. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

  1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

    1. Trap.

  2. Let \(b^\ast\) be the byte sequence \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\).

  1. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)\) to read \(N/8\) bytes \(b^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

  2. Let \(n\) be the integer for which \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast\).

  3. Let \(L\) be the integer \(128 / N\).

  4. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(n^L)\).

  5. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_splat}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8] \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(n^L)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_splat}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_splat}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(n^L)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_splat}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + N/8 > n) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_zero}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) be \(\href{../exec/runtime.html#syntax-ord}{\mathsf{unord}}\).

  2. Let \(F\) be the current frame.

  3. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  4. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  5. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  6. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  7. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  8. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  9. Let \(\mathit{ea}\) be the integer \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  10. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

  1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

    1. Trap.

  2. Let \(b^\ast\) be the byte sequence \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\).

  1. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)\) to read \(N/8\) bytes \(b^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

  2. Let \(n\) be the integer for which \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast\).

  3. Let \(c\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}^{\mathsf{u}}}_{N,128}(n)\).

  4. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_zero}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8] \\ \wedge & c = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}^{\mathsf{u}}}_{N,128}(n)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_zero}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_zero}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast \\ \wedge & c = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}^{\mathsf{u}}}_{N,128}(n)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_zero}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + N/8 > n) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x\)

  1. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) be \(\href{../exec/runtime.html#syntax-ord}{\mathsf{unord}}\).

  2. Let \(F\) be the current frame.

  3. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  4. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  5. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  6. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  7. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  8. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~v\) from the stack.

  9. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  10. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  11. Let \(\mathit{ea}\) be the integer \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  12. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

    2. Let \(b^\ast\) be the byte sequence \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\).

  13. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)\) to read \(N/8\) bytes \(b^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

  14. Let \(r\) be the constant for which \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(r) = b^\ast\).

  15. Let \(L\) be \(128 / N\).

  16. Let \(j^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(v)\).

  17. Let \(c\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(j^\ast \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} [x] = r)\).

  18. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~v)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8] \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(v) \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} [x] = r)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~v)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~v)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast \\ \wedge & c = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(v) \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} [x] = r)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~v)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + N/8 > n) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}) \\ \wedge & L = 128/N \\ \end{array} \end{array}\end{split}\]

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\) and \(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}{N}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) be \(\href{../exec/runtime.html#syntax-ord}{\mathsf{unord}}\).

  2. Let \(F\) be the current frame.

  3. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  4. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  5. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  6. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  7. Assert: due to validation, a value of value type \(t\) is on the top of the stack.

  8. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) from the stack.

  9. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  10. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  11. Let \(\mathit{ea}\) be the integer \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  12. If \(N\) is not part of the instruction, then:

    1. Let \(N\) be the bit width \(|t|\) of number type \(t\).

  13. If both \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) is \(\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}\) and \(\mathit{ea}\) modulo \(N/8\) is not equal to \(0\), then:

  1. Trap.

  1. Let \(n\) be the result of computing \(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c)\).

  2. Let \(b^\ast\) be the byte sequence \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n)\).

  3. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

    2. Replace the bytes \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\) with \(b^\ast\).

  4. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{notears}}^?\) be \(\href{../exec/relaxed.html#syntax-ord}{\mathrm{tearing}}(t, N, \mathit{ea})\).

    4. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{wr}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast~\href{../exec/runtime.html#syntax-ord}{\mathit{notears}}^?)\) to write the bytes \(b^\ast\) to data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(t.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}} N^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & (\href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \vee \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0) \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]].\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8] = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(t.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}} N^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(t.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}} N^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{wr}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)~\href{../exec/runtime.html#syntax-ord}{\mathit{notears}}}& S; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & (\href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \vee \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0) \\ \wedge & b^\ast = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(t.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}} N^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + N/8 > n \vee \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}} \wedge \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0)) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \\ \wedge & N = |t| \mathrel{\mbox{if}} N~\mbox{not present} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \href{../exec/runtime.html#syntax-ord}{\mathit{notears}}^? = \href{../exec/relaxed.html#syntax-ord}{\mathrm{tearing}}(t, N, \mathit{ea})) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x\)

  1. Let \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}\) be \(\href{../exec/runtime.html#syntax-ord}{\mathsf{unord}}\).

  2. Let \(F\) be the current frame.

  3. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  4. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  5. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  6. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  7. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) is on the top of the stack.

  8. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) from the stack.

  9. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  10. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  11. Let \(\mathit{ea}\) be the integer \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  12. Let \(L\) be \(128/N\).

  13. Let \(j^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(c)\).

  14. Let \(b^\ast\) be the result of computing \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(j^\ast[x])\).

  15. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

    2. Replace the bytes \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\) with \(b^\ast\).

  16. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{wr}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)\) to write the bytes \(b^\ast\) to data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]].\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8] = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(c)[x])) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{wr}}_{\href{../exec/runtime.html#syntax-ord}{\mathit{ord}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)}& S; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & b^\ast = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(c)[x])) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}{N}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + N/8 > n \vee \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}} \wedge \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0)) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & \href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{unord}} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & L = 128/N) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.size}}\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  3. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  5. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  6. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. Let \(n\) be the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\).

  7. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

  8. Let \(\mathit{sz}\) be \(n\) divided by the page size.

  9. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.size}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| = \mathit{sz}\cdot64\,\mathrm{Ki} \end{array} \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.size}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & n = \mathit{sz} \cdot 64\,\mathrm{Ki}) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}}\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  3. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) exists.

  5. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  6. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  7. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) from the stack.

  8. Let \(\mathit{err}\) be the \(\href{../syntax/values.html#syntax-int}{\mathit{i32}}\) value \(2^{32}-1\), for which \(\href{../exec/numerics.html#aux-signed}{\mathrm{signed}}_{32}(\mathit{err})\) is \(-1\).

  9. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. Let \(\mathit{sz}\) be the length of \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) divided by the page size.

    2. Either, try growing \(\mathit{mem}\) by \(n\) pages:

      1. If it succeeds, push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) to the stack.

      2. Else, push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) to the stack.

    3. Or, push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) to the stack.

  10. Else:

  1. Either successfully grow the memory:

    1. Let \(k\) be \(n\) multiplied by the page size.

    2. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rmw}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l~(l+k))\) to update the current length \(l\) of the shared memory instance at memory address \(a\) to \(l+k\).

    3. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{wr}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[l]~(0)^k)\) to append \(k\) zero bytes to the end of the shared memory instance at memory address \(a\).

    4. Let \(\mathit{sz}\) be \(l\) divided by the page size.

    5. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) to the stack.

  2. Or indicate failure:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l)\) to read the length \(l\) of the shared memory instance at memory address \(a\).

    2. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) to the stack.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{sz} = |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| / 64\,\mathrm{Ki} \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] = \href{../exec/modules.html#grow-mem}{\mathrm{growmem}}(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a], n)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\href{../exec/numerics.html#aux-signed}{\mathrm{signed}}_{32}^{-1}(-1)) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ \end{array} \\ % \\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rmw}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l~(l+k))~(\href{../exec/runtime.html#syntax-act}{\mathsf{wr}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[l]~(0)^k)}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{sz} = l / 64\,\mathrm{Ki} \\ \wedge & n = k / 64\,\mathrm{Ki}) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~{-1}) \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}}) \\ \end{array} \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]) \\ \end{array} \end{array}\end{split}\]

Note

The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}}\) instruction is non-deterministic, even on unshared memories. It may either succeed, returning the old memory size \(\mathit{sz}\), or fail, returning \({-1}\). Failure must occur if the referenced memory instance has a maximum size defined that would be exceeded. However, failure can occur in other cases as well. In practice, the choice depends on the resources available to the embedder.

\(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.fill}}\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  3. Let \(\mathit{ma}\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\) exists.

  5. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\).

  6. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  7. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) from the stack.

  8. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  9. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

  10. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  11. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) from the stack.

  12. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(d + n\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

  13. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l)\) to read the length \(l\) of the shared memory instance at memory address \(a\).

    2. If \(d + n\) is larger than \(l\), then:

      1. Trap.

  14. If \(n = 0\), then:

    1. Return.

  15. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) to the stack.

  16. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

  17. Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}\).

  18. Assert: due to the earlier check against the memory size, \(d+1 < 2^{32}\).

  19. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\) to the stack.

  20. Push the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) to the stack.

  21. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) to the stack.

  22. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.fill}}\).

\[\begin{split}~\\[-1ex] \begin{array}{l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.fill}} \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act} \quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & d + n > l \end{array} \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.fill}} \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act} \quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{otherwise}}) \\ \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n+1)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.fill}} \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act} \\ \qquad S; F; \begin{array}[t]{@{}l@{}} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d+1)~\href{../exec/runtime.html#syntax-val}{\mathit{val}}~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.fill}} \\ \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}) \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & ((\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \wedge l = |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \wedge \mathit{act} = \epsilon) \vee (\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \wedge \mathit{act} = (\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l))) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}}\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  3. Let \(\mathit{ma}\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\) exists.

  5. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\).

  6. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  7. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) from the stack.

  8. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  9. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) from the stack.

  10. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  11. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) from the stack.

  12. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(s + n\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) or \(d + n\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

  13. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l)\) to read the length \(l\) of the shared memory instance at memory address \(a\).

    1. If \(s + n\) is larger than \(l\) or \(d + n\) is larger than \(l\), then:

      1. Trap.

  14. If \(n = 0\), then:

  1. Return.

  1. If \(d \leq s\), then:

  1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) to the stack.

  2. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) to the stack.

  3. Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{8\_u}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}\).

  4. Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}\).

  5. Assert: due to the earlier check against the memory size, \(d+1 < 2^{32}\).

  6. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\) to the stack.

  7. Assert: due to the earlier check against the memory size, \(s+1 < 2^{32}\).

  8. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+1)\) to the stack.

  1. Else:

  1. Assert: due to the earlier check against the memory size, \(d+n-1 < 2^{32}\).

  2. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+n-1)\) to the stack.

  3. Assert: due to the earlier check against the memory size, \(s+n-1 < 2^{32}\).

  4. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+n-1)\) to the stack.

  5. Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{8\_u}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}\).

  6. Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}\).

  7. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) to the stack.

  8. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) to the stack.

  1. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) to the stack.

  2. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}}\).

\[\begin{split}~\\[-1ex] \begin{array}{l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}} \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & (s + n > l \\ \vee & d + n > l)) \\[1ex] \end{array} \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}} \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{otherwise}}) \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n+1)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}} \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act} \\ \qquad S; F; \begin{array}[t]{@{}l@{}} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{8\_u}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d+1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s+1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}} \\ \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}) \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n+1)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}} \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act} \\ \qquad S; F; \begin{array}[t]{@{}l@{}} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d+n) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s+n)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{8\_u}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}} \\ \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}) \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & ((\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \wedge l = |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \wedge \mathit{act} = \epsilon) \vee (\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \wedge \mathit{act} = (\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l))) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  3. Let \(\mathit{ma}\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\) exists.

  5. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\).

  6. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]\) exists.

  7. Let \(\mathit{da}\) be the data address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]\).

  8. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[\mathit{da}]\) exists.

  9. Let \(\mathit{data}\) be the data instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[\mathit{da}]\).

  10. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  11. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) from the stack.

  12. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  13. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\) from the stack.

  14. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  15. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) from the stack.

  16. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(s + n\) is larger than the length of \(\mathit{data}.\href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}\) or \(d + n\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

  17. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l)\) to read the length \(l\) of the shared memory instance at memory address \(a\).

    1. If \(s + n\) is larger than the length of \(\mathit{data}.\href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}\) or \(d + n\) is larger than \(l\), then:

      1. Trap.

  18. If \(n = 0\), then:

    1. Return.

  19. Let \(b\) be the byte \(\mathit{data}.\href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}[s]\).

  20. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\) to the stack.

  21. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~b\) to the stack.

  22. Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}\).

  23. Assert: due to the earlier check against the memory size, \(d+1 < 2^{32}\).

  24. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\) to the stack.

  25. Assert: due to the earlier check against the memory size, \(s+1 < 2^{32}\).

  26. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+1)\) to the stack.

  27. Push the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) to the stack.

  28. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}~x\).

\[\begin{split}~\\[-1ex] \begin{array}{l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}~x) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & (s + n > |S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]].\href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}| \\ \vee & d + n > l)) \\[1ex] \end{array} \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0)~(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}~x) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{otherwise}}) \\[1ex] S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n+1)~(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}~x) \quad\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^\mathit{act} \\ \qquad S; F; \begin{array}[t]{@{}l@{}} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~b)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~0, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~0 \}) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d+1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s+1)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n)~(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}~x) \\ \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}, \mathrel{\mbox{if}} b = S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]].\href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}[s]) \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & ((\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \wedge l = |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \wedge \mathit{act} = \epsilon) \vee (\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \wedge \mathit{act} = (\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~l))) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{data.drop}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]\) exists.

  3. Let \(a\) be the data address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[a]\) exists.

  5. Replace \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[a]\) with the data instance \(\{\href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}~\epsilon\}\).

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{data.drop}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad (\mathrel{\mbox{if}} S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]] = \{ \href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}~\epsilon \}) \\ \end{array}\end{split}\]

Atomic Memory Instructions

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.load}}({N}\mathsf{\_u})^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

The rules are identical to non-atomic loads, except that \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}\).

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.store}}{N}^?~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

The rules are identical to non-atomic stores, except that \(\href{../exec/runtime.html#syntax-ord}{\mathit{ord}} = \href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}\).

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?\mathsf{.}\href{../syntax/instructions.html#syntax-atop}{\mathit{atop}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. If \(N\) is not part of the instruction, then:

    1. Let \(N\) be the bit width \(|t|\) of value type \(t\).

  1. Assert: due to validation, a value of value type \(t\) is on the top of the stack.

  2. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\) from the stack.

  3. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  4. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  5. Let \(\mathit{ea}\) be \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  6. If \(\mathit{ea}\) modulo \(N/8\) is not equal to \(0\), then:

    1. Trap.

  7. Let \(F\) be the current frame.

  8. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  9. Let \(\mathit{a}\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  10. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{a}]\) exists.

  11. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{a}]\).

  12. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

    2. Let \(b^\ast_{\mathrm{r}}\) be the byte sequence \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\).

  1. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Let \(b_{\mathrm{r}}^\ast\) be chosen to represent \(N/8\) bytes of memory at location \(\mathit{ea}\) of \(\mathit{mem}\).

  2. Let \(c_{\mathrm{r}}\) be the integer for which \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b_{\mathrm{r}}^\ast\).

  3. Let \(c_1\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\mathsf{u}}_{N,|t|}(c_{\mathrm{r}})\).

  4. Let \(c\) be the result of computing \(\href{../syntax/instructions.html#syntax-atop}{\mathit{atop}}_t(c_1, c_2)\).

  5. Let \(c_{\mathrm{w}}\) be the result of computing \(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c)\).

  6. Let \(b^\ast_{\mathrm{w}}\) be the byte sequence \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(c_{\mathrm{w}})\).

  7. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. Replace the bytes \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\) with \(b^\ast_{\mathrm{w}}\).

  1. Else:

    1. Perform the atomic action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rmw}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b_{\mathrm{r}}^\ast~b_{\mathrm{w}}^\ast)\) to read \(N/8\) bytes \(b_{\mathrm{r}}^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\) and replace them with bytes \(b_{\mathrm{w}}^\ast\).

  1. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-atop}{\mathit{atop}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0 \\ \wedge & c_1 = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\mathsf{u}}_{N,|t|}(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}^{-1}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8])) \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a].\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8] = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(\href{../syntax/instructions.html#syntax-atop}{\mathit{atop}}_t(c_1, c_2)))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-atop}{\mathit{atop}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 > |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \vee \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0) \\ \end{array} \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-atop}{\mathit{atop}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rmw}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b_{\mathrm{r}}^\ast~b_{\mathrm{w}}^\ast)}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0 \\ \wedge & c_1 = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\mathsf{u}}_{N,|t|}(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}^{-1}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(b_{\mathrm{r}}^\ast)) \\ \wedge & b_{\mathrm{w}}^\ast = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(\href{../syntax/instructions.html#syntax-atop}{\mathit{atop}}_t(c_1, c_2)))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-atop}{\mathit{atop}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 > n \vee \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & N = |t| \mathrel{\mbox{if}} N~\mbox{not present} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}) \\ \end{array} \end{array}\end{split}\]

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?\mathsf{.}\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{cmpxchg}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. If \(N\) is not part of the instruction, then:

    1. Let \(N\) be the bit width \(|t|\) of value type \(t\).

  1. Assert: due to validation, two values of value type \(t\) are on the top of the stack.

  2. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_3\) from the stack.

  3. Pop the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\) from the stack.

  4. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  5. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  6. Let \(\mathit{ea}\) be \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  7. If \(\mathit{ea}\) modulo \(N/8\) is not equal to \(0\), then:

    1. Trap.

  8. Let \(F\) be the current frame.

  9. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  10. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  11. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  12. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

    2. Let \(b^\ast_{\mathrm{r}}\) be the byte sequence \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\).

  13. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Let \(b_{\mathrm{r}}^\ast\) be chosen to represent \(N/8\) bytes of memory at location \(\mathit{ea}\) of \(\mathit{mem}\).

  14. Let \(c_{\mathrm{r}}\) be the integer for which \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b_{\mathrm{r}}^\ast\).

  15. Let \(c_{\mathrm{ex}}\) be the result of computing \(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c_2)\).

  16. If \(c_{\mathrm{r}}\) equals \(c_{\mathrm{ex}}\), then:

    1. Let \(c_{\mathrm{w}}\) be the result of computing \(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c_3)\).

    2. Let \(b^\ast_{\mathrm{w}}\) be the byte sequence \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(c_{\mathrm{w}})\).

    3. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

      1. Replace the bytes \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\) with \(b^\ast_{\mathrm{w}}\).

    4. Else:

      1. Perform the atomic action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rmw}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b_{\mathrm{r}}^\ast~b_{\mathrm{w}}^\ast)\) to read \(N/8\) bytes \(b_{\mathrm{r}}^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\) and replace them with bytes \(b_{\mathrm{w}}^\ast\).

  17. Else:

    1. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}}\), then:

      1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b_{\mathrm{r}}^\ast)\) to read \(N/8\) bytes \(b_{\mathrm{r}}^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

  18. Let \(c_1\) be the result of computing \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\mathsf{u}}_{N,|t|}(c_{\mathrm{r}})\).

  19. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_3)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{cmpxchg}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\mathsf{u}}_{N,|t|}(c_{\mathrm{r}}))) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0 \\ \wedge & c_{\mathrm{r}} = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}^{-1}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]) \\ \wedge & c_{\mathrm{ex}} = \href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c_2) \\ \wedge & ((c_{\mathrm{r}} = c_{\mathrm{ex}} \wedge c = \href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c_3)) \vee (c_{\mathrm{r}} \neq c_{\mathrm{ex}} \wedge c = c_{\mathrm{r}})) \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{with}}} \href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a].\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8] = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(c)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_3)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{cmpxchg}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 > |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \vee \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0) \\ \end{array} \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_3)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{cmpxchg}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rmw}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b_{\mathrm{r}}^\ast~b_{\mathrm{w}}^\ast)}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0 \\ \wedge & c_{\mathrm{r}} = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}^{-1}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(b_{\mathrm{r}}^\ast) \\ \wedge & c_{\mathrm{ex}} = \href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c_2) \\ \wedge & c_{\mathrm{r}} = c_{\mathrm{ex}} \\ \wedge & b_{\mathrm{w}}^\ast = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c_3))) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_3)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{cmpxchg}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b_{\mathrm{r}}^\ast)}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0 \\ \wedge & c_{\mathrm{r}} = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}^{-1}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(b_{\mathrm{r}}^\ast) \\ \wedge & c_{\mathrm{ex}} = \href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c_2) \\ \wedge & c_{\mathrm{r}} \neq c_{\mathrm{ex}} \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2)~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_3)~(t.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.rmw}}({N}\mathsf{\_u})^?.\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{cmpxchg}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 > n \vee \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & N = |t| \mathrel{\mbox{if}} N~\mbox{not present} \\ \wedge & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.notify}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. Let \(N\) be 32.

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k\) from the stack.

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  3. Let \(\mathit{ea}\) be \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  4. If \(\mathit{ea}\) modulo \(N/8\) is not equal to \(0\), then:

    1. Trap.

  5. Let \(F\) be the current frame.

  6. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  7. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  8. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  9. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. If \(\mathit{ea} + N/8\) is larger than the length of \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:

      1. Trap.

    2. Else:

      1. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0\) to the stack.

  10. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Else:

      1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{notify}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~n~k)\) to notify \(n\) threads (up to \(k\)) waiting at data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

      2. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.notify}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & \mathit{ea} + N/8 \leq |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.notify}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}} \\ \wedge & (\mathit{ea} + N/8 > |\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}| ~\vee~ \mathit{ea} \mathbin{\mathrm{mod}}~N/8 \neq 0)) \\ \end{array} \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.notify}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} && \\ \qquad\qquad \href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{notify}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~j~k)} \quad S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~j) && \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & j \leq k \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.notify}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + N/8 > n ~\vee~ \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0)) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & N = 32) \\ \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.wait}}{N}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i64}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i64}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k\) from the stack.

  1. Assert: due to validation, a value of value type \(\href{../syntax/values.html#syntax-int}{\mathit{i}N}\) is on the top of the stack.

  1. Pop the value \(\href{../syntax/values.html#syntax-int}{\mathit{i}N}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) from the stack.

  2. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  3. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  4. Let \(\mathit{ea}\) be \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\).

  5. If \(\mathit{ea}\) modulo \(N/8\) is not equal to \(0\), then:

    1. Trap.

  6. Let \(F\) be the current frame.

  7. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) exists.

  8. Let \(a\) be the memory address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\).

  9. Let \(\mathit{mem}\) be the memory instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\).

  10. If \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) is \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}\), then:

    1. Trap.

  11. Else:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)\) to read the length \(n\) of the shared memory instance at memory address \(a\).

    2. If \(\mathit{ea} + N/8\) is larger than \(n\), then:

      1. Trap.

    3. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)\) to read \(N/8\) bytes \(b^\ast\) from data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

    4. If \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(c)\) is equal to \(b^\ast\) then:

      1. Let \(t\) be \(\href{../exec/numerics.html#aux-signed}{\mathrm{signed}}_{N}(k)\).

      2. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{wait}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~t)\) to register the current thread as waiting for a signal at data offset \(\mathit{ea}\) of the shared memory instance at memory address \(a\).

      3. Execute the instruction \(\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{wait'}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~k\).

    5. Else:

      1. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~1\) to the stack.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/values.html#syntax-int}{\mathit{i}N}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i64}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.wait}}{N}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} && \\ \qquad\qquad \href{../exec/conventions.html#formal-notation}{\hookrightarrow} \quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} && \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{unshared}}) \\ \end{array} \\ % ~\\ \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/values.html#syntax-int}{\mathit{i}N}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i64}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.wait}}{N}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} &&\\ \qquad\qquad \href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)~(\href{../exec/runtime.html#syntax-act}{\mathsf{wait}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~t)} \quad S; F; (\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{wait'}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~k) && \\ \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0 \\ \wedge & b^\ast = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(c))\\ \wedge & t = \href{../exec/numerics.html#aux-signed}{\mathrm{signed}}_{N}(k) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/values.html#syntax-int}{\mathit{i}N}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i64}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.wait}}{N}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} &&\\ \qquad\qquad \href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)~(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{data}}[\mathit{ea}]~b^\ast)} \quad S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~1) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & \mathit{ea} + N/8 \leq n \\ \wedge & \mathit{ea} \mathbin{\mathrm{mod}} N/8 = 0 \\ \wedge & b^\ast \neq \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(c)) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/values.html#syntax-int}{\mathit{i}N}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/types.html#syntax-valtype}{\mathsf{i64}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~k)~\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{memory.atomic.wait}}{N}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} &&\\ \qquad\qquad \href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{rd}}~a.\href{../exec/runtime.html#syntax-loc}{\mathsf{len}}~n)} \quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}} = \href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-memtype}{\mathsf{shared}} \\ \wedge & (\mathit{ea} + N/8 > n ~\vee~ \mathit{ea} \mathbin{\mathrm{mod}} N/8 \neq 0)) \\ \end{array} \\ % ~\\ \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{where}} & a = F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] \\ \wedge & \mathit{mem} = S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a] \\ \wedge & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}) \\ \end{array} \end{array}\end{split}\]

\(\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{wait'}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}}~n\)

  1. Either the thread has been notified by an \((\href{../exec/runtime.html#syntax-act}{\mathsf{notify}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}})\) action performed in another thread:

    1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{woken}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}})\).

    2. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0\) to the stack.

  2. Or:

    1. If \(n\) is less than \(0\):

      1. The thread remains suspended.

    2. Else:

      1. Either the thread’s suspension times out:

        1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{timeout}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}})\).

        2. Push the value \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~2\) to the stack.

      2. Or the thread remains suspended.

\[\begin{split}\begin{array}{l} \begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-instr-admin}{\mathsf{wait'}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}}~n &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{woken}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}})}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0) \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-instr-admin}{\mathsf{wait'}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}}~n &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{timeout}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}})}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~2) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & n \geq 0) \\ \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-instr-admin}{\mathsf{wait'}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}}~n &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-instr-admin}{\mathsf{wait'}}~\href{../exec/runtime.html#syntax-loc}{\mathit{loc}}~n \end{array} \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.fence}}\)

  1. Perform the action \((\href{../exec/runtime.html#syntax-act}{\mathsf{fence}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}})\).

\[\begin{array}{l} \begin{array}{lcl@{\qquad}l} \href{../syntax/instructions.html#syntax-instr-atomic-memory}{\mathsf{atomic.fence}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{(\href{../exec/runtime.html#syntax-act}{\mathsf{fence}}_{\href{../exec/runtime.html#syntax-ord}{\mathsf{seqcst}}})}& \epsilon \end{array} \end{array}\]

Control Instructions

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

  1. Do nothing.

\[\begin{array}{lcl@{\qquad}l} \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{nop}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \epsilon \end{array}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{unreachable}}\)

  1. Trap.

\[\begin{array}{lcl@{\qquad}l} \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{unreachable}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\) is defined.

  3. Let \([t_1^m] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^n]\) be the function type \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\).

  4. Let \(L\) be the label whose arity is \(n\) and whose continuation is the end of the block.

  5. Assert: due to validation, there are at least \(m\) values on the top of the stack.

  6. Pop the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\) from the stack.

  7. Enter the block \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) with label \(L\).

\[\begin{split}~\\[-1ex] \begin{array}{lcl} F; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}~\mathit{bt}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& F; \href{../exec/runtime.html#syntax-label}{\mathsf{label}}_n\{\epsilon\}~\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&\quad (\mathrel{\mbox{if}} \href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\mathit{bt}) = [t_1^m] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^n]) \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\) is defined.

  3. Let \([t_1^m] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^n]\) be the function type \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\).

  4. Let \(L\) be the label whose arity is \(m\) and whose continuation is the start of the loop.

  5. Assert: due to validation, there are at least \(m\) values on the top of the stack.

  6. Pop the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\) from the stack.

  7. Enter the block \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) with label \(L\).

\[\begin{split}~\\[-1ex] \begin{array}{lcl} F; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}~\mathit{bt}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& F; \href{../exec/runtime.html#syntax-label}{\mathsf{label}}_m\{\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}~\mathit{bt}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\}~\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&\quad (\mathrel{\mbox{if}} \href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\mathit{bt}) = [t_1^m] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^n]) \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_1^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{else}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_2^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) from the stack.

  3. If \(c\) is non-zero, then:

    1. Execute the block instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_1^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\).

  4. Else:

    1. Execute the block instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_2^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\).

\[\begin{split}~\\[-1ex] \begin{array}{lcl} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}~\mathit{bt}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_1^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{else}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_2^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}~\mathit{bt}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_1^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&\quad (\mathrel{\mbox{if}} c \neq 0) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}~\mathit{bt}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_1^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{else}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_2^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}~\mathit{bt}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}_2^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&\quad (\mathrel{\mbox{if}} c = 0) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l\)

  1. Assert: due to validation, the stack contains at least \(l+1\) labels.

  2. Let \(L\) be the \(l\)-th label appearing on the stack, starting from the top and counting from zero.

  3. Let \(n\) be the arity of \(L\).

  4. Assert: due to validation, there are at least \(n\) values on the top of the stack.

  5. Pop the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) from the stack.

  6. Repeat \(l+1\) times:

    1. While the top of the stack is a value, do:

      1. Pop the value from the stack.

    2. Assert: due to validation, the top of the stack now is a label.

    3. Pop the label from the stack.

  7. Push the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) to the stack.

  8. Jump to the continuation of \(L\).

\[\begin{split}~\\[-1ex] \begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-label}{\mathsf{label}}_n\{\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\}~\href{../exec/runtime.html#syntax-ctxt-block}{B}^l[\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l)]~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_if}}~l\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) from the stack.

  3. If \(c\) is non-zero, then:

    1. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l\).

  4. Else:

    1. Do nothing.

\[\begin{split}~\\[-1ex] \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_if}}~l) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l) & (\mathrel{\mbox{if}} c \neq 0) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c)~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_if}}~l) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \epsilon & (\mathrel{\mbox{if}} c = 0) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_table}}~l^\ast~l_N\)

  1. Assert: due to validation, a value of value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  2. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  3. If \(i\) is smaller than the length of \(l^\ast\), then:

    1. Let \(l_i\) be the label \(l^\ast[i]\).

    2. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l_i\).

  4. Else:

    1. Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l_N\).

\[\begin{split}~\\[-1ex] \begin{array}{lcl@{\qquad}l} (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_table}}~l^\ast~l_N) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l_i) & (\mathrel{\mbox{if}} l^\ast[i] = l_i) \\ (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_table}}~l^\ast~l_N) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& (\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l_N) & (\mathrel{\mbox{if}} |l^\ast| \leq i) \\ \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return}}\)

  1. Let \(F\) be the current frame.

  2. Let \(n\) be the arity of \(F\).

  3. Assert: due to validation, there are at least \(n\) values on the top of the stack.

  4. Pop the results \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) from the stack.

  5. Assert: due to validation, the stack contains at least one frame.

  6. While the top of the stack is not a frame, do:

    1. Pop the top element from the stack.

  7. Assert: the top of the stack is the frame \(F\).

  8. Pop the frame from the stack.

  9. Push \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) to the stack.

  10. Jump to the instruction after the original call that pushed the frame.

\[\begin{split}~\\[-1ex] \begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-frame}{\mathsf{frame}}_n\{F\}~\href{../exec/runtime.html#syntax-ctxt-block}{B}^k[\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return}}]~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n \end{array}\end{split}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call}}~x\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]\) exists.

  3. Let \(a\) be the function address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]\).

  4. Invoke the function instance at address \(a\).

\[\begin{array}{lcl@{\qquad}l} F; (\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call}}~x) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& F; (\href{../exec/runtime.html#syntax-invoke}{\mathsf{invoke}}~a) & (\mathrel{\mbox{if}} F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x] = a) \end{array}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}~x~y\)

  1. Let \(F\) be the current frame.

  2. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) exists.

  3. Let \(\mathit{ta}\) be the table address \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\).

  4. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\) exists.

  5. Let \(\mathit{tab}\) be the table instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\).

  6. Assert: due to validation, \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{types}}[y]\) exists.

  7. Let \(\mathit{ft}_{\mathrm{expect}}\) be the function type \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{types}}[y]\).

  8. Assert: due to validation, a value with value type \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) is on the top of the stack.

  9. Pop the value \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) from the stack.

  10. If \(i\) is not smaller than the length of \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\), then:

    1. Trap.

  11. Let \(r\) be the reference \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[i]\).

  12. If \(r\) is \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t\), then:

    1. Trap.

  13. Assert: due to validation of table mutation, \(r\) is a function reference.

  14. Let \(\href{../exec/runtime.html#syntax-ref}{\mathsf{ref}}~a\) be the function reference \(r\).

  15. Assert: due to validation of table mutation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\) exists.

  16. Let \(\mathit{f}\) be the function instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\).

  17. Let \(\mathit{ft}_{\mathrm{actual}}\) be the function type \(\mathit{f}.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}\).

  18. If \(\mathit{ft}_{\mathrm{actual}}\) and \(\mathit{ft}_{\mathrm{expect}}\) differ, then:

    1. Trap.

  19. Invoke the function instance at address \(a\).

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}~x~y) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; (\href{../exec/runtime.html#syntax-invoke}{\mathsf{invoke}}~a) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[i] = \href{../exec/runtime.html#syntax-ref}{\mathsf{ref}}~a \\ \wedge & S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a] = f \\ \wedge & F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{types}}[y] = f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}) \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i)~(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}~x~y) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}) \end{array}\end{split}\]

Blocks

The following auxiliary rules define the semantics of executing an instruction sequence that forms a block.

Entering \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) with label \(L\)

  1. Push \(L\) to the stack.

  2. Jump to the start of the instruction sequence \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\).

Note

No formal reduction rule is needed for entering an instruction sequence, because the label \(L\) is embedded in the administrative instruction that structured control instructions reduce to directly.

Exiting \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) with label \(L\)

When the end of a block is reached without a jump or trap aborting it, then the following steps are performed.

  1. Pop all values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) from the top of the stack.

  2. Assert: due to validation, the label \(L\) is now on the top of the stack.

  3. Pop the label from the stack.

  4. Push \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) back to the stack.

  5. Jump to the position after the \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) of the structured control instruction associated with the label \(L\).

\[\begin{split}~\\[-1ex] \begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-label}{\mathsf{label}}_n\{\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\}~\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast \end{array}\end{split}\]

Note

This semantics also applies to the instruction sequence contained in a \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}\) instruction. Therefore, execution of a loop falls off the end, unless a backwards branch is performed explicitly.

Function Calls

The following auxiliary rules define the semantics of invoking a function instance through one of the call instructions and returning from it.

Invocation of function address \(a\)

  1. Assert: due to validation, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\) exists.

  2. Let \(f\) be the function instance, \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\).

  3. Let \([t_1^n] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^m]\) be the function type \(f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}\).

  4. Let \(t^\ast\) be the list of value types \(f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{code}}.\href{../syntax/modules.html#syntax-func}{\mathsf{locals}}\).

  5. Let \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) be the expression \(f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{code}}.\href{../syntax/modules.html#syntax-func}{\mathsf{body}}\).

  6. Assert: due to validation, \(n\) values are on the top of the stack.

  7. Pop the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) from the stack.

  8. Let \(F\) be the frame \(\{ \href{../exec/runtime.html#syntax-frame}{\mathsf{module}}~f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{module}}, \href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}~\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~(\href{../exec/runtime.html#default-val}{\mathrm{default}}_t)^\ast \}\).

  9. Push the activation of \(F\) with arity \(m\) to the stack.

  10. Let \(L\) be the label whose arity is \(m\) and whose continuation is the end of the function.

  11. Enter the instruction sequence \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) with label \(L\).

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~(\href{../exec/runtime.html#syntax-invoke}{\mathsf{invoke}}~a) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; \href{../exec/runtime.html#syntax-frame}{\mathsf{frame}}_m\{F\}~\href{../exec/runtime.html#syntax-label}{\mathsf{label}}_m\{\}~\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{end}} \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a] = f \\ \wedge & f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}} = [t_1^n] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^m] \\ \wedge & f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{code}} = \{ \href{../syntax/modules.html#syntax-func}{\mathsf{type}}~x, \href{../syntax/modules.html#syntax-func}{\mathsf{locals}}~t^k, \href{../syntax/modules.html#syntax-func}{\mathsf{body}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \} \\ \wedge & F = \{ \href{../exec/runtime.html#syntax-frame}{\mathsf{module}}~f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{module}}, ~\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}~\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~(\href{../exec/runtime.html#default-val}{\mathrm{default}}_t)^k \}) \end{array} \\ \end{array}\end{split}\]

Returning from a function

When the end of a function is reached without a jump (i.e., \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return}}\)) or trap aborting it, then the following steps are performed.

  1. Let \(F\) be the current frame.

  2. Let \(n\) be the arity of the activation of \(F\).

  3. Assert: due to validation, there are \(n\) values on the top of the stack.

  4. Pop the results \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) from the stack.

  5. Assert: due to validation, the frame \(F\) is now on the top of the stack.

  6. Pop the frame from the stack.

  7. Push \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) back to the stack.

  8. Jump to the instruction after the original call.

\[\begin{split}~\\[-1ex] \begin{array}{lcl@{\qquad}l} \href{../exec/runtime.html#syntax-frame}{\mathsf{frame}}_n\{F\}~\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n \end{array}\end{split}\]

Host Functions

Invoking a host function has non-deterministic behavior. It may either terminate with a trap or return regularly. However, in the latter case, it must consume and produce the right number and types of WebAssembly values on the stack, according to its function type.

A host function may also modify the store. However, all store modifications must result in an extension of the original store, i.e., they must only modify mutable contents and must not have instances removed. Furthermore, the resulting store must be valid, i.e., all data and code in it is well-typed.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~(\href{../exec/runtime.html#syntax-invoke}{\mathsf{invoke}}~a) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; \href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t_2^m] \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a] = \{ \href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}~[t_1^n] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^m], \href{../exec/runtime.html#syntax-funcinst}{\mathsf{hostcode}}~\mathit{hf} \} \\ \end{array} \\ \end{array}\end{split}\]

During its execution, a host function call may do any of the following.

  • Instantiate an arbitrary WebAssembly module.

  • Allocate a new host function.

  • Continue execution, possibly spawning a new thread, with no other observable effects.

  • Terminate with a list of values that respects the host function’s type annotation.

  • Terminate with a trap.

\[\begin{split}~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} S; F; (\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t^\ast]) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; (\href{../exec/runtime.html#syntax-frame}{\mathsf{frame}}_0\{F_0\}~e^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}})~(\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t^\ast]) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \href{../exec/modules.html#exec-instantiation}{\mathrm{instantiate}}(S, \href{../syntax/modules.html#syntax-module}{\mathit{module}}, \href{../exec/runtime.html#syntax-externval}{\mathit{externval}}^k) = S'; F_0; e^\ast) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t^\ast]) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S'; F; (\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t^\ast]) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & \href{../exec/modules.html#alloc-hostfunc}{\mathrm{allochostfunc}}(S, \href{../syntax/types.html#syntax-functype}{\mathit{functype}}, \href{../exec/runtime.html#syntax-hostfunc}{\mathit{hostfunc}}) = S', \href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t^\ast]) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{\href{../exec/runtime.html#syntax-act}{\mathsf{spawn}}^?}& S; F; (\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t^\ast]) \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t^\ast]) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{if}} & S \href{../appendix/properties.html#valid-result}{\vdash} \href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast : [t^\ast]) \\[1ex] \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\href{../exec/runtime.html#syntax-instr-admin}{\mathsf{host}}~[t^\ast]) &\href{../exec/conventions.html#formal-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \end{array}\end{split}\]

Note

A host function can call back into WebAssembly by invoking a function exported from a module. However, the effects of any such call are subsumed by the non-deterministic behavior allowed for the host function.

Expressions

An expression is evaluated relative to a current frame pointing to its containing module instance.

  1. Jump to the start of the instruction sequence \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) of the expression.

  2. Execute the instruction sequence.

  3. Assert: due to validation, the top of the stack contains a value.

  4. Pop the value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) from the stack.

The value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) is the result of the evaluation.

\[S; F; \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast \href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{\href{../exec/runtime.html#syntax-act}{\mathit{act}}^\ast} S'; F'; \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}'^\ast \qquad (\mathrel{\mbox{if}} S; F; \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \href{../exec/conventions.html#formal-notation}{\hookrightarrow}^{\href{../exec/runtime.html#syntax-act}{\mathit{act}}^\ast} S'; F'; \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}'^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}})\]

Note

Evaluation iterates this reduction rule until reaching a value. Expressions constituting function bodies are executed during function invocation.