rtvm_primitives/
bytecode.rs1pub mod eof;
2pub mod legacy;
3
4pub use eof::Eof;
5pub use legacy::{JumpTable, LegacyAnalyzedBytecode};
6
7use crate::{keccak256, Bytes, B256, KECCAK_EMPTY};
8
9#[derive(Clone, Debug, PartialEq, Eq, Hash)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub enum Bytecode {
13 LegacyRaw(Bytes),
15 LegacyAnalyzed(LegacyAnalyzedBytecode),
17 Eof(Eof),
19}
20
21impl Default for Bytecode {
22 #[inline]
23 fn default() -> Self {
24 Self::new()
26 }
27}
28
29impl Bytecode {
30 #[inline]
32 pub fn new() -> Self {
33 Self::LegacyAnalyzed(LegacyAnalyzedBytecode::default())
34 }
35
36 #[inline]
38 pub fn legacy_jump_table(&self) -> Option<&JumpTable> {
39 match &self {
40 Self::LegacyAnalyzed(analyzed) => Some(analyzed.jump_table()),
41 _ => None,
42 }
43 }
44
45 pub fn hash_slow(&self) -> B256 {
47 if self.is_empty() {
48 KECCAK_EMPTY
49 } else {
50 keccak256(self.original_byte_slice())
51 }
52 }
53
54 #[inline]
56 pub const fn eof(&self) -> Option<&Eof> {
57 match self {
58 Self::Eof(eof) => Some(eof),
59 _ => None,
60 }
61 }
62
63 #[inline]
65 pub const fn is_eof(&self) -> bool {
66 matches!(self, Self::Eof(_))
67 }
68
69 #[inline]
71 pub fn new_raw(bytecode: Bytes) -> Self {
72 Self::LegacyRaw(bytecode)
73 }
74
75 pub unsafe fn new_analyzed(
82 bytecode: Bytes,
83 original_len: usize,
84 jump_table: JumpTable,
85 ) -> Self {
86 Self::LegacyAnalyzed(LegacyAnalyzedBytecode::new(
87 bytecode,
88 original_len,
89 jump_table,
90 ))
91 }
92
93 #[inline]
96 pub fn bytecode_bytes(&self) -> Bytes {
97 match self {
98 Self::LegacyRaw(bytes) => bytes.clone(),
99 Self::LegacyAnalyzed(analyzed) => analyzed.bytes(),
100 Self::Eof(eof) => eof
101 .body
102 .code(0)
103 .expect("Valid EOF has at least one code section")
104 .clone(),
105 }
106 }
107
108 pub fn is_execution_ready(&self) -> bool {
110 !matches!(self, Self::LegacyRaw(_))
111 }
112
113 #[inline]
115 pub fn original_bytes(&self) -> Bytes {
116 match self {
117 Self::LegacyRaw(bytes) => bytes.clone(),
118 Self::LegacyAnalyzed(analyzed) => analyzed.original_bytes(),
119 Self::Eof(eof) => eof.raw().clone(),
120 }
121 }
122
123 #[inline]
125 pub fn original_byte_slice(&self) -> &[u8] {
126 match self {
127 Self::LegacyRaw(bytes) => bytes,
128 Self::LegacyAnalyzed(analyzed) => analyzed.original_byte_slice(),
129 Self::Eof(eof) => eof.raw(),
130 }
131 }
132
133 #[inline]
135 pub fn len(&self) -> usize {
136 match self {
137 Self::LegacyRaw(bytes) => bytes.len(),
138 Self::LegacyAnalyzed(analyzed) => analyzed.original_len(),
139 Self::Eof(eof) => eof.size(),
140 }
141 }
142
143 #[inline]
145 pub fn is_empty(&self) -> bool {
146 self.len() == 0
147 }
148}