diff options
Diffstat (limited to 'third_party/rust/parity-wasm/examples')
-rw-r--r-- | third_party/rust/parity-wasm/examples/bench-decoder.rs | 28 | ||||
-rw-r--r-- | third_party/rust/parity-wasm/examples/build.rs | 47 | ||||
-rw-r--r-- | third_party/rust/parity-wasm/examples/data.rs | 48 | ||||
-rw-r--r-- | third_party/rust/parity-wasm/examples/exports.rs | 83 | ||||
-rw-r--r-- | third_party/rust/parity-wasm/examples/info.rs | 49 | ||||
-rw-r--r-- | third_party/rust/parity-wasm/examples/inject.rs | 63 | ||||
-rw-r--r-- | third_party/rust/parity-wasm/examples/roundtrip.rs | 27 | ||||
-rw-r--r-- | third_party/rust/parity-wasm/examples/show.rs | 36 |
8 files changed, 381 insertions, 0 deletions
diff --git a/third_party/rust/parity-wasm/examples/bench-decoder.rs b/third_party/rust/parity-wasm/examples/bench-decoder.rs new file mode 100644 index 0000000000..5749b5f6a9 --- /dev/null +++ b/third_party/rust/parity-wasm/examples/bench-decoder.rs @@ -0,0 +1,28 @@ +extern crate parity_wasm; +extern crate time; + +use std::fs; + +fn rate(file_name: &'static str, iterations: u64) { + let file_size = fs::metadata(file_name).expect(&format!("{} to exist", file_name)).len(); + let mut total_ms = 0; + + for _ in 0..iterations { + let start = time::PreciseTime::now(); + let _module = parity_wasm::deserialize_file(file_name); + let end = time::PreciseTime::now(); + + total_ms += start.to(end).num_milliseconds(); + } + + println!("Rate for {}: {} MB/s", file_name, + (file_size as f64 * iterations as f64 / (1024*1024) as f64) / // total work megabytes + (total_ms as f64 / 1000f64) // total seconds + ); +} + +fn main() { + rate("./res/cases/v1/clang.wasm", 10); + rate("./res/cases/v1/hello.wasm", 100); + rate("./res/cases/v1/with_names.wasm", 100); +}
\ No newline at end of file diff --git a/third_party/rust/parity-wasm/examples/build.rs b/third_party/rust/parity-wasm/examples/build.rs new file mode 100644 index 0000000000..6049466b84 --- /dev/null +++ b/third_party/rust/parity-wasm/examples/build.rs @@ -0,0 +1,47 @@ +// Simple example of how to use parity-wasm builder api. +// Builder api introduced as a method for fast generation of +// different small wasm modules. + +extern crate parity_wasm; + +use std::env; + +use parity_wasm::builder; +use parity_wasm::elements; + +fn main() { + + // Example binary accepts one parameter which is the output file + // where generated wasm module will be written at the end of execution + let args = env::args().collect::<Vec<_>>(); + if args.len() != 2 { + println!("Usage: {} output_file.wasm", args[0]); + return; + } + + // Main entry for the builder api is the module function + // It returns empty module builder structure which can be further + // appended with various wasm artefacts + let module = builder::module() + // Here we append function to the builder + // function() function returns a function builder attached + // to the module builder. + .function() + // We describe signature for the function via signature() + // function. In our simple example it's just one input + // argument of type 'i32' without return value + .signature().with_param(elements::ValueType::I32).build() + // body() without any further arguments means that the body + // of the function will be empty + .body().build() + // This is the end of the function builder. When `build()` is + // invoked, function builder returns original module builder + // from which it was invoked + .build() + // And finally we finish our module builder to produce actual + // wasm module. + .build(); + + // Module structure can be serialzed to produce a valid wasm file + parity_wasm::serialize_to_file(&args[1], module).unwrap(); +}
\ No newline at end of file diff --git a/third_party/rust/parity-wasm/examples/data.rs b/third_party/rust/parity-wasm/examples/data.rs new file mode 100644 index 0000000000..5cca373c3f --- /dev/null +++ b/third_party/rust/parity-wasm/examples/data.rs @@ -0,0 +1,48 @@ +// This short example provides the utility to inspect +// wasm file data section. + +extern crate parity_wasm; + +use std::env; + +fn main() { + + // Example executable takes one argument which must + // refernce the existing file with a valid wasm module + let args = env::args().collect::<Vec<_>>(); + if args.len() != 2 { + println!("Usage: {} somefile.wasm", args[0]); + return; + } + + // Here we load module using dedicated for this purpose + // `deserialize_file` function (which works only with modules) + let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); + + // We query module for data section. Note that not every valid + // wasm module must contain a data section. So in case the provided + // module does not contain data section, we panic with an error + let data_section = module.data_section().expect("no data section in module"); + + // Printing the total count of data segments + println!("Data segments: {}", data_section.entries().len()); + + let mut index = 0; + for entry in data_section.entries() { + // Printing the details info of each data segment + // see `elements::DataSegment` for more properties + // you can query + println!(" Entry #{}", index); + + // This shows the initialization member of data segment + // (expression which must resolve in the linear memory location). + if let Some(offset) = entry.offset() { + println!(" init: {}", offset.code()[0]); + } + + // This shows the total length of the data segment in bytes. + println!(" size: {}", entry.value().len()); + + index += 1; + } +} diff --git a/third_party/rust/parity-wasm/examples/exports.rs b/third_party/rust/parity-wasm/examples/exports.rs new file mode 100644 index 0000000000..af52ab299b --- /dev/null +++ b/third_party/rust/parity-wasm/examples/exports.rs @@ -0,0 +1,83 @@ +// This examples allow to query all function exports of the +// provided wasm module + +extern crate parity_wasm; + +use std::env::args; + +use parity_wasm::elements::{Internal, External, Type, FunctionType, Module}; + +// Auxillary function to resolve function type (signature) given it's callable index +fn type_by_index(module: &Module, index: usize) -> FunctionType { + + // Demand that function and type section exist. Otherwise, fail with a + // corresponding error. + let function_section = module.function_section().expect("No function section found"); + let type_section = module.type_section().expect("No type section found"); + + // This counts the number of _function_ imports listed by the module, excluding + // the globals, since indexing for actual functions for `call` and `export` purposes + // includes both imported and own functions. So we actualy need the imported function count + // to resolve actual index of the given function in own functions list. + let import_section_len: usize = match module.import_section() { + Some(import) => + import.entries().iter().filter(|entry| match entry.external() { + &External::Function(_) => true, + _ => false, + }).count(), + None => 0, + }; + + // Substract the value queried in the previous step from the provided index + // to get own function index from which we can query type next. + let function_index_in_section = index - import_section_len; + + // Query the own function given we have it's index + let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize; + + // Finally, return function type (signature) + match type_section.types()[func_type_ref] { + Type::Function(ref func_type) => func_type.clone(), + } +} + +fn main() { + + // Example executable takes one argument which must + // refernce the existing file with a valid wasm module + let args: Vec<_> = args().collect(); + if args.len() < 2 { + println!("Prints export function names with and their types"); + println!("Usage: {} <wasm file>", args[0]); + return; + } + + // Here we load module using dedicated for this purpose + // `deserialize_file` function (which works only with modules) + let module = parity_wasm::deserialize_file(&args[1]).expect("File to be deserialized"); + + // Query the export section from the loaded module. Note that not every + // wasm module obliged to contain export section. So in case there is no + // any export section, we panic with the corresponding error. + let export_section = module.export_section().expect("No export section found"); + + // Process all exports, leaving only those which reference the internal function + // of the wasm module + let exports: Vec<String> = export_section.entries().iter() + .filter_map(|entry| + // This is match on export variant, which can be function, global,table or memory + // We are interested only in functions for an example + match *entry.internal() { + // Return function export name (return by field() function and it's index) + Internal::Function(index) => Some((entry.field(), index as usize)), + _ => None + }) + // Another map to resolve function signature index given it's internal index and return + // the printable string of the export + .map(|(field, index)| format!("{:}: {:?}", field, type_by_index(&module, index).params())).collect(); + + // Print the result + for export in exports { + println!("{:}", export); + } +} diff --git a/third_party/rust/parity-wasm/examples/info.rs b/third_party/rust/parity-wasm/examples/info.rs new file mode 100644 index 0000000000..9717651df6 --- /dev/null +++ b/third_party/rust/parity-wasm/examples/info.rs @@ -0,0 +1,49 @@ +extern crate parity_wasm; + +use std::env; +use parity_wasm::elements::Section; + +fn main() { + let args = env::args().collect::<Vec<_>>(); + if args.len() != 2 { + println!("Usage: {} somefile.wasm", args[0]); + return; + } + + let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); + + println!("Module sections: {}", module.sections().len()); + + for section in module.sections() { + match *section { + Section::Import(ref import_section) => { + println!(" Imports: {}", import_section.entries().len()); + import_section.entries().iter().map(|e| println!(" {}.{}", e.module(), e.field())).count(); + }, + Section::Export(ref exports_section) => { + println!(" Exports: {}", exports_section.entries().len()); + exports_section.entries().iter().map(|e| println!(" {}", e.field())).count(); + }, + Section::Function(ref function_section) => { + println!(" Functions: {}", function_section.entries().len()); + }, + Section::Type(ref type_section) => { + println!(" Types: {}", type_section.types().len()); + }, + Section::Global(ref globals_section) => { + println!(" Globals: {}", globals_section.entries().len()); + }, + Section::Table(ref table_section) => { + println!(" Tables: {}", table_section.entries().len()); + }, + Section::Memory(ref memory_section) => { + println!(" Memories: {}", memory_section.entries().len()); + }, + Section::Data(ref data_section) if data_section.entries().len() > 0 => { + let data = &data_section.entries()[0]; + println!(" Data size: {}", data.value().len()); + }, + _ => {}, + } + } +}
\ No newline at end of file diff --git a/third_party/rust/parity-wasm/examples/inject.rs b/third_party/rust/parity-wasm/examples/inject.rs new file mode 100644 index 0000000000..0e58e23167 --- /dev/null +++ b/third_party/rust/parity-wasm/examples/inject.rs @@ -0,0 +1,63 @@ +extern crate parity_wasm; + +use std::env; + +use parity_wasm::elements; +use parity_wasm::builder; + +pub fn inject_nop(instructions: &mut elements::Instructions) { + use parity_wasm::elements::Instruction::*; + let instructions = instructions.elements_mut(); + let mut position = 0; + loop { + let need_inject = match &instructions[position] { + &Block(_) | &If(_) => true, + _ => false, + }; + if need_inject { + instructions.insert(position + 1, Nop); + } + + position += 1; + if position >= instructions.len() { + break; + } + } +} + +fn main() { + let args = env::args().collect::<Vec<_>>(); + if args.len() != 3 { + println!("Usage: {} input_file.wasm output_file.wasm", args[0]); + return; + } + + let mut module = parity_wasm::deserialize_file(&args[1]).unwrap(); + + for section in module.sections_mut() { + match section { + &mut elements::Section::Code(ref mut code_section) => { + for ref mut func_body in code_section.bodies_mut() { + inject_nop(func_body.code_mut()); + } + }, + _ => { } + } + } + + let mut build = builder::from_module(module); + let import_sig = build.push_signature( + builder::signature() + .param().i32() + .param().i32() + .return_type().i32() + .build_sig() + ); + let build = build.import() + .module("env") + .field("log") + .external().func(import_sig) + .build(); + + parity_wasm::serialize_to_file(&args[2], build.build()).unwrap(); +}
\ No newline at end of file diff --git a/third_party/rust/parity-wasm/examples/roundtrip.rs b/third_party/rust/parity-wasm/examples/roundtrip.rs new file mode 100644 index 0000000000..b3b951912a --- /dev/null +++ b/third_party/rust/parity-wasm/examples/roundtrip.rs @@ -0,0 +1,27 @@ +extern crate parity_wasm; + +use std::env; + +fn main() { + let args = env::args().collect::<Vec<_>>(); + if args.len() != 3 { + println!("Usage: {} in.wasm out.wasm", args[0]); + return; + } + + let module = match parity_wasm::deserialize_file(&args[1]) + .expect("Failed to load module") + .parse_names() + .and_then(|module| module.parse_reloc()) + { + Ok(m) => m, + Err((errors, m)) => { + for (index, error) in errors.into_iter() { + println!("Custom section #{} parse error: {:?}", index, error); + } + m + } + }; + + parity_wasm::serialize_to_file(&args[2], module).expect("Failed to write module"); +} diff --git a/third_party/rust/parity-wasm/examples/show.rs b/third_party/rust/parity-wasm/examples/show.rs new file mode 100644 index 0000000000..d4260818b1 --- /dev/null +++ b/third_party/rust/parity-wasm/examples/show.rs @@ -0,0 +1,36 @@ +extern crate parity_wasm; + +use std::env; + +fn main() { + let args = env::args().collect::<Vec<_>>(); + if args.len() != 3 { + println!("Usage: {} <wasm file> <index of function>", args[0]); + return; + } + + let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); + let function_index = args[2].parse::<usize>().expect("Failed to parse function index"); + + if module.code_section().is_none() { + println!("no code in module!"); + std::process::exit(1); + } + + let sig = match module.function_section().unwrap().entries().get(function_index) { + Some(s) => s, + None => { + println!("no such function in module!"); + std::process::exit(1) + } + }; + + let sig_type = &module.type_section().expect("No type section: module malformed").types()[sig.type_ref() as usize]; + let code = &module.code_section().expect("Already checked, impossible").bodies()[function_index]; + + println!("signature: {:?}", sig_type); + println!("code: "); + for instruction in code.code().elements() { + println!("{}", instruction); + } +}
\ No newline at end of file |