summaryrefslogtreecommitdiffstats
path: root/third_party/rust/parity-wasm/examples
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/parity-wasm/examples')
-rw-r--r--third_party/rust/parity-wasm/examples/bench-decoder.rs28
-rw-r--r--third_party/rust/parity-wasm/examples/build.rs47
-rw-r--r--third_party/rust/parity-wasm/examples/data.rs48
-rw-r--r--third_party/rust/parity-wasm/examples/exports.rs83
-rw-r--r--third_party/rust/parity-wasm/examples/info.rs49
-rw-r--r--third_party/rust/parity-wasm/examples/inject.rs63
-rw-r--r--third_party/rust/parity-wasm/examples/roundtrip.rs27
-rw-r--r--third_party/rust/parity-wasm/examples/show.rs36
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