use super::compact::Operand;
#[derive(Debug, Clone, PartialEq)]
pub enum Instruction {
Label {
label: u32,
},
FuncInfo {
module: Operand,
function: Operand,
arity: Operand,
},
Move {
source: Operand,
destination: Operand,
},
Call {
arity: Operand,
label: Operand,
},
CallOnly {
arity: Operand,
label: Operand,
},
CallExt {
arity: Operand,
import: Operand,
},
CallExtOnly {
arity: Operand,
import: Operand,
},
Fmove {
source: Operand,
dest: Operand,
},
Fconv {
source: Operand,
dest: Operand,
},
Fadd {
fail: Operand,
left: Operand,
right: Operand,
dest: Operand,
},
Fsub {
fail: Operand,
left: Operand,
right: Operand,
dest: Operand,
},
Fmul {
fail: Operand,
left: Operand,
right: Operand,
dest: Operand,
},
Fdiv {
fail: Operand,
left: Operand,
right: Operand,
dest: Operand,
},
Fnegate {
fail: Operand,
source: Operand,
dest: Operand,
},
CallLast {
arity: Operand,
label: Operand,
deallocate: Operand,
},
CallExtLast {
arity: Operand,
import: Operand,
deallocate: Operand,
},
Return,
Allocate {
stack_need: Operand,
live: Operand,
},
AllocateHeap {
stack_need: Operand,
heap_need: Operand,
live: Operand,
},
AllocateZero {
stack_need: Operand,
live: Operand,
},
Deallocate {
words: Operand,
},
TestHeap {
heap_need: Operand,
live: Operand,
},
PutList {
head: Operand,
tail: Operand,
destination: Operand,
},
PutTuple2 {
destination: Operand,
elements: Operand,
},
GetTupleElement {
source: Operand,
index: Operand,
destination: Operand,
},
GetList {
source: Operand,
head: Operand,
tail: Operand,
},
GetHd {
source: Operand,
destination: Operand,
},
GetTl {
source: Operand,
destination: Operand,
},
TypeTest {
op: TypeTestOp,
fail: Operand,
value: Operand,
},
Comparison {
op: ComparisonOp,
fail: Operand,
left: Operand,
right: Operand,
},
TestArity {
fail: Operand,
tuple: Operand,
arity: Operand,
},
IsTaggedTuple {
fail: Operand,
value: Operand,
arity: Operand,
tag: Operand,
},
SelectVal {
value: Operand,
fail: Operand,
list: Operand,
},
SelectTupleArity {
value: Operand,
fail: Operand,
list: Operand,
},
Jump {
target: Operand,
},
Bif {
op: BifOp,
operands: Vec<Operand>,
},
Send,
RemoveMessage,
Timeout,
LoopRec {
fail: Operand,
destination: Operand,
},
LoopRecEnd {
fail: Operand,
},
Wait {
fail: Operand,
},
WaitTimeout {
fail: Operand,
timeout: Operand,
},
RecvMarkerReserve {
dest: Operand,
},
RecvMarkerBind {
marker: Operand,
label: Operand,
},
RecvMarkerClear {
marker: Operand,
},
RecvMarkerUse {
marker: Operand,
},
Catch {
destination: Operand,
label: Operand,
},
CatchEnd {
source: Operand,
},
Try {
destination: Operand,
label: Operand,
},
TryEnd {
source: Operand,
},
TryCase {
source: Operand,
},
TryCaseEnd {
source: Operand,
},
BinaryOp {
op: BinaryOp,
operands: Vec<Operand>,
},
MapOp {
op: MapOp,
operands: Vec<Operand>,
},
MakeFun {
operands: Vec<Operand>,
},
CallFun {
arity: Operand,
},
CallFun2 {
function: Operand,
arity: Operand,
destination: Operand,
},
Apply {
arity: Operand,
},
ApplyLast {
arity: Operand,
deallocate: Operand,
},
Badmatch {
value: Operand,
},
Badrecord {
value: Operand,
},
CaseEnd {
value: Operand,
},
IfEnd,
Raise {
stacktrace: Operand,
reason: Operand,
},
RawRaise,
Line {
index: Operand,
},
Trim {
words: Operand,
remaining: Operand,
},
OnLoad,
BuildStacktrace,
Swap {
left: Operand,
right: Operand,
},
InitYregs {
registers: Operand,
},
NifStart,
UpdateRecord {
operands: Vec<Operand>,
},
Generic {
opcode: u8,
name: &'static str,
operands: Vec<Operand>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TypeTestOp {
IsInteger,
IsFloat,
IsNumber,
IsAtom,
IsPid,
IsReference,
IsPort,
IsNil,
IsBinary,
IsList,
IsNonemptyList,
IsTuple,
IsFunction,
IsBoolean,
IsFunction2,
IsBitstr,
IsMap,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ComparisonOp {
Lt,
Ge,
Eq,
Ne,
EqExact,
NeExact,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BifOp {
Bif0,
Bif1,
Bif2,
GcBif1,
GcBif2,
GcBif3,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinaryOp {
BsGetInteger2,
BsGetFloat2,
BsGetBinary2,
BsSkipBits2,
BsTestTail2,
BsTestUnit,
BsMatchString,
BsInitWritable,
BsGetUtf8,
BsSkipUtf8,
BsGetUtf16,
BsSkipUtf16,
BsGetUtf32,
BsSkipUtf32,
BsGetTail,
BsStartMatch3,
BsGetPosition,
BsSetPosition,
BsStartMatch4,
BsCreateBin,
BsMatch,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MapOp {
PutMapAssoc,
PutMapExact,
HasMapFields,
GetMapElements,
}
pub(crate) fn instruction_opcode(instruction: &Instruction) -> Option<u8> {
match instruction {
Instruction::Label { .. } => Some(1),
Instruction::FuncInfo { .. } => Some(2),
Instruction::Call { .. } => Some(4),
Instruction::CallLast { .. } => Some(5),
Instruction::CallOnly { .. } => Some(6),
Instruction::CallExt { .. } => Some(7),
Instruction::CallExtLast { .. } => Some(8),
Instruction::CallExtOnly { .. } => Some(78),
Instruction::Fmove { .. } => Some(96),
Instruction::Fconv { .. } => Some(97),
Instruction::Fadd { .. } => Some(98),
Instruction::Fsub { .. } => Some(99),
Instruction::Fmul { .. } => Some(100),
Instruction::Fdiv { .. } => Some(101),
Instruction::Fnegate { .. } => Some(102),
Instruction::RecvMarkerReserve { .. } => Some(173),
Instruction::RecvMarkerBind { .. } => Some(174),
Instruction::RecvMarkerClear { .. } => Some(175),
Instruction::RecvMarkerUse { .. } => Some(176),
Instruction::IsTaggedTuple { .. } => Some(159),
Instruction::Generic { opcode, .. } => Some(*opcode),
_ => None,
}
}