Skip to content

Instruction Set Reference

This page is the authoritative reference for every instruction in the Move bytecode instruction set as executed by the Aptos MoveVM. It is intended for developers building bytecode interpreters, disassemblers, static analyzers, or anyone who needs to understand exactly what the VM does for each opcode.

The MoveVM is a stack-based virtual machine. Each function invocation creates a new frame that contains:

  • An operand stack where intermediate values are pushed and popped.
  • A locals array indexed by LocalIndex (u8), holding function parameters and local variables.
  • A program counter (PC) pointing at the current instruction in the function body.

Instructions consume operands from the top of the stack, perform computation, and push results back. Control flow instructions modify the PC. The Call instruction creates a new frame on the call stack; Ret destroys the current frame and returns to the caller.

For a description of the types that values can have, see the Type System page. For the binary layout of a compiled module, see the Module Format page.

Each instruction entry documents the following:

FieldMeaning
OpcodeThe hexadecimal byte value that identifies the instruction in the bytecode stream.
OperandsImmediate values encoded after the opcode byte (indices, constants, offsets).
Stack effectValues consumed (popped) and produced (pushed). Notation: [..., a, b] means a was pushed first and b is on top. The arrow shows the transition: [..., a, b] -> [...] means both a and b are popped; [...] -> [..., c] means c is pushed.
DescriptionBehavior and error conditions.
SinceBytecode version that introduced the instruction, if later than v5 (the minimum supported version).

Index operands are encoded as ULEB128 integers in the bytecode stream unless otherwise noted. Immediate integer values (e.g., the value for LdU64) are encoded in little-endian fixed-width format matching their type width.

The table below lists every instruction with its opcode and a one-line summary. Click the instruction name to jump to its detailed entry.

