revm_bytecode/eof/
body.rs1use super::{Eof, EofDecodeError, EofHeader, TypesSection};
2use primitives::Bytes;
3use std::vec::Vec;
4
5#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct EofBody {
13 pub types_section: Vec<TypesSection>,
15 pub code_section: Vec<usize>,
17 pub code: Bytes,
18 pub code_offset: usize,
19 pub container_section: Vec<Bytes>,
20 pub data_section: Bytes,
21 pub is_data_filled: bool,
22}
23
24impl EofBody {
25 pub fn code(&self, index: usize) -> Option<Bytes> {
27 if index == 0 {
28 return Some(self.code.slice(..self.code_section[0]));
30 }
31 self.code_section
32 .get(index)
33 .map(|end| self.code.slice(self.code_section[index - 1]..*end))
34 }
35
36 pub fn into_eof(self) -> Eof {
38 let mut prev_value = 0;
39 let header = EofHeader {
40 types_size: self.types_section.len() as u16 * 4,
41 code_sizes: self
42 .code_section
43 .iter()
44 .map(|x| {
45 let ret = (x - prev_value) as u16;
46 prev_value = *x;
47 ret
48 })
49 .collect(),
50 container_sizes: self
51 .container_section
52 .iter()
53 .map(|x| x.len() as u16)
54 .collect(),
55 data_size: self.data_section.len() as u16,
56 sum_code_sizes: self.code.len(),
57 sum_container_sizes: self.container_section.iter().map(|x| x.len()).sum(),
58 };
59 let mut buffer = Vec::new();
60 header.encode(&mut buffer);
61 self.encode(&mut buffer);
62 Eof::decode(buffer.into()).expect("Failed to encode EOF")
63 }
64
65 pub fn eof_code_section_start(&self, idx: usize) -> Option<usize> {
69 let code_offset = self.code_offset;
71 if idx == 0 {
72 return Some(code_offset);
73 }
74 self.code_section.get(idx - 1).map(|i| i + code_offset)
75 }
76
77 pub fn encode(&self, buffer: &mut Vec<u8>) {
79 for types_section in &self.types_section {
80 types_section.encode(buffer);
81 }
82
83 buffer.extend_from_slice(&self.code);
84
85 for container_section in &self.container_section {
86 buffer.extend_from_slice(container_section);
87 }
88
89 buffer.extend_from_slice(&self.data_section);
90 }
91
92 pub fn decode(input: &Bytes, header: &EofHeader) -> Result<Self, EofDecodeError> {
94 let header_len = header.size();
95 let partial_body_len =
96 header.sum_code_sizes + header.sum_container_sizes + header.types_size as usize;
97 let full_body_len = partial_body_len + header.data_size as usize;
98
99 if input.len() < header_len + partial_body_len {
100 return Err(EofDecodeError::MissingBodyWithoutData);
101 }
102
103 if input.len() > header_len + full_body_len {
104 return Err(EofDecodeError::DanglingData);
105 }
106
107 let mut body = EofBody::default();
108
109 let mut types_input = &input[header_len..];
110 for _ in 0..header.types_count() {
111 let (types_section, local_input) = TypesSection::decode(types_input)?;
112 types_input = local_input;
113 body.types_section.push(types_section);
114 }
115
116 let start = header_len + header.types_size as usize;
118 body.code_offset = start;
119 let mut code_end = 0;
120 for size in header.code_sizes.iter().map(|x| *x as usize) {
121 code_end += size;
122 body.code_section.push(code_end);
123 }
124 body.code = input.slice(start..start + header.sum_code_sizes);
125
126 let mut start = start + header.sum_code_sizes;
128 for size in header.container_sizes.iter().map(|x| *x as usize) {
129 body.container_section
130 .push(input.slice(start..start + size));
131 start += size;
132 }
133
134 body.data_section = input.slice(start..);
135 body.is_data_filled = body.data_section.len() == header.data_size as usize;
136
137 Ok(body)
138 }
139}