Coverage Report

Created: 2026-09-28 08:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasm-mutate/src/info.rs
Line
Count
Source
1
use crate::{
2
    Error, Result,
3
    module::{PrimitiveTypeInfo, TypeInfo},
4
};
5
use std::{collections::HashSet, ops::Range};
6
use wasm_encoder::{RawSection, SectionId};
7
use wasmparser::{BinaryReader, Chunk, Parser, Payload};
8
9
/// Provides module information for future usage during mutation
10
/// an instance of ModuleInfo could be user to determine which mutation could be applied
11
#[derive(Default, Clone, Debug)]
12
pub struct ModuleInfo<'a> {
13
    // The following fields are offsets inside the `raw_sections` field.
14
    // The main idea is to maintain the order of the sections in the input Wasm.
15
    pub exports: Option<usize>,
16
    pub export_names: HashSet<String>,
17
18
    // Indices of various sections within `self.raw_sections`.
19
    pub types: Option<usize>,
20
    pub imports: Option<usize>,
21
    pub tables: Option<usize>,
22
    pub memories: Option<usize>,
23
    pub globals: Option<usize>,
24
    pub elements: Option<usize>,
25
    pub functions: Option<usize>,
26
    pub data_count: Option<usize>,
27
    pub data: Option<usize>,
28
    pub code: Option<usize>,
29
    pub start: Option<usize>,
30
31
    pub exports_count: u32,
32
    elements_count: u32,
33
    data_segments_count: u32,
34
    start_function: Option<u32>,
35
    memory_count: u32,
36
    table_count: u32,
37
    tag_count: u32,
38
39
    imported_functions_count: u32,
40
    imported_globals_count: u32,
41
    imported_memories_count: u32,
42
    imported_tables_count: u32,
43
    imported_tags_count: u32,
44
45
    // types for inner functions
46
    pub types_map: Vec<TypeInfo>,
47
48
    // function idx to type idx
49
    pub function_map: Vec<u32>,
50
    pub global_types: Vec<PrimitiveTypeInfo>,
51
    pub table_types: Vec<wasmparser::TableType>,
52
    pub memory_types: Vec<wasmparser::MemoryType>,
53
54
    // raw_sections
55
    pub raw_sections: Vec<RawSection<'a>>,
56
    pub input_wasm: &'a [u8],
