1use crate::io;
2use alloc::string::String;
3
4use super::{
5 index_map::IndexMap, Deserialize, Error, Module, Serialize, Type, VarUint32, VarUint7,
6};
7
8const NAME_TYPE_MODULE: u8 = 0;
9const NAME_TYPE_FUNCTION: u8 = 1;
10const NAME_TYPE_LOCAL: u8 = 2;
11
12#[derive(Clone, Debug, PartialEq)]
14pub struct NameSection {
15 module: Option<ModuleNameSubsection>,
17
18 functions: Option<FunctionNameSubsection>,
20
21 locals: Option<LocalNameSubsection>,
23}
24
25impl NameSection {
26 pub fn new(
28 module: Option<ModuleNameSubsection>,
29 functions: Option<FunctionNameSubsection>,
30 locals: Option<LocalNameSubsection>,
31 ) -> Self {
32 Self { module, functions, locals }
33 }
34
35 pub fn module(&self) -> Option<&ModuleNameSubsection> {
37 self.module.as_ref()
38 }
39
40 pub fn module_mut(&mut self) -> &mut Option<ModuleNameSubsection> {
42 &mut self.module
43 }
44
45 pub fn functions(&self) -> Option<&FunctionNameSubsection> {
47 self.functions.as_ref()
48 }
49
50 pub fn functions_mut(&mut self) -> &mut Option<FunctionNameSubsection> {
52 &mut self.functions
53 }
54
55 pub fn locals(&self) -> Option<&LocalNameSubsection> {
57 self.locals.as_ref()
58 }
59
60 pub fn locals_mut(&mut self) -> &mut Option<LocalNameSubsection> {
62 &mut self.locals
63 }
64}
65
66impl NameSection {
67 pub fn deserialize<R: io::Read>(module: &Module, rdr: &mut R) -> Result<Self, Error> {
69 let mut module_name: Option<ModuleNameSubsection> = None;
70 let mut function_names: Option<FunctionNameSubsection> = None;
71 let mut local_names: Option<LocalNameSubsection> = None;
72
73 while let Ok(raw_subsection_type) = VarUint7::deserialize(rdr) {
74 let subsection_type = raw_subsection_type.into();
75 let size: usize = VarUint32::deserialize(rdr)?.into();
77
78 match subsection_type {
79 NAME_TYPE_MODULE => {
80 if module_name.is_some() {
81 return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION))
82 }
83 module_name = Some(ModuleNameSubsection::deserialize(rdr)?);
84 },
85
86 NAME_TYPE_FUNCTION => {
87 if function_names.is_some() {
88 return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION))
89 }
90 function_names = Some(FunctionNameSubsection::deserialize(module, rdr)?);
91 },
92
93 NAME_TYPE_LOCAL => {
94 if local_names.is_some() {
95 return Err(Error::DuplicatedNameSubsections(NAME_TYPE_LOCAL))
96 }
97 local_names = Some(LocalNameSubsection::deserialize(module, rdr)?);
98 },
99
100 _ => {
101 let mut buf = vec![0; size];
104 rdr.read(&mut buf)?;
105 },
106 };
107 }
108
109 Ok(Self { module: module_name, functions: function_names, locals: local_names })
110 }
111}
112
113impl Serialize for NameSection {
114 type Error = Error;
115
116 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
117 fn serialize_subsection<W: io::Write>(
118 wtr: &mut W,
119 name_type: u8,
120 name_payload: &[u8],
121 ) -> Result<(), Error> {
122 VarUint7::from(name_type).serialize(wtr)?;
123 VarUint32::from(name_payload.len()).serialize(wtr)?;
124 wtr.write(name_payload).map_err(Into::into)
125 }
126
127 if let Some(module_name_subsection) = self.module {
128 let mut buffer = vec![];
129 module_name_subsection.serialize(&mut buffer)?;
130 serialize_subsection(wtr, NAME_TYPE_MODULE, &buffer)?;
131 }
132
133 if let Some(function_name_subsection) = self.functions {
134 let mut buffer = vec![];
135 function_name_subsection.serialize(&mut buffer)?;
136 serialize_subsection(wtr, NAME_TYPE_FUNCTION, &buffer)?;
137 }
138
139 if let Some(local_name_subsection) = self.locals {
140 let mut buffer = vec![];
141 local_name_subsection.serialize(&mut buffer)?;
142 serialize_subsection(wtr, NAME_TYPE_LOCAL, &buffer)?;
143 }
144
145 Ok(())
146 }
147}
148
149#[derive(Clone, Debug, PartialEq)]
151pub struct ModuleNameSubsection {
152 name: String,
153}
154
155impl ModuleNameSubsection {
156 pub fn new<S: Into<String>>(name: S) -> ModuleNameSubsection {
158 ModuleNameSubsection { name: name.into() }
159 }
160
161 pub fn name(&self) -> &str {
163 &self.name
164 }
165
166 pub fn name_mut(&mut self) -> &mut String {
168 &mut self.name
169 }
170}
171
172impl Serialize for ModuleNameSubsection {
173 type Error = Error;
174
175 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
176 self.name.serialize(wtr)
177 }
178}
179
180impl Deserialize for ModuleNameSubsection {
181 type Error = Error;
182
183 fn deserialize<R: io::Read>(rdr: &mut R) -> Result<ModuleNameSubsection, Error> {
184 let name = String::deserialize(rdr)?;
185 Ok(ModuleNameSubsection { name })
186 }
187}
188
189#[derive(Clone, Debug, Default, PartialEq)]
191pub struct FunctionNameSubsection {
192 names: NameMap,
193}
194
195impl FunctionNameSubsection {
196 pub fn names(&self) -> &NameMap {
198 &self.names
199 }
200
201 pub fn names_mut(&mut self) -> &mut NameMap {
203 &mut self.names
204 }
205
206 pub fn deserialize<R: io::Read>(
208 module: &Module,
209 rdr: &mut R,
210 ) -> Result<FunctionNameSubsection, Error> {
211 let names = IndexMap::deserialize(module.functions_space(), rdr)?;
212 Ok(FunctionNameSubsection { names })
213 }
214}
215
216impl Serialize for FunctionNameSubsection {
217 type Error = Error;
218
219 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
220 self.names.serialize(wtr)
221 }
222}
223
224#[derive(Clone, Debug, Default, PartialEq)]
226pub struct LocalNameSubsection {
227 local_names: IndexMap<NameMap>,
228}
229
230impl LocalNameSubsection {
231 pub fn local_names(&self) -> &IndexMap<NameMap> {
233 &self.local_names
234 }
235
236 pub fn local_names_mut(&mut self) -> &mut IndexMap<NameMap> {
239 &mut self.local_names
240 }
241
242 pub fn deserialize<R: io::Read>(
245 module: &Module,
246 rdr: &mut R,
247 ) -> Result<LocalNameSubsection, Error> {
248 let max_entry_space = module.functions_space();
249
250 let max_signature_args = module
251 .type_section()
252 .map(|ts| {
253 ts.types()
254 .iter()
255 .map(|x| {
256 let Type::Function(ref func) = *x;
257 func.params().len()
258 })
259 .max()
260 .unwrap_or(0)
261 })
262 .unwrap_or(0);
263
264 let max_locals = module
265 .code_section()
266 .map(|cs| {
267 cs.bodies()
268 .iter()
269 .map(|f| f.locals().iter().map(|l| l.count() as usize).sum())
270 .max()
271 .unwrap_or(0)
272 })
273 .unwrap_or(0);
274
275 let max_space = max_signature_args + max_locals;
276
277 let deserialize_locals = |_: u32, rdr: &mut R| IndexMap::deserialize(max_space, rdr);
278
279 let local_names = IndexMap::deserialize_with(max_entry_space, &deserialize_locals, rdr)?;
280 Ok(LocalNameSubsection { local_names })
281 }
282}
283
284impl Serialize for LocalNameSubsection {
285 type Error = Error;
286
287 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
288 self.local_names.serialize(wtr)
289 }
290}
291
292pub type NameMap = IndexMap<String>;
294
295#[cfg(test)]
296mod tests {
297 use super::*;
298
299 fn serialize_test(original: NameSection) -> Vec<u8> {
302 let mut buffer = vec![];
303 original.serialize(&mut buffer).expect("serialize error");
304 buffer
305 }
307
308 #[test]
309 fn serialize_module_name() {
310 let module_name_subsection = ModuleNameSubsection::new("my_mod");
311 let original = NameSection::new(Some(module_name_subsection), None, None);
312 serialize_test(original);
313 }
314
315 #[test]
316 fn serialize_function_names() {
317 let mut function_name_subsection = FunctionNameSubsection::default();
318 function_name_subsection.names_mut().insert(0, "hello_world".to_string());
319 let name_section = NameSection::new(None, Some(function_name_subsection), None);
320 serialize_test(name_section);
321 }
322
323 #[test]
324 fn serialize_local_names() {
325 let mut local_name_subsection = LocalNameSubsection::default();
326 let mut locals = NameMap::default();
327 locals.insert(0, "msg".to_string());
328 local_name_subsection.local_names_mut().insert(0, locals);
329
330 let name_section = NameSection::new(None, None, Some(local_name_subsection));
331 serialize_test(name_section);
332 }
333
334 #[test]
335 fn serialize_all_subsections() {
336 let module_name_subsection = ModuleNameSubsection::new("ModuleNameSubsection");
337
338 let mut function_name_subsection = FunctionNameSubsection::default();
339 function_name_subsection.names_mut().insert(0, "foo".to_string());
340 function_name_subsection.names_mut().insert(1, "bar".to_string());
341
342 let mut local_name_subsection = LocalNameSubsection::default();
343 let mut locals = NameMap::default();
344 locals.insert(0, "msg1".to_string());
345 locals.insert(1, "msg2".to_string());
346 local_name_subsection.local_names_mut().insert(0, locals);
347
348 let name_section = NameSection::new(
349 Some(module_name_subsection),
350 Some(function_name_subsection),
351 Some(local_name_subsection),
352 );
353 serialize_test(name_section);
354 }
355
356 #[test]
357 fn deserialize_local_names() {
358 let module = super::super::deserialize_file("./res/cases/v1/names_with_imports.wasm")
359 .expect("Should be deserialized")
360 .parse_names()
361 .expect("Names to be parsed");
362
363 let name_section = module.names_section().expect("name_section should be present");
364 let local_names = name_section.locals().expect("local_name_section should be present");
365
366 let locals = local_names.local_names().get(0).expect("entry #0 should be present");
367 assert_eq!(locals.get(0).expect("entry #0 should be present"), "abc");
368
369 let locals = local_names.local_names().get(1).expect("entry #1 should be present");
370 assert_eq!(locals.get(0).expect("entry #0 should be present"), "def");
371 }
372}