mirror of
https://github.com/pezkuwichain/wasm-instrument.git
synced 2026-04-29 12:37:56 +00:00
optimize types
This commit is contained in:
Generated
+4
-4
@@ -2,7 +2,7 @@
|
||||
name = "wasm-opt"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"parity-wasm 0.3.2 (git+https://github.com/nikvolf/parity-wasm)",
|
||||
"parity-wasm 0.4.0 (git+https://github.com/nikvolf/parity-wasm)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -12,12 +12,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "parity-wasm"
|
||||
version = "0.3.2"
|
||||
source = "git+https://github.com/nikvolf/parity-wasm#b11f34f2e5410d0773dcf32699d767d7359e4ca9"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/nikvolf/parity-wasm#5d7c7b4094c18e71c394e83a097cd634d36f74b2"
|
||||
dependencies = [
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
|
||||
"checksum parity-wasm 0.3.2 (git+https://github.com/nikvolf/parity-wasm)" = "<none>"
|
||||
"checksum parity-wasm 0.4.0 (git+https://github.com/nikvolf/parity-wasm)" = "<none>"
|
||||
|
||||
+74
-6
@@ -6,6 +6,7 @@ use parity_wasm::elements;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||
enum Symbol {
|
||||
Type(usize),
|
||||
Import(usize),
|
||||
Global(usize),
|
||||
Function(usize),
|
||||
@@ -100,6 +101,19 @@ fn expand_symbols(module: &elements::Module, set: &mut HashSet<Symbol>) {
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
Import(idx) => {
|
||||
let entry = &module.import_section().expect("Import section to exist").entries()[idx];
|
||||
match entry.external() {
|
||||
&elements::External::Function(type_idx) => {
|
||||
let type_symbol = Symbol::Type(type_idx as usize);
|
||||
if !stop.contains(&type_symbol) {
|
||||
fringe.push(type_symbol);
|
||||
}
|
||||
set.insert(type_symbol);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
Function(idx) => {
|
||||
let body = &module.code_section().expect("Code section to exist").bodies()[idx];
|
||||
let mut code_symbols = Vec::new();
|
||||
@@ -110,6 +124,13 @@ fn expand_symbols(module: &elements::Module, set: &mut HashSet<Symbol>) {
|
||||
}
|
||||
set.insert(symbol);
|
||||
}
|
||||
|
||||
let signature = &module.functions_section().expect("Functions section to exist").entries()[idx];
|
||||
let type_symbol = Symbol::Type(signature.type_ref() as usize);
|
||||
if !stop.contains(&type_symbol) {
|
||||
fringe.push(type_symbol);
|
||||
}
|
||||
set.insert(type_symbol);
|
||||
},
|
||||
Global(idx) => {
|
||||
let entry = &module.global_section().expect("Global section to exist").entries()[idx];
|
||||
@@ -224,6 +245,18 @@ pub fn export_section<'a>(module: &'a mut elements::Module) -> Option<&'a mut el
|
||||
None
|
||||
}
|
||||
|
||||
pub fn type_section<'a>(module: &'a mut elements::Module) -> Option<&'a mut elements::TypeSection> {
|
||||
for section in module.sections_mut() {
|
||||
match section {
|
||||
&mut elements::Section::Type(ref mut sect) => {
|
||||
return Some(sect);
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
let args = env::args().collect::<Vec<_>>();
|
||||
@@ -278,14 +311,34 @@ fn main() {
|
||||
// Keep track of referreable symbols to rewire calls/globals
|
||||
let mut eliminated_funcs = Vec::new();
|
||||
let mut eliminated_globals = Vec::new();
|
||||
let mut eliminated_types = Vec::new();
|
||||
|
||||
// First iterate throgh imports
|
||||
// First, iterate through types
|
||||
let mut index = 0;
|
||||
let mut old_index = 0;
|
||||
|
||||
{
|
||||
loop {
|
||||
if type_section(&mut module).expect("Functons section to exist").types_mut().len() == index { break; }
|
||||
|
||||
if stay.contains(&Symbol::Type(old_index)) {
|
||||
index += 1;
|
||||
} else {
|
||||
type_section(&mut module).expect("Code section to exist").types_mut().remove(index);
|
||||
eliminated_types.push(old_index);
|
||||
println!("Eliminated type({})", old_index);
|
||||
}
|
||||
old_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Second, iterate through imports
|
||||
let mut top_funcs = 0;
|
||||
let mut top_globals = 0;
|
||||
|
||||
{
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
let imports = import_section(&mut module).expect("Import section to exist");
|
||||
loop {
|
||||
let mut remove = false;
|
||||
@@ -324,7 +377,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Senond, iterate through globals
|
||||
// Third, iterate through globals
|
||||
{
|
||||
let globals = global_section(&mut module).expect("Global section to exist");
|
||||
|
||||
@@ -344,7 +397,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Third, delete orphaned functions
|
||||
// Forth, delete orphaned functions
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
|
||||
@@ -362,7 +415,7 @@ fn main() {
|
||||
old_index += 1;
|
||||
}
|
||||
|
||||
// Forth, eliminate unused exports
|
||||
// Fivth, eliminate unused exports
|
||||
{
|
||||
let exports = export_section(&mut module).expect("Export section to exist");
|
||||
|
||||
@@ -381,14 +434,29 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
if eliminated_globals.len() > 0 || eliminated_funcs.len() > 0 {
|
||||
// Finaly, rewire all calls and globals references to the new indices
|
||||
if eliminated_globals.len() > 0 || eliminated_funcs.len() > 0 || eliminated_types.len() > 0 {
|
||||
// Finaly, rewire all calls, globals references and types to the new indices
|
||||
// (only if there is anything to do)
|
||||
eliminated_globals.sort();
|
||||
eliminated_funcs.sort();
|
||||
eliminated_types.sort();
|
||||
|
||||
for section in module.sections_mut() {
|
||||
match section {
|
||||
&mut elements::Section::Function(ref mut function_section) => {
|
||||
for ref mut func_signature in function_section.entries_mut() {
|
||||
let totalle = eliminated_types.iter().take_while(|i| (**i as u32) < func_signature.type_ref()).count();
|
||||
*func_signature.type_ref_mut() -= totalle as u32;
|
||||
}
|
||||
},
|
||||
&mut elements::Section::Import(ref mut import_section) => {
|
||||
for ref mut import_entry in import_section.entries_mut() {
|
||||
if let &mut elements::External::Function(ref mut type_ref) = import_entry.external_mut() {
|
||||
let totalle = eliminated_types.iter().take_while(|i| (**i as u32) < *type_ref).count();
|
||||
*type_ref -= totalle as u32;
|
||||
}
|
||||
}
|
||||
},
|
||||
&mut elements::Section::Code(ref mut code_section) => {
|
||||
for ref mut func_body in code_section.bodies_mut() {
|
||||
update_call_index(func_body.code_mut(), &eliminated_funcs);
|
||||
|
||||
@@ -12,21 +12,13 @@ pub fn call() {
|
||||
}
|
||||
|
||||
/* This produces the following code (after injecting gas counter & optimizing)
|
||||
|
||||
(module
|
||||
(type (;0;) (func (result i32)))
|
||||
(type (;1;) (func))
|
||||
(type (;2;) (func (param i32)))
|
||||
(type (;3;) (func (param i32 i32 i64 i32 i32) (result i32)))
|
||||
(type (;4;) (func (param i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(type (;5;) (func (param i32) (result i32)))
|
||||
(type (;6;) (func (param i32 i32)))
|
||||
(type (;7;) (func (param i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(type (;8;) (func (param i32)))
|
||||
(type (;0;) (func))
|
||||
(type (;1;) (func (param i32)))
|
||||
(import "env" "memory" (memory (;0;) 256 256))
|
||||
(import "env" "table" (table (;0;) 0 0 anyfunc))
|
||||
(import "env" "gas" (func (;0;) (type 8)))
|
||||
(func (;1;) (type 1)
|
||||
(import "env" "gas" (func (;0;) (type 1)))
|
||||
(func (;1;) (type 0)
|
||||
i32.const 2
|
||||
call 0
|
||||
nop)
|
||||
|
||||
Reference in New Issue
Block a user