57
}
58
59
impl<'a> ModuleInfo<'a> {
60
    /// Parse the given Wasm bytes and fill out a `ModuleInfo` AST for it.
61
3.86k
    pub fn new(input_wasm: &[u8]) -> Result<ModuleInfo<'_>> {
62
3.86k
        let mut parser = Parser::new(0);
63
3.86k
        let mut info = ModuleInfo::default();
64
3.86k
        let mut wasm = input_wasm;
65
3.86k
        info.input_wasm = wasm;
66
67
        loop {
68
            // Convert into a range into the wasm input
69
27.5k
            let offset = parser.offset();
70
27.5k
            let get_input_data = |range: &Range<u64>| {
71
20.2k
                &wasm[(range.start - offset) as usize..(range.end - offset) as usize]
72
20.2k
            };
73
27.5k
            let (payload, consumed) = match parser.parse(wasm, true)? {
74
0
                Chunk::NeedMoreData(hint) => {
75
0
                    panic!("Invalid Wasm module {hint:?}");
76
                }
77
27.5k
                Chunk::Parsed { consumed, payload } => (payload, consumed),
78
            };
79
27.5k
            match payload {
80
                Payload::CodeSectionStart {
81
                    count: _,
82
2.48k
                    range,
83
                    size: _,
84
                } => {
85
2.48k
                    info.code = Some(info.raw_sections.len());
86
2.48k
                    info.section(SectionId::Code.into(), get_input_data(&range));
87
2.48k
                    parser.skip_section();
88
                    // update slice, bypass the section
89
2.48k
                    wasm = &wasm[(range.end - offset) as usize..];
90
91
2.48k
                    continue;
92
                }
93
3.41k
                Payload::TypeSection(reader) => {
94
3.41k
                    info.types = Some(info.raw_sections.len());
95
3.41k
                    info.section(SectionId::Type.into(), get_input_data(&reader.range()));
96
97
                    // Save function types
98
24.0k
                    for ty in reader.into_iter_err_on_gc_types() {
99
24.0k
                        info.types_map.push(ty?.try_into()?);
100
                    }
101
                }
102
2.29k
                Payload::ImportSection(reader) => {
103
2.29k
                    info.imports = Some(info.raw_sections.len());
104
2.29k
                    info.section(SectionId::Import.into(), get_input_data(&reader.range()));
105
106
25.1k
                    for ty in reader.into_imports() {
107
25.1k
                        match ty?.ty {
108
8.10k
                            wasmparser::TypeRef::Func(ty) | wasmparser::TypeRef::FuncExact(ty) => {
109
8.10k
                                // Save imported functions
110
8.10k
                                info.function_map.push(ty);
111
8.10k
                                info.imported_functions_count += 1;
112
8.10k
                            }
113
11.6k
                            wasmparser::TypeRef::Global(ty) => {
114
11.6k
                                let ty = PrimitiveTypeInfo::try_from(ty.content_type)?;
115
11.5k
                                info.global_types.push(ty);
116
11.5k
                                info.imported_globals_count += 1;
117
                            }
118
1.99k
                            wasmparser::TypeRef::Memory(ty) => {
119
1.99k
                                info.memory_count += 1;
120
1.99k
                                info.imported_memories_count += 1;
121
1.99k
                                info.memory_types.push(ty);
122
1.99k
                            }
123
2.14k
                            wasmparser::TypeRef::Table(ty) => {
124
2.14k
                                info.table_count += 1;
125
2.14k
                                info.imported_tables_count += 1;
126
2.14k
                                info.table_types.push(ty);
127
2.14k
                            }
128
1.32k
                            wasmparser::TypeRef::Tag(_ty) => {
129
1.32k
                                info.tag_count += 1;
130
1.32k
                                info.imported_tags_count += 1;
131
1.32k
                            }
132
                        }
133
                    }
134
                }
135
2.49k
                Payload::FunctionSection(reader) => {
136
2.49k
                    info.functions = Some(info.raw_sections.len());
137
2.49k
                    info.section(SectionId::Function.into(), get_input_data(&reader.range()));
138
139
62.2k
                    for ty in reader {
140
62.2k
                        info.function_map.push(ty?);
141
                    }
142
                }
143
1.35k
                Payload::TableSection(reader) => {
144
1.35k
                    info.tables = Some(info.raw_sections.len());
145
1.35k
                    info.table_count += reader.count();
146
1.35k
                    info.section(SectionId::Table.into(), get_input_data(&reader.range()));
147
148
5.78k
                    for table in reader {
149
5.78k
                        let table = table?;
150
5.78k
                        info.table_types.push(table.ty);
151
                    }
152
                }
153
1.61k
                Payload::MemorySection(reader) => {
154
1.61k
                    info.memories = Some(info.raw_sections.len());
155
1.61k
                    info.memory_count += reader.count();
156
1.61k
                    info.section(SectionId::Memory.into(), get_input_data(&reader.range()));
157
158
11.0k
                    for ty in reader {
159
11.0k
                        info.memory_types.push(ty?);
160
                    }
161
                }
162
194
                Payload::TagSection(reader) => {
163
194
                    info.tag_count += reader.count();
164
194
                    info.section(SectionId::Tag.into(), get_input_data(&reader.range()));
165
194
                }
166
2.39k
                Payload::GlobalSection(reader) => {
167
2.39k
                    info.globals = Some(info.raw_sections.len());
168
2.39k
                    info.section(SectionId::Global.into(), get_input_data(&reader.range()));
169
170
35.5k
                    for ty in reader {
171
35.5k
                        let ty = ty?;
172
                        // We only need the type of the global, not necessarily if is mutable or not
173
35.5k
                        let ty = PrimitiveTypeInfo::try_from(ty.ty.content_type)?;
174
35.5k
                        info.global_types.push(ty);
175
                    }
176
                }
177
1.37k
                Payload::ExportSection(reader) => {
178
1.37k
                    info.exports = Some(info.raw_sections.len());
179
1.37k
                    info.exports_count = reader.count();
180
181
15.4k
                    for entry in reader.clone() {
182
15.4k
                        info.export_names.insert(entry?.name.into());
183
                    }
184
185
1.37k
                    info.section(SectionId::Export.into(), get_input_data(&reader.range()));
186
                }
187
280
                Payload::StartSection { func, range } => {
188
280
                    info.start = Some(info.raw_sections.len());
189
280
                    info.start_function = Some(func);
190
280
                    info.section(SectionId::Start.into(), get_input_data(&range));
191
280
                }
192
850
                Payload::ElementSection(reader) => {
193
850
                    info.elements = Some(info.raw_sections.len());
194
850
                    info.elements_count = reader.count();
195
850
                    info.section(SectionId::Element.into(), get_input_data(&reader.range()));
196
850
                }
197
884
                Payload::DataSection(reader) => {
198
884
                    info.data = Some(info.raw_sections.len());
199
884
                    info.data_segments_count = reader.count();
200
884
                    info.section(SectionId::Data.into(), get_input_data(&reader.range()));
201
884
                }
202
0
                Payload::CustomSection(c) => {
203
0
                    info.section(SectionId::Custom.into(), get_input_data(&c.range()));
204
0
                }
205
                Payload::UnknownSection {
206
0
                    id,
207
                    contents: _,
208
0
                    range,
209
0
                } => {
210
0
                    info.section(id, get_input_data(&range));
211
0
                }
212
648
                Payload::DataCountSection { count: _, range } => {
213
648
                    info.data_count = Some(info.raw_sections.len());
214
648
                    info.section(SectionId::DataCount.into(), get_input_data(&range));
215
648
                }
216
3.86k
                Payload::Version { .. } => {}
217
                Payload::End(_) => {
218
3.36k
                    break;
219
                }
220
0
                _ => return Err(Error::unsupported(format!("section: {payload:?}"))),
221
            }
222
21.1k
            wasm = &wasm[consumed..];
223
        }
224
225
3.36k
        Ok(info)
226
3.86k
    }