OpcodeInstructionSummary
0x01PopDiscard the top stack value.
0x02RetReturn from the current function.
0x03BrTrueBranch if top of stack is true.
0x04BrFalseBranch if top of stack is false.
0x05BranchUnconditional branch.
0x06LdU64Push a u64 immediate.
0x07LdConstPush a value from the constant pool.
0x08LdTruePush true.
0x09LdFalsePush false.
0x0ACopyLocCopy a local onto the stack.
0x0BMoveLocMove a local onto the stack.
0x0CStLocPop and store into a local.
0x0DMutBorrowLocPush &mut reference to a local.
0x0EImmBorrowLocPush & reference to a local.
0x0FMutBorrowFieldMutable borrow a struct field.
0x10ImmBorrowFieldImmutable borrow a struct field.
0x11CallCall a function by handle index.
0x12PackCreate a struct instance.
0x13UnpackDestroy a struct, push its fields.
0x14ReadRefDereference and copy.
0x15WriteRefWrite through a mutable reference.
0x16AddInteger addition.
0x17SubInteger subtraction.
0x18MulInteger multiplication.
0x19ModInteger modulo.
0x1ADivInteger division.
0x1BBitOrBitwise OR.
0x1CBitAndBitwise AND.
0x1DXorBitwise XOR.
0x1EOrBoolean OR.
0x1FAndBoolean AND.
0x20NotBoolean negation.
0x21EqEquality test.
0x22NeqInequality test.
0x23LtLess than.
0x24GtGreater than.
0x25LeLess than or equal.
0x26GeGreater than or equal.
0x27AbortAbort with error code.
0x28NopNo operation.
0x29ExistsTest if resource exists at address.
0x2AMutBorrowGlobalMutable borrow a global resource.
0x2BImmBorrowGlobalImmutable borrow a global resource.
0x2CMoveFromRemove a resource from global storage.
0x2DMoveToPublish a resource to global storage.
0x2EFreezeRefConvert &mut T to &T.
0x2FShlShift left.
0x30ShrShift right.
0x31LdU8Push a u8 immediate.
0x32LdU128Push a u128 immediate.
0x33CastU8Cast to u8.
0x34CastU64Cast to u64.
0x35CastU128Cast to u128.
0x36MutBorrowFieldGenericGeneric mutable field borrow.
0x37ImmBorrowFieldGenericGeneric immutable field borrow.
0x38CallGenericCall a generic function instantiation.
0x39PackGenericCreate a generic struct instance.
0x3AUnpackGenericDestroy a generic struct, push its fields.
0x3BExistsGenericGeneric resource existence test.
0x3CMutBorrowGlobalGenericGeneric mutable global borrow.
0x3DImmBorrowGlobalGenericGeneric immutable global borrow.
0x3EMoveFromGenericGeneric remove resource.
0x3FMoveToGenericGeneric publish resource.
0x40VecPackCreate a vector from stack values.
0x41VecLenGet vector length.
0x42VecImmBorrowImmutable borrow vector element.
0x43VecMutBorrowMutable borrow vector element.
0x44VecPushBackAppend to vector.
0x45VecPopBackRemove last vector element.
0x46VecUnpackDestroy vector, push all elements.
0x47VecSwapSwap two vector elements.
0x48LdU16Push a u16 immediate.
0x49LdU32Push a u32 immediate.
0x4ALdU256Push a u256 immediate.
0x4BCastU16Cast to u16.
0x4CCastU32Cast to u32.
0x4DCastU256Cast to u256.
0x4EImmBorrowVariantFieldImmutable borrow variant field (v7).
0x4FMutBorrowVariantFieldMutable borrow variant field (v7).
0x50ImmBorrowVariantFieldGenericGeneric immutable variant field borrow (v7).
0x51MutBorrowVariantFieldGenericGeneric mutable variant field borrow (v7).
0x52PackVariantCreate an enum variant (v7).
0x53PackVariantGenericCreate a generic enum variant (v7).
0x54UnpackVariantDestroy an enum variant, push fields (v7).
0x55UnpackVariantGenericDestroy a generic enum variant (v7).
0x56TestVariantTest whether a value is a given variant (v7).
0x57TestVariantGenericGeneric variant test (v7).
0x58PackClosureCreate a closure (v8).
0x59PackClosureGenericCreate a generic closure (v8).
0x5ACallClosureInvoke a closure (v8).
0x5BLdI8Push an i8 immediate (v9).
0x5CLdI16Push an i16 immediate (v9).
0x5DLdI32Push an i32 immediate (v9).
0x5ELdI64Push an i64 immediate (v9).
0x5FLdI128Push an i128 immediate (v9).
0x60LdI256Push an i256 immediate (v9).
0x61CastI8Cast to i8 (v9).
0x62CastI16Cast to i16 (v9).
0x63CastI32Cast to i32 (v9).
0x64CastI64Cast to i64 (v9).
0x65CastI128Cast to i128 (v9).
0x66CastI256Cast to i256 (v9).
0x67NegateNegate a signed integer (v9).
0x68AbortMsgAbort with error code and message (v10).

These instructions manipulate the operand stack directly — pushing constants, loading from the constant pool, or discarding values.

Opcode0x01
OperandsNone
Stack[..., value] -> [...]

Pop and discard the top value on the stack. The value must have the drop ability.

Opcode0x08
OperandsNone
Stack[...] -> [..., true]

Push the boolean value true onto the stack.

Opcode0x09
OperandsNone
Stack[...] -> [..., false]

Push the boolean value false onto the stack.

Opcode0x31
Operandsu8_value (1 byte)
Stack[...] -> [..., u8_value]

Push the given u8 constant onto the stack. The immediate byte follows the opcode directly.

Opcode0x48
Operandsu16_value (2 bytes, little-endian)
Stack[...] -> [..., u16_value]

Push the given u16 constant onto the stack.

Opcode0x49
Operandsu32_value (4 bytes, little-endian)
Stack[...] -> [..., u32_value]

Push the given u32 constant onto the stack.

Opcode0x06
Operandsu64_value (8 bytes, little-endian)
Stack[...] -> [..., u64_value]

Push the given u64 constant onto the stack.

Opcode0x32
Operandsu128_value (16 bytes, little-endian)
Stack[...] -> [..., u128_value]

Push the given u128 constant onto the stack.

Opcode0x4A
Operandsu256_value (32 bytes, little-endian)
Stack[...] -> [..., u256_value]

Push the given u256 constant onto the stack.

