指令

WebAssembly 计算通过执行单独的指令来完成。

数值指令

数值指令根据通用数值运算符定义。数值指令与其底层运算符的映射由以下定义表示

\[\begin{split}\begin{array}{lll@{\qquad}l} \mathit{op}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}}(i_1,\dots,i_k) &=& \href{../exec/numerics.html#int-ops}{\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) &=& \href{../exec/numerics.html#float-ops}{\mathrm{f}\mathit{op}}_N(z_1,\dots,z_k) \\ \end{array}\end{split}\]

以及对于转换运算符

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

当底层运算符为部分运算符时,如果结果未定义,则相应的指令将陷入陷阱。当底层运算符为非确定性运算符时,因为它们可能返回多个可能的NaN值,相应的指令也是如此。

注意

例如,指令\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}\)应用于操作数\(i_1, i_2\)将调用\(\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}}(i_1, i_2)\),通过上述定义映射到通用\(\href{../exec/numerics.html#op-iadd}{\mathrm{iadd}}_{32}(i_1, i_2)\)。类似地,\(\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}\)应用于\(z\)将调用\(\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)\),映射到通用\(\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. 将值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)推入栈。

注意

此指令不需要正式的归约规则,因为\(\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}\)指令本身就是

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

  1. 断言:由于验证,栈顶有一个值类型\(t\)的值。

  2. 从栈顶弹出值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\)

  3. 如果\(\href{../exec/instructions.html#exec-instr-numeric}{\mathit{unop}}_t(c_1)\)已定义,则

    1. \(c\)为计算\(\href{../exec/instructions.html#exec-instr-numeric}{\mathit{unop}}_t(c_1)\)的可能结果。

    2. 将值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)推入栈。

  4. 否则

    1. 陷入陷阱。

\[\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#exec-notation}{\hookrightarrow}& (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c \in \href{../exec/instructions.html#exec-instr-numeric}{\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#exec-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} & (\mathrel{\mbox{if}} \href{../exec/instructions.html#exec-instr-numeric}{\mathit{unop}}_{t}(c_1) = \{\}) \end{array}\end{split}\]

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

  1. 断言:由于验证,栈顶有两个值类型\(t\)的值。

  2. 从栈顶弹出值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\)

  3. 从栈顶弹出值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\)

  4. 如果\(\href{../exec/instructions.html#exec-instr-numeric}{\mathit{binop}}_t(c_1, c_2)\)已定义,则

    1. \(c\)为计算\(\href{../exec/instructions.html#exec-instr-numeric}{\mathit{binop}}_t(c_1, c_2)\)的可能结果。

    2. 将值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)推入栈。

  5. 否则

    1. 陷入陷阱。

\[\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#exec-notation}{\hookrightarrow}& (t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c) & (\mathrel{\mbox{if}} c \in \href{../exec/instructions.html#exec-instr-numeric}{\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#exec-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} & (\mathrel{\mbox{if}} \href{../exec/instructions.html#exec-instr-numeric}{\mathit{binop}}_{t}(c_1,c_2) = \{\}) \end{array}\end{split}\]

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

  1. 断言:由于验证,栈顶有一个值类型\(t\)的值。

  2. 从栈顶弹出值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\)

  3. \(c\)为计算\(\href{../exec/instructions.html#exec-instr-numeric}{\mathit{testop}}_t(c_1)\)的结果。

  4. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)推入栈。

\[\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#exec-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/instructions.html#exec-instr-numeric}{\mathit{testop}}_t(c_1)) \\ \end{array}\end{split}\]

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

  1. 断言:由于验证,栈顶有两个值类型\(t\)的值。

  2. 从栈顶弹出值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\)

  3. 从栈顶弹出值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\)

  4. \(c\)为计算\(\href{../exec/instructions.html#exec-instr-numeric}{\mathit{relop}}_t(c_1, c_2)\)的结果。

  5. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)推入栈。

\[\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#exec-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/instructions.html#exec-instr-numeric}{\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. 断言:由于验证,栈顶有一个值类型\(t_1\)的值。

  2. 从栈顶弹出值\(t_1.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\)

  3. 如果\(\href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{t_1,t_2}(c_1)\)已定义

    1. \(c_2\)为计算\(\href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{t_1,t_2}(c_1)\)的可能结果。

    2. 将值\(t_2.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\)推入栈。

  4. 否则

    1. 陷入陷阱。

\[\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#exec-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#exec-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}\]

引用指令

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

  1. 将值\(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t\)推入栈。

注意

此指令不需要正式的归约规则,因为\(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}\)指令本身就是一个

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

  1. 断言:由于验证,栈顶有一个引用值

  2. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

  3. 如果\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)\(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t\),则

    1. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~1\)推入栈。

  4. 否则

    1. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0\)推入栈。

\[\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#exec-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#exec-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. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]\) 存在。

  3. \(a\) 为函数地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]\)

  4. 将值 \(\href{../exec/runtime.html#syntax-ref}{\mathsf{ref}}~a\) 推入栈中。

\[\begin{split}\begin{array}{lcl@{\qquad}l} F; (\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}func}}~x) &\href{../exec/conventions.html#exec-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}\]

向量指令

按位操作的向量指令被视为相应宽度的整数操作。

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

大多数其他向量指令根据给定的 形状,以逐车道应用的数值运算符来定义。

\[\begin{split}\begin{array}{llll} \mathit{op}_{t\mathsf{x}N}(n_1,\dots,n_k) &=& \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t\mathsf{x}N}(\href{../exec/instructions.html#exec-instr-numeric}{\mathit{op}}_t(i_1,\dots,i_k)^\ast) & \qquad(\mathrel{\mbox{if}} i_1^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(n_1) \land \dots \land i_k^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(n_k) \\ \end{array}\end{split}\]

注意

例如,指令 \(\mathsf{i32x4}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}\) 应用于操作数 \(v_1, v_2\) 的结果会调用 \(\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{add}}_{\mathsf{i32x4}}(v_1, v_2)\),这映射到 \(\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)^\ast)\),其中 \(i_1^\ast\)\(i_2^\ast\) 分别是调用 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\mathsf{i32x4}}(v_1)\)\(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\mathsf{i32x4}}(v_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}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

注意

