1//! A WebAssembly encoder.
2//!
3//! The main builder is the [`Module`]. You can build a section with a
4//! section-specific builder, like [`TypeSection`] or [`ImportSection`], and
5//! then add it to the module with [`Module::section`]. When you are finished
6//! building the module, call either [`Module::as_slice`] or [`Module::finish`]
7//! to get the encoded bytes. The former gives a shared reference to the
8//! underlying bytes as a slice, while the latter gives you ownership of them as
9//! a vector.
10//!
11//! # Example
12//!
13//! If we wanted to build this module:
14//!
15//! ```wasm
16//! (module
17//! (type (func (param i32 i32) (result i32)))
18//! (func (type 0)
19//! local.get 0
20//! local.get 1
21//! i32.add)
22//! (export "f" (func 0)))
23//! ```
24//!
25//! then we would do this:
26//!
27//! ```
28//! use wasm_encoder::{
29//! CodeSection, ExportKind, ExportSection, Function, FunctionSection, Instruction,
30//! Module, TypeSection, ValType,
31//! };
32//!
33//! let mut module = Module::new();
34//!
35//! // Encode the type section.
36//! let mut types = TypeSection::new();
37//! let params = vec![ValType::I32, ValType::I32];
38//! let results = vec![ValType::I32];
39//! types.ty().function(params, results);
40//! module.section(&types);
41//!
42//! // Encode the function section.
43//! let mut functions = FunctionSection::new();
44//! let type_index = 0;
45//! functions.function(type_index);
46//! module.section(&functions);
47//!
48//! // Encode the export section.
49//! let mut exports = ExportSection::new();
50//! exports.export("f", ExportKind::Func, 0);
51//! module.section(&exports);
52//!
53//! // Encode the code section.
54//! let mut codes = CodeSection::new();
55//! let locals = vec![];
56//! let mut f = Function::new(locals);
57//! f.instruction(&Instruction::LocalGet(0));
58//! f.instruction(&Instruction::LocalGet(1));
59//! f.instruction(&Instruction::I32Add);
60//! f.instruction(&Instruction::End);
61//! codes.function(&f);
62//! module.section(&codes);
63//!
64//! // Extract the encoded Wasm bytes for this module.
65//! let wasm_bytes = module.finish();
66//!
67//! // We generated a valid Wasm module!
68//! assert!(wasmparser::validate(&wasm_bytes).is_ok());
69//! ```
70
71#![cfg_attr(docsrs, feature(doc_auto_cfg))]
72#![no_std]
73#![deny(missing_docs, missing_debug_implementations)]
74
75extern crate alloc;
76#[cfg(feature = "std")]
77#[macro_use]
78extern crate std;
79
80#[cfg(feature = "component-model")]
81mod component;
82mod core;
83mod raw;
84#[cfg(feature = "wasmparser")]
85pub mod reencode;
86
87#[cfg(feature = "component-model")]
88pub use self::component::*;
89pub use self::core::*;
90pub use self::raw::*;
91
92use alloc::vec::Vec;
93
94/// Implemented by types that can be encoded into a byte sink.
95pub trait Encode {
96 /// Encode the type into the given byte sink.
97 fn encode(&self, sink: &mut Vec<u8>);
98}
99
100impl<T: Encode + ?Sized> Encode for &'_ T {
101 fn encode(&self, sink: &mut Vec<u8>) {
102 T::encode(self, sink)
103 }
104}
105
106impl<T: Encode> Encode for [T] {
107 fn encode(&self, sink: &mut Vec<u8>) {
108 self.len().encode(sink);
109 for item: &T in self {
110 item.encode(sink);
111 }
112 }
113}
114
115impl Encode for [u8] {
116 fn encode(&self, sink: &mut Vec<u8>) {
117 self.len().encode(sink);
118 sink.extend(self);
119 }
120}
121
122impl Encode for str {
123 fn encode(&self, sink: &mut Vec<u8>) {
124 self.len().encode(sink);
125 sink.extend_from_slice(self.as_bytes());
126 }
127}
128
129impl Encode for usize {
130 fn encode(&self, sink: &mut Vec<u8>) {
131 assert!(*self <= u32::max_value() as usize);
132 (*self as u32).encode(sink)
133 }
134}
135
136impl Encode for u32 {
137 fn encode(&self, sink: &mut Vec<u8>) {
138 leb128::write::unsigned(w:sink, (*self).into()).unwrap();
139 }
140}
141
142impl Encode for i32 {
143 fn encode(&self, sink: &mut Vec<u8>) {
144 leb128::write::signed(w:sink, (*self).into()).unwrap();
145 }
146}
147
148impl Encode for u64 {
149 fn encode(&self, sink: &mut Vec<u8>) {
150 leb128::write::unsigned(w:sink, *self).unwrap();
151 }
152}
153
154impl Encode for i64 {
155 fn encode(&self, sink: &mut Vec<u8>) {
156 leb128::write::signed(w:sink, *self).unwrap();
157 }
158}
159
160impl Encode for f32 {
161 fn encode(&self, sink: &mut Vec<u8>) {
162 let bits: u32 = self.to_bits();
163 sink.extend(iter:bits.to_le_bytes())
164 }
165}
166
167impl Encode for f64 {
168 fn encode(&self, sink: &mut Vec<u8>) {
169 let bits: u64 = self.to_bits();
170 sink.extend(iter:bits.to_le_bytes())
171 }
172}
173
174fn encode_vec<T, V>(elements: V, sink: &mut Vec<u8>)
175where
176 T: Encode,
177 V: IntoIterator<Item = T>,
178 V::IntoIter: ExactSizeIterator,
179{
180 let elements: impl ExactSizeIterator = elements.into_iter();
181 u32::try_from(elements.len()).unwrap().encode(sink);
182 for x: T in elements {
183 x.encode(sink);
184 }
185}
186
187impl<T> Encode for Option<T>
188where
189 T: Encode,
190{
191 fn encode(&self, sink: &mut Vec<u8>) {
192 match self {
193 Some(v: &T) => {
194 sink.push(0x01);
195 v.encode(sink);
196 }
197 None => sink.push(0x00),
198 }
199 }
200}
201
202fn encoding_size(n: u32) -> usize {
203 let mut buf: [u8; 5] = [0u8; 5];
204 leb128::write::unsigned(&mut &mut buf[..], val:n.into()).unwrap()
205}
206
207fn encode_section(sink: &mut Vec<u8>, count: u32, bytes: &[u8]) {
208 (encoding_size(count) + bytes.len()).encode(sink);
209 count.encode(sink);
210 sink.extend(iter:bytes);
211}
212
213#[cfg(test)]
214mod test {
215 use super::*;
216
217 #[test]
218 fn it_encodes_an_empty_module() {
219 let bytes = Module::new().finish();
220 assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x01, 0x00, 0x00, 0x00]);
221 }
222
223 #[test]
224 fn it_encodes_an_empty_component() {
225 let bytes = Component::new().finish();
226 assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0d, 0x00, 0x01, 0x00]);
227 }
228}
229