revm_primitives/bytecode/eof/
body.rs
1use super::{Eof, EofDecodeError, EofHeader, TypesSection};
2use crate::Bytes;
3use std::vec::Vec;
4
5#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct EofBody {
13 pub types_section: Vec<TypesSection>,
14 pub code_section: Vec<Bytes>,
15 pub container_section: Vec<Bytes>,
16 pub data_section: Bytes,
17 pub is_data_filled: bool,
18}
19
20impl EofBody {
21 pub fn code(&self, index: usize) -> Option<&Bytes> {
23 self.code_section.get(index)
24 }
25
26 pub fn into_eof(self) -> Eof {
28 let header = EofHeader {
30 types_size: self.types_section.len() as u16 * 4,
31 code_sizes: self.code_section.iter().map(|x| x.len() as u16).collect(),
32 container_sizes: self
33 .container_section
34 .iter()
35 .map(|x| x.len() as u16)
36 .collect(),
37 data_size: self.data_section.len() as u16,
38 sum_code_sizes: self.code_section.iter().map(|x| x.len()).sum(),
39 sum_container_sizes: self.container_section.iter().map(|x| x.len()).sum(),
40 };
41 let mut buffer = Vec::new();
42 header.encode(&mut buffer);
43 self.encode(&mut buffer);
44 Eof {
45 header,
46 body: self,
47 raw: buffer.into(),
48 }
49 }
50
51 pub fn encode(&self, buffer: &mut Vec<u8>) {
53 for types_section in &self.types_section {
54 types_section.encode(buffer);
55 }
56
57 for code_section in &self.code_section {
58 buffer.extend_from_slice(code_section);
59 }
60
61 for container_section in &self.container_section {
62 buffer.extend_from_slice(container_section);
63 }
64
65 buffer.extend_from_slice(&self.data_section);
66 }
67
68 pub fn decode(input: &Bytes, header: &EofHeader) -> Result<Self, EofDecodeError> {
70 let header_len = header.size();
71 let partial_body_len =
72 header.sum_code_sizes + header.sum_container_sizes + header.types_size as usize;
73 let full_body_len = partial_body_len + header.data_size as usize;
74
75 if input.len() < header_len + partial_body_len {
76 return Err(EofDecodeError::MissingBodyWithoutData);
77 }
78
79 if input.len() > header_len + full_body_len {
80 return Err(EofDecodeError::DanglingData);
81 }
82
83 let mut body = EofBody::default();
84
85 let mut types_input = &input[header_len..];
86 for _ in 0..header.types_count() {
87 let (types_section, local_input) = TypesSection::decode(types_input)?;
88 types_input = local_input;
89 body.types_section.push(types_section);
90 }
91
92 let mut start = header_len + header.types_size as usize;
94 for size in header.code_sizes.iter().map(|x| *x as usize) {
95 body.code_section.push(input.slice(start..start + size));
96 start += size;
97 }
98
99 for size in header.container_sizes.iter().map(|x| *x as usize) {
101 body.container_section
102 .push(input.slice(start..start + size));
103 start += size;
104 }
105
106 body.data_section = input.slice(start..);
107 body.is_data_filled = body.data_section.len() == header.data_size as usize;
108
109 Ok(body)
110 }
111}