1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use parity_wasm::builder;
use parity_wasm::elements::Module;

use super::{ChiselModule, ModuleError, ModuleKind, ModuleTranslator};

pub struct Repack;

impl Repack {
    pub fn new() -> Self {
        Repack {}
    }
}

impl<'a> ChiselModule<'a> for Repack {
    type ObjectReference = &'a dyn ModuleTranslator;

    fn id(&'a self) -> String {
        "repack".to_string()
    }

    fn kind(&'a self) -> ModuleKind {
        ModuleKind::Translator
    }

    fn as_abstract(&'a self) -> Self::ObjectReference {
        self as Self::ObjectReference
    }
}

impl ModuleTranslator for Repack {
    fn translate_inplace(&self, _module: &mut Module) -> Result<bool, ModuleError> {
        Err(ModuleError::NotSupported)
    }

    fn translate(&self, module: &Module) -> Result<Option<Module>, ModuleError> {
        // TODO: check in names section is carried over.
        let module = module.clone();
        let module = builder::from_module(module).build();
        Ok(Some(module))
    }
}

#[cfg(test)]
mod tests {
    use parity_wasm::builder;
    use parity_wasm::elements::CustomSection;
    use rustc_hex::FromHex;

    use super::*;

    #[test]
    fn smoke_test() {
        let module = Module::default();

        let repack = Repack::new();
        assert_eq!(module, repack.translate(&module).unwrap().unwrap());
    }

    #[test]
    fn basic_sections_only() {
        let module = builder::module()
            .function()
            .signature()
            .build()
            .body()
            .build()
            .build()
            .export()
            .field("main")
            .internal()
            .func(0)
            .build()
            .export()
            .field("memory")
            .internal()
            .memory(0)
            .build()
            .build();

        let repack = Repack::new();
        assert_eq!(module, repack.translate(&module).unwrap().unwrap());
    }

    #[test]
    fn custom_section() {
        let mut module = builder::module()
            .function()
            .signature()
            .build()
            .body()
            .build()
            .build()
            .export()
            .field("main")
            .internal()
            .func(0)
            .build()
            .export()
            .field("memory")
            .internal()
            .memory(0)
            .build()
            .build();

        let custom = CustomSection::new("test".to_string(), vec![42u8; 16]);
        module
            .sections_mut()
            .push(parity_wasm::elements::Section::Custom(custom));

        let repack = Repack::new();
        assert_ne!(module, repack.translate(&module).unwrap().unwrap());
    }

    #[test]
    fn names_section() {
        let input = FromHex::from_hex(
            "0061736d010000000104016000000303020000070801046d61696e00010a
0a020300010b040010000b0014046e616d65010d0200047465737401046d
61696e",
        )
        .unwrap();
        let module = Module::from_bytes(&input).unwrap();
        // Forcefully parse names section here.
        let module = module
            .parse_names()
            .expect("parsing the names section failed");
        assert_eq!(module.names_section().is_some(), true);
        let repack = Repack::new();
        // Repack drops names section too.
        let output = repack.translate(&module).unwrap().unwrap();
        assert_eq!(output.has_names_section(), false);
    }
}