227
228
86
    pub fn has_nonempty_code(&self) -> bool {
229
86
        if let Some(section) = self.code {
230
22
            let section_data = self.raw_sections[section].data;
231
22
            let reader = BinaryReader::new(section_data, 0);
232
22
            wasmparser::CodeSectionReader::new(reader)
233
22
                .map(|r| r.count() != 0)
234
22
                .unwrap_or(false)
235
        } else {
236
64
            false
237
        }
238
86
    }
239
240
1.44k
    pub fn has_code(&self) -> bool {
241
1.44k
        self.code != None
242
1.44k
    }
243
244
    /// Does this module have any custom sections?
245
451
    pub fn has_custom_section(&self) -> bool {
246
451
        self.raw_sections
247
451
            .iter()
248
2.11k
            .any(|s| s.id == SectionId::Custom as u8)
249
451
    }
250
251
    /// Registers a new raw_section in the ModuleInfo
252
20.2k
    pub fn section(&mut self, id: u8, data: &'a [u8]) {
253
20.2k
        self.raw_sections.push(RawSection { id, data });
254
20.2k
    }
255
256
1.14k
    pub fn get_code_section(&self) -> RawSection<'a> {
257
1.14k
        self.raw_sections[self.code.unwrap()]
258
1.14k
    }
259
260
15.7k
    pub fn get_binary_reader(&self, i: usize) -> wasmparser::BinaryReader<'a> {
261
15.7k
        BinaryReader::new(self.raw_sections[i].data, 0)
262
15.7k
    }
263
264
95
    pub fn has_exports(&self) -> bool {
265
95
        self.exports != None
266
95
    }
267
268
    /// Returns the function type based on the index of the function type
269
    /// `types[functions[idx]]`
270
2.12k
    pub fn get_functype_idx(&self, idx: u32) -> &TypeInfo {
271
2.12k
        let functpeindex = self.function_map[idx as usize] as usize;
272
2.12k
        &self.types_map[functpeindex]
273
2.12k
    }
274
275
    /// Returns the number of globals used by the Wasm binary including imported
276
    /// glboals
277
40.5k
    pub fn get_global_count(&self) -> usize {
278
40.5k
        self.global_types.len()
279
40.5k
    }
280
281
    /// Insert a new section as the `i`th section in the Wasm module.
