Coverage Report

Created: 2026-03-26 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/wasm-encoder-0.245.1/src/lib.rs
Line
Count
Source
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,
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.instructions()
58
//!     .local_get(0)
59
//!     .local_get(1)
60
//!     .i32_add()
61
//!     .end();
62
//! codes.function(&f);
63
//! module.section(&codes);
64
//!
65
//! // Extract the encoded Wasm bytes for this module.
66
//! let wasm_bytes = module.finish();
67
//!
68
//! // We generated a valid Wasm module!
69
//! assert!(wasmparser::validate(&wasm_bytes).is_ok());
70
//! ```
71
72
#![cfg_attr(docsrs, feature(doc_cfg))]
73
#![no_std]
74
#![deny(missing_docs, missing_debug_implementations)]
75
76
extern crate alloc;
77
#[cfg(feature = "std")]
78
#[macro_use]
79
extern crate std;
80
81
#[cfg(feature = "component-model")]
82
mod component;
83
mod core;
84
mod raw;
85
#[cfg(feature = "wasmparser")]
86
pub mod reencode;
87
88
#[cfg(feature = "component-model")]
89
pub use self::component::*;
90
pub use self::core::*;
91
pub use self::raw::*;
92
93
use alloc::vec::Vec;
94
95
/// Implemented by types that can be encoded into a byte sink.
96
pub trait Encode {
97
    /// Encode the type into the given byte sink.
98
    fn encode(&self, sink: &mut Vec<u8>);
99
}
100
101
impl<T: Encode + ?Sized> Encode for &'_ T {
102
78.6k
    fn encode(&self, sink: &mut Vec<u8>) {
103
78.6k
        T::encode(self, sink)
104
78.6k
    }
<&wasm_encoder::core::code::ConstExpr as wasm_encoder::Encode>::encode
Line
Count
Source
102
78.6k
    fn encode(&self, sink: &mut Vec<u8>) {
103
78.6k
        T::encode(self, sink)
104
78.6k
    }
Unexecuted instantiation: <&str as wasm_encoder::Encode>::encode
105
}
106
107
impl<T: Encode> Encode for [T] {
108
52.1k
    fn encode(&self, sink: &mut Vec<u8>) {
109
52.1k
        self.len().encode(sink);
110
1.69M
        for item in self {
111
1.69M
            item.encode(sink);
112
1.69M
        }
113
52.1k
    }
Unexecuted instantiation: <[u32] as wasm_encoder::Encode>::encode
<[wasm_encoder::core::types::ValType] as wasm_encoder::Encode>::encode
Line
Count
Source
108
698
    fn encode(&self, sink: &mut Vec<u8>) {
109
698
        self.len().encode(sink);
110
698
        for item in self {
111
698
            item.encode(sink);
112
698
        }
113
698
    }
<[u32] as wasm_encoder::Encode>::encode
Line
Count
Source
108
51.4k
    fn encode(&self, sink: &mut Vec<u8>) {
109
51.4k
        self.len().encode(sink);
110
1.69M
        for item in self {
111
1.69M
            item.encode(sink);
112
1.69M
        }
113
51.4k
    }
114
}
115
116
impl Encode for [u8] {
117
253k
    fn encode(&self, sink: &mut Vec<u8>) {
118
253k
        self.len().encode(sink);
119
253k
        sink.extend(self);
120
253k
    }
121
}
122
123
impl Encode for str {
124
126k
    fn encode(&self, sink: &mut Vec<u8>) {
125
126k
        self.len().encode(sink);
126
126k
        sink.extend_from_slice(self.as_bytes());
127
126k
    }
128
}
129
130
impl Encode for usize {
131
1.15M
    fn encode(&self, sink: &mut Vec<u8>) {
132
1.15M
        assert!(*self <= u32::max_value() as usize);
133
1.15M
        (*self as u32).encode(sink)
134
1.15M
    }
135
}
136
137
impl Encode for u32 {
138
16.2M
    fn encode(&self, sink: &mut Vec<u8>) {
139
16.2M
        let (value, pos) = leb128fmt::encode_u32(*self).unwrap();
140
16.2M
        sink.extend_from_slice(&value[..pos]);
141
16.2M
    }
142
}
143
144
impl Encode for i32 {
145
1.62M
    fn encode(&self, sink: &mut Vec<u8>) {
146
1.62M
        let (value, pos) = leb128fmt::encode_s32(*self).unwrap();
147
1.62M
        sink.extend_from_slice(&value[..pos]);
148
1.62M
    }
149
}
150
151
impl Encode for u64 {
152
518k
    fn encode(&self, sink: &mut Vec<u8>) {
153
518k
        let (value, pos) = leb128fmt::encode_u64(*self).unwrap();
154
518k
        sink.extend_from_slice(&value[..pos]);
155
518k
    }
156
}
157
158
impl Encode for i64 {
159
2.05M
    fn encode(&self, sink: &mut Vec<u8>) {
160
2.05M
        let (value, pos) = leb128fmt::encode_s64(*self).unwrap();
161
2.05M
        sink.extend_from_slice(&value[..pos]);
162
2.05M
    }
163
}
164
165
195k
fn encode_vec<T, V>(elements: V, sink: &mut Vec<u8>)
166
195k
where
167
195k
    T: Encode,
