yz_basic_block/
bb.rs

1use crate::jump::{self, ForeachTarget};
2use alloc::vec::Vec;
3
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Debug, PartialEq, Eq)]
8#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
9pub enum BasicBlockInner<S, C, T> {
10    Concrete {
11        statements: Vec<S>,
12        condjmp: Option<C>,
13        next: jump::Unconditional<T>,
14    },
15    /// placeholder for linker references to other files
16    Placeholder { is_extern: bool },
17}
18
19impl<S, C, T> Default for BasicBlockInner<S, C, T> {
20    #[inline]
21    fn default() -> Self {
22        Self::Placeholder { is_extern: false }
23    }
24}
25
26impl<S, C, T> BasicBlockInner<S, C, T> {
27    #[inline]
28    pub fn is_concrete(&self) -> bool {
29        if let Self::Concrete { .. } = self {
30            true
31        } else {
32            false
33        }
34    }
35
36    #[inline]
37    pub fn is_placeholder(&self) -> bool {
38        if let Self::Placeholder { .. } = self {
39            true
40        } else {
41            false
42        }
43    }
44}
45
46#[derive(Clone, Debug, PartialEq, Eq)]
47#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
48pub struct BasicBlock<S, C, T> {
49    #[cfg_attr(feature = "serde", serde(flatten))]
50    pub inner: BasicBlockInner<S, C, T>,
51    pub is_public: bool,
52}
53
54impl<S, C, T> ForeachTarget for BasicBlockInner<S, C, T>
55where
56    S: ForeachTarget<JumpTarget = T>,
57    C: ForeachTarget<JumpTarget = T>,
58{
59    type JumpTarget = T;
60
61    fn foreach_target<F>(&self, mut f: F)
62    where
63        F: FnMut(&Self::JumpTarget),
64    {
65        if let BasicBlockInner::Concrete {
66            statements,
67            condjmp,
68            next,
69        } = self
70        {
71            statements.foreach_target(&mut f);
72            condjmp.foreach_target(&mut f);
73            next.foreach_target(f);
74        }
75    }
76
77    fn foreach_target_mut<F>(&mut self, mut f: F)
78    where
79        F: FnMut(&mut Self::JumpTarget),
80    {
81        if let BasicBlockInner::Concrete {
82            statements,
83            condjmp,
84            next,
85        } = self
86        {
87            statements.foreach_target_mut(&mut f);
88            condjmp.foreach_target_mut(&mut f);
89            next.foreach_target_mut(f);
90        }
91    }
92}
93
94impl<S, C, T> ForeachTarget for BasicBlock<S, C, T>
95where
96    S: ForeachTarget<JumpTarget = T>,
97    C: ForeachTarget<JumpTarget = T>,
98{
99    type JumpTarget = T;
100
101    #[inline(always)]
102    fn foreach_target<F>(&self, f: F)
103    where
104        F: FnMut(&Self::JumpTarget),
105    {
106        self.inner.foreach_target(f);
107    }
108
109    #[inline(always)]
110    fn foreach_target_mut<F>(&mut self, f: F)
111    where
112        F: FnMut(&mut Self::JumpTarget),
113    {
114        self.inner.foreach_target_mut(f);
115    }
116}