Opcode0x07
Operandsconst_idx (ULEB128 — ConstantPoolIndex)
Stack[...] -> [..., constant_value]

Load a constant from the module’s constant pool, deserialize it according to its declared type, and push the resulting value onto the stack. The constant pool entry stores both the serialized bytes and the type signature.

Opcode0x28
OperandsNone
Stack[...] -> [...]

No operation. The PC advances by one. This instruction can serve as a placeholder or alignment padding in the bytecode stream.


These instructions transfer values between the operand stack and the frame’s locals array.

Opcode0x0A
Operandslocal_idx (u8)
Stack[...] -> [..., value]

Copy the value stored in locals[local_idx] and push it onto the stack. The local remains valid for subsequent use. The type of the local must have the copy ability.

Opcode0x0B
Operandslocal_idx (u8)
Stack[...] -> [..., value]

Move the value out of locals[local_idx] onto the stack. After this instruction the local is invalidated. Any read of the local before a subsequent StLoc to that index is a verification error.

Opcode0x0C
Operandslocal_idx (u8)
Stack[..., value] -> [...]

Pop the top value from the stack and store it into locals[local_idx]. If the local already holds a value, that previous value is dropped (the type must have the drop ability in that case). The type of the value must match the declared type of the local.

Opcode0x0D
Operandslocal_idx (u8)
Stack[...] -> [..., &mut T]

Push a mutable reference to locals[local_idx] onto the stack. The local must currently hold a valid value.

Opcode0x0E
Operandslocal_idx (u8)
Stack[...] -> [..., &T]

Push an immutable reference to locals[local_idx] onto the stack.


These instructions interact with the global resource storage — the persistent key-value store keyed by (address, type) pairs. The struct types used must have the key ability.

Opcode0x29
Operandsstruct_def_idx (ULEB128 — StructDefinitionIndex)
Stack[..., address] -> [..., bool]

Pop an address from the stack and push true if an instance of the specified struct type exists at that address in global storage, false otherwise.

Opcode0x3B
Operandsstruct_inst_idx (ULEB128 — StructDefInstantiationIndex)
Stack[..., address] -> [..., bool]

Generic version of Exists. The operand indexes into the struct instantiation table which provides the concrete type arguments.

Opcode0x2C
Operandsstruct_def_idx (ULEB128 — StructDefinitionIndex)
Stack[..., address] -> [..., struct_value]

Pop an address, remove the resource of the specified type from global storage at that address, and push the value onto the stack. Aborts if no such resource exists.

Opcode0x3E
Operandsstruct_inst_idx (ULEB128 — StructDefInstantiationIndex)
Stack[..., address] -> [..., struct_value]

Generic version of MoveFrom.

Opcode0x2D
Operandsstruct_def_idx (ULEB128 — StructDefinitionIndex)
Stack[..., signer_ref, struct_value] -> [...]

Pop a struct value and a &signer reference from the stack. Publish the struct value to global storage under the signer’s address. Aborts if a resource of the same type already exists at that address.

Opcode0x3F
Operandsstruct_inst_idx (ULEB128 — StructDefInstantiationIndex)
Stack[..., signer_ref, struct_value] -> [...]

Generic version of MoveTo.

Opcode0x2A
Operandsstruct_def_idx (ULEB128 — StructDefinitionIndex)
Stack[..., address] -> [..., &mut T]

Pop an address, acquire a mutable reference to the resource of the specified type at that address, and push the reference. Aborts if the resource does not exist.

Opcode0x3C
Operandsstruct_inst_idx (ULEB128 — StructDefInstantiationIndex)
Stack[..., address] -> [..., &mut T]

Generic version of MutBorrowGlobal.

Opcode0x2B
Operandsstruct_def_idx (ULEB128 — StructDefinitionIndex)
Stack[..., address] -> [..., &T]

Pop an address, acquire an immutable reference to the resource of the specified type at that address, and push the reference. Aborts if the resource does not exist.

Opcode0x3D
Operandsstruct_inst_idx (ULEB128 — StructDefInstantiationIndex)
Stack[..., address] -> [..., &T]

Generic version of ImmBorrowGlobal.


These instructions borrow individual fields from struct references on the stack.