此指令不需要正式的归约规则,因为 \(\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}\) 指令与 相符。

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

  1. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  3. \(c\) 为计算 \(\href{../syntax/instructions.html#syntax-vvunop}{\mathit{vvunop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1)\) 的结果。

  4. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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. 断言:由于 验证,栈顶有两个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. \(c\) 为计算 \(\href{../syntax/instructions.html#syntax-vvbinop}{\mathit{vvbinop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1, c_2)\) 的结果。

  5. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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. 断言:由于 验证,栈顶有三个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_3\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  4. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  5. \(c\) 为计算 \(\href{../syntax/instructions.html#syntax-vvternop}{\mathit{vvternop}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}}(c_1, c_2, c_3)\) 的结果。

  6. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  3. \(i\) 为计算 \(\href{../exec/numerics.html#op-ine}{\mathrm{ine}}_{128}(c_1, 0)\) 的结果。

  4. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) 推入栈中。

\[\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#exec-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. 断言:由于 验证,栈顶有两个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  3. \(i^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_2)\) 的结果。

  4. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  5. \(j^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_1)\) 的结果。

  6. \(c^\ast\) 为两个序列 \(j^\ast\)\(0^{240}\) 的连接。

  7. \(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] ])\) 的结果。

  8. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c'\) 推入栈中。

\[\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#exec-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. 断言:由于 验证,栈顶有两个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 断言:由于 验证,对于 \(x^\ast\) 中的所有 \(x_i\),都有 \(x_i < 32\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  4. \(i_2^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_2)\) 的结果。

  5. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  6. \(i_1^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i8x16}}}(c_1)\) 的结果。

  7. \(i^\ast\) 为两个序列 \(i_1^\ast\)\(i_2^\ast\) 的连接。

  8. \(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]])\) 的结果。

  9. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈顶。

\[\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#exec-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{如果}} & 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. \(t\) 为类型 \(\href{../valid/instructions.html#aux-unpacked}{\mathrm{unpacked}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})\)

  2. 断言:由于 验证,栈顶的值的 值类型\(t\)

  3. 从栈顶弹出值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_1\)

  4. \(N\) 为整数 \(\href{../valid/instructions.html#aux-dim}{\mathrm{dim}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})\)

  5. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1^N)\) 的结果。

  6. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{如果}} 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. 断言:由于 验证\(x < N\)

  2. 断言:由于 验证,栈顶的值的 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. \(i^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}N}(c_1)\) 的结果。

  5. \(t_2\) 为类型 \(\href{../valid/instructions.html#aux-unpacked}{\mathrm{unpacked}}(t_1\mathsf{x}N)\)

  6. \(c_2\) 为计算 \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{sx^?}_{t_1,t_2}(i^\ast[x])\) 的结果。

  7. 将值\(t_2.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\)推入栈。

\[\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#exec-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{如果}} & 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. 断言:由于 验证\(x < \href{../valid/instructions.html#aux-dim}{\mathrm{dim}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})\)

  2. \(t_2\) 为类型 \(\href{../valid/instructions.html#aux-unpacked}{\mathrm{unpacked}}(\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}})\)

  3. 断言:由于 验证,栈顶的值的 值类型\(t_1\)

  4. 弹出栈顶的值 \(t_2.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_2\)

  5. 断言:由于 验证,栈顶的值的 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  6. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  7. \(i^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1)\) 的结果。

  8. \(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{替换}}} [x] = c_2)\) 的结果。

  9. \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈顶。