282
428
    pub fn insert_section(
283
428
        &self,
284
428
        i: usize,
285
428
        new_section: &impl wasm_encoder::Section,
286
428
    ) -> wasm_encoder::Module {
287
428
        log::trace!("inserting new section at {i}");
288
428
        let mut module = wasm_encoder::Module::new();
289
1.31k
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
1.31k
            if i == j {
291
263
                module.section(new_section);
292
1.05k
            }
293
1.31k
            module.section(s);
294
1.31k
        });
<wasm_mutate::info::ModuleInfo>::insert_section::<wasm_encoder::core::types::TypeSection>::{closure#0}
Line
Count
Source
289
115
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
115
            if i == j {
291
48
                module.section(new_section);
292
67
            }
293
115
            module.section(s);
294
115
        });
<wasm_mutate::info::ModuleInfo>::insert_section::<wasm_encoder::core::custom::CustomSection>::{closure#0}
Line
Count
Source
289
1.04k
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
1.04k
            if i == j {
291
197
                module.section(new_section);
292
844
            }
293
1.04k
            module.section(s);
294
1.04k
        });
<wasm_mutate::info::ModuleInfo>::insert_section::<wasm_encoder::core::exports::ExportSection>::{closure#0}
Line
Count
Source
289
103
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
103
            if i == j {
291
8
                module.section(new_section);
292
95
            }
293
103
            module.section(s);
294
103
        });
<wasm_mutate::info::ModuleInfo>::insert_section::<wasm_encoder::core::globals::GlobalSection>::{closure#0}
Line
Count
Source
289
60
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
60
            if i == j {
291
10
                module.section(new_section);
292
50
            }
293
60
            module.section(s);
294
60
        });
295
428
        if self.raw_sections.len() == i {
296
165
            module.section(new_section);
297
263
        }
298
428
        module
299
428
    }
<wasm_mutate::info::ModuleInfo>::insert_section::<wasm_encoder::core::types::TypeSection>
Line
Count
Source
282
101
    pub fn insert_section(
283
101
        &self,
284
101
        i: usize,
285
101
        new_section: &impl wasm_encoder::Section,
286
101
    ) -> wasm_encoder::Module {
287
101
        log::trace!("inserting new section at {i}");
288
101
        let mut module = wasm_encoder::Module::new();
289
101
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
            if i == j {
291
                module.section(new_section);
292
            }
293
            module.section(s);
294
        });
295
101
        if self.raw_sections.len() == i {
296
53
            module.section(new_section);
297
53
        }
298
101
        module
299
101
    }
<wasm_mutate::info::ModuleInfo>::insert_section::<wasm_encoder::core::custom::CustomSection>
Line
Count
Source
282
275
    pub fn insert_section(
283
275
        &self,
284
275
        i: usize,
285
275
        new_section: &impl wasm_encoder::Section,
286
275
    ) -> wasm_encoder::Module {
287
275
        log::trace!("inserting new section at {i}");
288
275
        let mut module = wasm_encoder::Module::new();
289
275
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
            if i == j {
291
                module.section(new_section);
292
            }
293
            module.section(s);
294
        });
295
275
        if self.raw_sections.len() == i {
296
78
            module.section(new_section);
297
197
        }
298
275
        module
299
275
    }
<wasm_mutate::info::ModuleInfo>::insert_section::<wasm_encoder::core::exports::ExportSection>
Line
Count
Source
282
35
    pub fn insert_section(
283
35
        &self,
284
35
        i: usize,
285
35
        new_section: &impl wasm_encoder::Section,
286
35
    ) -> wasm_encoder::Module {
287
35
        log::trace!("inserting new section at {i}");
288
35
        let mut module = wasm_encoder::Module::new();
289
35
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
            if i == j {
291
                module.section(new_section);
292
            }
293
            module.section(s);
294
        });
295
35
        if self.raw_sections.len() == i {
296
27
            module.section(new_section);
297
27
        }
298
35
        module
299
35
    }
<wasm_mutate::info::ModuleInfo>::insert_section::<wasm_encoder::core::globals::GlobalSection>
Line
Count
Source
282
17
    pub fn insert_section(
283
17
        &self,
284
17
        i: usize,
285
17
        new_section: &impl wasm_encoder::Section,
286
17
    ) -> wasm_encoder::Module {
287
17
        log::trace!("inserting new section at {i}");
288
17
        let mut module = wasm_encoder::Module::new();
289
17
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
290
            if i == j {
291
                module.section(new_section);
292
            }
293
            module.section(s);
294
        });