168
195k
    V: IntoIterator<Item = T>,
169
195k
    V::IntoIter: ExactSizeIterator,
170
{
171
195k
    let elements = elements.into_iter();
172
195k
    u32::try_from(elements.len()).unwrap().encode(sink);
173
761k
    for x in elements {
174
761k
        x.encode(sink);
175
761k
    }
176
195k
}
wasm_encoder::encode_vec::<wasm_encoder::core::code::Catch, core::iter::adapters::cloned::Cloned<core::slice::iter::Iter<wasm_encoder::core::code::Catch>>>
Line
Count
Source
165
178k
fn encode_vec<T, V>(elements: V, sink: &mut Vec<u8>)
166
178k
where
167
178k
    T: Encode,
168
178k
    V: IntoIterator<Item = T>,
169
178k
    V::IntoIter: ExactSizeIterator,
170
{
171
178k
    let elements = elements.into_iter();
172
178k
    u32::try_from(elements.len()).unwrap().encode(sink);
173
430k
    for x in elements {
174
430k
        x.encode(sink);
175
430k
    }
176
178k
}
Unexecuted instantiation: wasm_encoder::encode_vec::<wasm_encoder::core::code::Handle, core::iter::adapters::cloned::Cloned<core::slice::iter::Iter<wasm_encoder::core::code::Handle>>>
wasm_encoder::encode_vec::<u32, core::iter::adapters::copied::Copied<core::slice::iter::Iter<u32>>>
Line
Count
Source
165
16.3k
fn encode_vec<T, V>(elements: V, sink: &mut Vec<u8>)
166
16.3k
where
167
16.3k
    T: Encode,
168
16.3k
    V: IntoIterator<Item = T>,
169
16.3k
    V::IntoIter: ExactSizeIterator,
170
{
171
16.3k
    let elements = elements.into_iter();
172
16.3k
    u32::try_from(elements.len()).unwrap().encode(sink);
173
331k
    for x in elements {
174
331k
        x.encode(sink);
175
331k
    }
176
16.3k
}
177
178
impl<T> Encode for Option<T>
179
where
180
    T: Encode,
181
{
182
0
    fn encode(&self, sink: &mut Vec<u8>) {
183
0
        match self {
184
0
            Some(v) => {
185
0
                sink.push(0x01);
186
0
                v.encode(sink);
187
0
            }
188
0
            None => sink.push(0x00),
189
        }
190
0
    }
Unexecuted instantiation: <core::option::Option<wasm_encoder::component::types::ComponentValType> as wasm_encoder::Encode>::encode
Unexecuted instantiation: <core::option::Option<wasm_encoder::component::types::ComponentValType> as wasm_encoder::Encode>::encode
Unexecuted instantiation: <core::option::Option<u32> as wasm_encoder::Encode>::encode
191
}
192
193
28.0k
fn encoding_size(n: u32) -> usize {
194
28.0k
    let (_value, pos) = leb128fmt::encode_u32(n).unwrap();
195
28.0k
    pos
196
28.0k
}
197
198
26.7k
fn encode_section(sink: &mut Vec<u8>, count: u32, bytes: &[u8]) {
199
26.7k
    (encoding_size(count) + bytes.len()).encode(sink);
200
26.7k
    count.encode(sink);
201
26.7k
    sink.extend(bytes);
202
26.7k
}
203
204
#[cfg(test)]
205
mod test {
206
    use super::*;
207
208
    #[test]
209
    fn test_encoding_size() {
210
        assert_eq!(encoding_size(624485), 3);
211
    }
212
213
    #[test]
214
    fn it_encodes_an_empty_module() {
215
        let bytes = Module::new().finish();
216
        assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x01, 0x00, 0x00, 0x00]);
217
    }
218
219
    #[test]
220
    fn it_encodes_an_empty_component() {
221
        let bytes = Component::new().finish();
222
        assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0d, 0x00, 0x01, 0x00]);
223
    }
224
}