1mod branch_hints;
2mod code;
3mod custom;
4mod data;
5mod dump;
6mod elements;
7mod exports;
8mod functions;
9mod globals;
10mod imports;
11mod linking;
12mod memories;
13mod names;
14mod producers;
15mod start;
16mod tables;
17mod tags;
18mod types;
19
20pub use branch_hints::*;
21pub use code::*;
22pub use custom::*;
23pub use data::*;
24pub use dump::*;
25pub use elements::*;
26pub use exports::*;
27pub use functions::*;
28pub use globals::*;
29pub use imports::*;
30pub use linking::*;
31pub use memories::*;
32pub use names::*;
33pub use producers::*;
34pub use start::*;
35pub use tables::*;
36pub use tags::*;
37pub use types::*;
38
39use crate::Encode;
40use alloc::vec::Vec;
41
42pub(crate) const CORE_FUNCTION_SORT: u8 = 0x00;
43pub(crate) const CORE_TABLE_SORT: u8 = 0x01;
44pub(crate) const CORE_MEMORY_SORT: u8 = 0x02;
45pub(crate) const CORE_GLOBAL_SORT: u8 = 0x03;
46pub(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.
53pub 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)]
67pub 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
100impl From<SectionId> for u8 {
101 #[inline]
102 fn from(id: SectionId) -> u8 {
103 id as u8
104 }
105}
106
107impl 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)]
119pub struct Module {
120 pub(crate) bytes: Vec<u8>,
121}
122
123impl 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
172impl Default for Module {
173 fn default() -> Self {
174 Self::new()
175 }
176}
177