Opcode0x0F
Operandsfield_handle_idx (ULEB128 — FieldHandleIndex)
Stack[..., &mut Struct] -> [..., &mut FieldType]

Pop a mutable reference to a struct, and push a mutable reference to the field identified by the field handle. The field handle encodes both the struct definition and the field offset within that struct.

Opcode0x36
Operandsfield_inst_idx (ULEB128 — FieldInstantiationIndex)
Stack[..., &mut Struct<T>] -> [..., &mut FieldType]

Generic version of MutBorrowField. The field instantiation table provides the concrete type arguments for the struct.

Opcode0x10
Operandsfield_handle_idx (ULEB128 — FieldHandleIndex)
Stack[..., &Struct] -> [..., &FieldType] or [..., &mut Struct] -> [..., &FieldType]

Pop an immutable or mutable reference to a struct, and push an immutable reference to the specified field.

Opcode0x37
Operandsfield_inst_idx (ULEB128 — FieldInstantiationIndex)
Stack[..., &Struct<T>] -> [..., &FieldType] or [..., &mut Struct<T>] -> [..., &FieldType]

Generic version of ImmBorrowField.


These instructions dereference, write through, or convert references.

Opcode0x14
OperandsNone
Stack[..., &T] -> [..., T] or [..., &mut T] -> [..., T]

Pop a reference (mutable or immutable), copy the referenced value, and push the copy onto the stack. The referenced type must have the copy ability.

Opcode0x15
OperandsNone
Stack[..., value, &mut T] -> [...]

Pop a mutable reference and a value from the stack, then write the value through the reference. The previous value at that location is dropped, so the type must have the drop ability. The type of the value must match the reference’s inner type.

Opcode0x2E
OperandsNone
Stack[..., &mut T] -> [..., &T]

Pop a mutable reference and push it back as an immutable reference. This is a type-level conversion only — no runtime work is performed beyond the borrow tracking update.


All arithmetic instructions pop two integer operands of the same type from the stack and push the result. For unsigned types, Sub aborts on underflow and Add/Mul abort on overflow. For signed types, overflow and underflow both cause an arithmetic abort. Div and Mod abort when the divisor is zero. Div on signed integers also aborts on overflow (the minimum value divided by -1).

Opcode0x16
OperandsNone
Stack[..., lhs, rhs] -> [..., result]

Compute lhs + rhs. Aborts on overflow.

Opcode0x17
OperandsNone
Stack[..., lhs, rhs] -> [..., result]

Compute lhs - rhs. For unsigned types, aborts if lhs < rhs. For signed types, aborts on underflow.

Opcode0x18
OperandsNone
Stack[..., lhs, rhs] -> [..., result]

Compute lhs * rhs. Aborts on overflow.

Opcode0x19
OperandsNone
Stack[..., lhs, rhs] -> [..., result]

Compute lhs % rhs. Aborts if rhs == 0.

Opcode0x1A
OperandsNone
Stack[..., lhs, rhs] -> [..., result]

Compute lhs / rhs (integer division, truncating toward zero). Aborts if rhs == 0. For signed types, also aborts if lhs == MIN_VALUE && rhs == -1 (overflow).

Opcode0x67
OperandsNone
Stack[..., value] -> [..., result]
SinceBytecode v9

Negate the signed integer on top of the stack. Computes -value. Aborts if the value is the minimum of its signed integer type (e.g., i8::MIN), because the positive counterpart is not representable.


Bitwise instructions operate on two integer values of the same type (except for shift operations, where the shift amount is always u8).

Opcode0x1B
OperandsNone
Stack[..., lhs, rhs] -> [..., result]

Compute lhs | rhs (bitwise OR). Both operands must be the same integer type.

Opcode0x1C
OperandsNone
Stack[..., lhs, rhs] -> [..., result]

Compute lhs & rhs (bitwise AND). Both operands must be the same integer type.

Opcode0x1D
OperandsNone
Stack[..., lhs, rhs] -> [..., result]

Compute lhs ^ rhs (bitwise XOR). Both operands must be the same integer type.

Opcode0x2F
OperandsNone
Stack[..., value, shift_amount] -> [..., result]

