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 { 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}