\[\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{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\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#exec-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{如果}} & i^\ast = \href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1) \\ \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{替换}}} [x] = c_2)) \end{array} \end{array}\end{split}\]

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

  1. 断言:由于 验证,栈顶的值的 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  3. \(c\) 为计算 \(\href{../syntax/instructions.html#syntax-vunop}{\mathit{vunop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1)\) 的结果。

  4. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

\[\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-vunop}{\mathit{vunop}} &\href{../exec/conventions.html#exec-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{如果}} 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. 断言:由于 验证,栈顶有两个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. 如果 \(\href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1, c_2)\) 已定义

    1. \(c\) 为计算 \(\href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c_1, c_2)\) 的一个可能结果。

    2. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

  5. 否则

    1. 陷入陷阱。

\[\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#exec-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c) & (\mathrel{\mbox{如果}} 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#exec-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-trap}{\mathsf{陷阱}} & (\mathrel{\mbox{如果}} \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. 断言:由于 验证,栈顶有两个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. \(i_1^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_1)\) 的结果。

  5. \(i_2^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_2)\) 的结果。

  6. \(i^\ast\) 为计算 \(\href{../syntax/instructions.html#syntax-vrelop}{\mathit{vrelop}}_t(i_1^\ast, i_2^\ast)\) 的结果。

  7. \(j^\ast\) 为计算 \(\href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{1,|t|}(i^\ast)\) 的结果。

  8. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t\mathsf{x}N}(j^\ast)\) 的结果。

  9. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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{如果}} 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. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\)

  3. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  4. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  5. \(i^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c_1)\) 的结果。

  6. \(j^\ast\) 为计算 \(\href{../syntax/instructions.html#syntax-vishiftop}{\mathit{vishiftop}}_{t}(i^\ast, s^N)\) 的结果。

  7. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t\mathsf{x}N}(j^\ast)\) 的结果。

  8. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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{如果}} & 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. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\)

  3. \(i_1^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}}(c)\) 的结果。

  4. \(i\) 为计算 \(\href{../exec/numerics.html#aux-bool}{\mathrm{bool}}(\bigwedge(i_1 \neq 0)^\ast)\) 的结果。

  5. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) 推入栈中。

\[\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)~\href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{all\_true}} &\href{../exec/conventions.html#exec-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{如果}} & 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. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\)

  3. \(i_1^N\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t\mathsf{x}N}(c)\) 的结果。

  4. \(B\) 为值类型 \(t\)位宽 \(|t|\)

  5. \(i_2^N\) 为计算 \(\href{../exec/numerics.html#op-ilt-s}{\mathrm{ilt\_s}}_{B}(i_1^N, 0^N)\) 的结果。

  6. \(j^\ast\) 为两个序列 \(i_2^N\)\(0^{32-N}\) 的连接。

  7. \(i\) 为计算 \(\href{../exec/numerics.html#aux-ibits}{\mathrm{ibits}}_{32}^{-1}(j^\ast)\) 的结果。

  8. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) 推入栈中。

\[\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)~t\mathsf{x}N\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{bitmask}} &\href{../exec/conventions.html#exec-notation}{\hookrightarrow}& (\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i) & (\mathrel{\mbox{如果}} i = \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. 断言:根据 语法\(N = 2\cdot M\)

  2. 断言:由于 验证,栈顶有两个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  4. \(i_2^M\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_2)\) 的结果。

  5. \(d_2^M\) 为计算 \(\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. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  7. \(i_1^M\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\) 的结果。

  8. \(d_1^M\) 为计算 \(\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. \(j^N\) 为两个序列 \(d_1^M\)\(d_2^M\) 的连接。

  10. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(j^N)\) 的结果。

  11. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈顶。

\[\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#exec-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{如果}} & 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. 断言:根据 语法\(N = M\)

  2. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. \(i^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\) 的结果。

  5. \(j^\ast\) 为计算 \(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(i^\ast)\) 的结果。

  6. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(j^\ast)\) 的结果。

  7. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈顶。

\[\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#exec-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{如果}} & 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. 断言:根据 语法\(N = M / 2\)

  2. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. \(i^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\) 的结果。

  5. 如果 \(\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\)\(\mathsf{low}\),则

    1. \(j^\ast\) 为序列 \(i^\ast[0 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\)

  6. 否则

    1. \(j^\ast\) 为序列 \(i^\ast[N \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\)

  7. \(k^\ast\) 为计算 \(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{|t_1|,|t_2|}(j^\ast)\) 的结果。

  8. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(k^\ast)\) 的结果。

  9. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈顶。

\[\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#exec-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{如果}} & 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}\]

其中

\[\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. 断言:由于 语法\(N = 2 \cdot M\)

  2. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. \(i^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\) 的结果。

  5. \(j^\ast\) 为计算 \(\href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}^?}_{|t_1|,|t_2|}(i^\ast)\) 的结果。

  6. \(k^\ast\) 为两个序列 \(j^\ast\)\(0^M\) 的连接。

  7. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(k^\ast)\) 的结果。

  8. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈顶。

\[\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#exec-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{如果}} & 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. 断言:由于 验证,栈顶有两个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. \(i_1^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i16x8}}}(c_1)\) 的结果。

  5. \(j_1^\ast\) 为计算 \(\href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{16,32}(i_1^\ast)\) 的结果。

  6. \(i_2^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i16x8}}}(c_2)\) 的结果。

  7. \(j_2^\ast\) 为计算 \(\href{../exec/numerics.html#op-extend-s}{\mathrm{extend}^{\mathsf{s}}}_{16,32}(i_2^\ast)\) 的结果。

  8. \((k_1~k_2)^\ast\) 为计算 \(\href{../exec/numerics.html#op-imul}{\mathrm{imul}}_{32}(j_1^\ast, j_2^\ast)\) 的结果。

  9. \(k^\ast\) 为计算 \(\href{../exec/numerics.html#op-iadd}{\mathrm{iadd}}_{32}(k_1, k_2)^\ast\) 的结果。

  10. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i32x4}}}(k^\ast)\) 的结果。

  11. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈顶。

\[\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#exec-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{如果}} & (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. 断言:根据 语法\(N = M / 2\)

  2. 断言:由于 验证,栈顶有两个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_2\)

  4. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  5. \(i_1^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\) 的结果。

  6. \(i_2^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_2)\) 的结果。

  7. 如果 \(\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\)\(\mathsf{low}\),则

    1. \(j_1^\ast\) 为序列 \(i_1^\ast[0 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\)

    2. \(j_2^\ast\) 为序列 \(i_2^\ast[0 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\)

  8. 否则

    1. \(j_1^\ast\) 为序列 \(i_1^\ast[N \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\)

    2. \(j_2^\ast\) 为序列 \(i_2^\ast[N \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N]\)

  9. \(k_1^\ast\) 为计算 \(\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. \(k_2^\ast\) 为计算 \(\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. \(k^\ast\) 为计算 \(\href{../exec/numerics.html#op-imul}{\mathrm{imul}}_{|t_2|}(k_1^\ast, k_2^\ast)\) 的结果。

  12. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(k^\ast)\) 的结果。

  13. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈顶。

\[\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#exec-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{如果}} & 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|}(\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}\]

其中

\[\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. 断言:根据 语法\(N = M / 2\)

  2. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) 的值。

  3. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c_1\)

  4. \(i^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{t_1\mathsf{x}M}(c_1)\) 的结果。

  5. \((j_1~j_2)^\ast\) 为计算 \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{|t_1|,|t_2|}(i^\ast)\) 的结果。

  6. \(k^\ast\) 为计算 \(\href{../exec/numerics.html#op-iadd}{\mathrm{iadd}}_{|t_2|}(j_1, j_2)^\ast\) 的结果。

  7. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{t_2\mathsf{x}N}(k^\ast)\) 的结果。

  8. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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{如果}} & (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}}_{|t_2|}(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}\]

参数化指令

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

  1. 断言:由于 验证,栈顶有一个值。

  2. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

\[\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#exec-notation}{\hookrightarrow}& \epsilon \end{array}\]

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

  1. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)

  3. 断言:由于验证,栈顶有两个更多相同值类型的值。

  4. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_2\)

  5. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_1\)

  6. 如果\(c\)不等于\(0\),则

    1. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_1\)压回栈顶。

  7. 否则

    1. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_2\)压回栈顶。

\[\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#exec-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}_1 & (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#exec-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}_2 & (c = 0 的情况) \\ \end{array}\end{split}\]

注意

在 WebAssembly 的未来版本中,\(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}\) 可能允许每个选择有多个值。

变量指令

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

  1. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x]\) 存在。

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

  4. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

\[\begin{split}\begin{array}{lcl@{\qquad}l} F; (\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.get}}~x) &\href{../exec/conventions.html#exec-notation}{\hookrightarrow}& F; \href{../exec/runtime.html#syntax-val}{\mathit{val}} & (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. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x]\) 存在。

  3. 断言:由于验证,栈顶有一个值。

  4. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

  5. 用值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)替换\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}[x]\)

