use super::{debug, ByteWriter, Instruction, Node, OpCode, Serializable};
use crate::ast::MAX_BODY_LEN;
impl Serializable for Node {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
match self {
Self::Instruction(inner) => inner.write_into(target),
Self::IfElse {
true_case,
false_case,
} => {
OpCode::IfElse.write_into(target);
assert!(true_case.nodes().len() <= MAX_BODY_LEN, "too many body nodes");
target.write_u16(true_case.nodes().len() as u16);
target.write_many(true_case.nodes());
assert!(false_case.nodes().len() <= MAX_BODY_LEN, "too many body nodes");
target.write_u16(false_case.nodes().len() as u16);
target.write_many(false_case.nodes());
}
Self::Repeat { times, body } => {
OpCode::Repeat.write_into(target);
target.write_u32(*times);
assert!(body.nodes().len() <= MAX_BODY_LEN, "too many body nodes");
target.write_u16(body.nodes().len() as u16);
target.write_many(body.nodes());
}
Self::While { body } => {
OpCode::While.write_into(target);
assert!(body.nodes().len() <= MAX_BODY_LEN, "too many body nodes");
target.write_u16(body.nodes().len() as u16);
target.write_many(body.nodes());
}
}
}
}
impl Serializable for Instruction {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
match self {
Self::Assert => OpCode::Assert.write_into(target),
Self::AssertWithError(err_code) => {
OpCode::AssertWithError.write_into(target);
target.write_u32(*err_code);
}
Self::AssertEq => OpCode::AssertEq.write_into(target),
Self::AssertEqWithError(err_code) => {
OpCode::AssertEqWithError.write_into(target);
target.write_u32(*err_code);
}
Self::AssertEqw => OpCode::AssertEqw.write_into(target),
Self::AssertEqwWithError(err_code) => {
OpCode::AssertEqwWithError.write_into(target);
target.write_u32(*err_code);
}
Self::Assertz => OpCode::Assertz.write_into(target),
Self::AssertzWithError(err_code) => {
OpCode::AssertzWithError.write_into(target);
target.write_u32(*err_code);
}
Self::Add => OpCode::Add.write_into(target),
Self::AddImm(v) => {
OpCode::AddImm.write_into(target);
v.write_into(target);
}
Self::Sub => OpCode::Sub.write_into(target),
Self::SubImm(v) => {
OpCode::SubImm.write_into(target);
v.write_into(target);
}
Self::Mul => OpCode::Mul.write_into(target),
Self::MulImm(v) => {
OpCode::MulImm.write_into(target);
v.write_into(target);
}
Self::Div => OpCode::Div.write_into(target),
Self::DivImm(v) => {
OpCode::DivImm.write_into(target);
v.write_into(target);
}
Self::Neg => OpCode::Neg.write_into(target),
Self::Inv => OpCode::Inv.write_into(target),
Self::Incr => OpCode::Incr.write_into(target),
Self::Pow2 => OpCode::Pow2.write_into(target),
Self::Exp => OpCode::Exp.write_into(target),
Self::ExpImm(v) => {
OpCode::ExpImm.write_into(target);
v.write_into(target);
}
Self::ExpBitLength(v) => {
OpCode::ExpBitLength.write_into(target);
target.write_u8(*v);
}
Self::ILog2 => OpCode::ILog2.write_into(target),
Self::Not => OpCode::Not.write_into(target),
Self::And => OpCode::And.write_into(target),
Self::Or => OpCode::Or.write_into(target),
Self::Xor => OpCode::Xor.write_into(target),
Self::Eq => OpCode::Eq.write_into(target),
Self::EqImm(v) => {
OpCode::EqImm.write_into(target);
v.write_into(target);
}
Self::Neq => OpCode::Neq.write_into(target),
Self::NeqImm(v) => {
OpCode::NeqImm.write_into(target);
v.write_into(target);
}
Self::Eqw => OpCode::Eqw.write_into(target),
Self::Lt => OpCode::Lt.write_into(target),
Self::Lte => OpCode::Lte.write_into(target),
Self::Gt => OpCode::Gt.write_into(target),
Self::Gte => OpCode::Gte.write_into(target),
Self::IsOdd => OpCode::IsOdd.write_into(target),
Self::Ext2Add => OpCode::Ext2Add.write_into(target),
Self::Ext2Sub => OpCode::Ext2Sub.write_into(target),
Self::Ext2Mul => OpCode::Ext2Mul.write_into(target),
Self::Ext2Div => OpCode::Ext2Div.write_into(target),
Self::Ext2Neg => OpCode::Ext2Neg.write_into(target),
Self::Ext2Inv => OpCode::Ext2Inv.write_into(target),
Self::U32Test => OpCode::U32Test.write_into(target),
Self::U32TestW => OpCode::U32TestW.write_into(target),
Self::U32Assert => OpCode::U32Assert.write_into(target),
Self::U32AssertWithError(err_code) => {
OpCode::U32AssertWithError.write_into(target);
target.write_u32(*err_code);
}
Self::U32Assert2 => OpCode::U32Assert2.write_into(target),
Self::U32Assert2WithError(err_code) => {
OpCode::U32Assert2WithError.write_into(target);
target.write_u32(*err_code);
}
Self::U32AssertW => OpCode::U32AssertW.write_into(target),
Self::U32AssertWWithError(err_code) => {
OpCode::U32AssertWWithError.write_into(target);
target.write_u32(*err_code);
}
Self::U32Split => OpCode::U32Split.write_into(target),
Self::U32Cast => OpCode::U32Cast.write_into(target),
Self::U32WrappingAdd => OpCode::U32WrappingAdd.write_into(target),
Self::U32WrappingAddImm(v) => {
OpCode::U32WrappingAddImm.write_into(target);
target.write_u32(*v);
}
Self::U32OverflowingAdd => OpCode::U32OverflowingAdd.write_into(target),
Self::U32OverflowingAddImm(v) => {
OpCode::U32OverflowingAddImm.write_into(target);
target.write_u32(*v);
}
Self::U32OverflowingAdd3 => OpCode::U32OverflowingAdd3.write_into(target),
Self::U32WrappingAdd3 => OpCode::U32WrappingAdd3.write_into(target),
Self::U32WrappingSub => OpCode::U32WrappingSub.write_into(target),
Self::U32WrappingSubImm(v) => {
OpCode::U32WrappingSubImm.write_into(target);
target.write_u32(*v);
}
Self::U32OverflowingSub => OpCode::U32OverflowingSub.write_into(target),
Self::U32OverflowingSubImm(v) => {
OpCode::U32OverflowingSubImm.write_into(target);
target.write_u32(*v);
}
Self::U32WrappingMul => OpCode::U32WrappingMul.write_into(target),
Self::U32WrappingMulImm(v) => {
OpCode::U32WrappingMulImm.write_into(target);
target.write_u32(*v);
}
Self::U32OverflowingMul => OpCode::U32OverflowingMul.write_into(target),
Self::U32OverflowingMulImm(v) => {
OpCode::U32OverflowingMulImm.write_into(target);
target.write_u32(*v);
}
Self::U32OverflowingMadd => OpCode::U32OverflowingMadd.write_into(target),
Self::U32WrappingMadd => OpCode::U32WrappingMadd.write_into(target),
Self::U32Div => OpCode::U32Div.write_into(target),
Self::U32DivImm(v) => {
OpCode::U32DivImm.write_into(target);
target.write_u32(*v);
}
Self::U32Mod => OpCode::U32Mod.write_into(target),
Self::U32ModImm(v) => {
OpCode::U32ModImm.write_into(target);
target.write_u32(*v);
}
Self::U32DivMod => OpCode::U32DivMod.write_into(target),
Self::U32DivModImm(v) => {
OpCode::U32DivModImm.write_into(target);
target.write_u32(*v);
}
Self::U32And => OpCode::U32And.write_into(target),
Self::U32Or => OpCode::U32Or.write_into(target),
Self::U32Xor => OpCode::U32Xor.write_into(target),
Self::U32Not => OpCode::U32Not.write_into(target),
Self::U32Shr => OpCode::U32Shr.write_into(target),
Self::U32ShrImm(v) => {
OpCode::U32ShrImm.write_into(target);
target.write_u8(*v);
}
Self::U32Shl => OpCode::U32Shl.write_into(target),
Self::U32ShlImm(v) => {
OpCode::U32ShlImm.write_into(target);
target.write_u8(*v);
}
Self::U32Rotr => OpCode::U32Rotr.write_into(target),
Self::U32RotrImm(v) => {
OpCode::U32RotrImm.write_into(target);
target.write_u8(*v);
}
Self::U32Rotl => OpCode::U32Rotl.write_into(target),
Self::U32RotlImm(v) => {
OpCode::U32RotlImm.write_into(target);
target.write_u8(*v);
}
Self::U32Popcnt => OpCode::U32Popcnt.write_into(target),
Self::U32Clz => OpCode::U32Clz.write_into(target),
Self::U32Ctz => OpCode::U32Ctz.write_into(target),
Self::U32Clo => OpCode::U32Clo.write_into(target),
Self::U32Cto => OpCode::U32Cto.write_into(target),
Self::U32Lt => OpCode::U32Lt.write_into(target),
Self::U32Lte => OpCode::U32Lte.write_into(target),
Self::U32Gt => OpCode::U32Gt.write_into(target),
Self::U32Gte => OpCode::U32Gte.write_into(target),
Self::U32Min => OpCode::U32Min.write_into(target),
Self::U32Max => OpCode::U32Max.write_into(target),
Self::Drop => OpCode::Drop.write_into(target),
Self::DropW => OpCode::DropW.write_into(target),
Self::PadW => OpCode::PadW.write_into(target),
Self::Dup0 => OpCode::Dup0.write_into(target),
Self::Dup1 => OpCode::Dup1.write_into(target),
Self::Dup2 => OpCode::Dup2.write_into(target),
Self::Dup3 => OpCode::Dup3.write_into(target),
Self::Dup4 => OpCode::Dup4.write_into(target),
Self::Dup5 => OpCode::Dup5.write_into(target),
Self::Dup6 => OpCode::Dup6.write_into(target),
Self::Dup7 => OpCode::Dup7.write_into(target),
Self::Dup8 => OpCode::Dup8.write_into(target),
Self::Dup9 => OpCode::Dup9.write_into(target),
Self::Dup10 => OpCode::Dup10.write_into(target),
Self::Dup11 => OpCode::Dup11.write_into(target),
Self::Dup12 => OpCode::Dup12.write_into(target),
Self::Dup13 => OpCode::Dup13.write_into(target),
Self::Dup14 => OpCode::Dup14.write_into(target),
Self::Dup15 => OpCode::Dup15.write_into(target),
Self::DupW0 => OpCode::DupW0.write_into(target),
Self::DupW1 => OpCode::DupW1.write_into(target),
Self::DupW2 => OpCode::DupW2.write_into(target),
Self::DupW3 => OpCode::DupW3.write_into(target),
Self::Swap1 => OpCode::Swap1.write_into(target),
Self::Swap2 => OpCode::Swap2.write_into(target),
Self::Swap3 => OpCode::Swap3.write_into(target),
Self::Swap4 => OpCode::Swap4.write_into(target),
Self::Swap5 => OpCode::Swap5.write_into(target),
Self::Swap6 => OpCode::Swap6.write_into(target),
Self::Swap7 => OpCode::Swap7.write_into(target),
Self::Swap8 => OpCode::Swap8.write_into(target),
Self::Swap9 => OpCode::Swap9.write_into(target),
Self::Swap10 => OpCode::Swap10.write_into(target),
Self::Swap11 => OpCode::Swap11.write_into(target),
Self::Swap12 => OpCode::Swap12.write_into(target),
Self::Swap13 => OpCode::Swap13.write_into(target),
Self::Swap14 => OpCode::Swap14.write_into(target),
Self::Swap15 => OpCode::Swap15.write_into(target),
Self::SwapW1 => OpCode::SwapW1.write_into(target),
Self::SwapW2 => OpCode::SwapW2.write_into(target),
Self::SwapW3 => OpCode::SwapW3.write_into(target),
Self::SwapDw => OpCode::SwapDW.write_into(target),
Self::MovUp2 => OpCode::MovUp2.write_into(target),
Self::MovUp3 => OpCode::MovUp3.write_into(target),
Self::MovUp4 => OpCode::MovUp4.write_into(target),
Self::MovUp5 => OpCode::MovUp5.write_into(target),
Self::MovUp6 => OpCode::MovUp6.write_into(target),
Self::MovUp7 => OpCode::MovUp7.write_into(target),
Self::MovUp8 => OpCode::MovUp8.write_into(target),
Self::MovUp9 => OpCode::MovUp9.write_into(target),
Self::MovUp10 => OpCode::MovUp10.write_into(target),
Self::MovUp11 => OpCode::MovUp11.write_into(target),
Self::MovUp12 => OpCode::MovUp12.write_into(target),
Self::MovUp13 => OpCode::MovUp13.write_into(target),
Self::MovUp14 => OpCode::MovUp14.write_into(target),
Self::MovUp15 => OpCode::MovUp15.write_into(target),
Self::MovUpW2 => OpCode::MovUpW2.write_into(target),
Self::MovUpW3 => OpCode::MovUpW3.write_into(target),
Self::MovDn2 => OpCode::MovDn2.write_into(target),
Self::MovDn3 => OpCode::MovDn3.write_into(target),
Self::MovDn4 => OpCode::MovDn4.write_into(target),
Self::MovDn5 => OpCode::MovDn5.write_into(target),
Self::MovDn6 => OpCode::MovDn6.write_into(target),
Self::MovDn7 => OpCode::MovDn7.write_into(target),
Self::MovDn8 => OpCode::MovDn8.write_into(target),
Self::MovDn9 => OpCode::MovDn9.write_into(target),
Self::MovDn10 => OpCode::MovDn10.write_into(target),
Self::MovDn11 => OpCode::MovDn11.write_into(target),
Self::MovDn12 => OpCode::MovDn12.write_into(target),
Self::MovDn13 => OpCode::MovDn13.write_into(target),
Self::MovDn14 => OpCode::MovDn14.write_into(target),
Self::MovDn15 => OpCode::MovDn15.write_into(target),
Self::MovDnW2 => OpCode::MovDnW2.write_into(target),
Self::MovDnW3 => OpCode::MovDnW3.write_into(target),
Self::CSwap => OpCode::CSwap.write_into(target),
Self::CSwapW => OpCode::CSwapW.write_into(target),
Self::CDrop => OpCode::CDrop.write_into(target),
Self::CDropW => OpCode::CDropW.write_into(target),
Self::PushU8(value) => {
OpCode::PushU8.write_into(target);
target.write_u8(*value);
}
Self::PushU16(value) => {
OpCode::PushU16.write_into(target);
target.write_u16(*value);
}
Self::PushU32(value) => {
OpCode::PushU32.write_into(target);
target.write_u32(*value);
}
Self::PushFelt(value) => {
OpCode::PushFelt.write_into(target);
value.write_into(target);
}
Self::PushWord(values) => {
OpCode::PushWord.write_into(target);
values.iter().for_each(|&v| v.write_into(target));
}
Self::PushU8List(values) => {
OpCode::PushU8List.write_into(target);
target.write_u8(values.len() as u8);
values.iter().for_each(|&v| target.write_u8(v));
}
Self::PushU16List(values) => {
OpCode::PushU16List.write_into(target);
target.write_u8(values.len() as u8);
values.iter().for_each(|&v| target.write_u16(v));
}
Self::PushU32List(values) => {
OpCode::PushU32List.write_into(target);
target.write_u8(values.len() as u8);
values.iter().for_each(|&v| target.write_u32(v));
}
Self::PushFeltList(values) => {
OpCode::PushFeltList.write_into(target);
target.write_u8(values.len() as u8);
values.iter().for_each(|&v| v.write_into(target));
}
Self::Locaddr(v) => {
OpCode::Locaddr.write_into(target);
target.write_u16(*v);
}
Self::Sdepth => OpCode::Sdepth.write_into(target),
Self::Caller => OpCode::Caller.write_into(target),
Self::Clk => OpCode::Clk.write_into(target),
Self::MemLoad => OpCode::MemLoad.write_into(target),
Self::MemLoadImm(v) => {
OpCode::MemLoadImm.write_into(target);
target.write_u32(*v);
}
Self::MemLoadW => OpCode::MemLoadW.write_into(target),
Self::MemLoadWImm(v) => {
OpCode::MemLoadWImm.write_into(target);
target.write_u32(*v);
}
Self::LocLoad(v) => {
OpCode::LocLoad.write_into(target);
target.write_u16(*v);
}
Self::LocLoadW(v) => {
OpCode::LocLoadW.write_into(target);
target.write_u16(*v);
}
Self::MemStore => OpCode::MemStore.write_into(target),
Self::MemStoreImm(v) => {
OpCode::MemStoreImm.write_into(target);
target.write_u32(*v);
}
Self::LocStore(v) => {
OpCode::LocStore.write_into(target);
target.write_u16(*v);
}
Self::MemStoreW => OpCode::MemStoreW.write_into(target),
Self::MemStoreWImm(v) => {
OpCode::MemStoreWImm.write_into(target);
target.write_u32(*v);
}
Self::LocStoreW(v) => {
OpCode::LocStoreW.write_into(target);
target.write_u16(*v);
}
Self::MemStream => OpCode::MemStream.write_into(target),
Self::AdvPipe => OpCode::AdvPipe.write_into(target),
Self::AdvPush(v) => {
OpCode::AdvPush.write_into(target);
target.write_u8(*v);
}
Self::AdvLoadW => OpCode::AdvLoadW.write_into(target),
Self::AdvInject(injector) => {
OpCode::AdvInject.write_into(target);
injector.write_into(target);
}
Self::Hash => OpCode::Hash.write_into(target),
Self::HMerge => OpCode::HMerge.write_into(target),
Self::HPerm => OpCode::HPerm.write_into(target),
Self::MTreeGet => OpCode::MTreeGet.write_into(target),
Self::MTreeSet => OpCode::MTreeSet.write_into(target),
Self::MTreeMerge => OpCode::MTreeMerge.write_into(target),
Self::MTreeVerify => OpCode::MTreeVerify.write_into(target),
Self::FriExt2Fold4 => OpCode::FriExt2Fold4.write_into(target),
Self::RCombBase => OpCode::RCombBase.write_into(target),
Self::ExecLocal(v) => {
OpCode::ExecLocal.write_into(target);
target.write_u16(*v);
}
Self::ExecImported(imported) => {
OpCode::ExecImported.write_into(target);
imported.write_into(target)
}
Self::CallLocal(v) => {
OpCode::CallLocal.write_into(target);
target.write_u16(*v);
}
Self::CallMastRoot(root) => {
OpCode::CallMastRoot.write_into(target);
root.write_into(target);
}
Self::CallImported(imported) => {
OpCode::CallImported.write_into(target);
imported.write_into(target)
}
Self::SysCall(imported) => {
OpCode::SysCall.write_into(target);
imported.write_into(target)
}
Self::DynExec => OpCode::DynExec.write_into(target),
Self::DynCall => OpCode::DynCall.write_into(target),
Self::ProcRefLocal(v) => {
OpCode::ProcRefLocal.write_into(target);
target.write_u16(*v)
}
Self::ProcRefImported(imported) => {
OpCode::ProcRefImported.write_into(target);
imported.write_into(target)
}
Self::Breakpoint => {
}
Self::Debug(options) => {
OpCode::Debug.write_into(target);
debug::write_options_into(target, options);
}
Self::Emit(event_id) => {
OpCode::Emit.write_into(target);
target.write_u32(*event_id);
}
Self::Trace(trace_id) => {
OpCode::Trace.write_into(target);
target.write_u32(*trace_id);
}
}
}
}