Skip to main content

wasm_metadata/names/
module.rs

1use std::fmt::{self, Debug};
2
3use anyhow::Result;
4use wasm_encoder::Encode;
5use wasm_encoder::reencode::{Reencode, RoundtripReencoder};
6use wasmparser::{BinaryReader, NameSectionReader};
7
8/// Helper for rewriting a module's name section with a new module name.
9pub struct ModuleNames<'a> {
10    module_name: Option<String>,
11    names: Vec<wasmparser::Name<'a>>,
12}
13
14impl<'a> Debug for ModuleNames<'a> {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        f.debug_struct("ModuleNames")
17            .field("module_name", &self.module_name)
18            .finish_non_exhaustive()
19    }
20}
21
22impl<'a> ModuleNames<'a> {
23    /// Create an empty name section.
24    pub fn empty() -> Self {
25        ModuleNames {
26            module_name: None,
27            names: Vec::new(),
28        }
29    }
30    /// Read a name section from a WebAssembly binary. Records the module name, and all other
31    /// contents of name section, for later serialization.
32    pub fn from_bytes(bytes: &'a [u8], offset: u64) -> Result<ModuleNames<'a>> {
33        let reader = BinaryReader::new(bytes, offset);
34        let section = NameSectionReader::new(reader);
35        let mut s = Self::empty();
36        for name in section.into_iter() {
37            let name = name?;
38            match name {
39                wasmparser::Name::Module { name, .. } => s.module_name = Some(name.to_owned()),
40                _ => s.names.push(name),
41            }
42        }
43        Ok(s)
44    }
45    /// Update module section according to [`AddMetadata`]
46    pub(crate) fn from_name(name: &Option<String>) -> Self {
47        let mut s = Self::empty();
48        s.module_name = name.clone();
49        s
50    }
51
52    /// Merge with another section
53    pub(crate) fn merge(&mut self, other: &Self) {
54        if other.module_name.is_some() {
55            self.module_name = other.module_name.clone();
56        }
57        self.names.extend_from_slice(&other.names);
58    }
59
60    /// Set module name
61    pub fn set_name(&mut self, name: &str) {
62        self.module_name = Some(name.to_owned())
63    }
64    /// Get module name
65    pub fn get_name(&self) -> Option<&String> {
66        self.module_name.as_ref()
67    }
68    /// Serialize into [`wasm_encoder::NameSection`].
69    pub(crate) fn section(&self) -> Result<wasm_encoder::NameSection> {
70        let mut section = wasm_encoder::NameSection::new();
71        if let Some(module_name) = &self.module_name {
72            section.module(&module_name);
73        }
74        for n in self.names.iter() {
75            RoundtripReencoder.parse_custom_name_subsection(&mut section, n.clone())?;
76        }
77        Ok(section)
78    }
79
80    /// Serialize into the raw bytes of a wasm custom section.
81    pub fn raw_custom_section(&self) -> Result<Vec<u8>> {
82        let mut ret = Vec::new();
83        self.section()?.encode(&mut ret);
84        Ok(ret)
85    }
86}