1use parity_wasm::elements::Module;
2
3use super::{ChiselModule, ModuleError, ModuleKind, ModuleTranslator};
4
5#[derive(Clone)]
6pub struct Snip(wasm_snip::Options);
7
8impl Snip {
9 pub fn new() -> Self {
10 let mut options = wasm_snip::Options::default();
11 options.snip_rust_fmt_code = true;
13 options.snip_rust_panicking_code = true;
14 options.skip_producers_section = true;
15 Snip { 0: options }
16 }
17}
18
19impl<'a> ChiselModule<'a> for Snip {
20 type ObjectReference = &'a dyn ModuleTranslator;
21
22 fn id(&'a self) -> String {
23 "snip".to_string()
24 }
25
26 fn kind(&'a self) -> ModuleKind {
27 ModuleKind::Translator
28 }
29
30 fn as_abstract(&'a self) -> Self::ObjectReference {
31 self as Self::ObjectReference
32 }
33}
34
35impl From<failure::Error> for ModuleError {
36 fn from(error: failure::Error) -> Self {
37 ModuleError::Custom(error.to_string())
38 }
39}
40
41impl ModuleTranslator for Snip {
42 fn translate_inplace(&self, _module: &mut Module) -> Result<bool, ModuleError> {
43 Err(ModuleError::NotSupported)
44 }
45
46 fn translate(&self, module: &Module) -> Result<Option<Module>, ModuleError> {
47 let serialized = module.clone().to_bytes()?;
48
49 let mut options = self.0.clone();
51 options.input = wasm_snip::Input::Buffer(serialized);
52 let ret = wasm_snip::snip(options)?;
53 let output = ret.emit_wasm()?;
54
55 let output = Module::from_bytes(&output[..])?;
56 Ok(Some(output))
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use rustc_hex::FromHex;
63
64 use super::*;
65
66 #[test]
67 fn smoke_test() {
68 let wasm: Vec<u8> = FromHex::from_hex(
81 "0061736d0100000001080260017e0060000002170103656e760f65746865
827265756d5f75736547617300000304030101010503010001071102046d61
83696e0001066d656d6f727902000a10030600100210030b0300010b030001
840b007f046e616d650178040011696d706f72742466756e6374696f6e2430
8501046d61696e02377374643a3a70616e69636b696e673a3a727573745f70
86616e69635f776974685f686f6f6b3a3a6831326237323339656434333438
876561650323636f72653a3a666d743a3a77726974653a3a68396632383461
8865386538653962393461",
89 )
90 .unwrap();
91
92 let module = Module::from_bytes(&wasm).unwrap();
93 let module = Snip::new().translate(&module);
94 let module = module
95 .expect("translation to be succesful")
96 .expect("new module to be returned");
97 assert!(module.to_bytes().unwrap().len() < wasm.len());
98 }
99}