Coverage Report

Created: 2026-06-07 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasm-encoder/src/component.rs
Line
Count
Source
1
mod aliases;
2
mod builder;
3
mod canonicals;
4
mod components;
5
mod exports;
6
mod imports;
7
mod instances;
8
mod modules;
9
mod names;
10
mod start;
11
mod types;
12
13
pub use self::aliases::*;
14
pub use self::builder::*;
15
pub use self::canonicals::*;
16
pub use self::components::*;
17
pub use self::exports::*;
18
pub use self::imports::*;
19
pub use self::instances::*;
20
pub use self::modules::*;
21
pub use self::names::*;
22
pub use self::start::*;
23
pub use self::types::*;
24
25
use crate::{CustomSection, Encode, ProducersSection, RawCustomSection};
26
use alloc::vec::Vec;
27
28
// Core sorts extended by the component model
29
const CORE_TYPE_SORT: u8 = 0x10;
30
const CORE_MODULE_SORT: u8 = 0x11;
31
const CORE_INSTANCE_SORT: u8 = 0x12;
32
33
const CORE_SORT: u8 = 0x00;
34
const FUNCTION_SORT: u8 = 0x01;
35
const VALUE_SORT: u8 = 0x02;
36
const TYPE_SORT: u8 = 0x03;
37
const COMPONENT_SORT: u8 = 0x04;
38
const INSTANCE_SORT: u8 = 0x05;
39
40
/// A WebAssembly component section.
41
///
42
/// Various builders defined in this crate already implement this trait, but you
43
/// can also implement it yourself for your own custom section builders, or use
44
/// `RawSection` to use a bunch of raw bytes as a section.
45
pub trait ComponentSection: Encode {
46
    /// Gets the section identifier for this section.
47
    fn id(&self) -> u8;
48
49
    /// Appends this section to the specified destination list of bytes.
50
0
    fn append_to_component(&self, dst: &mut Vec<u8>) {
51
0
        dst.push(self.id());
52
0
        self.encode(dst);
53
0
    }
Unexecuted instantiation: <wasm_encoder::component::names::ComponentNameSection as wasm_encoder::component::ComponentSection>::append_to_component
Unexecuted instantiation: <_ as wasm_encoder::component::ComponentSection>::append_to_component
54
}
55
56
/// Known section identifiers of WebAssembly components.
57
///
58
/// These sections are supported by the component model proposal.
59
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
60
#[repr(u8)]
61
pub enum ComponentSectionId {
62
    /// The section is a core custom section.
63
    CoreCustom = 0,
64
    /// The section is a core module section.
65
    CoreModule = 1,
66
    /// The section is a core instance section.
67
    CoreInstance = 2,
68
    /// The section is a core type section.
69
    CoreType = 3,
70
    /// The section is a component section.
71
    Component = 4,
72
    /// The section is an instance section.
73
    Instance = 5,
74
    /// The section is an alias section.
75
    Alias = 6,
76
    /// The section is a type section.
77
    Type = 7,
78
    /// The section is a canonical function section.
79
    CanonicalFunction = 8,
80
    /// The section is a start section.
81
    Start = 9,
82
    /// The section is an import section.
83
    Import = 10,
84
    /// The section is an export section.
85
    Export = 11,
86
}
87
88
impl From<ComponentSectionId> for u8 {
89
    #[inline]
90
265k
    fn from(id: ComponentSectionId) -> u8 {
91
265k
        id as u8
92
265k
    }
93
}
94
95
impl Encode for ComponentSectionId {
96
0
    fn encode(&self, sink: &mut Vec<u8>) {
97
0
        sink.push(*self as u8);
98
0
    }
99
}
100
101
/// Represents a WebAssembly component that is being encoded.
102
///
103
/// Unlike core WebAssembly modules, the sections of a component
104
/// may appear in any order and may be repeated.
105
///
106
/// Components may also added as a section to other components.
107
#[derive(Clone, Debug)]
108
pub struct Component {
109
    bytes: Vec<u8>,
110
}
111
112
impl Component {
113
    /// The 8-byte header at the beginning of all components.
114
    #[rustfmt::skip]
115
    pub const HEADER: [u8; 8] = [
116
        // Magic
117
        0x00, 0x61, 0x73, 0x6D,
118
        // Version
119
        0x0d, 0x00, 0x01, 0x00,
120
    ];
121
122
    /// Begin writing a new `Component`.
123
19.4k
    pub fn new() -> Self {
124
19.4k
        Self {
125
19.4k
            bytes: Self::HEADER.to_vec(),
126
19.4k
        }
127
19.4k
    }
128
129
    /// Finish writing this component and extract ownership of the encoded bytes.
130
17.4k
    pub fn finish(self) -> Vec<u8> {
131
17.4k
        self.bytes
132
17.4k
    }
133
134
    /// Write a section to this component.
135
265k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
265k
        self.bytes.push(section.id());
137
265k
        section.encode(&mut self.bytes);
138
265k
        self
139
265k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::component::canonicals::CanonicalFunctionSection>
Line
Count
Source
135
9.41k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
9.41k
        self.bytes.push(section.id());
137
9.41k
        section.encode(&mut self.bytes);
138
9.41k
        self
139
9.41k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::component::components::NestedComponentSection>
Line
Count
Source
135
2.04k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
2.04k
        self.bytes.push(section.id());
137
2.04k
        section.encode(&mut self.bytes);
138
2.04k
        self
139
2.04k
    }