Shift value left by shift_amount bits. The shift_amount must be of type u8 and must be less than the bit width of the value’s type. Aborts with an arithmetic error if the shift amount is out of range.

Opcode0x30
OperandsNone
Stack[..., value, shift_amount] -> [..., result]

Shift value right by shift_amount bits. The shift_amount must be of type u8 and must be less than the bit width of the value’s type. For signed integers this performs an arithmetic right shift (sign-extending). Aborts with an arithmetic error if the shift amount is out of range.


These instructions compare two integer values and push a boolean result. Both operands must be the same integer type.

Opcode0x23
OperandsNone
Stack[..., lhs, rhs] -> [..., bool]

Push true if lhs < rhs, false otherwise.

Opcode0x24
OperandsNone
Stack[..., lhs, rhs] -> [..., bool]

Push true if lhs > rhs, false otherwise.

Opcode0x25
OperandsNone
Stack[..., lhs, rhs] -> [..., bool]

Push true if lhs <= rhs, false otherwise.

Opcode0x26
OperandsNone
Stack[..., lhs, rhs] -> [..., bool]

Push true if lhs >= rhs, false otherwise.


Equality is defined for primitive types (bool, address, all integer types), vector<T> where T supports equality, and references &T/&mut T where T supports equality. Both values are consumed (the type must have the drop ability).

Opcode0x21
OperandsNone
Stack[..., lhs, rhs] -> [..., bool]

Push true if lhs == rhs, false otherwise.

Opcode0x22
OperandsNone
Stack[..., lhs, rhs] -> [..., bool]

Push true if lhs != rhs, false otherwise.


These instructions operate on bool values.

Opcode0x1F
OperandsNone
Stack[..., lhs, rhs] -> [..., bool]

Compute lhs && rhs (logical AND).

Opcode0x1E
OperandsNone
Stack[..., lhs, rhs] -> [..., bool]

Compute lhs || rhs (logical OR).

Opcode0x20
OperandsNone
Stack[..., value] -> [..., bool]

Compute !value (logical NOT).


Cast instructions convert one integer type to another. If the source value is outside the representable range of the target type, the instruction aborts with an arithmetic error. For unsigned target types, negative source values cause an abort. For CastU256 and CastI256, all non-negative integer values fit (though negative values still abort for CastU256).

Opcode0x33
OperandsNone
Stack[..., int_value] -> [..., u8]

Cast the top integer value to u8. Aborts if the value is negative or exceeds u8::MAX (255).

Opcode0x4B
OperandsNone
Stack[..., int_value] -> [..., u16]

Cast the top integer value to u16. Aborts if the value is negative or exceeds u16::MAX (65535).

Opcode0x4C
OperandsNone
Stack[..., int_value] -> [..., u32]

Cast the top integer value to u32. Aborts if the value is negative or exceeds u32::MAX.

Opcode0x34
OperandsNone
Stack[..., int_value] -> [..., u64]

Cast the top integer value to u64. Aborts if the value is negative or exceeds u64::MAX.

Opcode0x35
OperandsNone
Stack[..., int_value] -> [..., u128]

Cast the top integer value to u128. Aborts if the value is negative or exceeds u128::MAX.

Opcode0x4D
OperandsNone
Stack[..., int_value] -> [..., u256]

Cast the top integer value to u256. Aborts if the value is negative.

Opcode0x61
OperandsNone
Stack[..., int_value] -> [..., i8]
SinceBytecode v9

Cast the top integer value to i8. Aborts if the value is outside the range i8::MIN (-128) to i8::MAX (127).

Opcode0x62
OperandsNone
Stack[..., int_value] -> [..., i16]
SinceBytecode v9

Cast the top integer value to i16. Aborts if the value is outside the range i16::MIN (-32768) to i16::MAX (32767).

Opcode0x63
OperandsNone
Stack[..., int_value] -> [..., i32]
SinceBytecode v9

Cast the top integer value to i32. Aborts if the value is outside the representable range.

Opcode0x64
OperandsNone
Stack[..., int_value] -> [..., i64]
SinceBytecode v9

Cast the top integer value to i64. Aborts if the value is outside the representable range.

