Coverage Report

Created: 2026-08-08 08:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasm-encoder/src/component/instances.rs
Line
Count
Source
1
use super::CORE_INSTANCE_SORT;
2
use crate::{
3
    ComponentExportKind, ComponentExternName, ComponentSection, ComponentSectionId, Encode,
4
    ExportKind, encode_section,
5
};
6
use alloc::vec::Vec;
7
8
/// Represents an argument to a module instantiation.
9
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10
pub enum ModuleArg {
11
    /// The argument is an instance.
12
    Instance(u32),
13
}
14
15
impl Encode for ModuleArg {
16
5.45k
    fn encode(&self, sink: &mut Vec<u8>) {
17
5.45k
        let (sort, idx) = match self {
18
5.45k
            Self::Instance(idx) => (CORE_INSTANCE_SORT, *idx),
19
5.45k
        };
20
5.45k
        sink.push(sort);
21
5.45k
        idx.encode(sink);
22
5.45k
    }
23
}
24
25
/// An encoder for the core instance section of WebAssembly components.
26
///
27
/// # Example
28
///
29
/// ```rust
30
/// use wasm_encoder::{Component, InstanceSection, ExportKind, ModuleArg};
31
///
32
/// let mut instances = InstanceSection::new();
33
/// instances.export_items([("foo", ExportKind::Func, 0)]);
34
/// instances.instantiate(1, [("foo", ModuleArg::Instance(0))]);
35
///
36
/// let mut component = Component::new();
37
/// component.section(&instances);
38
///
39
/// let bytes = component.finish();
40
/// ```
41
#[derive(Clone, Debug, Default)]
42
pub struct InstanceSection {
43
    bytes: Vec<u8>,
44
    num_added: u32,
45
}
46
47
impl InstanceSection {
48
    /// Create a new core instance section encoder.
49
8.01k
    pub fn new() -> Self {
50
8.01k
        Self::default()
51
8.01k
    }
52
53
    /// The number of instances in the section.
54
0
    pub fn len(&self) -> u32 {
55
0
        self.num_added
56
0
    }
57
58
    /// Determines if the section is empty.
59
0
    pub fn is_empty(&self) -> bool {
60
0
        self.num_added == 0
61
0
    }
62
63
    /// Define an instance by instantiating a core module.
64
7.15k
    pub fn instantiate<A, S>(&mut self, module_index: u32, args: A) -> &mut Self
65
7.15k
    where
66
7.15k
        A: IntoIterator<Item = (S, ModuleArg)>,
67
7.15k
        A::IntoIter: ExactSizeIterator,
68
7.15k
        S: AsRef<str>,
69
    {
70
7.15k
        let args = args.into_iter();
71
7.15k
        self.bytes.push(0x00);
72
7.15k
        module_index.encode(&mut self.bytes);
73
7.15k
        args.len().encode(&mut self.bytes);
74
7.15k
        for (name, arg) in args {
75
5.45k
            name.as_ref().encode(&mut self.bytes);
76
5.45k
            arg.encode(&mut self.bytes);
77
5.45k
        }
78
7.15k
        self.num_added += 1;
79
7.15k
        self
80
7.15k
    }
<wasm_encoder::component::instances::InstanceSection>::instantiate::<[(&str, wasm_encoder::component::instances::ModuleArg); 0], &str>
Line
Count
Source
64
651
    pub fn instantiate<A, S>(&mut self, module_index: u32, args: A) -> &mut Self
65
651
    where
66
651
        A: IntoIterator<Item = (S, ModuleArg)>,
67
651
        A::IntoIter: ExactSizeIterator,
68
651
        S: AsRef<str>,
69
    {
70
651
        let args = args.into_iter();
71
651
        self.bytes.push(0x00);
72
651
        module_index.encode(&mut self.bytes);
73
651
        args.len().encode(&mut self.bytes);
74
651
        for (name, arg) in args {
75
0
            name.as_ref().encode(&mut self.bytes);
76
0
            arg.encode(&mut self.bytes);
77
0
        }
78
651
        self.num_added += 1;
79
651
        self
80
651
    }
<wasm_encoder::component::instances::InstanceSection>::instantiate::<[(&str, wasm_encoder::component::instances::ModuleArg); 1], &str>
Line
Count
Source
64
3.57k
    pub fn instantiate<A, S>(&mut self, module_index: u32, args: A) -> &mut Self
65
3.57k
    where
66
3.57k
        A: IntoIterator<Item = (S, ModuleArg)>,
67
3.57k
        A::IntoIter: ExactSizeIterator,
68
3.57k
        S: AsRef<str>,
69
    {
70
3.57k
        let args = args.into_iter();
71
3.57k
        self.bytes.push(0x00);
72
3.57k
        module_index.encode(&mut self.bytes);
73
3.57k
        args.len().encode(&mut self.bytes);
74
3.57k
        for (name, arg) in args {
75
3.57k
            name.as_ref().encode(&mut self.bytes);
76
3.57k
            arg.encode(&mut self.bytes);
77
3.57k
        }
78
3.57k
        self.num_added += 1;
79
3.57k
        self
80
3.57k
    }
<wasm_encoder::component::instances::InstanceSection>::instantiate::<alloc::vec::Vec<(&str, wasm_encoder::component::instances::ModuleArg)>, &str>
Line
Count
Source
64
2.92k
    pub fn instantiate<A, S>(&mut self, module_index: u32, args: A) -> &mut Self
65
2.92k
    where
66
2.92k
        A: IntoIterator<Item = (S, ModuleArg)>,
67
2.92k
        A::IntoIter: ExactSizeIterator,
68
2.92k
        S: AsRef<str>,
69
    {
70
2.92k
        let args = args.into_iter();
71
2.92k
        self.bytes.push(0x00);
72
2.92k
        module_index.encode(&mut self.bytes);
73
2.92k
        args.len().encode(&mut self.bytes);
74
2.92k
        for (name, arg) in args {
75
1.87k
            name.as_ref().encode(&mut self.bytes);
76
1.87k
            arg.encode(&mut self.bytes);
77
1.87k
        }
78
2.92k
        self.num_added += 1;
79
2.92k
        self
80
2.92k
    }
Unexecuted instantiation: <wasm_encoder::component::instances::InstanceSection>::instantiate::<_, _>
81
82
    /// Define an instance by exporting core WebAssembly items.
83
5.45k
    pub fn export_items<E, S>(&mut self, exports: E) -> &mut Self
84
5.45k
    where
85
5.45k
        E: IntoIterator<Item = (S, ExportKind, u32)>,
86
5.45k
        E::IntoIter: ExactSizeIterator,
87
5.45k
        S: AsRef<str>,
88
    {
89
5.45k
        let exports = exports.into_iter();
90
5.45k
        self.bytes.push(0x01);
91
5.45k
        exports.len().encode(&mut self.bytes);
92
15.4k
        for (name, kind, index) in exports {
93
15.4k
            name.as_ref().encode(&mut self.bytes);
94
15.4k
            kind.encode(&mut self.bytes);
95
15.4k
            index.encode(&mut self.bytes);
96
15.4k
        }
97
5.45k
        self.num_added += 1;
98
5.45k
        self
99
5.45k
    }
<wasm_encoder::component::instances::InstanceSection>::export_items::<alloc::vec::Vec<(&str, wasm_encoder::core::exports::ExportKind, u32)>, &str>
Line
Count
Source
83
5.45k
    pub fn export_items<E, S>(&mut self, exports: E) -> &mut Self
84
5.45k
    where
85
5.45k
        E: IntoIterator<Item = (S, ExportKind, u32)>,
86
5.45k
        E::IntoIter: ExactSizeIterator,
87
5.45k
        S: AsRef<str>,
88
    {
89
5.45k
        let exports = exports.into_iter();
90
5.45k
        self.bytes.push(0x01);
91
5.45k
        exports.len().encode(&mut self.bytes);
92
15.4k
        for (name, kind, index) in exports {
93
15.4k
            name.as_ref().encode(&mut self.bytes);
94
15.4k
            kind.encode(&mut self.bytes);
95
15.4k
            index.encode(&mut self.bytes);
96
15.4k
        }
97
5.45k
        self.num_added += 1;
98
5.45k
        self
99
5.45k
    }
Unexecuted instantiation: <wasm_encoder::component::instances::InstanceSection>::export_items::<core::iter::adapters::map::Map<core::slice::iter::Iter<(alloc::string::String, wasm_encoder::core::exports::ExportKind, u32)>, <wit_component::encoding::EncodingState>::create_export_task_initialization_wrappers::{closure#4}>, &str>
Unexecuted instantiation: <wasm_encoder::component::instances::InstanceSection>::export_items::<_, _>
100
}
101
102
impl Encode for InstanceSection {
103
8.01k
    fn encode(&self, sink: &mut Vec<u8>) {
104
8.01k
        encode_section(sink, self.num_added, &self.bytes);
105
8.01k
    }
106
}
107
108
impl ComponentSection for InstanceSection {
109
8.01k
    fn id(&self) -> u8 {
110
8.01k
        ComponentSectionId::CoreInstance.into()
111
8.01k
    }
112
}
113
114
/// An encoder for the instance section of WebAssembly components.
115
///
116
/// # Example
117
///
118
/// ```rust
119
/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind};
120
///
121
/// let mut instances = ComponentInstanceSection::new();
122
/// instances.export_items([("foo", ComponentExportKind::Func, 0)]);
123
/// instances.instantiate(1, [("foo", ComponentExportKind::Instance, 0)]);
124
///
125
/// let mut component = Component::new();
126
/// component.section(&instances);
127
///
128
/// let bytes = component.finish();
129
/// ```
130
#[derive(Clone, Debug, Default)]
131
pub struct ComponentInstanceSection {
132
    bytes: Vec<u8>,
133
    num_added: u32,
134
}
135
136
impl ComponentInstanceSection {
137
    /// Create a new instance section encoder.
138
1.65k
    pub fn new() -> Self {
139
1.65k
        Self::default()
140
1.65k
    }
141
142
    /// The number of instances in the section.
143
0
    pub fn len(&self) -> u32 {
144
0
        self.num_added
145
0
    }
146
147
    /// Determines if the section is empty.
148
0
    pub fn is_empty(&self) -> bool {
149
0
        self.num_added == 0
150
0
    }
151
152
    /// Define an instance by instantiating a component.
153
1.65k
    pub fn instantiate<A, S>(&mut self, component_index: u32, args: A) -> &mut Self
154
1.65k
    where
155
1.65k
        A: IntoIterator<Item = (S, ComponentExportKind, u32)>,
156
1.65k
        A::IntoIter: ExactSizeIterator,
157
1.65k
        S: AsRef<str>,
158
    {
159
1.65k
        let args = args.into_iter();
160
1.65k
        self.bytes.push(0x00);
161
1.65k
        component_index.encode(&mut self.bytes);
162
1.65k
        args.len().encode(&mut self.bytes);
163
2.93k
        for (name, kind, index) in args {
164
2.93k
            name.as_ref().encode(&mut self.bytes);
165
2.93k
            kind.encode(&mut self.bytes);
166
2.93k
            index.encode(&mut self.bytes);
167
2.93k
        }
168
1.65k
        self.num_added += 1;
169
1.65k
        self
170
1.65k
    }
<wasm_encoder::component::instances::ComponentInstanceSection>::instantiate::<alloc::vec::Vec<(alloc::string::String, wasm_encoder::component::exports::ComponentExportKind, u32)>, alloc::string::String>
Line
Count
Source
153
1.65k
    pub fn instantiate<A, S>(&mut self, component_index: u32, args: A) -> &mut Self
154
1.65k
    where
155
1.65k
        A: IntoIterator<Item = (S, ComponentExportKind, u32)>,
156
1.65k
        A::IntoIter: ExactSizeIterator,
157
1.65k
        S: AsRef<str>,
158
    {
159
1.65k
        let args = args.into_iter();
160
1.65k
        self.bytes.push(0x00);
161
1.65k
        component_index.encode(&mut self.bytes);
162
1.65k
        args.len().encode(&mut self.bytes);
163
2.93k
        for (name, kind, index) in args {
164
2.93k
            name.as_ref().encode(&mut self.bytes);
165
2.93k
            kind.encode(&mut self.bytes);
166
2.93k
            index.encode(&mut self.bytes);
167
2.93k
        }
168
1.65k
        self.num_added += 1;
169
1.65k
        self
170
1.65k
    }
Unexecuted instantiation: <wasm_encoder::component::instances::ComponentInstanceSection>::instantiate::<_, _>
171
172
    /// Define an instance by exporting items.
173
0
    pub fn export_items<'a, N, E>(&mut self, exports: E) -> &mut Self
174
0
    where
175
0
        E: IntoIterator<Item = (N, ComponentExportKind, u32)>,
176
0
        E::IntoIter: ExactSizeIterator,
177
0
        N: Into<ComponentExternName<'a>>,
178
    {
179
0
        let exports = exports.into_iter();
180
0
        self.bytes.push(0x01);
181
0
        exports.len().encode(&mut self.bytes);
182
0
        for (name, kind, index) in exports {
183
0
            name.into().encode(&mut self.bytes);
184
0
            kind.encode(&mut self.bytes);
185
0
            index.encode(&mut self.bytes);
186
0
        }
187
0
        self.num_added += 1;
188
0
        self
189
0
    }
190
}
191
192
impl Encode for ComponentInstanceSection {
193
1.65k
    fn encode(&self, sink: &mut Vec<u8>) {
194
1.65k
        encode_section(sink, self.num_added, &self.bytes);
195
1.65k
    }
196
}
197
198
impl ComponentSection for ComponentInstanceSection {
199
1.65k
    fn id(&self) -> u8 {
200
1.65k
        ComponentSectionId::Instance.into()
201
1.65k
    }
202
}