wasm_encoder/core/memories.rs
1use crate::{encode_section, Encode, Section, SectionId};
2use alloc::vec::Vec;
3
4/// An encoder for the memory section.
5///
6/// Memory sections are only supported for modules.
7///
8/// # Example
9///
10/// ```
11/// use wasm_encoder::{Module, MemorySection, MemoryType};
12///
13/// let mut memories = MemorySection::new();
14/// memories.memory(MemoryType {
15/// minimum: 1,
16/// maximum: None,
17/// memory64: false,
18/// shared: false,
19/// page_size_log2: None,
20/// });
21///
22/// let mut module = Module::new();
23/// module.section(&memories);
24///
25/// let wasm_bytes = module.finish();
26/// ```
27#[derive(Clone, Default, Debug)]
28pub struct MemorySection {
29 bytes: Vec<u8>,
30 num_added: u32,
31}
32
33impl MemorySection {
34 /// Create a new memory section encoder.
35 pub fn new() -> Self {
36 Self::default()
37 }
38
39 /// The number of memories in the section.
40 pub fn len(&self) -> u32 {
41 self.num_added
42 }
43
44 /// Determines if the section is empty.
45 pub fn is_empty(&self) -> bool {
46 self.num_added == 0
47 }
48
49 /// Define a memory.
50 pub fn memory(&mut self, memory_type: MemoryType) -> &mut Self {
51 memory_type.encode(&mut self.bytes);
52 self.num_added += 1;
53 self
54 }
55}
56
57impl Encode for MemorySection {
58 fn encode(&self, sink: &mut Vec<u8>) {
59 encode_section(sink, self.num_added, &self.bytes);
60 }
61}
62
63impl Section for MemorySection {
64 fn id(&self) -> u8 {
65 SectionId::Memory.into()
66 }
67}
68
69/// A memory's type.
70#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
71pub struct MemoryType {
72 /// Minimum size, in pages, of this memory
73 pub minimum: u64,
74 /// Maximum size, in pages, of this memory
75 pub maximum: Option<u64>,
76 /// Whether or not this is a 64-bit memory.
77 pub memory64: bool,
78 /// Whether or not this memory is shared.
79 pub shared: bool,
80 /// The log base 2 of a custom page size for this memory.
81 ///
82 /// The default page size for Wasm memories is 64KiB, i.e. 2<sup>16</sup> or
83 /// `65536`.
84 ///
85 /// After the introduction of [the custom-page-sizes
86 /// proposal](https://github.com/WebAssembly/custom-page-sizes), Wasm can
87 /// customize the page size. It must be a power of two that is less than or
88 /// equal to 64KiB. Attempting to encode an invalid page size may panic.
89 pub page_size_log2: Option<u32>,
90}
91
92impl Encode for MemoryType {
93 fn encode(&self, sink: &mut Vec<u8>) {
94 let mut flags = 0;
95 if self.maximum.is_some() {
96 flags |= 0b0001;
97 }
98 if self.shared {
99 flags |= 0b0010;
100 }
101 if self.memory64 {
102 flags |= 0b0100;
103 }
104 if self.page_size_log2.is_some() {
105 flags |= 0b1000;
106 }
107 sink.push(flags);
108 self.minimum.encode(sink);
109 if let Some(max) = self.maximum {
110 max.encode(sink);
111 }
112 if let Some(p) = self.page_size_log2 {
113 p.encode(sink);
114 }
115 }
116}