Opcode0x65
OperandsNone
Stack[..., int_value] -> [..., i128]
SinceBytecode v9

Cast the top integer value to i128. Aborts if the value is outside the representable range.

Opcode0x66
OperandsNone
Stack[..., int_value] -> [..., i256]
SinceBytecode v9

Cast the top integer value to i256. Aborts if the value exceeds i256::MAX.


Opcode0x05
Operandscode_offset (u16, little-endian)
Stack[...] -> [...]

Unconditionally set the PC to code_offset. The offset is relative to the beginning of the function’s instruction stream.

Opcode0x03
Operandscode_offset (u16, little-endian)
Stack[..., bool] -> [...]

Pop a boolean from the stack. If true, set the PC to code_offset. Otherwise, advance the PC by one.

Opcode0x04
Operandscode_offset (u16, little-endian)
Stack[..., bool] -> [...]

Pop a boolean from the stack. If false, set the PC to code_offset. Otherwise, advance the PC by one.

Opcode0x02
OperandsNone
Stack[..., ret_val_0, ..., ret_val_n] (return values must match the function signature)

Return from the current function. The frame is popped from the call stack. Return values (if any) remain on the caller’s operand stack. The number and types of values on the stack must match the function’s return type signature.

Opcode0x27
OperandsNone
Stack[..., error_code]

Pop a u64 error code from the stack and abort the transaction. All changes made during the transaction are rolled back.

Opcode0x68
OperandsNone
Stack[..., error_code, error_message]
SinceBytecode v10

Pop a vector<u8> error message and a u64 error code from the stack and abort the transaction with both. This provides richer diagnostics than Abort alone.


Opcode0x11
Operandsfunc_handle_idx (ULEB128 — FunctionHandleIndex)
Stack[..., arg_0, ..., arg_n-1] -> [..., ret_0, ..., ret_m]

Call the function identified by func_handle_idx. Arguments are on the stack in declaration order (first parameter pushed first, last parameter on top). All arguments are consumed.

For non-native functions, a new frame is pushed onto the call stack with the arguments loaded as the first locals. For native functions, the VM dispatches directly to the native implementation; when it returns, the return values are on the caller’s stack.

Opcode0x38
Operandsfunc_inst_idx (ULEB128 — FunctionInstantiationIndex)
Stack[..., arg_0, ..., arg_n-1] -> [..., ret_0, ..., ret_m]

Generic version of Call. The function instantiation table entry specifies both the function handle and the concrete type arguments to substitute for the function’s generic parameters.


These instructions create and destroy struct instances.

Opcode0x12
Operandsstruct_def_idx (ULEB128 — StructDefinitionIndex)
Stack[..., field_0, ..., field_n-1] -> [..., struct_value]

Pop field values from the stack in declaration order (first field pushed first) and create a new struct instance. All fields must be provided.

Opcode0x39
Operandsstruct_inst_idx (ULEB128 — StructDefInstantiationIndex)
Stack[..., field_0, ..., field_n-1] -> [..., struct_value]

Generic version of Pack. The struct instantiation entry provides the concrete type arguments.

Opcode0x13
Operandsstruct_def_idx (ULEB128 — StructDefinitionIndex)
Stack[..., struct_value] -> [..., field_0, ..., field_n-1]

Pop a struct value, destroy it, and push its field values onto the stack in declaration order (first field pushed first, last field on top).

Opcode0x3A
Operandsstruct_inst_idx (ULEB128 — StructDefInstantiationIndex)
Stack[..., struct_value] -> [..., field_0, ..., field_n-1]

Generic version of Unpack.


These instructions work with enum types (structs with multiple variants). They were introduced in bytecode version 7. See the Version History for details on when enum support was added.

Opcode0x52
Operandsstruct_variant_handle_idx (ULEB128 — StructVariantHandleIndex)
Stack[..., field_0, ..., field_n-1] -> [..., variant_value]
SinceBytecode v7

Pop field values in declaration order and create a new instance of the specified enum variant. The variant handle identifies both the struct definition and the specific variant.

