libchisel/
repack.rs

1use parity_wasm::builder;
2use parity_wasm::elements::Module;
3
4use super::{ChiselModule, ModuleError, ModuleKind, ModuleTranslator};
5
6pub struct Repack;
7
8impl Repack {
9    pub fn new() -> Self {
10        Repack {}
11    }
12}
13
14impl<'a> ChiselModule<'a> for Repack {
15    type ObjectReference = &'a dyn ModuleTranslator;
16
17    fn id(&'a self) -> String {
18        "repack".to_string()
19    }
20
21    fn kind(&'a self) -> ModuleKind {
22        ModuleKind::Translator
23    }
24
25    fn as_abstract(&'a self) -> Self::ObjectReference {
26        self as Self::ObjectReference
27    }
28}
29
30impl ModuleTranslator for Repack {
31    fn translate_inplace(&self, _module: &mut Module) -> Result<bool, ModuleError> {
32        Err(ModuleError::NotSupported)
33    }
34
35    fn translate(&self, module: &Module) -> Result<Option<Module>, ModuleError> {
36        // TODO: check in names section is carried over.
37        let module = module.clone();
38        let module = builder::from_module(module).build();
39        Ok(Some(module))
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use parity_wasm::builder;
46    use parity_wasm::elements::CustomSection;
47    use rustc_hex::FromHex;
48
49    use super::*;
50
51    #[test]
52    fn smoke_test() {
53        let module = Module::default();
54
55        let repack = Repack::new();
56        assert_eq!(module, repack.translate(&module).unwrap().unwrap());
57    }
58
59    #[test]
60    fn basic_sections_only() {
61        let module = builder::module()
62            .function()
63            .signature()
64            .build()
65            .body()
66            .build()
67            .build()
68            .export()
69            .field("main")
70            .internal()
71            .func(0)
72            .build()
73            .export()
74            .field("memory")
75            .internal()
76            .memory(0)
77            .build()
78            .build();
79
80        let repack = Repack::new();
81        assert_eq!(module, repack.translate(&module).unwrap().unwrap());
82    }
83
84    #[test]
85    fn custom_section() {
86        let mut module = builder::module()
87            .function()
88            .signature()
89            .build()
90            .body()
91            .build()
92            .build()
93            .export()
94            .field("main")
95            .internal()
96            .func(0)
97            .build()
98            .export()
99            .field("memory")
100            .internal()
101            .memory(0)
102            .build()
103            .build();
104
105        let custom = CustomSection::new("test".to_string(), vec![42u8; 16]);
106        module
107            .sections_mut()
108            .push(parity_wasm::elements::Section::Custom(custom));
109
110        let repack = Repack::new();
111        assert_ne!(module, repack.translate(&module).unwrap().unwrap());
112    }
113
114    #[test]
115    fn names_section() {
116        let input = FromHex::from_hex(
117            "0061736d010000000104016000000303020000070801046d61696e00010a
1180a020300010b040010000b0014046e616d65010d0200047465737401046d
11961696e",
120        )
121        .unwrap();
122        let module = Module::from_bytes(&input).unwrap();
123        // Forcefully parse names section here.
124        let module = module
125            .parse_names()
126            .expect("parsing the names section failed");
127        assert_eq!(module.names_section().is_some(), true);
128        let repack = Repack::new();
129        // Repack drops names section too.
130        let output = repack.translate(&module).unwrap().unwrap();
131        assert_eq!(output.has_names_section(), false);
132    }
133}