revm_bytecode/eof/
types_section.rsuse super::{
decode_helpers::{consume_u16, consume_u8},
EofDecodeError,
};
use std::vec::Vec;
const EOF_NON_RETURNING_FUNCTION: u8 = 0x80;
#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TypesSection {
pub inputs: u8,
pub outputs: u8,
pub max_stack_size: u16,
}
impl TypesSection {
pub fn new(inputs: u8, outputs: u8, max_stack_size: u16) -> Self {
Self {
inputs,
outputs,
max_stack_size,
}
}
pub fn is_non_returning(&self) -> bool {
self.outputs == EOF_NON_RETURNING_FUNCTION
}
#[inline]
pub const fn io_diff(&self) -> i32 {
self.outputs as i32 - self.inputs as i32
}
#[inline]
pub fn encode(&self, buffer: &mut Vec<u8>) {
buffer.push(self.inputs);
buffer.push(self.outputs);
buffer.extend_from_slice(&self.max_stack_size.to_be_bytes());
}
#[inline]
pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), EofDecodeError> {
let (input, inputs) = consume_u8(input)?;
let (input, outputs) = consume_u8(input)?;
let (input, max_stack_size) = consume_u16(input)?;
let section = Self {
inputs,
outputs,
max_stack_size,
};
section.validate()?;
Ok((section, input))
}
pub fn validate(&self) -> Result<(), EofDecodeError> {
if self.inputs > 0x7f || self.outputs > 0x80 || self.max_stack_size > 0x03FF {
return Err(EofDecodeError::InvalidTypesSection);
}
if self.inputs as u16 > self.max_stack_size {
return Err(EofDecodeError::InvalidTypesSection);
}
Ok(())
}
}