Expand description
FuelVM opcodes representation
Fuel ASM
Instruction set for the FuelVM.
Compile features
std
: Unless set, the crate will link to the core-crate instead of the std-crate. More info here.serde
: Add support for serde for the types exposed by this crate.
Example
use fuel_asm::*;
use Opcode::*;
// A sample program to perform ecrecover
let program = vec![
MOVE(0x10, 0x01), // set r[0x10] := $one
SLLI(0x20, 0x10, 5), // set r[0x20] := `r[0x10] << 5 == 32`
SLLI(0x21, 0x10, 6), // set r[0x21] := `r[0x10] << 6 == 64`
ALOC(0x21), // alloc `r[0x21] == 64` to the heap
ADDI(0x10, 0x07, 1), // set r[0x10] := `$hp + 1` (allocated heap)
MOVE(0x11, 0x04), // set r[0x11] := $ssp
ADD(0x12, 0x04, 0x20), // set r[0x12] := `$ssp + r[0x20]`
ECR(0x10, 0x11, 0x12), // recover public key in memory[r[0x10], 64]
RET(0x01), // return `1`
];
// Convert program to bytes representation
let bytes: Vec<u8> = program.iter().copied().collect();
// A program can be reconstructed from an iterator of bytes
let restored = Opcode::from_bytes_iter(bytes.iter().copied());
assert_eq!(program, restored);
// Every instruction can be described as `u32` big-endian bytes
let halfwords: Vec<u32> = program.iter().copied().map(u32::from).collect();
let bytes = halfwords.iter().copied().map(u32::to_be_bytes).flatten();
let restored = Opcode::from_bytes_iter(bytes);
assert_eq!(program, restored);
// We can also reconstruct the instructions individually
let restored: Vec<Opcode> = halfwords.iter().copied().map(Opcode::from).collect();
assert_eq!(program, restored);
// We have an unchecked variant for optimal performance
let restored: Vec<Opcode> = halfwords
.iter()
.copied()
.map(|w| unsafe { Opcode::from_bytes_unchecked(&w.to_be_bytes()) })
.collect();
assert_eq!(program, restored);
// Finally, we have [`Instruction`] to allow optimal runtime parsing of the components of the
// opcode
//
// `Opcode` itself is only but an abstraction/helper to facilitate visualization, but the VM is
// expected to use raw instructions
let instrs: Vec<Instruction> = program.iter().copied().map(Instruction::from).collect();
let restored: Vec<Opcode> = instrs.iter().copied().map(Opcode::from).collect();
assert_eq!(program, restored);
// An instruction is composed by the opcode representation registers Id and immediate values
assert_eq!(instrs[1].op(), OpcodeRepr::SLLI as u8);
assert_eq!(instrs[1].ra(), 0x20);
assert_eq!(instrs[1].rb(), 0x10);
assert_eq!(instrs[1].imm12(), 5);
Re-exports
pub use fuel_types;
pub use fuel_types::Immediate06;
pub use fuel_types::Immediate12;
pub use fuel_types::Immediate18;
pub use fuel_types::Immediate24;
pub use fuel_types::RegisterId;
pub use fuel_types::Word;
pub use serde;
pub use arbitrary;
Structs
A version of Opcode that can used without unnecessary branching
Describe a panic reason with the instruction that generated it
Enums
Argument list for GM (get metadata) instruction
Argument list for GTF (get tx fields) instruction
Instruction representation for the interpreter.
Byte representation of an opcode
Panic reason representation for the interpreter.