wasm_encoder/
core.rs

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