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