mirror of
https://github.com/pezkuwichain/wasm-instrument.git
synced 2026-06-21 22:41:10 +00:00
optimize types
This commit is contained in:
Generated
+4
-4
@@ -2,7 +2,7 @@
|
|||||||
name = "wasm-opt"
|
name = "wasm-opt"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
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]]
|
[[package]]
|
||||||
@@ -12,12 +12,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-wasm"
|
name = "parity-wasm"
|
||||||
version = "0.3.2"
|
version = "0.4.0"
|
||||||
source = "git+https://github.com/nikvolf/parity-wasm#b11f34f2e5410d0773dcf32699d767d7359e4ca9"
|
source = "git+https://github.com/nikvolf/parity-wasm#5d7c7b4094c18e71c394e83a097cd634d36f74b2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
|
"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)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||||
enum Symbol {
|
enum Symbol {
|
||||||
|
Type(usize),
|
||||||
Import(usize),
|
Import(usize),
|
||||||
Global(usize),
|
Global(usize),
|
||||||
Function(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) => {
|
Function(idx) => {
|
||||||
let body = &module.code_section().expect("Code section to exist").bodies()[idx];
|
let body = &module.code_section().expect("Code section to exist").bodies()[idx];
|
||||||
let mut code_symbols = Vec::new();
|
let mut code_symbols = Vec::new();
|
||||||
@@ -110,6 +124,13 @@ fn expand_symbols(module: &elements::Module, set: &mut HashSet<Symbol>) {
|
|||||||
}
|
}
|
||||||
set.insert(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) => {
|
Global(idx) => {
|
||||||
let entry = &module.global_section().expect("Global section to exist").entries()[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
|
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() {
|
fn main() {
|
||||||
|
|
||||||
let args = env::args().collect::<Vec<_>>();
|
let args = env::args().collect::<Vec<_>>();
|
||||||
@@ -278,14 +311,34 @@ fn main() {
|
|||||||
// Keep track of referreable symbols to rewire calls/globals
|
// Keep track of referreable symbols to rewire calls/globals
|
||||||
let mut eliminated_funcs = Vec::new();
|
let mut eliminated_funcs = Vec::new();
|
||||||
let mut eliminated_globals = 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 index = 0;
|
||||||
let mut old_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_funcs = 0;
|
||||||
let mut top_globals = 0;
|
let mut top_globals = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
index = 0;
|
||||||
|
old_index = 0;
|
||||||
let imports = import_section(&mut module).expect("Import section to exist");
|
let imports = import_section(&mut module).expect("Import section to exist");
|
||||||
loop {
|
loop {
|
||||||
let mut remove = false;
|
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");
|
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;
|
index = 0;
|
||||||
old_index = 0;
|
old_index = 0;
|
||||||
|
|
||||||
@@ -362,7 +415,7 @@ fn main() {
|
|||||||
old_index += 1;
|
old_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forth, eliminate unused exports
|
// Fivth, eliminate unused exports
|
||||||
{
|
{
|
||||||
let exports = export_section(&mut module).expect("Export section to exist");
|
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 {
|
if eliminated_globals.len() > 0 || eliminated_funcs.len() > 0 || eliminated_types.len() > 0 {
|
||||||
// Finaly, rewire all calls and globals references to the new indices
|
// Finaly, rewire all calls, globals references and types to the new indices
|
||||||
// (only if there is anything to do)
|
// (only if there is anything to do)
|
||||||
eliminated_globals.sort();
|
eliminated_globals.sort();
|
||||||
eliminated_funcs.sort();
|
eliminated_funcs.sort();
|
||||||
|
eliminated_types.sort();
|
||||||
|
|
||||||
for section in module.sections_mut() {
|
for section in module.sections_mut() {
|
||||||
match section {
|
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) => {
|
&mut elements::Section::Code(ref mut code_section) => {
|
||||||
for ref mut func_body in code_section.bodies_mut() {
|
for ref mut func_body in code_section.bodies_mut() {
|
||||||
update_call_index(func_body.code_mut(), &eliminated_funcs);
|
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)
|
/* This produces the following code (after injecting gas counter & optimizing)
|
||||||
|
|
||||||
(module
|
(module
|
||||||
(type (;0;) (func (result i32)))
|
(type (;0;) (func))
|
||||||
(type (;1;) (func))
|
(type (;1;) (func (param i32)))
|
||||||
(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)))
|
|
||||||
(import "env" "memory" (memory (;0;) 256 256))
|
(import "env" "memory" (memory (;0;) 256 256))
|
||||||
(import "env" "table" (table (;0;) 0 0 anyfunc))
|
(import "env" "table" (table (;0;) 0 0 anyfunc))
|
||||||
(import "env" "gas" (func (;0;) (type 8)))
|
(import "env" "gas" (func (;0;) (type 1)))
|
||||||
(func (;1;) (type 1)
|
(func (;1;) (type 0)
|
||||||
i32.const 2
|
i32.const 2
|
||||||
call 0
|
call 0
|
||||||
nop)
|
nop)
|
||||||
|
|||||||
Reference in New Issue
Block a user