revm_primitives/bytecode/eof/
types_section.rs
1use super::{
2 decode_helpers::{consume_u16, consume_u8},
3 EofDecodeError,
4};
5use std::vec::Vec;
6
7const EOF_NON_RETURNING_FUNCTION: u8 = 0x80;
9
10#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Copy)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct TypesSection {
14 pub inputs: u8,
17 pub outputs: u8,
20 pub max_stack_size: u16,
23}
24
25impl TypesSection {
26 pub fn new(inputs: u8, outputs: u8, max_stack_size: u16) -> Self {
28 Self {
29 inputs,
30 outputs,
31 max_stack_size,
32 }
33 }
34
35 pub fn is_non_returning(&self) -> bool {
37 self.outputs == EOF_NON_RETURNING_FUNCTION
38 }
39
40 #[inline]
42 pub const fn io_diff(&self) -> i32 {
43 self.outputs as i32 - self.inputs as i32
44 }
45
46 #[inline]
48 pub fn encode(&self, buffer: &mut Vec<u8>) {
49 buffer.push(self.inputs);
50 buffer.push(self.outputs);
51 buffer.extend_from_slice(&self.max_stack_size.to_be_bytes());
52 }
53
54 #[inline]
56 pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), EofDecodeError> {
57 let (input, inputs) = consume_u8(input)?;
58 let (input, outputs) = consume_u8(input)?;
59 let (input, max_stack_size) = consume_u16(input)?;
60 let section = Self {
61 inputs,
62 outputs,
63 max_stack_size,
64 };
65 section.validate()?;
66 Ok((section, input))
67 }
68
69 pub fn validate(&self) -> Result<(), EofDecodeError> {
71 if self.inputs > 0x7f || self.outputs > 0x80 || self.max_stack_size > 0x03FF {
72 return Err(EofDecodeError::InvalidTypesSection);
73 }
74 if self.inputs as u16 > self.max_stack_size {
75 return Err(EofDecodeError::InvalidTypesSection);
76 }
77 Ok(())
78 }
79}