295
17
        if self.raw_sections.len() == i {
296
7
            module.section(new_section);
297
10
        }
298
17
        module
299
17
    }
300
301
    /// Move a section from index `src_idx` to `dest_idx` in the Wasm module
302
0
    pub fn move_section(&self, src_idx: usize, dest_idx: usize) -> wasm_encoder::Module {
303
0
        log::trace!("moving section from index {src_idx} to index {dest_idx}");
304
0
        assert!(src_idx < self.raw_sections.len());
305
0
        assert!(dest_idx < self.raw_sections.len());
306
0
        assert_ne!(src_idx, dest_idx);
307
0
        let mut sections = self.raw_sections.clone();
308
0
        let to_move = sections.remove(src_idx);
309
0
        let mut module = wasm_encoder::Module::new();
310
0
        for (i, section) in sections.iter().enumerate() {
311
0
            if i == dest_idx {
312
0
                module.section(&to_move);
313
0
            }
314
0
            module.section(section);
315
        }
316
0
        if sections.len() == dest_idx {
317
0
            module.section(&to_move);
318
0
        }
319
0
        module
320
0
    }
321
322
    /// Replace the `i`th section in this module with the given new section.
323
527
    pub fn replace_section(
324
527
        &self,
325
527
        i: usize,
326
527
        new_section: &impl wasm_encoder::Section,
327
527
    ) -> wasm_encoder::Module {
328
527
        log::trace!("replacing section {i}");
329
527
        let mut module = wasm_encoder::Module::new();
330
3.12k
        for (j, s) in self.raw_sections.iter().enumerate() {
331
3.12k
            if i == j {
332
527
                module.section(new_section);
333
2.59k
            } else {
334
2.59k
                module.section(s);
335
2.59k
            }
336
        }
337
527
        module
338
527
    }
<wasm_mutate::info::ModuleInfo>::replace_section::<wasm_encoder::core::code::CodeSection>
Line
Count
Source
323
178
    pub fn replace_section(
324
178
        &self,
325
178
        i: usize,
326
178
        new_section: &impl wasm_encoder::Section,
327
178
    ) -> wasm_encoder::Module {
328
178
        log::trace!("replacing section {i}");
329
178
        let mut module = wasm_encoder::Module::new();
330
1.17k
        for (j, s) in self.raw_sections.iter().enumerate() {
331
1.17k
            if i == j {
332
178
                module.section(new_section);
333
994
            } else {
334
994
                module.section(s);
335
994
            }
336
        }
337
178
        module
338
178
    }
<wasm_mutate::info::ModuleInfo>::replace_section::<wasm_encoder::core::data::DataSection>
Line
Count
Source
323
28
    pub fn replace_section(
324
28
        &self,
325
28
        i: usize,
326
28
        new_section: &impl wasm_encoder::Section,
327
28
    ) -> wasm_encoder::Module {
328
28
        log::trace!("replacing section {i}");
329
28
        let mut module = wasm_encoder::Module::new();
330
174
        for (j, s) in self.raw_sections.iter().enumerate() {
331
174
            if i == j {
332
28
                module.section(new_section);
333
146
            } else {
334
146
                module.section(s);
335
146
            }
336
        }
337
28
        module
338
28
    }
<wasm_mutate::info::ModuleInfo>::replace_section::<wasm_encoder::core::types::TypeSection>
Line
Count
Source
323
229
    pub fn replace_section(
324
229
        &self,
325
229
        i: usize,
326
229
        new_section: &impl wasm_encoder::Section,
327
229
    ) -> wasm_encoder::Module {
328
229
        log::trace!("replacing section {i}");
329
229
        let mut module = wasm_encoder::Module::new();
330
1.26k
        for (j, s) in self.raw_sections.iter().enumerate() {
331
1.26k
            if i == j {
332
229
                module.section(new_section);
333
1.03k
            } else {
334
1.03k
                module.section(s);
335
1.03k
            }
336
        }
337
229
        module
338
229
    }