\[\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#exec-notation}{\hookrightarrow}& F'; \epsilon & (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. 断言:由于验证,栈顶有一个值。

  2. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

  3. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

  4. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

  5. 执行指令\(\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#exec-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. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]\) 存在。

  3. \(a\)全局地址\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\) 存在。

  5. \(\mathit{glob}\)全局实例\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\)

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

  7. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

\[\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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-val}{\mathit{val}} \end{array} \\ \qquad (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. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]\) 存在。

  3. \(a\)全局地址\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}[x]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\) 存在。

  5. \(\mathit{glob}\)全局实例\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\)

  6. 断言:由于验证,栈顶有一个值。

  7. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

  8. 用值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)替换\(\mathit{glob}.\href{../exec/runtime.html#syntax-globalinst}{\mathsf{value}}\)

\[\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#exec-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad (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}\]

注意

验证确保全局变量实际上被标记为可变的。

表指令

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

  1. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) 存在。

  3. \(a\)表地址\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) 存在。

  5. \(\mathit{tab}\)表实例\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\)

  6. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  7. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  8. 如果\(i\)不小于\(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\)的长度,则

    1. 陷入陷阱。

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

  10. 将值\(\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{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~x) &\href{../exec/conventions.html#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-val}{\mathit{val}} \end{array} \\ \qquad (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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (其他情况) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) 存在。

  3. \(a\)表地址\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) 存在。

  5. \(\mathit{tab}\)表实例\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\)

  6. 断言:由于验证,栈顶有一个引用值

  7. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

  8. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  9. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  10. 如果\(i\)不小于\(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\)的长度,则

    1. 陷入陷阱。

  11. \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)替换元素\(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[i]\)

\[\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#exec-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad (\mathrel{\mbox{如果}} S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{替换}}} \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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{否则}}) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) 存在。

  3. \(a\)表地址\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) 存在。

  5. \(\mathit{tab}\)表实例\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\)

  6. \(\mathit{sz}\)\(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\) 的长度。

  7. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) 推入栈中。

\[\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#exec-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{如果}} |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. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) 存在。

  3. \(a\)表地址\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) 存在。

  5. \(\mathit{tab}\)表实例\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\)

  6. \(\mathit{sz}\)\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) 的长度。

  7. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  8. 从栈顶弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\)

  9. 断言:由于 验证,栈顶有一个 引用值

  10. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

  11. \(\mathit{err}\)\(\href{../syntax/values.html#syntax-int}{\mathit{i32}}\)\(2^{32}-1\),其中 \(\href{../exec/numerics.html#aux-signed}{\mathrm{signed}}_{32}(\mathit{err})\)\(-1\)

  12. 或者

  1. 如果 扩展 \(\mathit{tab}\) \(n\) 个条目并使用初始化值 \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) 成功,则

    1. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) 推入栈中。

  2. 否则

    1. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) 推入栈中。

  1. 或者

  1. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) 推入栈中。

\[\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#exec-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{如果}} & 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{替换}}} \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#exec-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}\]

注意

\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.grow}}\) 指令是非确定性的。它可能成功,返回旧的表大小 \(\mathit{sz}\),也可能失败,返回 \({-1}\)。如果引用的表实例定义了最大大小并且会被超出,则**必须**发生失败。但是,在其他情况下也**可能**发生失败。在实践中,选择取决于 资源 可用于 嵌入器

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

  1. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) 存在。

  3. \(\mathit{ta}\)表地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\) 存在。

  5. \(\mathit{tab}\)表实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\)

  6. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  7. 从栈顶弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\)

  8. 断言:由于 验证,栈顶有一个 引用值

  9. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

  10. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  11. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  12. 如果 \(i + n\) 大于 \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\) 的长度,则

    1. 陷入陷阱。

  1. 如果 \(n\)\(0\),则

    1. 返回。

  2. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\) 推入栈中。

  3. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

  4. 执行指令 \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\)

  5. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(i+1)\) 推入栈中。

  6. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

  7. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) 推入栈中。

  8. 执行指令 \(\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#exec-notation}{\hookrightarrow}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{如果}} & 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#exec-notation}{\hookrightarrow}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{否则}}) \\[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#exec-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{否则}}) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\) 存在。

  3. \(\mathit{ta}_x\)表地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}_x]\) 存在。

  5. \(\mathit{tab}_x\)表实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}_x]\)

  6. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[y]\) 存在。

  7. \(\mathit{ta}_y\)表地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[y]\)

  8. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}_y]\) 存在。

  9. \(\mathit{tab}_y\)表实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}_y]\)

  10. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  11. 从栈顶弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\)

  12. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  13. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\)

  14. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  15. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)

  16. 如果\(s + n\)大于\(\mathit{tab}_y.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\)的长度,或者\(d + n\)大于\(\mathit{tab}_x.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\)的长度,则

    1. 陷入陷阱。

  17. 如果\(n = 0\),则

  1. 返回。

  1. 如果\(d \leq s\),则

  1. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)压入栈中。

  2. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\)压入栈中。

  3. 执行指令\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~y\)

  4. 执行指令 \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\)

  5. 断言:由于之前对表格大小的检查,\(d+1 < 2^{32}\)

  6. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\)压入栈中。

  7. 断言:由于之前对表格大小的检查,\(s+1 < 2^{32}\)

  8. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+1)\)压入栈中。

  1. 否则

  1. 断言:由于之前对表格大小的检查,\(d+n-1 < 2^{32}\)

  2. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+n-1)\)压入栈中。

  3. 断言:由于之前对表格大小的检查,\(s+n-1 < 2^{32}\)

  4. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+n-1)\)压入栈中。

  1. 执行指令\(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~y\)

  1. 执行指令 \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\)

  2. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)压入栈中。

  3. 将值\(\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-1)\) 推入栈中。

  2. 执行指令\(\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#exec-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#exec-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#exec-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#exec-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. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)存在。

  3. \(\mathit{ta}\)表地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\)存在。

  5. \(\mathit{tab}\)表实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\)

  6. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[y]\)存在。

  7. \(\mathit{ea}\)元素地址\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[y]\)

  8. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[\mathit{ea}]\)存在。

  9. \(\mathit{elem}\)元素实例\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[\mathit{ea}]\)

  10. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  11. 从栈顶弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\)

  12. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  13. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\)

  14. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  15. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)

  16. 如果\(s + n\)大于\(\mathit{elem}.\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}\)的长度,或者\(d + n\)大于\(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\)的长度,则

    1. 陷入陷阱。

  17. 如果\(n = 0\),则

    1. 返回。

  18. \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)引用值\(\mathit{elem}.\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}[s]\)

  19. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)压入栈中。

  20. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

  21. 执行指令 \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~x\)

  22. 断言:由于之前对表格大小的检查,\(d+1 < 2^{32}\)

  23. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\)压入栈中。

  24. 断言:由于之前对段大小的检查,\(s+1 < 2^{32}\)

  25. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+1)\)压入栈中。

  26. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) 推入栈中。

  27. 执行指令\(\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#exec-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#exec-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#exec-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. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[x]\)存在。

  3. \(a\)元素地址\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{elemaddrs}}[x]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[a]\)存在。

  5. \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}[a].\href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}\)替换为\(\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#exec-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad (\mathrel{\mbox{如果}} S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{替换}}} \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}\]

内存指令

注意

加载和存储指令中的对齐方式 \(\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}\) 不会影响语义。它表示访问内存的偏移量 \(\mathit{ea}\) 旨在满足属性 \(\mathit{ea} \mathbin{\mathrm{mod}} 2^{\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}} = 0\)。WebAssembly 实现可以使用此提示针对预期用途进行优化。违反该属性的未对齐访问仍然允许并且必须成功,无论注释如何。但是,在某些硬件上,它可能会慢得多。

