Coverage Report

Created: 2025-01-06 07:43

/src/wasm-tools/crates/wasm-metadata/src/names/module.rs
Line
Count
Source (jump to first uncovered line)
1
use std::fmt::{self, Debug};
2
3
use anyhow::Result;
4
use wasm_encoder::Encode;
5
use wasmparser::{BinaryReader, NameSectionReader};
6
7
use crate::utils::{indirect_name_map, name_map};
8
9
/// Helper for rewriting a module's name section with a new module name.
10
pub struct ModuleNames<'a> {
11
    module_name: Option<String>,
12
    names: Vec<wasmparser::Name<'a>>,
13
}
14
15
impl<'a> Debug for ModuleNames<'a> {
16
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17
0
        f.debug_struct("ModuleNames")
18
0
            .field("module_name", &self.module_name)
19
0
            .finish_non_exhaustive()
20
0
    }
21
}
22
23
impl<'a> ModuleNames<'a> {
24
    /// Create an empty name section.
25
0
    pub fn empty() -> Self {
26
0
        ModuleNames {
27
0
            module_name: None,
28
0
            names: Vec::new(),
29
0
        }
30
0
    }
31
    /// Read a name section from a WebAssembly binary. Records the module name, and all other
32
    /// contents of name section, for later serialization.
33
0
    pub fn from_bytes(bytes: &'a [u8], offset: usize) -> Result<ModuleNames<'a>> {
34
0
        let reader = BinaryReader::new(bytes, offset);
35
0
        let section = NameSectionReader::new(reader);
36
0
        let mut s = Self::empty();
37
0
        for name in section.into_iter() {
38
0
            let name = name?;
39
0
            match name {
40
0
                wasmparser::Name::Module { name, .. } => s.module_name = Some(name.to_owned()),
41
0
                _ => s.names.push(name),
42
            }
43
        }
44
0
        Ok(s)
45
0
    }
46
    /// Update module section according to [`AddMetadata`]
47
0
    pub(crate) fn from_name(name: &Option<String>) -> Self {
48
0
        let mut s = Self::empty();
49
0
        s.module_name = name.clone();
50
0
        s
51
0
    }
52
53
    /// Merge with another section
54
0
    pub(crate) fn merge(&mut self, other: &Self) {
55
0
        if other.module_name.is_some() {
56
0
            self.module_name = other.module_name.clone();
57
0
        }
58
0
        self.names.extend_from_slice(&other.names);
59
0
    }
60
61
    /// Set module name
62
0
    pub fn set_name(&mut self, name: &str) {
63
0
        self.module_name = Some(name.to_owned())
64
0
    }
65
    /// Get module name
66
0
    pub fn get_name(&self) -> Option<&String> {
67
0
        self.module_name.as_ref()
68
0
    }
69
    /// Serialize into [`wasm_encoder::NameSection`].
70
0
    pub(crate) fn section(&self) -> Result<wasm_encoder::NameSection> {
71
0
        let mut section = wasm_encoder::NameSection::new();
72
0
        if let Some(module_name) = &self.module_name {
73
0
            section.module(&module_name);
74
0
        }
75
0
        for n in self.names.iter() {
76
0
            match n {
77
0
                wasmparser::Name::Module { .. } => unreachable!(),
78
0
                wasmparser::Name::Function(m) => section.functions(&name_map(&m)?),
79
0
                wasmparser::Name::Local(m) => section.locals(&indirect_name_map(&m)?),
80
0
                wasmparser::Name::Label(m) => section.labels(&indirect_name_map(&m)?),
81
0
                wasmparser::Name::Type(m) => section.types(&name_map(&m)?),
82
0
                wasmparser::Name::Table(m) => section.tables(&name_map(&m)?),
83
0
                wasmparser::Name::Memory(m) => section.memories(&name_map(&m)?),
84
0
                wasmparser::Name::Global(m) => section.globals(&name_map(&m)?),
85
0
                wasmparser::Name::Element(m) => section.elements(&name_map(&m)?),
86
0
                wasmparser::Name::Data(m) => section.data(&name_map(&m)?),
87
0
                wasmparser::Name::Field(m) => section.fields(&indirect_name_map(&m)?),
88
0
                wasmparser::Name::Tag(m) => section.tags(&name_map(&m)?),
89
0
                wasmparser::Name::Unknown { .. } => {} // wasm-encoder doesn't support it
90
            }
91
        }
92
0
        Ok(section)
93
0
    }
94
95
    /// Serialize into the raw bytes of a wasm custom section.
96
0
    pub fn raw_custom_section(&self) -> Result<Vec<u8>> {
97
0
        let mut ret = Vec::new();
98
0
        self.section()?.encode(&mut ret);
99
0
        Ok(ret)
100
0
    }
101
}