use crate::{Instruction, PanicReason, RawInstruction, Word};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct InstructionResult {
reason: PanicReason,
instruction: RawInstruction,
}
impl InstructionResult {
pub const fn error(reason: PanicReason, instruction: RawInstruction) -> Self {
Self { reason, instruction }
}
pub const fn reason(&self) -> &PanicReason {
&self.reason
}
pub const fn instruction(&self) -> &RawInstruction {
&self.instruction
}
pub const fn is_success(&self) -> bool {
matches!(self.reason, PanicReason::Success)
}
pub const fn is_error(&self) -> bool {
!self.is_success()
}
}
const WORD_SIZE: usize = core::mem::size_of::<Word>();
const REASON_OFFSET: Word = (WORD_SIZE * 8 - 8) as Word;
const INSTR_OFFSET: Word = REASON_OFFSET - (Instruction::SIZE * 8) as Word;
impl From<InstructionResult> for Word {
fn from(r: InstructionResult) -> Word {
let reason = Word::from(r.reason as u8);
let instruction = Word::from(r.instruction);
(reason << REASON_OFFSET) | (instruction << INSTR_OFFSET)
}
}
impl From<Word> for InstructionResult {
fn from(val: Word) -> Self {
let reason_u8 = (val >> REASON_OFFSET) as u8;
let instruction = (val >> INSTR_OFFSET) as u32;
let reason = PanicReason::from(reason_u8);
Self { reason, instruction }
}
}