\(t\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\)\(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. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  7. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  8. \(\mathit{ea}\) 为整数 \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\)

  9. 如果 \(N\) 不是指令的一部分,则

    1. \(N\)位宽 \(|t|\)数值类型 \(t\)

  10. 如果 \(\mathit{ea} + N/8\) 大于 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  11. \(b^\ast\) 为字节序列 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\)

  12. 如果 \(N\)\(\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\) 是指令的一部分,则

    1. \(n\) 为使得 \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast\) 的整数。

    2. \(c\) 为计算 \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{N,|t|}(n)\) 的结果。

  13. 否则

    1. \(c\) 为使得 \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_t(c) = b^\ast\) 的常量。

  14. 将值\(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)推入栈。

\[\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}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#exec-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{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + |t|/8 \leq |S.\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}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_t(c) = S.\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{:}}} |t|/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#exec-notation}{\hookrightarrow}& S; F; (t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{N,|t|}(n)) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + N/8 \leq |S.\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}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = S.\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]) \\[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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{否则}}) \\ \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. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  7. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  8. \(\mathit{ea}\) 为整数 \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\)

  9. 如果 \(\mathit{ea} + M \cdot N /8\) 大于 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  10. \(b^\ast\) 为字节序列 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} M \cdot N /8]\)

  11. \(m_k\) 为使得 \(\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]\) 的整数。

  12. \(W\) 为整数 \(M \cdot 2\)

  13. \(n_k\) 为计算 \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}}^{\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}}_{M,W}(m_k)\) 的结果。

  14. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\mathsf{i}W\mathsf{x}N}(n_0 \dots n_{N-1})\) 的结果。

  15. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + M \cdot N / 8 \leq |S.\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}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}M}}(m_k) = S.\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} + k \cdot M/8 \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} M/8] \\ \wedge & W = M \cdot 2 \\ \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}))) \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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{否则}}) \\ \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. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  7. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  8. \(\mathit{ea}\) 为整数 \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\)

  9. 如果 \(\mathit{ea} + N/8\) 大于 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  10. \(b^\ast\) 为字节序列 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\)

  11. \(n\) 为使得 \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast\) 的整数。

  12. \(L\) 为整数 \(128 / N\)

  13. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(n^L)\) 的结果。

  14. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + N/8 \leq |S.\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}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = S.\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] \\ \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)) \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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{否则}}) \\ \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. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  7. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  8. \(\mathit{ea}\) 为整数 \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\)

  9. 如果 \(\mathit{ea} + N/8\) 大于 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  10. \(b^\ast\) 为字节序列 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\)

  11. \(n\) 为使得 \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = b^\ast\) 的整数。

  12. \(c\) 为计算 \(\href{../exec/numerics.html#op-extend-u}{\mathrm{extend}^{\mathsf{u}}}_{N,128}(n)\) 的结果。

  13. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + N/8 \leq |S.\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}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n) = S.\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] \\ \wedge & c = \href{../exec/numerics.html#op-extend-u}{\mathrm{extend}^{\mathsf{u}}}_{N,128}(n)) \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{\_zero}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{否则}}) \\ \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. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  7. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~v\)

  8. 断言:由于 验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  9. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  10. \(\mathit{ea}\) 为整数 \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\)

  11. 如果 \(\mathit{ea} + N/8\) 大于 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  12. \(b^\ast\) 为字节序列 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\)

  13. \(r\) 为满足 \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(r) = b^\ast\) 的常量。

  14. \(L\)\(128 / N\)

  15. \(j^\ast\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(v)\) 的结果。

  16. \(c\) 为计算 \(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}^{-1}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(j^\ast \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{替换}}} [x] = r)\) 的结果。

  17. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\) 推入栈中。

\[\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#exec-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{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + N/8 \leq |S.\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}}| \\ \wedge & \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(r) = S.\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] \\ \wedge & L = 128/N \\ \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{替换}}} [x] = r)) \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}}.\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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{否则}}) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. 断言:由于 验证,栈顶的值类型为 值类型 \(t\)

  7. 从栈中弹出值 \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)

  8. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)

  9. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  10. \(\mathit{ea}\) 为整数 \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\)

  11. 如果 \(N\) 不是指令的一部分,则

    1. \(N\)位宽 \(|t|\)数值类型 \(t\)

  12. 如果 \(\mathit{ea} + N/8\) 大于 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  13. 如果 \(N\) 是指令的一部分,则

    1. \(n\) 为计算 \(\href{../exec/numerics.html#op-wrap}{\mathrm{wrap}}_{|t|,N}(c)\) 的结果。

    2. \(b^\ast\) 为字节序列 \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(n)\)

  14. 否则

    1. \(b^\ast\) 为字节序列 \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_t(c)\)

  15. \(b^\ast\) 替换字节 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\)

