mirror of
https://github.com/fluencelabs/wasm-utils
synced 2025-06-28 05:51:44 +00:00
opt in progress
This commit is contained in:
@ -4,7 +4,7 @@ use std::env;
|
||||
use std::collections::HashSet;
|
||||
use parity_wasm::elements;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||
enum Symbol {
|
||||
Import(usize),
|
||||
Global(usize),
|
||||
@ -50,6 +50,25 @@ fn resolve_global(module: &elements::Module, index: u32) -> Symbol {
|
||||
}
|
||||
}
|
||||
|
||||
fn push_code_symbols(module: &elements::Module, opcodes: &[elements::Opcode], dest: &mut Vec<Symbol>) {
|
||||
use parity_wasm::elements::Opcode::*;
|
||||
|
||||
for opcode in opcodes {
|
||||
match opcode {
|
||||
&Call(idx) | &CallIndirect(idx, _) => {
|
||||
dest.push(resolve_function(module, idx));
|
||||
},
|
||||
&GetGlobal(idx) | &SetGlobal(idx) => {
|
||||
dest.push(resolve_global(module, idx))
|
||||
},
|
||||
&If(_, ref block) | &Loop(_, ref block) | &Block(_, ref block) => {
|
||||
push_code_symbols(module, block.elements(), dest);
|
||||
},
|
||||
_ => { },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn expand_symbols(module: &elements::Module, set: &mut HashSet<Symbol>) {
|
||||
use Symbol::*;
|
||||
|
||||
@ -58,23 +77,55 @@ fn expand_symbols(module: &elements::Module, set: &mut HashSet<Symbol>) {
|
||||
let mut fringe = set.iter().cloned().collect::<Vec<Symbol>>();
|
||||
loop {
|
||||
let next = match fringe.pop() {
|
||||
Some(s) if stop.contains(&s) => { continue; }
|
||||
Some(s) => s,
|
||||
_ => { break; }
|
||||
};
|
||||
|
||||
if stop.contains(&next) {
|
||||
continue;
|
||||
}
|
||||
println!("Processing symbol {:?}", next);
|
||||
|
||||
match next {
|
||||
Export(idx) => {
|
||||
let entry = &module.export_section().expect("Export section to exist").entries()[idx];
|
||||
match entry.internal() {
|
||||
&elements::Internal::Function(func_idx) => { fringe.push(resolve_function(module, func_idx)); },
|
||||
&elements::Internal::Global(global_idx) => { fringe.push(resolve_global(module, global_idx)); },
|
||||
&elements::Internal::Function(func_idx) => {
|
||||
let symbol = resolve_function(module, func_idx);
|
||||
if !stop.contains(&symbol) {
|
||||
fringe.push(symbol);
|
||||
}
|
||||
set.insert(symbol);
|
||||
},
|
||||
&elements::Internal::Global(global_idx) => {
|
||||
let symbol = resolve_global(module, global_idx);
|
||||
if !stop.contains(&symbol) {
|
||||
fringe.push(symbol);
|
||||
}
|
||||
set.insert(symbol);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
Function(idx) => {
|
||||
let body = &module.code_section().expect("Code section to exist").bodies()[idx];
|
||||
let mut code_symbols = Vec::new();
|
||||
push_code_symbols(module, body.code().elements(), &mut code_symbols);
|
||||
for symbol in code_symbols.drain(..) {
|
||||
if !stop.contains(&symbol) {
|
||||
fringe.push(symbol);
|
||||
}
|
||||
set.insert(symbol);
|
||||
}
|
||||
},
|
||||
Global(idx) => {
|
||||
let entry = &module.global_section().expect("Global section to exist").entries()[idx];
|
||||
let mut code_symbols = Vec::new();
|
||||
push_code_symbols(module, entry.init_expr().code(), &mut code_symbols);
|
||||
for symbol in code_symbols.drain(..) {
|
||||
if !stop.contains(&symbol) {
|
||||
fringe.push(symbol);
|
||||
}
|
||||
set.insert(symbol);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -112,6 +163,10 @@ fn main() {
|
||||
// that are already used by those which already there
|
||||
expand_symbols(&mut module, &mut stay);
|
||||
|
||||
for symbol in stay.iter() {
|
||||
println!("symbol to stay: {:?}", symbol);
|
||||
}
|
||||
|
||||
// Finally, delete all items one by one, updating reference indices in the process
|
||||
// (todo: initial naive impementation can be optimized to avoid multiple passes)
|
||||
|
||||
|
Reference in New Issue
Block a user