sleigh_rs/semantic/
table.rs

1use crate::pattern::BitConstraint;
2use crate::semantic::display::Display;
3use crate::semantic::execution::Execution;
4use crate::semantic::pattern::{Pattern, PatternLen};
5use crate::{NumberNonZeroUnsigned, Span};
6
7#[derive(Clone, Copy, Debug, Default)]
8pub enum ExecutionExport {
9    //don't return
10    #[default]
11    None,
12    //value that is known at Dissassembly time
13    Const(NumberNonZeroUnsigned),
14    //value that can be know at execution time
15    Value(NumberNonZeroUnsigned),
16    //References/registers and other mem locations, all with the same size
17    Reference(NumberNonZeroUnsigned),
18    //multiple source, can by any kind of return, value or address,
19    //but all with the same size
20    Multiple(NumberNonZeroUnsigned),
21}
22
23impl ExecutionExport {
24    pub fn len(&self) -> Option<NumberNonZeroUnsigned> {
25        match self {
26            Self::None => None,
27            Self::Const(len)
28            | Self::Value(len)
29            | Self::Reference(len)
30            | Self::Multiple(len) => Some(*len),
31        }
32    }
33}
34
35#[derive(Clone, Copy, Debug, PartialEq, Eq)]
36pub struct ConstructorId(pub usize);
37
38#[derive(Clone, Copy, Debug, PartialEq, Eq)]
39pub struct VariantId(pub usize);
40
41#[derive(Clone, Debug)]
42pub struct Constructor {
43    pub pattern: Pattern,
44    pub display: Display,
45    pub execution: Option<Execution>,
46    pub location: Span,
47    // the bit pattern for all possible variants in the pattern,
48    // impossible variants are simply not present here
49    pub(crate) variants_bits:
50        Box<[(VariantId, Box<[BitConstraint]>, Box<[BitConstraint]>)]>,
51}
52
53impl Constructor {
54    pub fn variants<'a>(
55        &'a self,
56    ) -> impl Iterator<
57        Item = (VariantId, &'a [BitConstraint], &'a [BitConstraint]),
58    > + 'a {
59        self.variants_bits.iter().map(|(id, context, token)| {
60            (*id, context.as_ref(), token.as_ref())
61        })
62    }
63    pub fn variant(
64        &self,
65        id: VariantId,
66    ) -> (&[BitConstraint], &[BitConstraint]) {
67        self.variants_bits
68            .iter()
69            .find(|(current, _, _)| *current == id)
70            .map(|(_, c, t)| (c.as_ref(), t.as_ref()))
71            .unwrap()
72    }
73}
74
75#[derive(Clone, Copy, Debug, PartialEq, Eq)]
76pub struct Matcher {
77    pub constructor: ConstructorId,
78    pub variant_id: VariantId,
79}
80
81#[derive(Clone, Debug)]
82pub struct Table {
83    pub(crate) name: Box<str>,
84    pub(crate) is_root: bool,
85    pub(crate) constructors: Box<[Constructor]>,
86    pub matcher_order: Box<[Matcher]>,
87    pub export: ExecutionExport,
88    pub pattern_len: PatternLen,
89}
90
91impl Table {
92    pub fn is_root(&self) -> bool {
93        self.is_root
94    }
95    pub fn name(&self) -> &str {
96        &self.name
97    }
98    pub fn constructors(&self) -> &[Constructor] {
99        &self.constructors
100    }
101    pub fn constructor(&self, id: ConstructorId) -> &Constructor {
102        &self.constructors[id.0]
103    }
104}