\[\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}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}) &\href{../exec/conventions.html#exec-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + |t|/8 \leq |S.\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}}| \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{替换}}} \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{:}}} |t|/8] = \href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_t(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#exec-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + N/8 \leq |S.\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}}| \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{替换}}} \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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{否则}}) \\ \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. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\)

  7. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)

  8. 断言:由于 验证,栈顶的值类型为 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)

  9. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  10. \(\mathit{ea}\) 为整数 \(i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}\)

  11. 如果 \(\mathit{ea} + N/8\) 大于 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

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

  13. \(j^\ast\) 为计算\(\href{../exec/numerics.html#aux-lanes}{\mathrm{lanes}}_{\href{../syntax/types.html#syntax-valtype}{\mathsf{i}N}\mathsf{x}L}(c)\) 的结果。

  14. \(b^\ast\) 为计算\(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}_{\href{../syntax/values.html#syntax-int}{\mathit{i}N}}(j^\ast[x])\) 的结果。

  15. \(b^\ast\) 替换字节 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{ea} \href{../syntax/conventions.html#notation-slice}{\mathrel{\mathbf{:}}} N/8]\)

\[\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#exec-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{如果}} & \mathit{ea} = i + \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}.\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}} \\ \wedge & \mathit{ea} + N \leq |S.\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}}| \\ \wedge & L = 128/N \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{用}}} \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])) \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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{否则}}) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. \(\mathit{sz}\)\(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度除以页面大小 的结果。

  7. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) 推入栈中。

\[\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#exec-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{如果}} |S.\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{sz}\cdot64\,\mathrm{Ki}) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(a\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\)

  6. \(\mathit{sz}\)\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) 的长度除以页面大小 的结果。

  7. 断言:由于验证,栈顶有一个值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  8. 从栈顶弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\)

  9. \(\mathit{err}\)\(\href{../syntax/values.html#syntax-int}{\mathit{i32}}\)\(2^{32}-1\),其中 \(\href{../exec/numerics.html#aux-signed}{\mathrm{signed}}_{32}(\mathit{err})\)\(-1\)

  10. 或者

  1. 如果将\(\mathit{mem}\) 的大小增加\(n\)页面 成功,则

    1. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{sz}\) 推入栈中。

  2. 否则

    1. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) 推入栈中。

  1. 或者

  1. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{err}\) 推入栈中。

\[\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#exec-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{如果}} & F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0] = a \\ \wedge & \mathit{sz} = |S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a].\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}|/64\,\mathrm{Ki} \\ \wedge & S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{用}}} \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#exec-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}\]

注意

\(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}}\) 指令是不确定的。它可能会成功,返回旧的内存大小\(\mathit{sz}\),也可能失败,返回\({-1}\)。如果引用的内存实例定义了最大大小,并且该大小会被超出,则**必须**发生失败。但是,在其他情况下也**可能**发生失败。在实践中,选择取决于资源 是否可供嵌入器 使用。

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

  1. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(\mathit{ma}\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\)

  6. 断言:由于验证,栈顶有一个值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  7. 从栈顶弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\)

  8. 断言:由于验证,栈顶有一个值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  9. 从栈顶弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

  10. 断言:由于验证,栈顶有一个值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  11. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)

  12. 如果\(d + n\) 大于\(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  13. 如果\(n = 0\),则

    1. 返回。

  14. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)压入栈中。

  15. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

  16. 执行指令\(\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 \}\)

  17. 断言:由于之前对内存大小的检查,\(d+1 < 2^{32}\)

  18. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\)压入栈中。

  19. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)压入栈顶。

  20. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) 推入栈中。

  21. 执行指令\(\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#exec-notation}{\hookrightarrow}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad (\mathrel{\mbox{如果}} d + n > |S.\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}}|) \\[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#exec-notation}{\hookrightarrow}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{否则}}) \\[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#exec-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/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{否则}}) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(\mathit{ma}\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\)

  6. 断言:由于验证,栈顶有一个值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  7. 从栈顶弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\)

  8. 断言:由于验证,栈顶有一个值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  9. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\)

  10. 断言:由于验证,栈顶有一个值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  11. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)

  12. 如果\(s + n\) 大于\(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度或\(d + n\) 大于\(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  13. 如果\(n = 0\),则

  1. 返回。

  1. 如果\(d \leq s\),则

  1. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)压入栈中。

  2. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\)压入栈中。

  3. 执行指令\(\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. 执行指令\(\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. 断言:由于之前对内存大小的检查,\(d+1 < 2^{32}\)

  6. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\)压入栈中。

  7. 断言:由于之前对内存大小的检查,\(s+1 < 2^{32}\)

  8. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+1)\)压入栈中。

  1. 否则

  1. 断言:由于之前对内存大小的检查,\(d+n-1 < 2^{32}\)

  2. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+n-1)\)压入栈中。

  3. 断言:由于之前对内存大小的检查,\(s+n-1 < 2^{32}\)

  4. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+n-1)\)压入栈中。

  5. 执行指令\(\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. 执行指令\(\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. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)压入栈中。

  8. 将值\(\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-1)\) 推入栈中。

  2. 执行指令\(\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#exec-notation}{\hookrightarrow}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{如果}} & s + n > |S.\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}}| \\ \vee & d + n > |S.\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}}|) \\[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#exec-notation}{\hookrightarrow}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{否则}}) \\[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#exec-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/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{否则}}, \mathrel{\mbox{如果}} 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-memory}{\mathsf{memory.copy}} \quad\href{../exec/conventions.html#exec-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/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{否则}}, \mathrel{\mbox{如果}} d > s) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\) 存在。

  3. \(\mathit{ma}\)内存地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[0]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\) 存在。

  5. \(\mathit{mem}\)内存实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\mathit{ma}]\)

  6. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]\) 存在。

  7. \(\mathit{da}\)数据地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]\)

  8. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[\mathit{da}]\) 存在。

  9. \(\mathit{data}\)数据实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[\mathit{da}]\)

  10. 断言:由于 验证,栈顶有一个 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  11. 从栈顶弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\)

  12. 断言:由于 验证,栈顶有一个 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  13. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~s\)

  14. 断言:由于 验证,栈顶有一个 值类型 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  15. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)

  16. 如果 \(s + n\) 大于 \(\mathit{data}.\href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}\) 的长度,或者 \(d + n\) 大于 \(\mathit{mem}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) 的长度,则

    1. 陷入陷阱。

  17. 如果\(n = 0\),则

    1. 返回。

  18. \(b\) 为字节 \(\mathit{data}.\href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}[s]\)

  19. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~d\)压入栈中。

  20. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~b\) 推入栈中。

  21. 执行指令\(\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 \}\)

  22. 断言:由于之前对内存大小的检查,\(d+1 < 2^{32}\)

  23. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(d+1)\)压入栈中。

  24. 断言:由于之前对内存大小的检查,\(s+1 < 2^{32}\)

  25. 将值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(s+1)\)压入栈中。

  26. 将值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~(n-1)\) 推入栈中。

  27. 执行指令 \(\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#exec-notation}{\hookrightarrow}\quad S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\mathrel{\mbox{如果}} & 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 > |S.\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}}|) \\[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#exec-notation}{\hookrightarrow}\quad S; F; \epsilon \\ \qquad (\mathrel{\mbox{否则}}) \\[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#exec-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}}~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{否则}}, \mathrel{\mbox{如果}} 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]) \\ \end{array}\end{split}\]

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

  1. \(F\)当前

  2. 断言:由于 验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]\) 存在。

  3. \(a\)数据地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{dataaddrs}}[x]\)

  4. 断言:由于 验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[a]\) 存在。

  5. \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}[a]\) 替换为 数据实例 \(\{\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#exec-notation}{\hookrightarrow}& S'; F; \epsilon \end{array} \\ \qquad (\mathrel{\mbox{如果}} S' = S \href{../syntax/conventions.html#notation-replace}{\mathrel{\mbox{用}}} \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}\]

控制指令

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

  1. 什么也不做。

\[\begin{array}{lcl@{\qquad}l} \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{nop}} &\href{../exec/conventions.html#exec-notation}{\hookrightarrow}& \epsilon \end{array}\]

\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{unreachable}}\)

  1. 陷入陷阱。

\[\begin{array}{lcl@{\qquad}l} \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{unreachable}} &\href{../exec/conventions.html#exec-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. \(F\)当前

  2. 断言:由于 验证\(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\) 已定义。

  3. \( [t_1^m] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^n] \)函数类型 \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\)

  4. \(L\) 为一个元数为 \(n\) 且延续为块末尾的标签。

  5. 断言:由于验证,栈顶至少有\(m\)个值。

  6. 从栈中弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\)

  7. 进入带有标签\(L\)的块\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\)

