mirror of
https://github.com/fluencelabs/wasm-utils
synced 2025-06-28 14:01:39 +00:00
opt in progress
This commit is contained in:
@ -4,7 +4,7 @@ use std::env;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use parity_wasm::elements;
|
use parity_wasm::elements;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||||
enum Symbol {
|
enum Symbol {
|
||||||
Import(usize),
|
Import(usize),
|
||||||
Global(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>) {
|
fn expand_symbols(module: &elements::Module, set: &mut HashSet<Symbol>) {
|
||||||
use 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>>();
|
let mut fringe = set.iter().cloned().collect::<Vec<Symbol>>();
|
||||||
loop {
|
loop {
|
||||||
let next = match fringe.pop() {
|
let next = match fringe.pop() {
|
||||||
|
Some(s) if stop.contains(&s) => { continue; }
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
_ => { break; }
|
_ => { break; }
|
||||||
};
|
};
|
||||||
|
println!("Processing symbol {:?}", next);
|
||||||
if stop.contains(&next) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
match next {
|
match next {
|
||||||
Export(idx) => {
|
Export(idx) => {
|
||||||
let entry = &module.export_section().expect("Export section to exist").entries()[idx];
|
let entry = &module.export_section().expect("Export section to exist").entries()[idx];
|
||||||
match entry.internal() {
|
match entry.internal() {
|
||||||
&elements::Internal::Function(func_idx) => { fringe.push(resolve_function(module, func_idx)); },
|
&elements::Internal::Function(func_idx) => {
|
||||||
&elements::Internal::Global(global_idx) => { fringe.push(resolve_global(module, global_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
|
// that are already used by those which already there
|
||||||
expand_symbols(&mut module, &mut stay);
|
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
|
// Finally, delete all items one by one, updating reference indices in the process
|
||||||
// (todo: initial naive impementation can be optimized to avoid multiple passes)
|
// (todo: initial naive impementation can be optimized to avoid multiple passes)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user