diff options
author | iximeow <me@iximeow.net> | 2020-01-03 19:52:15 -0800 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2020-01-12 17:23:02 -0800 |
commit | 41c9be12ed724b792f870ccecfff2adc699caaa6 (patch) | |
tree | deaf87991c4eb98f5ec9425ba8c2f666fcaca447 | |
parent | 05b4ccbbc19f98a97e23e5acd3252ac0a48afc48 (diff) |
match changes in arch to have Resulty decode, instead of Option
-rw-r--r-- | src/lib.rs | 46 |
1 files changed, 38 insertions, 8 deletions
@@ -9,6 +9,8 @@ extern crate yaxpeax_arch; use yaxpeax_arch::{Arch, Decoder, LengthedInstruction}; +use std::fmt; + #[derive(Debug)] pub enum Opcode { NOP @@ -29,24 +31,51 @@ impl LengthedInstruction for Instruction { } } +#[derive(Debug, PartialEq)] +pub enum DecodeError { + ExhaustedInput, + InvalidOpcode, + InvalidOperand, +} + +impl fmt::Display for DecodeError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + DecodeError::ExhaustedInput => write!(f, "exhausted input"), + DecodeError::InvalidOpcode => write!(f, "invalid opcode"), + DecodeError::InvalidOperand => write!(f, "invalid operand"), + } + } +} + +impl yaxpeax_arch::DecodeError for DecodeError { + fn data_exhausted(&self) -> bool { self == &DecodeError::ExhaustedInput } + fn bad_opcode(&self) -> bool { self == &DecodeError::InvalidOpcode } + fn bad_operand(&self) -> bool { self == &DecodeError::InvalidOperand } +} + +impl yaxpeax_arch::Instruction for Instruction { + // TODO: this is wrong!! + fn well_defined(&self) -> bool { true } +} + #[derive(Default, Debug)] pub struct InstDecoder {} impl Decoder<Instruction> for InstDecoder { - fn decode<T: IntoIterator<Item=u8>>(&self, bytes: T) -> Option<Instruction> { + type Error = DecodeError; + + fn decode<T: IntoIterator<Item=u8>>(&self, bytes: T) -> Result<Instruction, Self::Error> { let mut blank = Instruction { opcode: Opcode::NOP }; - match self.decode_into(&mut blank, bytes) { - Some(_) => Some(blank), - None => None - } + self.decode_into(&mut blank, bytes).map(|_: ()| blank) } - fn decode_into<T: IntoIterator<Item=u8>>(&self, instr: &mut Instruction, bytes: T) -> Option<()> { + fn decode_into<T: IntoIterator<Item=u8>>(&self, instr: &mut Instruction, bytes: T) -> Result<(), Self::Error> { match bytes.into_iter().next() { Some(0x00) => { instr.opcode = Opcode::NOP; - Some(()) + Ok(()) }, - _ => None + _ => Err(DecodeError::ExhaustedInput) } } } @@ -62,6 +91,7 @@ pub struct PIC24; impl Arch for PIC24 { type Address = u32; type Instruction = Instruction; + type DecodeError = DecodeError; type Decoder = InstDecoder; type Operand = (); } |