\[\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#exec-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. \(F\)当前

  2. 断言:由于 验证\(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\) 已定义。

  3. \( [t_1^m] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^n] \)函数类型 \(\href{../exec/runtime.html#exec-expand}{\mathrm{expand}}_F(\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}})\)

  4. \(L\)为元数为\(m\)且其延续为循环开头的标签。

  5. 断言:由于验证,栈顶至少有\(m\)个值。

  6. 从栈中弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m\)

  7. 进入带有标签\(L\)的块\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^m~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\)

\[\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#exec-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. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)

  3. 如果\(c\)不为零,则

    1. 执行块指令\(\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. 否则

    1. 执行块指令\(\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#exec-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#exec-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. 断言:由于验证,栈包含至少\(l+1\)个标签。

  2. \(L\)为栈中从顶部开始,从零开始计数的第\(l\)个标签。

  3. \(n\)\(L\)的元数。

  4. 断言:由于验证,栈顶至少有\(n\)个值。

  5. 从栈中弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\)

  6. 重复\(l+1\)

    1. 当栈顶为值时,执行

      1. 从栈中弹出该值。

    2. 断言:由于验证,栈顶现在是一个标签。

    3. 从栈中弹出该标签。

  7. 将值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\)压入栈中。

  8. 跳转到\(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#exec-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. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  2. 从栈中弹出值 \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)

  3. 如果\(c\)不为零,则

    1. 执行指令\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l\)

  4. 否则

    1. 什么也不做。

\[\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#exec-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#exec-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. 断言:由于验证,栈顶有一个值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\)的值。

  2. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  3. 如果\(i\)小于\(l^\ast\)的长度,则

    1. \(l_i\)为标签\(l^\ast[i]\)

    2. 执行指令\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~l_i\)

  4. 否则

    1. 执行指令\(\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#exec-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#exec-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. \(F\)当前

  2. \(n\)\(F\)的元数。

  3. 断言:由于验证,栈顶至少有\(n\)个值。

  4. 从栈中弹出结果\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\)

  5. 断言:由于验证,栈至少包含一个

  6. 当栈顶不是帧时,执行

    1. 从栈中弹出栈顶元素。

  7. 断言:栈顶是帧\(F\)

  8. 从栈中弹出该帧。

  9. \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\)压入栈中。

  10. 跳转到最初压入该帧的调用的下一条指令。

\[\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#exec-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. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]\)存在。

  3. \(a\) 为函数地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[x]\)

  4. 调用地址\(a\)处的函数实例。