Unexecuted instantiation: <wasm_mutate::info::ModuleInfo>::replace_section::<wasm_encoder::core::custom::CustomSection>
<wasm_mutate::info::ModuleInfo>::replace_section::<wasm_encoder::core::exports::ExportSection>
Line
Count
Source
323
33
    pub fn replace_section(
324
33
        &self,
325
33
        i: usize,
326
33
        new_section: &impl wasm_encoder::Section,
327
33
    ) -> wasm_encoder::Module {
328
33
        log::trace!("replacing section {i}");
329
33
        let mut module = wasm_encoder::Module::new();
330
206
        for (j, s) in self.raw_sections.iter().enumerate() {
331
206
            if i == j {
332
33
                module.section(new_section);
333
173
            } else {
334
173
                module.section(s);
335
173
            }
336
        }
337
33
        module
338
33
    }
<wasm_mutate::info::ModuleInfo>::replace_section::<wasm_encoder::core::globals::GlobalSection>
Line
Count
Source
323
59
    pub fn replace_section(
324
59
        &self,
325
59
        i: usize,
326
59
        new_section: &impl wasm_encoder::Section,
327
59
    ) -> wasm_encoder::Module {
328
59
        log::trace!("replacing section {i}");
329
59
        let mut module = wasm_encoder::Module::new();
330
304
        for (j, s) in self.raw_sections.iter().enumerate() {
331
304
            if i == j {
332
59
                module.section(new_section);
333
245
            } else {
334
245
                module.section(s);
335
245
            }
336
        }
337
59
        module
338
59
    }
Unexecuted instantiation: <wasm_mutate::info::ModuleInfo>::replace_section::<wasm_encoder::core::elements::ElementSection>
339
340
    /// Replaces raw sections in the passed indexes and return a new module
341
    ///
342
    /// This method will be helpful to add more than one custom section. For
343
    /// example, some code mutations might need to add a few globals. This
344
    /// method can be used to write a new or custom global section before the
345
    /// code section.
346
    /// * `section_writer` this callback should write the custom section and
347
    ///   returns true if it was successful, if false is returned then the
348
    ///   default section will be written to the module
349
7.73k
    pub fn replace_multiple_sections<P>(&self, mut section_writer: P) -> wasm_encoder::Module
350
7.73k
    where
351
7.73k
        P: FnMut(usize, u8, &mut wasm_encoder::Module) -> bool,
352
    {
353
7.73k
        let mut module = wasm_encoder::Module::new();
354
53.3k
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
355
            // Write if the section_writer did not write a custom section
356
53.3k
            if !section_writer(j, s.id, &mut module) {
357
39.2k
                module.section(s);
358
39.2k
            }
359
53.3k
        });
<wasm_mutate::info::ModuleInfo>::replace_multiple_sections::<<wasm_mutate::mutators::peephole::PeepholeMutator>::random_mutate::{closure#1}::{closure#0}>::{closure#0}
Line
Count
Source
354
52.9k
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
355
            // Write if the section_writer did not write a custom section
356
52.9k
            if !section_writer(j, s.id, &mut module) {
357
38.9k
                module.section(s);
358
38.9k
            }
359
52.9k
        });
<wasm_mutate::info::ModuleInfo>::replace_multiple_sections::<<wasm_mutate::mutators::add_function::AddFunctionMutator as wasm_mutate::mutators::Mutator>::mutate::{closure#0}>::{closure#0}
Line
Count
Source
354
348
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
355
            // Write if the section_writer did not write a custom section
356
348
            if !section_writer(j, s.id, &mut module) {
357
238
                module.section(s);
358
238
            }
359
348
        });
<wasm_mutate::info::ModuleInfo>::replace_multiple_sections::<<wasm_mutate::mutators::add_function::AddFunctionMutator as wasm_mutate::mutators::Mutator>::mutate::{closure#1}>::{closure#0}
Line
Count
Source
354
48
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
355
            // Write if the section_writer did not write a custom section
356
48
            if !section_writer(j, s.id, &mut module) {
357
48
                module.section(s);
358
48
            }
359
48
        });
360
7.73k
        module
361
7.73k
    }
