use std::rc::Rc;
use crate::sema::{BinOp, EventId, FunId, InterfaceId, PType, StateId};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Root {
Local(u32),
Field(u32),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PathElem {
TupleField(u32),
SeqIndex,
MapKey,
}
#[derive(Debug, Clone)]
pub struct ReceiveCase {
pub event: EventId,
pub param_slot: Option<u32>,
pub target: u32,
}
#[derive(Debug, Clone)]
pub enum Op {
PushNull,
PushBool(bool),
PushInt(i64),
PushFloat(f64),
PushEvent(EventId),
PushThis,
LoadLocal(u32),
StoreLocal(u32),
LoadField(u32),
LoadGlobal(u32),
Pop,
Dup,
MakeTuple(u32),
MakeNamedTuple(Rc<[String]>),
TupleGet(u32),
SeqGet,
SetGet,
MapGet {
java_null: bool,
},
Keys,
Values,
Sizeof,
Contains,
Default(crate::checker::value::Value),
Format {
base: Rc<str>,
nargs: u32,
types: Rc<[PType]>,
},
Bin(BinOp),
Neg,
Not,
Jump(u32),
JumpIfFalse(u32),
JumpIfTrue(u32),
Cast(std::rc::Rc<PType>),
CoerceFloat,
CoerceInt,
CoerceInterface(InterfaceId),
ChooseBool,
ChooseInt,
ChooseSeq,
ChooseSet,
ChooseMap,
Call {
fun: FunId,
nargs: u32,
},
Return,
Store {
root: Root,
path: Rc<[PathElem]>,
},
Insert {
root: Root,
path: Rc<[PathElem]>,
},
Add {
root: Root,
path: Rc<[PathElem]>,
},
Remove {
root: Root,
path: Rc<[PathElem]>,
},
Assert,
Print,
Create {
iface: InterfaceId,
has_payload: bool,
},
Send {
has_payload: bool,
},
Raise {
has_payload: bool,
},
Announce {
has_payload: bool,
},
Goto {
state: StateId,
has_payload: bool,
},
Receive {
cases: Rc<[ReceiveCase]>,
},
ForeachInit {
iter_slot: u32,
root: Option<Root>,
},
ForeachNext {
iter_slot: u32,
item_slot: u32,
exit: u32,
},
StoreField(u32),
StoreLocalConst {
slot: u32,
value: crate::checker::value::Value,
},
LocalTupleGet {
slot: u32,
index: u32,
},
LocalSizeof(u32),
MapGetLocal {
slot: u32,
java_null: bool,
},
KeysSizeof,
KeysContains,
KeyAtLocal(u32),
IntBin {
op: BinOp,
rhs: Operand,
},
IntCmpJumpIfFalse {
op: BinOp,
rhs: Operand,
target: u32,
},
JumpIfFalseElsePop(u32),
JumpIfTrueElsePop(u32),
ReturnNull,
UnreadFormat {
base: Rc<str>,
nargs: u32,
types: Rc<[PType]>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Operand {
Stack,
Local(u32),
Int(i64),
}
impl Operand {
pub fn work(self) -> u64 {
match self {
Operand::Stack => 0,
Operand::Local(_) | Operand::Int(_) => 1,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct CodeBlock {
pub ops: Vec<Op>,
pub frame_size: u32,
pub param_slots: Vec<u32>,
pub params_in_order: bool,
}