\[\begin{array}{lcl@{\qquad}l} F; (\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call}}~x) &\href{../exec/conventions.html#exec-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. \(F\)当前

  2. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)存在。

  3. \(\mathit{ta}\)表地址 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[x]\)

  4. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\)存在。

  5. \(\mathit{tab}\)表实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\mathit{ta}]\)

  6. 断言:由于验证\(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{types}}[y]\) 存在。

  7. \(\mathit{ft}_{\mathrm{expect}}\)函数类型 \(F.\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{types}}[y]\)

  8. 断言:由于验证,栈顶有一个 值类型\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}\) 的值。

  9. 从栈顶弹出值\(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~i\)

  10. 如果\(i\)不小于\(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\)的长度,则

    1. 陷入陷阱。

  11. \(r\)引用 \(\mathit{tab}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[i]\)

  12. 如果 \(r\)\(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t\),则

    1. 陷入陷阱。

  13. 断言:由于表格变异的验证\(r\) 是一个 函数引用

  14. \(\href{../exec/runtime.html#syntax-ref}{\mathsf{ref}}~a\)函数引用 \(r\)

  15. 断言:由于表格变异的验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\) 存在。

  16. \(\mathit{f}\)函数实例 \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\)

  17. \(\mathit{ft}_{\mathrm{actual}}\)函数类型 \(\mathit{f}.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}\)

  18. 如果 \(\mathit{ft}_{\mathrm{actual}}\)\(\mathit{ft}_{\mathrm{expect}}\) 不同,则

    1. 陷入陷阱。

  19. 调用地址\(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#exec-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#exec-notation}{\hookrightarrow}& S; F; \href{../exec/runtime.html#syntax-trap}{\mathsf{trap}} \end{array} \\ \qquad (\mathrel{\mbox{otherwise}}) \end{array}\end{split}\]

以下辅助规则定义了执行构成指令序列的语义。

进入带有标签 \(L\)\(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\)

  1. \(L\) 推入栈中。

  2. 跳转到指令序列 \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) 的开头。

注意

进入指令序列不需要正式的规约规则,因为标签 \(L\) 已嵌入到结构化控制指令直接规约到的管理指令中。

退出带有标签 \(L\)\(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\)

当到达块的末尾且没有跳转或陷阱终止它时,执行以下步骤。

  1. 从栈顶弹出所有值 \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\)

  2. 断言:由于验证,标签 \(L\) 现在位于栈顶。

  3. 从栈中弹出该标签。

  4. \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) 推回栈中。

  5. 跳转到与标签 \(L\) 关联的结构化控制指令\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) 之后的位置。

\[\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#exec-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast \end{array}\end{split}\]

注意

此语义也适用于\(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}\) 指令中包含的指令序列。因此,循环的执行会从末尾掉出来,除非显式执行向后分支。

函数调用

以下辅助规则定义了通过其中一个调用指令调用函数实例并从中返回的语义。

调用函数地址 \(a\)

  1. 断言:由于验证\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\) 存在。

  2. \(f\)函数实例\(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\)

  3. \([t_1^n] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^m]\)函数类型 \(f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}\)

  4. \(t^\ast\)值类型 列表 \(f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{code}}.\href{../syntax/modules.html#syntax-func}{\mathsf{locals}}\)

  5. \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\)表达式 \(f.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{code}}.\href{../syntax/modules.html#syntax-func}{\mathsf{body}}\)

  6. 断言:由于验证,栈顶有 \(n\) 个值。

  7. 从栈中弹出值\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\)

  8. \(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)^\ast \}\)

  9. \(F\) 的激活(元数为 \(m\))推入栈中。

  10. \(L\) 为元数为 \(m\) 且延续为函数末尾的标签

  11. 进入 带有标签 \(L\) 的指令序列 \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\)

\[\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#exec-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}\]

从函数返回

当到达函数的末尾且没有跳转(即 \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return}}\))或陷阱终止它时,执行以下步骤。

  1. \(F\)当前

  2. \(n\)\(F\) 的激活的元数。

  3. 断言:由于验证,栈顶有 \(n\) 个值。

  4. 从栈中弹出结果\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\)

  5. 断言:由于验证,帧 \(F\) 现在位于栈顶。

  6. 从栈中弹出该帧。

  7. \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) 推回栈中。

  8. 跳转到原始调用的下一条指令。

\[\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#exec-notation}{\hookrightarrow}& \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n \end{array}\end{split}\]

宿主函数

调用宿主函数的行为是不确定的。它可能以陷阱终止,也可能正常返回。但是,在后一种情况下,它必须根据其函数类型,在栈上消耗和生成正确数量和类型的 WebAssembly

主机函数也可以修改存储。但是,所有存储修改都必须导致原始存储的扩展,即它们只能修改可变内容,并且不能删除实例。此外,生成的存储必须是有效的,即其中的所有数据和代码都具有良好的类型。

\[\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#exec-notation}{\hookrightarrow}& S'; \href{../exec/runtime.html#syntax-result}{\mathit{result}} \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} \} \\ \wedge & (S'; \href{../exec/runtime.html#syntax-result}{\mathit{result}}) \in \mathit{hf}(S; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n)) \\ \end{array} \\ \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#exec-notation}{\hookrightarrow}& S; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n~(\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{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} \} \\ \wedge & \bot \in \mathit{hf}(S; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n)) \\ \end{array} \\ \end{array}\end{split}\]

这里,\(\mathit{hf}(S; \href{../exec/runtime.html#syntax-val}{\mathit{val}}^n)\) 表示主机函数 \(\mathit{hf}\) 在当前存储 \(S\) 中使用参数 \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\) 的实现定义执行。它产生一组可能的结果,其中每个元素要么是一对修改后的存储 \(S'\) 和一个结果,要么是表示发散的特殊值 \(\bot\)。如果至少存在一个参数,其结果集不是单一的,则主机函数是非确定性的。

为了使 WebAssembly 实现健全(在存在主机函数的情况下),每个主机函数实例都必须是有效的,这意味着它符合合适的先决条件和后置条件:在有效存储 \(S\) 下,并且给定与指定的参数类型 \(t_1^n\) 匹配的参数 \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^n\),执行主机函数必须产生一组非空可能的结果,每个结果要么是发散,要么包含一个有效的存储 \(S'\)(它是 \(S\)扩展)和与指定的返回类型 \(t_2^m\) 匹配的结果。所有这些概念都在附录中进行了精确定义。

注意

主机函数可以通过调用模块导出的函数来回调到 WebAssembly 中。但是,任何此类调用的影响都包含在主机函数允许的非确定性行为中。

表达式

一个表达式相对于当前进行评估,该帧指向其包含的模块实例

  1. 跳转到表达式指令序列 \(\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast\) 的开头。

  2. 执行指令序列。

  3. 断言:由于验证,栈顶包含一个

  4. 从栈中弹出 \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\)

\(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) 是评估的结果。

\[S; F; \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast \href{../exec/conventions.html#exec-notation}{\hookrightarrow} 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#exec-notation}{\hookrightarrow} S'; F'; \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}'^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}})\]

注意

评估迭代此归约规则,直到达到一个值。构成函数体的表达式在函数调用期间执行。