<wasm_mutate::info::ModuleInfo>::replace_multiple_sections::<<wasm_mutate::mutators::peephole::PeepholeMutator>::random_mutate::{closure#1}::{closure#0}>
Line
Count
Source
349
7.66k
    pub fn replace_multiple_sections<P>(&self, mut section_writer: P) -> wasm_encoder::Module
350
7.66k
    where
351
7.66k
        P: FnMut(usize, u8, &mut wasm_encoder::Module) -> bool,
352
    {
353
7.66k
        let mut module = wasm_encoder::Module::new();
354
7.66k
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
355
            // Write if the section_writer did not write a custom section
356
            if !section_writer(j, s.id, &mut module) {
357
                module.section(s);
358
            }
359
        });
360
7.66k
        module
361
7.66k
    }
<wasm_mutate::info::ModuleInfo>::replace_multiple_sections::<<wasm_mutate::mutators::add_function::AddFunctionMutator as wasm_mutate::mutators::Mutator>::mutate::{closure#0}>
Line
Count
Source
349
55
    pub fn replace_multiple_sections<P>(&self, mut section_writer: P) -> wasm_encoder::Module
350
55
    where
351
55
        P: FnMut(usize, u8, &mut wasm_encoder::Module) -> bool,
352
    {
353
55
        let mut module = wasm_encoder::Module::new();
354
55
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
355
            // Write if the section_writer did not write a custom section
356
            if !section_writer(j, s.id, &mut module) {
357
                module.section(s);
358
            }
359
        });
360
55
        module
361
55
    }
<wasm_mutate::info::ModuleInfo>::replace_multiple_sections::<<wasm_mutate::mutators::add_function::AddFunctionMutator as wasm_mutate::mutators::Mutator>::mutate::{closure#1}>
Line
Count
Source
349
16
    pub fn replace_multiple_sections<P>(&self, mut section_writer: P) -> wasm_encoder::Module
350
16
    where
351
16
        P: FnMut(usize, u8, &mut wasm_encoder::Module) -> bool,
352
    {
353
16
        let mut module = wasm_encoder::Module::new();
354
16
        self.raw_sections.iter().enumerate().for_each(|(j, s)| {
355
            // Write if the section_writer did not write a custom section
356
            if !section_writer(j, s.id, &mut module) {
357
                module.section(s);
358
            }
359
        });
360
16
        module
361
16
    }
362
363
2.53k
    pub fn num_functions(&self) -> u32 {
364
2.53k
        self.function_map.len() as u32
365
2.53k
    }
366
367
1.14k
    pub fn num_local_functions(&self) -> u32 {
368
1.14k
        self.num_functions() - self.num_imported_functions()
369
1.14k
    }
370
371
5.04k
    pub fn num_imported_functions(&self) -> u32 {
372
5.04k
        self.imported_functions_count
373
5.04k
    }
374
375
509
    pub fn num_tables(&self) -> u32 {
376
509
        self.table_count
377
509
    }
378
379
527
    pub fn num_imported_tables(&self) -> u32 {
380
527
        self.imported_tables_count
381
527
    }
382
383
443
    pub fn num_memories(&self) -> u32 {
384
443
        self.memory_count
385
443
    }
386
387
644
    pub fn num_imported_memories(&self) -> u32 {
388
644
        self.imported_memories_count
389
644
    }
390
391
676
    pub fn num_globals(&self) -> u32 {
392
676
        self.global_types.len() as u32
393
676
    }
394
395
905
    pub fn num_imported_globals(&self) -> u32 {
396
905
        self.imported_globals_count
397
905
    }
398
399
0
    pub fn num_local_globals(&self) -> u32 {
400
0
        self.global_types.len() as u32 - self.imported_globals_count
401
0
    }
402
403
745
    pub fn num_tags(&self) -> u32 {
404
745
        self.tag_count
405
745
    }
406
407
107
    pub fn num_imported_tags(&self) -> u32 {
408
107
        self.imported_tags_count
409
107
    }
410
411
144
    pub fn num_data(&self) -> u32 {
412
144
        self.data_segments_count
413
144
    }
414
415
64
    pub fn num_elements(&self) -> u32 {
416
64
        self.elements_count
417
64
    }
418
419
578
    pub fn num_types(&self) -> u32 {
420
578
        self.types_map.len() as u32
421
578
    }
422
}