diff --git a/crates/ir/src/inst/inst_set.rs b/crates/ir/src/inst/inst_set.rs index e5220dd3..b99d8ffd 100644 --- a/crates/ir/src/inst/inst_set.rs +++ b/crates/ir/src/inst/inst_set.rs @@ -48,10 +48,75 @@ define_inst_set_base! { basic::Nop, } -pub trait StaticInstSet: InstSetBase { - type InstKind; - type InstKindMut; +pub trait InstSetExt: InstSetBase { + type InstKind<'i>; + type InstKindMut<'i>; - fn resolve_inst(inst: &dyn Inst) -> Self::InstKind; - fn resolve_inst_mut(inst: &mut dyn Inst) -> Self::InstKindMut; + fn resolve_inst<'i>(&self, inst: &'i dyn Inst) -> Self::InstKind<'i>; + fn resolve_inst_mut<'i>(&self, inst: &'i mut dyn Inst) -> Self::InstKindMut<'i>; +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::Value; + use basic::*; + use macros::inst_set; + + #[inst_set(InstKind = "TestInstSetKind")] + struct TestInstSet(Add, Sub, Not, Phi, Jump); + + #[test] + fn ctor() { + let _ = TestInstSet::new(); + } + + #[test] + fn test_cast_isa() { + let inst_set = TestInstSet::new(); + assert!(inst_set.has_add().is_some()); + assert!(inst_set.has_sub().is_some()); + assert!(inst_set.has_not().is_some()); + assert!(inst_set.has_phi().is_some()); + assert!(inst_set.has_jump().is_some()); + + assert!(inst_set.has_lt().is_none()); + assert!(inst_set.has_br().is_none()); + } + + #[test] + fn inst_creation() { + let inst_set = TestInstSet::new(); + let v = Value::from_u32(1); + let _add = Add::new(&inst_set, v, v); + let _sub = Sub::new(&inst_set, v, v); + } + + #[test] + fn inst_resolution() { + let inst_set = TestInstSet::new(); + let mut insts: Vec> = Vec::new(); + + let value = Value::from_u32(1); + let add = Add::new(&inst_set, value, value); + insts.push(Box::new(add)); + let sub = Sub::new(&inst_set, value, value); + insts.push(Box::new(sub)); + let not = Not::new(&inst_set, value); + insts.push(Box::new(not)); + + let resolved = inst_set.resolve_inst(insts[0].as_ref()); + assert!(matches!(resolved, TestInstSetKind::Add(_))); + let resolved = inst_set.resolve_inst(insts[1].as_ref()); + assert!(matches!(resolved, TestInstSetKind::Sub(_))); + let resolved = inst_set.resolve_inst(insts[2].as_ref()); + assert!(matches!(resolved, TestInstSetKind::Not(_))); + + let resolved = inst_set.resolve_inst_mut(insts[0].as_mut()); + assert!(matches!(resolved, TestInstSetKindMut::Add(_))); + let resolved = inst_set.resolve_inst_mut(insts[1].as_mut()); + assert!(matches!(resolved, TestInstSetKindMut::Sub(_))); + let resolved = inst_set.resolve_inst_mut(insts[2].as_mut()); + assert!(matches!(resolved, TestInstSetKindMut::Not(_))); + } } diff --git a/crates/ir/src/lib.rs b/crates/ir/src/lib.rs index 67bc4a99..0635e983 100644 --- a/crates/ir/src/lib.rs +++ b/crates/ir/src/lib.rs @@ -26,7 +26,7 @@ pub use global_variable::{GlobalVariable, GlobalVariableData}; pub use graphviz::render_to; pub use insn::{BranchInfo, DataLocationKind, Insn, InsnData}; pub use inst::{ - inst_set::{InstSetBase, StaticInstSet}, + inst_set::{InstSetBase, InstSetExt}, HasInst, Inst, }; pub use layout::Layout; @@ -39,7 +39,7 @@ pub(crate) use inst::ValueVisitable; pub mod prelude { pub use crate::inst::{ - inst_set::{InstSetBase, StaticInstSet}, + inst_set::{InstSetBase, InstSetExt}, HasInst, Inst, }; }