1 | mod branch_hints; |
2 | mod code; |
3 | mod custom; |
4 | mod data; |
5 | mod dump; |
6 | mod elements; |
7 | mod exports; |
8 | mod functions; |
9 | mod globals; |
10 | mod imports; |
11 | mod linking; |
12 | mod memories; |
13 | mod names; |
14 | mod producers; |
15 | mod start; |
16 | mod tables; |
17 | mod tags; |
18 | mod types; |
19 | |
20 | pub use branch_hints::*; |
21 | pub use code::*; |
22 | pub use custom::*; |
23 | pub use data::*; |
24 | pub use dump::*; |
25 | pub use elements::*; |
26 | pub use exports::*; |
27 | pub use functions::*; |
28 | pub use globals::*; |
29 | pub use imports::*; |
30 | pub use linking::*; |
31 | pub use memories::*; |
32 | pub use names::*; |
33 | pub use producers::*; |
34 | pub use start::*; |
35 | pub use tables::*; |
36 | pub use tags::*; |
37 | pub use types::*; |
38 | |
39 | use crate::Encode; |
40 | use alloc::vec::Vec; |
41 | |
42 | pub(crate) const CORE_FUNCTION_SORT: u8 = 0x00; |
43 | pub(crate) const CORE_TABLE_SORT: u8 = 0x01; |
44 | pub(crate) const CORE_MEMORY_SORT: u8 = 0x02; |
45 | pub(crate) const CORE_GLOBAL_SORT: u8 = 0x03; |
46 | pub(crate) const CORE_TAG_SORT: u8 = 0x04; |
47 | |
48 | /// A WebAssembly module section. |
49 | /// |
50 | /// Various builders defined in this crate already implement this trait, but you |
51 | /// can also implement it yourself for your own custom section builders, or use |
52 | /// `RawSection` to use a bunch of raw bytes as a section. |
53 | pub trait Section: Encode { |
54 | /// Gets the section identifier for this section. |
55 | fn id(&self) -> u8; |
56 | |
57 | /// Appends this section to the specified destination list of bytes. |
58 | fn append_to(&self, dst: &mut Vec<u8>) { |
59 | dst.push(self.id()); |
60 | self.encode(sink:dst); |
61 | } |
62 | } |
63 | |
64 | /// Known section identifiers of WebAssembly modules. |
65 | #[derive (Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] |
66 | #[repr (u8)] |
67 | pub enum SectionId { |
68 | /// The custom section. |
69 | Custom = 0, |
70 | /// The type section. |
71 | Type = 1, |
72 | /// The import section. |
73 | Import = 2, |
74 | /// The function section. |
75 | Function = 3, |
76 | /// The table section. |
77 | Table = 4, |
78 | /// The memory section. |
79 | Memory = 5, |
80 | /// The global section. |
81 | Global = 6, |
82 | /// The export section. |
83 | Export = 7, |
84 | /// The start section. |
85 | Start = 8, |
86 | /// The element section. |
87 | Element = 9, |
88 | /// The code section. |
89 | Code = 10, |
90 | /// The data section. |
91 | Data = 11, |
92 | /// The data count section. |
93 | DataCount = 12, |
94 | /// The tag section. |
95 | /// |
96 | /// This section is supported by the exception handling proposal. |
97 | Tag = 13, |
98 | } |
99 | |
100 | impl From<SectionId> for u8 { |
101 | #[inline ] |
102 | fn from(id: SectionId) -> u8 { |
103 | id as u8 |
104 | } |
105 | } |
106 | |
107 | impl Encode for SectionId { |
108 | fn encode(&self, sink: &mut Vec<u8>) { |
109 | sink.push(*self as u8); |
110 | } |
111 | } |
112 | |
113 | /// Represents a WebAssembly component that is being encoded. |
114 | /// |
115 | /// Sections within a WebAssembly module are encoded in a specific order. |
116 | /// |
117 | /// Modules may also added as a section to a WebAssembly component. |
118 | #[derive (Clone, Debug)] |
119 | pub struct Module { |
120 | pub(crate) bytes: Vec<u8>, |
121 | } |
122 | |
123 | impl Module { |
124 | /// The 8-byte header at the beginning of all core wasm modules. |
125 | #[rustfmt::skip] |
126 | pub const HEADER: [u8; 8] = [ |
127 | // Magic |
128 | 0x00, 0x61, 0x73, 0x6D, |
129 | // Version |
130 | 0x01, 0x00, 0x00, 0x00, |
131 | ]; |
132 | |
133 | /// Begin writing a new `Module`. |
134 | #[rustfmt::skip] |
135 | pub fn new() -> Self { |
136 | Module { |
137 | bytes: Self::HEADER.to_vec(), |
138 | } |
139 | } |
140 | |
141 | /// Write a section into this module. |
142 | /// |
143 | /// It is your responsibility to define the sections in the [proper |
144 | /// order](https://webassembly.github.io/spec/core/binary/modules.html#binary-module), |
145 | /// and to ensure that each kind of section (other than custom sections) is |
146 | /// only defined once. While this is a potential footgun, it also allows you |
147 | /// to use this crate to easily construct test cases for bad Wasm module |
148 | /// encodings. |
149 | pub fn section(&mut self, section: &impl Section) -> &mut Self { |
150 | self.bytes.push(section.id()); |
151 | section.encode(&mut self.bytes); |
152 | self |
153 | } |
154 | |
155 | /// Get the encoded Wasm module as a slice. |
156 | pub fn as_slice(&self) -> &[u8] { |
157 | &self.bytes |
158 | } |
159 | |
160 | /// Give the current size of the module in bytes. |
161 | pub fn len(&self) -> usize { |
162 | self.bytes.len() |
163 | } |
164 | |
165 | /// Finish writing this Wasm module and extract ownership of the encoded |
166 | /// bytes. |
167 | pub fn finish(self) -> Vec<u8> { |
168 | self.bytes |
169 | } |
170 | } |
171 | |
172 | impl Default for Module { |
173 | fn default() -> Self { |
174 | Self::new() |
175 | } |
176 | } |
177 | |