Opcode0x53
Operandsstruct_variant_inst_idx (ULEB128 — StructVariantInstantiationIndex)
Stack[..., field_0, ..., field_n-1] -> [..., variant_value]
SinceBytecode v7

Generic version of PackVariant.

Opcode0x54
Operandsstruct_variant_handle_idx (ULEB128 — StructVariantHandleIndex)
Stack[..., variant_value] -> [..., field_0, ..., field_n-1]
SinceBytecode v7

Pop a value that is expected to be the specified variant. Destroy it and push its fields onto the stack in declaration order. Aborts if the value is not the expected variant.

Opcode0x55
Operandsstruct_variant_inst_idx (ULEB128 — StructVariantInstantiationIndex)
Stack[..., variant_value] -> [..., field_0, ..., field_n-1]
SinceBytecode v7

Generic version of UnpackVariant.

Opcode0x56
Operandsstruct_variant_handle_idx (ULEB128 — StructVariantHandleIndex)
Stack[..., &variant_value] -> [..., bool] or [..., &mut variant_value] -> [..., bool]
SinceBytecode v7

Pop a reference (immutable or mutable) to an enum value and push true if the value is the specified variant, false otherwise. The reference is consumed.

Opcode0x57
Operandsstruct_variant_inst_idx (ULEB128 — StructVariantInstantiationIndex)
Stack[..., &variant_value] -> [..., bool] or [..., &mut variant_value] -> [..., bool]
SinceBytecode v7

Generic version of TestVariant.

Opcode0x4E
Operandsvariant_field_handle_idx (ULEB128 — VariantFieldHandleIndex)
Stack[..., &variant_value] -> [..., &FieldType] or [..., &mut variant_value] -> [..., &FieldType]
SinceBytecode v7

Pop a reference to an enum value. If the value is the expected variant, push an immutable reference to the specified field. Aborts if the value is not the expected variant.

Opcode0x50
Operandsvariant_field_inst_idx (ULEB128 — VariantFieldInstantiationIndex)
Stack[..., &variant_value] -> [..., &FieldType] or [..., &mut variant_value] -> [..., &FieldType]
SinceBytecode v7

Generic version of ImmBorrowVariantField.

Opcode0x4F
Operandsvariant_field_handle_idx (ULEB128 — VariantFieldHandleIndex)
Stack[..., &mut variant_value] -> [..., &mut FieldType]
SinceBytecode v7

Pop a mutable reference to an enum value. If the value is the expected variant, push a mutable reference to the specified field. Aborts if the value is not the expected variant.

Opcode0x51
Operandsvariant_field_inst_idx (ULEB128 — VariantFieldInstantiationIndex)
Stack[..., &mut variant_value] -> [..., &mut FieldType]
SinceBytecode v7

Generic version of MutBorrowVariantField.


Closures capture a subset of a function’s arguments at creation time, producing a callable value. These instructions were introduced in bytecode version 8.

Opcode0x58
Operandsfunc_handle_idx (ULEB128 — FunctionHandleIndex), mask (ULEB128 — u64 bitmask)
Stack[..., captured_m, ..., captured_1] -> [..., closure]
SinceBytecode v8

Create a closure for the function identified by func_handle_idx. The mask is a u64 bitmask indicating which parameters of the function are captured. If the function has parameters (t1, t2, ..., tn) and the jth bit of mask is set, then the jth parameter is captured from the stack.

The captured values are popped from the stack (in reverse order of their parameter positions). The resulting closure, when called, will accept only the uncaptured parameters as arguments.

The ability set of the closure value is the intersection of the abilities of all captured values intersected with the inherent abilities of a function handle (copy + drop, plus store if the function is public).

Opcode0x59
Operandsfunc_inst_idx (ULEB128 — FunctionInstantiationIndex), mask (ULEB128 — u64 bitmask)
Stack[..., captured_m, ..., captured_1] -> [..., closure]
SinceBytecode v8

Generic version of PackClosure. Used when the function being captured is a generic instantiation. An uninstantiated generic function cannot be used to create a closure.

Opcode0x5A
Operandssig_idx (ULEB128 — SignatureIndex, encoding the function type)
Stack[..., arg_1, ..., arg_n, closure] -> [..., ret_0, ..., ret_m]
SinceBytecode v8

