capstone_git/arch/
evm.rs

1//! Contains EVM-specific types
2
3use core::fmt;
4
5use capstone_sys::cs_evm;
6
7// XXX todo(tmfink): create rusty versions
8pub use capstone_sys::evm_insn_group as EvmInsnGroup;
9pub use capstone_sys::evm_insn as EvmInsn;
10
11pub use crate::arch::arch_builder::evm::*;
12use crate::arch::DetailsArchInsn;
13
14/// Contains EVM-specific details for an instruction
15pub struct EvmInsnDetail<'a>(pub(crate) &'a cs_evm);
16
17impl EvmInsnDetail<'_> {
18    /// Number of items popped from the stack
19    pub fn popped_items(&self) -> u8 {
20        self.0.pop
21    }
22
23    /// Number of items pushed into the stack
24    pub fn pushed_items(&self) -> u8 {
25        self.0.push
26    }
27
28    /// Gas fee for the instruction
29    pub fn fee(&self) -> u32 {
30        self.0.fee as u32
31    }
32}
33
34impl_PartialEq_repr_fields!(EvmInsnDetail<'a> [ 'a ];
35    popped_items, pushed_items, fee
36);
37
38/// EVM has no operands, so this is a zero-size type.
39#[derive(Clone, Debug, Eq, PartialEq, Default)]
40pub struct EvmOperand(());
41
42// Do not use def_arch_details_struct! since EVM does not have operands
43
44/// Iterates over instruction operands
45#[derive(Clone)]
46pub struct EvmOperandIterator(());
47
48impl EvmOperandIterator {
49    fn new() -> EvmOperandIterator {
50        EvmOperandIterator(())
51    }
52}
53
54impl Iterator for EvmOperandIterator {
55    type Item = EvmOperand;
56
57    fn next(&mut self) -> Option<Self::Item> {
58        None
59    }
60}
61
62impl ExactSizeIterator for EvmOperandIterator {
63    fn len(&self) -> usize {
64        0
65    }
66}
67
68impl PartialEq for EvmOperandIterator {
69    fn eq(&self, _other: &EvmOperandIterator) -> bool {
70        false
71    }
72}
73
74impl fmt::Debug for EvmOperandIterator {
75    fn fmt(&self, fmt: &mut fmt::Formatter) -> ::core::fmt::Result {
76        fmt.debug_struct("EvmOperandIterator").finish()
77    }
78}
79
80impl fmt::Debug for EvmInsnDetail<'_> {
81    fn fmt(&self, fmt: &mut fmt::Formatter) -> ::core::fmt::Result {
82        fmt.debug_struct("EvmInsnDetail")
83            .field("cs_evm", &(self.0 as *const cs_evm))
84            .finish()
85    }
86}
87
88impl DetailsArchInsn for EvmInsnDetail<'_> {
89    type OperandIterator = EvmOperandIterator;
90    type Operand = EvmOperand;
91
92    fn operands(&self) -> EvmOperandIterator {
93        EvmOperandIterator::new()
94    }
95}
96
97#[cfg(test)]
98mod test {
99    use super::*;
100
101    #[test]
102    fn test_evm_detail() {
103        let cs_evm = cs_evm {
104            pop: 1,
105            push: 2,
106            fee: 42,
107        };
108        let d = EvmInsnDetail(&cs_evm);
109        assert_eq!(d.popped_items(), 1);
110        assert_eq!(d.pushed_items(), 2);
111        assert_eq!(d.fee(), 42);
112    }
113}