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