revm_bytecode/eof/
types_section.rs1use 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, PartialOrd, Ord)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct TypesSection {
14 pub inputs: u8,
18 pub outputs: u8,
22 pub max_stack_size: u16,
26}
27
28impl TypesSection {
29 pub fn new(inputs: u8, outputs: u8, max_stack_size: u16) -> Self {
31 Self {
32 inputs,
33 outputs,
34 max_stack_size,
35 }
36 }
37
38 pub fn is_non_returning(&self) -> bool {
40 self.outputs == EOF_NON_RETURNING_FUNCTION
41 }
42
43 #[inline]
45 pub const fn io_diff(&self) -> i32 {
46 self.outputs as i32 - self.inputs as i32
47 }
48
49 #[inline]
51 pub fn encode(&self, buffer: &mut Vec<u8>) {
52 buffer.push(self.inputs);
53 buffer.push(self.outputs);
54 buffer.extend_from_slice(&self.max_stack_size.to_be_bytes());
55 }
56
57 #[inline]
59 pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), EofDecodeError> {
60 let (input, inputs) = consume_u8(input)?;
61 let (input, outputs) = consume_u8(input)?;
62 let (input, max_stack_size) = consume_u16(input)?;
63 let section = Self {
64 inputs,
65 outputs,
66 max_stack_size,
67 };
68 section.validate()?;
69 Ok((section, input))
70 }
71
72 pub fn validate(&self) -> Result<(), EofDecodeError> {
74 if self.inputs > 0x7f || self.outputs > 0x80 || self.max_stack_size > 0x03FF {
75 return Err(EofDecodeError::InvalidTypesSection);
76 }
77 if self.inputs as u16 > self.max_stack_size {
78 return Err(EofDecodeError::InvalidTypesSection);
79 }
80 Ok(())
81 }
82}