use crate::{encode_section, Encode, Section, SectionId}; /// An encoder for the memory section. /// /// Memory sections are only supported for modules. /// /// # Example /// /// ``` /// use wasm_encoder::{Module, MemorySection, MemoryType}; /// /// let mut memories = MemorySection::new(); /// memories.memory(MemoryType { /// minimum: 1, /// maximum: None, /// memory64: false, /// shared: false, /// page_size_log2: None, /// }); /// /// let mut module = Module::new(); /// module.section(&memories); /// /// let wasm_bytes = module.finish(); /// ``` #[derive(Clone, Default, Debug)] pub struct MemorySection { bytes: Vec, num_added: u32, } impl MemorySection { /// Create a new memory section encoder. pub fn new() -> Self { Self::default() } /// The number of memories in the section. pub fn len(&self) -> u32 { self.num_added } /// Determines if the section is empty. pub fn is_empty(&self) -> bool { self.num_added == 0 } /// Define a memory. pub fn memory(&mut self, memory_type: MemoryType) -> &mut Self { memory_type.encode(&mut self.bytes); self.num_added += 1; self } } impl Encode for MemorySection { fn encode(&self, sink: &mut Vec) { encode_section(sink, self.num_added, &self.bytes); } } impl Section for MemorySection { fn id(&self) -> u8 { SectionId::Memory.into() } } /// A memory's type. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct MemoryType { /// Minimum size, in pages, of this memory pub minimum: u64, /// Maximum size, in pages, of this memory pub maximum: Option, /// Whether or not this is a 64-bit memory. pub memory64: bool, /// Whether or not this memory is shared. pub shared: bool, /// The log base 2 of a custom page size for this memory. /// /// The default page size for Wasm memories is 64KiB, i.e. 216 or /// `65536`. /// /// After the introduction of [the custom-page-sizes /// proposal](https://github.com/WebAssembly/custom-page-sizes), Wasm can /// customize the page size. It must be a power of two that is less than or /// equal to 64KiB. Attempting to encode an invalid page size may panic. pub page_size_log2: Option, } impl Encode for MemoryType { fn encode(&self, sink: &mut Vec) { let mut flags = 0; if self.maximum.is_some() { flags |= 0b0001; } if self.shared { flags |= 0b0010; } if self.memory64 { flags |= 0b0100; } if self.page_size_log2.is_some() { flags |= 0b1000; } sink.push(flags); self.minimum.encode(sink); if let Some(max) = self.maximum { max.encode(sink); } if let Some(p) = self.page_size_log2 { p.encode(sink); } } } #[cfg(feature = "wasmparser")] impl From for MemoryType { fn from(memory_ty: wasmparser::MemoryType) -> Self { MemoryType { minimum: memory_ty.initial, maximum: memory_ty.maximum, memory64: memory_ty.memory64, shared: memory_ty.shared, page_size_log2: memory_ty.page_size_log2, } } }