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 VarUint32::deserialize(rdr)?;
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 _ => return Err(Error::UnknownNameSubsectionType(subsection_type)),
101 };
102 }
103
104 Ok(Self { module: module_name, functions: function_names, locals: local_names })
105 }
106}
107
108impl Serialize for NameSection {
109 type Error = Error;
110
111 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
112 fn serialize_subsection<W: io::Write>(
113 wtr: &mut W,
114 name_type: u8,
115 name_payload: &[u8],
116 ) -> Result<(), Error> {
117 VarUint7::from(name_type).serialize(wtr)?;
118 VarUint32::from(name_payload.len()).serialize(wtr)?;
119 wtr.write(name_payload).map_err(Into::into)
120 }
121
122 if let Some(module_name_subsection) = self.module {
123 let mut buffer = vec![];
124 module_name_subsection.serialize(&mut buffer)?;
125 serialize_subsection(wtr, NAME_TYPE_MODULE, &buffer)?;
126 }
127
128 if let Some(function_name_subsection) = self.functions {
129 let mut buffer = vec![];
130 function_name_subsection.serialize(&mut buffer)?;
131 serialize_subsection(wtr, NAME_TYPE_FUNCTION, &buffer)?;
132 }
133
134 if let Some(local_name_subsection) = self.locals {
135 let mut buffer = vec![];
136 local_name_subsection.serialize(&mut buffer)?;
137 serialize_subsection(wtr, NAME_TYPE_LOCAL, &buffer)?;
138 }
139
140 Ok(())
141 }
142}
143
144#[derive(Clone, Debug, PartialEq)]
146pub struct ModuleNameSubsection {
147 name: String,
148}
149
150impl ModuleNameSubsection {
151 pub fn new<S: Into<String>>(name: S) -> ModuleNameSubsection {
153 ModuleNameSubsection { name: name.into() }
154 }
155
156 pub fn name(&self) -> &str {
158 &self.name
159 }
160
161 pub fn name_mut(&mut self) -> &mut String {
163 &mut self.name
164 }
165}
166
167impl Serialize for ModuleNameSubsection {
168 type Error = Error;
169
170 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
171 self.name.serialize(wtr)
172 }
173}
174
175impl Deserialize for ModuleNameSubsection {
176 type Error = Error;
177
178 fn deserialize<R: io::Read>(rdr: &mut R) -> Result<ModuleNameSubsection, Error> {
179 let name = String::deserialize(rdr)?;
180 Ok(ModuleNameSubsection { name })
181 }
182}
183
184#[derive(Clone, Debug, Default, PartialEq)]
186pub struct FunctionNameSubsection {
187 names: NameMap,
188}
189
190impl FunctionNameSubsection {
191 pub fn names(&self) -> &NameMap {
193 &self.names
194 }
195
196 pub fn names_mut(&mut self) -> &mut NameMap {
198 &mut self.names
199 }
200
201 pub fn deserialize<R: io::Read>(
203 module: &Module,
204 rdr: &mut R,
205 ) -> Result<FunctionNameSubsection, Error> {
206 let names = IndexMap::deserialize(module.functions_space(), rdr)?;
207 Ok(FunctionNameSubsection { names })
208 }
209}
210
211impl Serialize for FunctionNameSubsection {
212 type Error = Error;
213
214 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
215 self.names.serialize(wtr)
216 }
217}
218
219#[derive(Clone, Debug, Default, PartialEq)]
221pub struct LocalNameSubsection {
222 local_names: IndexMap<NameMap>,
223}
224
225impl LocalNameSubsection {
226 pub fn local_names(&self) -> &IndexMap<NameMap> {
228 &self.local_names
229 }
230
231 pub fn local_names_mut(&mut self) -> &mut IndexMap<NameMap> {
234 &mut self.local_names
235 }
236
237 pub fn deserialize<R: io::Read>(
240 module: &Module,
241 rdr: &mut R,
242 ) -> Result<LocalNameSubsection, Error> {
243 let max_entry_space = module.functions_space();
244
245 let max_signature_args = module
246 .type_section()
247 .map(|ts| {
248 ts.types()
249 .iter()
250 .map(|x| {
251 let Type::Function(ref func) = *x;
252 func.params().len()
253 })
254 .max()
255 .unwrap_or(0)
256 })
257 .unwrap_or(0);
258
259 let max_locals = module
260 .code_section()
261 .map(|cs| {
262 cs.bodies()
263 .iter()
264 .map(|f| f.locals().iter().map(|l| l.count() as usize).sum())
265 .max()
266 .unwrap_or(0)
267 })
268 .unwrap_or(0);
269
270 let max_space = max_signature_args + max_locals;
271
272 let deserialize_locals = |_: u32, rdr: &mut R| IndexMap::deserialize(max_space, rdr);
273
274 let local_names = IndexMap::deserialize_with(max_entry_space, &deserialize_locals, rdr)?;
275 Ok(LocalNameSubsection { local_names })
276 }
277}
278
279impl Serialize for LocalNameSubsection {
280 type Error = Error;
281
282 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
283 self.local_names.serialize(wtr)
284 }
285}
286
287pub type NameMap = IndexMap<String>;
289
290#[cfg(test)]
291mod tests {
292 use super::*;
293
294 fn serialize_test(original: NameSection) -> Vec<u8> {
297 let mut buffer = vec![];
298 original.serialize(&mut buffer).expect("serialize error");
299 buffer
300 }
302
303 #[test]
304 fn serialize_module_name() {
305 let module_name_subsection = ModuleNameSubsection::new("my_mod");
306 let original = NameSection::new(Some(module_name_subsection), None, None);
307 serialize_test(original);
308 }
309
310 #[test]
311 fn serialize_function_names() {
312 let mut function_name_subsection = FunctionNameSubsection::default();
313 function_name_subsection.names_mut().insert(0, "hello_world".to_string());
314 let name_section = NameSection::new(None, Some(function_name_subsection), None);
315 serialize_test(name_section);
316 }
317
318 #[test]
319 fn serialize_local_names() {
320 let mut local_name_subsection = LocalNameSubsection::default();
321 let mut locals = NameMap::default();
322 locals.insert(0, "msg".to_string());
323 local_name_subsection.local_names_mut().insert(0, locals);
324
325 let name_section = NameSection::new(None, None, Some(local_name_subsection));
326 serialize_test(name_section);
327 }
328
329 #[test]
330 fn serialize_all_subsections() {
331 let module_name_subsection = ModuleNameSubsection::new("ModuleNameSubsection");
332
333 let mut function_name_subsection = FunctionNameSubsection::default();
334 function_name_subsection.names_mut().insert(0, "foo".to_string());
335 function_name_subsection.names_mut().insert(1, "bar".to_string());
336
337 let mut local_name_subsection = LocalNameSubsection::default();
338 let mut locals = NameMap::default();
339 locals.insert(0, "msg1".to_string());
340 locals.insert(1, "msg2".to_string());
341 local_name_subsection.local_names_mut().insert(0, locals);
342
343 let name_section = NameSection::new(
344 Some(module_name_subsection),
345 Some(function_name_subsection),
346 Some(local_name_subsection),
347 );
348 serialize_test(name_section);
349 }
350
351 #[test]
352 fn deserialize_local_names() {
353 let module = super::super::deserialize_file("./res/cases/v1/names_with_imports.wasm")
354 .expect("Should be deserialized")
355 .parse_names()
356 .expect("Names to be parsed");
357
358 let name_section = module.names_section().expect("name_section should be present");
359 let local_names = name_section.locals().expect("local_name_section should be present");
360
361 let locals = local_names.local_names().get(0).expect("entry #0 should be present");
362 assert_eq!(locals.get(0).expect("entry #0 should be present"), "abc");
363
364 let locals = local_names.local_names().get(1).expect("entry #1 should be present");
365 assert_eq!(locals.get(0).expect("entry #0 should be present"), "def");
366 }
367}