Invoke a closure. The closure is on top of the stack, with the remaining (uncaptured) arguments beneath it. The sig_idx encodes the expected function type for bytecode verification purposes. At runtime, the captured arguments stored inside the closure are combined with the provided arguments to form the complete parameter list, and the underlying function is called.

Semantically:

CallClosure(PackClosure(f, mask, c1..cn), a1..am) == f(mask.compose(c1..cn, a1..am))

These built-in instructions provide efficient vector manipulation without going through native function calls. Each takes a SignatureIndex operand that identifies the element type of the vector.

Opcode0x40
Operandselem_ty_idx (ULEB128 — SignatureIndex), num_elements (ULEB128 — u64)
Stack[..., elem_0, ..., elem_n-1] -> [..., vector]

Pop num_elements values from the stack and create a new vector containing them in order (first pushed = first element). All values must match the element type identified by elem_ty_idx.

Opcode0x41
Operandselem_ty_idx (ULEB128 — SignatureIndex)
Stack[..., &vector<T>] -> [..., u64] or [..., &mut vector<T>] -> [..., u64]

Pop a reference to a vector and push its length as a u64.

Opcode0x42
Operandselem_ty_idx (ULEB128 — SignatureIndex)
Stack[..., &vector<T>, index] -> [..., &T] or [..., &mut vector<T>, index] -> [..., &T]

Pop a u64 index and a reference to a vector, then push an immutable reference to the element at that index. Aborts if the index is out of bounds.

Opcode0x43
Operandselem_ty_idx (ULEB128 — SignatureIndex)
Stack[..., &mut vector<T>, index] -> [..., &mut T]

Pop a u64 index and a mutable vector reference, then push a mutable reference to the element at that index. Aborts if the index is out of bounds.

Opcode0x44
Operandselem_ty_idx (ULEB128 — SignatureIndex)
Stack[..., &mut vector<T>, value] -> [...]

Pop a value and a mutable vector reference, then append the value to the end of the vector.

Opcode0x45
Operandselem_ty_idx (ULEB128 — SignatureIndex)
Stack[..., &mut vector<T>] -> [..., T]

Pop a mutable vector reference, remove the last element from the vector, and push that element onto the stack. Aborts if the vector is empty.

Opcode0x46
Operandselem_ty_idx (ULEB128 — SignatureIndex), num_elements (ULEB128 — u64)
Stack[..., vector<T>] -> [..., elem_0, ..., elem_n-1]

Pop a vector (by value), destroy it, and push all num_elements elements onto the stack in order (first element pushed first). Aborts if the vector’s actual length does not equal num_elements.

Opcode0x47
Operandselem_ty_idx (ULEB128 — SignatureIndex)
Stack[..., &mut vector<T>, i, j] -> [...]

Pop two u64 indices (j on top, then i) and a mutable vector reference, then swap the elements at positions i and j. Aborts if either index is out of bounds.


These instructions push signed integer constants onto the stack. They were introduced in bytecode version 9 along with the signed integer type system.

Opcode0x5B
Operandsi8_value (1 byte, signed)
Stack[...] -> [..., i8_value]
SinceBytecode v9

Push the given i8 constant onto the stack.

Opcode0x5C
Operandsi16_value (2 bytes, little-endian, signed)
Stack[...] -> [..., i16_value]
SinceBytecode v9

Push the given i16 constant onto the stack.

Opcode0x5D
Operandsi32_value (4 bytes, little-endian, signed)
Stack[...] -> [..., i32_value]
SinceBytecode v9

Push the given i32 constant onto the stack.

Opcode0x5E
Operandsi64_value (8 bytes, little-endian, signed)
Stack[...] -> [..., i64_value]
SinceBytecode v9

Push the given i64 constant onto the stack.

Opcode0x5F
Operandsi128_value (16 bytes, little-endian, signed)
Stack[...] -> [..., i128_value]
SinceBytecode v9

Push the given i128 constant onto the stack.

Opcode0x60
Operandsi256_value (32 bytes, little-endian, signed)
Stack[...] -> [..., i256_value]
SinceBytecode v9

Push the given i256 constant onto the stack.