Unexecuted instantiation: <wasm_encoder::component::Component>::section::<wasm_encoder::component::types::CoreTypeSection>
<wasm_encoder::component::Component>::section::<wasm_encoder::component::types::ComponentTypeSection>
Line
Count
Source
135
93.3k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
93.3k
        self.bytes.push(section.id());
137
93.3k
        section.encode(&mut self.bytes);
138
93.3k
        self
139
93.3k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::component::aliases::ComponentAliasSection>
Line
Count
Source
135
11.6k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
11.6k
        self.bytes.push(section.id());
137
11.6k
        section.encode(&mut self.bytes);
138
11.6k
        self
139
11.6k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::component::exports::ComponentExportSection>
Line
Count
Source
135
87.1k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
87.1k
        self.bytes.push(section.id());
137
87.1k
        section.encode(&mut self.bytes);
138
87.1k
        self
139
87.1k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::component::imports::ComponentImportSection>
Line
Count
Source
135
6.54k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
6.54k
        self.bytes.push(section.id());
137
6.54k
        section.encode(&mut self.bytes);
138
6.54k
        self
139
6.54k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::component::modules::ModuleSection>
Line
Count
Source
135
5.03k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
5.03k
        self.bytes.push(section.id());
137
5.03k
        section.encode(&mut self.bytes);
138
5.03k
        self
139
5.03k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::component::instances::InstanceSection>
Line
Count
Source
135
9.75k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
9.75k
        self.bytes.push(section.id());
137
9.75k
        section.encode(&mut self.bytes);
138
9.75k
        self
139
9.75k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::component::instances::ComponentInstanceSection>
Line
Count
Source
135
2.04k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
2.04k
        self.bytes.push(section.id());
137
2.04k
        section.encode(&mut self.bytes);
138
2.04k
        self
139
2.04k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::raw::RawSection>
Line
Count
Source
135
3.45k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
3.45k
        self.bytes.push(section.id());
137
3.45k
        section.encode(&mut self.bytes);
138
3.45k
        self
139
3.45k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::core::custom::CustomSection>
Line
Count
Source
135
17.4k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
17.4k
        self.bytes.push(section.id());
137
17.4k
        section.encode(&mut self.bytes);
138
17.4k
        self
139
17.4k
    }
<wasm_encoder::component::Component>::section::<wasm_encoder::core::custom::RawCustomSection>
Line
Count
Source
135
17.4k
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
136
17.4k
        self.bytes.push(section.id());
137
17.4k
        section.encode(&mut self.bytes);
138
17.4k
        self
139
17.4k
    }
140
141
    /// View the encoded bytes.
142
0
    pub fn as_slice(&self) -> &[u8] {
143
0
        &self.bytes
144
0
    }
145
}
146
147
impl Default for Component {
148
19.4k
    fn default() -> Self {
149
19.4k
        Self::new()
150
19.4k
    }
151
}
152
153
impl ComponentSection for CustomSection<'_> {
154
17.4k
    fn id(&self) -> u8 {
155
17.4k
        ComponentSectionId::CoreCustom.into()
156
17.4k
    }
157
}
158
159
impl ComponentSection for RawCustomSection<'_> {
160
17.4k
    fn id(&self) -> u8 {
161
17.4k
        ComponentSectionId::CoreCustom.into()
162
17.4k
    }
163
}
164
165
impl ComponentSection for ProducersSection {
166
0
    fn id(&self) -> u8 {
167
0
        ComponentSectionId::CoreCustom.into()
168
0
    }
169
}