mirror of
https://github.com/fluencelabs/wasm-utils
synced 2025-05-07 20:52:15 +00:00
functions and globals elimination
This commit is contained in:
parent
1051b60020
commit
7fd6ffabba
2
opt/Cargo.lock
generated
2
opt/Cargo.lock
generated
@ -13,7 +13,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
[[package]]
|
||||
name = "parity-wasm"
|
||||
version = "0.3.1"
|
||||
source = "git+https://github.com/nikvolf/parity-wasm#825169d34ea6d9c3909fe762e36ccc3ba5ae98cf"
|
||||
source = "git+https://github.com/nikvolf/parity-wasm#c52ccb7cd3c54cb0dbf9495dec550b5848737dcb"
|
||||
dependencies = [
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
107
opt/src/main.rs
107
opt/src/main.rs
@ -13,15 +13,11 @@ enum Symbol {
|
||||
}
|
||||
|
||||
fn resolve_function(module: &elements::Module, index: u32) -> Symbol {
|
||||
println!("Resolving function {}", index);
|
||||
|
||||
let mut functions = 0;
|
||||
let mut non_functions = 0;
|
||||
for (item_index, item) in module.import_section().expect("Functions section to exist").entries().iter().enumerate() {
|
||||
match item.external() {
|
||||
&elements::External::Function(_) => {
|
||||
if functions == index {
|
||||
println!("Import {}", item_index);
|
||||
return Symbol::Import(item_index as usize);
|
||||
}
|
||||
functions += 1;
|
||||
@ -34,22 +30,20 @@ fn resolve_function(module: &elements::Module, index: u32) -> Symbol {
|
||||
}
|
||||
|
||||
fn resolve_global(module: &elements::Module, index: u32) -> Symbol {
|
||||
let imports_len = module
|
||||
.import_section()
|
||||
.expect("Functions section to exist")
|
||||
.entries()
|
||||
.iter()
|
||||
.map(|e| match e.external() {
|
||||
&elements::External::Global(_) => 1,
|
||||
_ => 0,
|
||||
})
|
||||
.sum();
|
||||
|
||||
if index < imports_len {
|
||||
Symbol::Import(index as usize)
|
||||
} else {
|
||||
Symbol::Global(index as usize - imports_len as usize)
|
||||
let mut globals = 0;
|
||||
for (item_index, item) in module.import_section().expect("Functions section to exist").entries().iter().enumerate() {
|
||||
match item.external() {
|
||||
&elements::External::Global(_) => {
|
||||
if globals == index {
|
||||
return Symbol::Import(item_index as usize);
|
||||
}
|
||||
globals += 1;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Symbol::Global(index as usize - globals as usize)
|
||||
}
|
||||
|
||||
fn push_code_symbols(module: &elements::Module, opcodes: &[elements::Opcode], dest: &mut Vec<Symbol>) {
|
||||
@ -177,6 +171,42 @@ pub fn import_section<'a>(module: &'a mut elements::Module) -> Option<&'a mut el
|
||||
None
|
||||
}
|
||||
|
||||
pub fn global_section<'a>(module: &'a mut elements::Module) -> Option<&'a mut elements::GlobalSection> {
|
||||
for section in module.sections_mut() {
|
||||
match section {
|
||||
&mut elements::Section::Global(ref mut sect) => {
|
||||
return Some(sect);
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn functions_section<'a>(module: &'a mut elements::Module) -> Option<&'a mut elements::FunctionsSection> {
|
||||
for section in module.sections_mut() {
|
||||
match section {
|
||||
&mut elements::Section::Function(ref mut sect) => {
|
||||
return Some(sect);
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn code_section<'a>(module: &'a mut elements::Module) -> Option<&'a mut elements::CodeSection> {
|
||||
for section in module.sections_mut() {
|
||||
match section {
|
||||
&mut elements::Section::Code(ref mut sect) => {
|
||||
return Some(sect);
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
let args = env::args().collect::<Vec<_>>();
|
||||
@ -242,6 +272,7 @@ fn main() {
|
||||
} else {
|
||||
remove = true;
|
||||
eliminated_globals.push(top_globals);
|
||||
println!("Eliminated import({}) global({}, {})", old_index, top_globals, imports.entries()[index].field());
|
||||
}
|
||||
top_globals += 1;
|
||||
},
|
||||
@ -259,6 +290,44 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Senond, iterate through globals
|
||||
{
|
||||
let globals = global_section(&mut module).expect("Global section to exist");
|
||||
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
|
||||
loop {
|
||||
if globals.entries_mut().len() == index { break; }
|
||||
if stay.contains(&Symbol::Global(old_index)) {
|
||||
index += 1;
|
||||
} else {
|
||||
globals.entries_mut().remove(index);
|
||||
eliminated_globals.push(top_globals + old_index);
|
||||
println!("Eliminated global({})", top_globals + old_index);
|
||||
}
|
||||
old_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Third, delete orphaned functions
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
|
||||
loop {
|
||||
if functions_section(&mut module).expect("Functons section to exist").entries_mut().len() == index { break; }
|
||||
if stay.contains(&Symbol::Function(old_index)) {
|
||||
index += 1;
|
||||
} else {
|
||||
functions_section(&mut module).expect("Functons section to exist").entries_mut().remove(index);
|
||||
code_section(&mut module).expect("Functons section to exist").bodies_mut().remove(index);
|
||||
|
||||
eliminated_funcs.push(top_funcs + old_index);
|
||||
println!("Eliminated function({})", top_funcs + old_index);
|
||||
}
|
||||
old_index += 1;
|
||||
}
|
||||
|
||||
// Finally, delete all items one by one, updating reference indices in the process
|
||||
// (todo: initial naive impementation can be optimized to avoid multiple passes)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user