pub enum ControlInstruction {
Nop,
Unreachable,
Block(BlockType, Expression),
Loop(BlockType, Expression),
If(BlockType, Expression, Option<Expression>),
Branch(LabelIndex),
BranchIf(LabelIndex),
BranchTable(Vec<LabelIndex>, LabelIndex),
Return,
Call(FunctionIndex),
CallIndirect(TypeIndex, TableIndex),
}Expand description
Instructions in this group affect the flow of control. The π»π ππΌπ, π πππ and ππΏ instructions are structured instructions. They bracket nested sequences of instructions, called blocks, terminated with, or separated by, πΎππ½ or πΎπ ππΎ pseudo-instructions. As the grammar prescribes, they must be well-nested.
A structured instruction can consume input and produce output on the operand stack according to its annotated block type. It is given either as a type index that refers to a suitable function type, or as an optional value type inline, which is a shorthand for the function type []β[valtype?].
Each structured control instruction introduces an implicit label. Labels are targets for branch instructions that reference them with label indices. Unlike with other index spaces, indexing of labels is relative by nesting depth, that is, label 0 refers to the innermost structured control instruction enclosing the referring branch instruction, while increasing indices refer to those farther out. Consequently, labels can only be referenced from within the associated structured control instruction. This also implies that branches can only be directed outwards, βbreakingβ from the block of the control construct they target. The exact effect depends on that control construct. In case of π»π ππΌπ or ππΏ it is a forward jump, resuming execution after the matching πΎππ½. In case of π πππ it is a backward jump to the beginning of the loop.
Taking a branch unwinds the operand stack up to the height where the targeted structured control instruction was entered. However, branches may additionally consume operands themselves, which they push back on the operand stack after unwinding. Forward branches require operands according to the output of the targeted blockβs type, i.e., represent the values produced by the terminated block. Backward branches require operands according to the input of the targeted blockβs type, i.e., represent the values consumed by the restarted block.
See https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions
Β§Examples
Β§Simple
use wasm_ast::{ControlInstruction, Instruction};
assert_eq!(Instruction::Control(ControlInstruction::Nop), ControlInstruction::Nop.into());
assert_eq!(Instruction::Control(ControlInstruction::Unreachable), ControlInstruction::Unreachable.into());
assert_eq!(Instruction::Control(ControlInstruction::Branch(0)), ControlInstruction::Branch(0).into());
assert_eq!(Instruction::Control(ControlInstruction::BranchIf(1)), ControlInstruction::BranchIf(1).into());
assert_eq!(Instruction::Control(ControlInstruction::BranchTable(vec![0], 1)), ControlInstruction::BranchTable(vec![0], 1).into());
assert_eq!(Instruction::Control(ControlInstruction::Return), ControlInstruction::Return.into());
assert_eq!(Instruction::Control(ControlInstruction::Call(1)), ControlInstruction::Call(1).into());
assert_eq!(Instruction::Control(ControlInstruction::CallIndirect(0, 1)), ControlInstruction::CallIndirect(0, 1).into());Β§Block
use wasm_ast::{ControlInstruction, Instruction, Expression, BlockType, ValueType};
let expression = Expression::new(vec![ControlInstruction::Nop.into(), 0i32.into()]);
assert_eq!(
Instruction::Control(ControlInstruction::Block(BlockType::ValueType(ValueType::I32), expression.clone())),
ControlInstruction::Block(BlockType::ValueType(ValueType::I32), expression.clone()).into()
);Β§Loop
use wasm_ast::{ControlInstruction, Instruction, BlockType, Expression};
let expression = Expression::new(vec![ControlInstruction::Nop.into(), 0i32.into()]);
assert_eq!(
Instruction::Control(ControlInstruction::Loop(BlockType::Index(0), expression.clone())),
ControlInstruction::Loop(BlockType::Index(0), expression.clone()).into()
);Β§If
use wasm_ast::{ControlInstruction, Instruction, Expression, BlockType};
let expression = Expression::new(vec![ControlInstruction::Nop.into()]);
assert_eq!(
Instruction::Control(ControlInstruction::If(BlockType::None, expression.clone(), None)),
ControlInstruction::If(BlockType::None, expression.clone(), None).into()
);
assert_eq!(
Instruction::Control(ControlInstruction::If(BlockType::None, expression.clone(), Some(expression.clone()))),
ControlInstruction::If(BlockType::None, expression.clone(), Some(expression.clone())).into()
);VariantsΒ§
Nop
The πππ instruction does nothing.
Unreachable
The ππππΎπΊπΌππΊπ»π πΎ instruction causes an unconditional trap.
Block(BlockType, Expression)
A logical grouping used introduce a label around an expression.
Loop(BlockType, Expression)
Executes the expression in a loop.
If(BlockType, Expression, Option<Expression>)
Conditionally executes a positive or (optional) negative branch based on a test value.
Branch(LabelIndex)
The π»π instruction performs an unconditional branch.
BranchIf(LabelIndex)
The π»π_ππΏ instruction performs a conditional branch
BranchTable(Vec<LabelIndex>, LabelIndex)
The π»π_ππΊπ»π πΎ instruction performs an indirect branch through an operand indexing into the label vector that is an immediate to the instruction, or to a default target if the operand is out of bounds.
Return
The ππΎππππ instruction is a shortcut for an unconditional branch to the outermost block, which implicitly is the body of the current function.
Call(FunctionIndex)
The πΌπΊπ π instruction invokes another function, consuming the necessary arguments from the stack and returning the result values of the call.
CallIndirect(TypeIndex, TableIndex)
The πΌπΊπ π _πππ½πππΎπΌπ instruction calls a function indirectly through an operand indexing into a table that is denoted by a table index and must have type πΏπππΌππΎπΏ. Since it may contain functions of heterogeneous type, the callee is dynamically checked against the function type indexed by the instructionβs second immediate, and the call is aborted with a trap if it does not match.
Trait ImplementationsΒ§
SourceΒ§impl Clone for ControlInstruction
impl Clone for ControlInstruction
SourceΒ§fn clone(&self) -> ControlInstruction
fn clone(&self) -> ControlInstruction
1.0.0 Β· SourceΒ§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more