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
extern crate parity_wasm;
#[macro_use]
extern crate log;
extern crate rustc_demangle;
mod gc;
mod error;
use std::path::Path;
use parity_wasm::elements::{
Module,
Serialize,
Deserialize
};
pub use error::Error;
pub struct Config {
demangle: bool,
keep_debug: bool,
}
impl Config {
pub fn new() -> Config {
Config {
demangle: true,
keep_debug: false,
}
}
pub fn demangle(&mut self, demangle: bool) -> &mut Self {
self.demangle = demangle;
self
}
pub fn keep_debug(&mut self, keep_debug: bool) -> &mut Self {
self.keep_debug = keep_debug;
self
}
pub fn gc(&mut self, mut bytecode: &[u8]) -> Result<Vec<u8>, Error> {
let mut module = Module::deserialize(&mut bytecode)
.map_err(error::from)?
.parse_names()
.map_err(|(mut l, _)| l.remove(0).1)
.map_err(error::from)?;
self._gc(&mut module);
let mut output = Vec::new();
module.serialize(&mut output).map_err(error::from)?;
Ok(output)
}
fn _gc(&mut self, module: &mut Module) {
gc::run(self, module);
}
}
pub fn garbage_collect_file<I, O>(input_path: I, output_path: O) -> Result<(), Error>
where
I: AsRef<Path>,
O: AsRef<Path>,
{
_gc_file(input_path.as_ref(), output_path.as_ref())
}
fn _gc_file(input: &Path, output: &Path) -> Result<(), Error> {
let mut module = parity_wasm::deserialize_file(input)
.map_err(error::from)?
.parse_names()
.map_err(|(mut l, _)| l.remove(0).1)
.map_err(error::from)?;
Config::new()._gc(&mut module);
parity_wasm::serialize_to_file(output, module).map_err(error::from)?;
Ok(())
}
pub fn garbage_collect_slice(bytecode: &[u8]) -> Result<Vec<u8>, Error> {
Config::new().gc(bytecode)
}