mirror of
https://github.com/pezkuwichain/wasm-instrument.git
synced 2026-04-22 06:48:03 +00:00
54213f77f6
Updates the requirements on [wasmi](https://github.com/paritytech/wasmi) to permit the latest version. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/paritytech/wasmi/releases">wasmi's releases</a>.</em></p> <blockquote> <h2>v0.21.0 - 2023-01-04</h2> <h3>Added</h3> <ul> <li>Add support for resumable function calls. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/598">paritytech/wasmi#598</a>) <ul> <li>This feature allows to resume a function call upon encountering a host trap.</li> </ul> </li> <li>Add support for concurrently running function executions using a single <code>wasmi</code> engine. <ul> <li>This feature also allows to call Wasm functions from host functions. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/590">paritytech/wasmi#590</a>)</li> </ul> </li> <li>Add initial naive WASI support for <code>wasmi</code> using the new <code>wasmi_wasi</code> crate. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/557">paritytech/wasmi#557</a>) <ul> <li>Special thanks to <a href="https://github.com/OLUWAMUYIWA">Onigbinde Oluwamuyiwa Elijah</a> for carrying the WASI support efforts!</li> <li>Also thanks to <a href="https://github.com/Berrysoft">Yuyi Wang</a> for testing and improving initial WASI support. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/592">paritytech/wasmi#592</a>, <a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/571">paritytech/wasmi#571</a>, <a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/568">paritytech/wasmi#568</a>)</li> <li><strong>Note:</strong> There is ongoing work to integrate WASI support in <code>wasmi_cli</code> so that the <code>wasmi</code> CLI will then be able to execute arbitrary <code>wasm-wasi</code> files out of the box in the future.</li> </ul> </li> <li>Add <code>Module::imports</code> that allows to query Wasm module imports. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/573">paritytech/wasmi#573</a>, <a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/583">paritytech/wasmi#583</a>)</li> </ul> <h3>Fixed</h3> <ul> <li>Fix a bug that imported linear memories and tables were initialized twice upon instantiation. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/593">paritytech/wasmi#593</a>)</li> <li>The <code>wasmi</code> CLI now properly hints for file path arguments. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/596">paritytech/wasmi#596</a>)</li> </ul> <h3>Changed</h3> <ul> <li>The <code>wasmi::Trap</code> type is now more similar to Wasmtime's <code>Trap</code> type. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/559">paritytech/wasmi#559</a>)</li> <li>The <code>wasmi::Store</code> type is now <code>Send</code> and <code>Sync</code> as intended. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/566">paritytech/wasmi#566</a>)</li> <li>The <code>wasmi</code> CLI now prints exported functions names if the function name CLI argument is missing. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/579">paritytech/wasmi#579</a>)</li> <li>Improve feedback when running a Wasm module without exported function using <code>wasmi</code> CLI. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/584">paritytech/wasmi#584</a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/paritytech/wasmi/blob/master/CHANGELOG.md">wasmi's changelog</a>.</em></p> <blockquote> <h2>[0.21.0] - 2023-01-04</h2> <h3>Added</h3> <ul> <li>Add support for resumable function calls. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/598">paritytech/wasmi#598</a>) <ul> <li>This feature allows to resume a function call upon encountering a host trap.</li> </ul> </li> <li>Add support for concurrently running function executions using a single <code>wasmi</code> engine. <ul> <li>This feature also allows to call Wasm functions from host functions. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/590">paritytech/wasmi#590</a>)</li> </ul> </li> <li>Add initial naive WASI support for <code>wasmi</code> using the new <code>wasmi_wasi</code> crate. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/557">paritytech/wasmi#557</a>) <ul> <li>Special thanks to <a href="https://github.com/OLUWAMUYIWA">Onigbinde Oluwamuyiwa Elijah</a> for carrying the WASI support efforts!</li> <li>Also thanks to <a href="https://github.com/Berrysoft">Yuyi Wang</a> for testing and improving initial WASI support. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/592">paritytech/wasmi#592</a>, <a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/571">paritytech/wasmi#571</a>, <a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/568">paritytech/wasmi#568</a>)</li> <li><strong>Note:</strong> There is ongoing work to integrate WASI support in <code>wasmi_cli</code> so that the <code>wasmi</code> CLI will then be able to execute arbitrary <code>wasm-wasi</code> files out of the box in the future.</li> </ul> </li> <li>Add <code>Module::imports</code> that allows to query Wasm module imports. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/573">paritytech/wasmi#573</a>, <a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/583">paritytech/wasmi#583</a>)</li> </ul> <h3>Fixed</h3> <ul> <li>Fix a bug that imported linear memories and tables were initialized twice upon instantiation. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/593">paritytech/wasmi#593</a>)</li> <li>The <code>wasmi</code> CLI now properly hints for file path arguments. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/596">paritytech/wasmi#596</a>)</li> </ul> <h3>Changed</h3> <ul> <li>The <code>wasmi::Trap</code> type is now more similar to Wasmtime's <code>Trap</code> type. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/559">paritytech/wasmi#559</a>)</li> <li>The <code>wasmi::Store</code> type is now <code>Send</code> and <code>Sync</code> as intended. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/566">paritytech/wasmi#566</a>)</li> <li>The <code>wasmi</code> CLI now prints exported functions names if the function name CLI argument is missing. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/579">paritytech/wasmi#579</a>)</li> <li>Improve feedback when running a Wasm module without exported function using <code>wasmi</code> CLI. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/584">paritytech/wasmi#584</a>)</li> </ul> <h2>[0.20.0] - 2022-11-04</h2> <h3>Added</h3> <ul> <li>Contribution documentation about fuzz testing. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/529">paritytech/wasmi#529</a>)</li> </ul> <h3>Removed</h3> <ul> <li>Removed some deprecated functions in the <code>wasmi_core</code> crate. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/545">paritytech/wasmi#545</a>)</li> </ul> <h3>Fixed</h3> <ul> <li>Fixed a critical performance regression introduced in Rust 1.65. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/518">paritytech/wasmi#518</a>) <ul> <li>While the PR's main job was to clean up some code it was found out that it also fixes a critical performance regression introduced in Rust 1.65.</li> <li>You can read more about this performance regression <a href="https://github-redirect.dependabot.com/rust-lang/rust/issues/102952">in this thread</a>.</li> </ul> </li> </ul> <h3>Changed</h3> <ul> <li>Fixed handling of edge cases with respect to Wasm linear memory. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/449">paritytech/wasmi#449</a>) <ul> <li>This allows for <code>wasmi</code> to properly setup and use linear memory instances of up to 4GB.</li> </ul> </li> <li>Optimize and improve Wasm instantiation. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/531">paritytech/wasmi#531</a>)</li> <li>Optimize <code>global.get</code> of immutable non-imported globals. (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/pull/533">paritytech/wasmi#533</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/paritytech/wasmi/commit/9e228e8a253074bf25cfcfeff11b07ff2033170e"><code>9e228e8</code></a> Bump <code>wasmi</code> version to <code>0.21.0</code> (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/604">#604</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/8fb3a58de76a10b0072d0c71fd1677a96f33009f"><code>8fb3a58</code></a> Prepare for <code>wasmi</code> version <code>0.21.0</code> release (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/603">#603</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/829ae5b115e8d8f484c93798309ac9e1eb7351eb"><code>829ae5b</code></a> Resumable Function Calls (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/598">#598</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/3c62031d096a73c59edb05ea5cc508e5bc65b0f6"><code>3c62031</code></a> Add <code>res: EngineResources</code> field to <code>EngineExecutor</code> (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/602">#602</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/bbcfc21deea430f82aac6c268ffea61587173060"><code>bbcfc21</code></a> Refactor <code>Engine</code> internals (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/601">#601</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/3186c023210a537d0fd70517942a1ebd0c5ad3f7"><code>3186c02</code></a> Return <code>()</code> from <code>CallResults</code> for slices (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/600">#600</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/8965c9af96beb189919c0a2aa306a8ae111141ad"><code>8965c9a</code></a> Refactor FuncType verification (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/599">#599</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/2b5a48618fa9acb1d36e91ba9325623d6858e0e6"><code>2b5a486</code></a> CLI: Improve CLI parsing (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/596">#596</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/da8e4a694054ea218b316c31f28aae5494a42119"><code>da8e4a6</code></a> Allow host functions to call Wasm functions (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/590">#590</a>)</li> <li><a href="https://github.com/paritytech/wasmi/commit/f82ed77000b520046918b4e75cd733a2a7650d5b"><code>f82ed77</code></a> Fix duplicated imported linear memories and tables (<a href="https://github-redirect.dependabot.com/paritytech/wasmi/issues/593">#593</a>)</li> <li>Additional commits viewable in <a href="https://github.com/paritytech/wasmi/compare/v0.20.0...v0.21.0">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alexander Theißen <alex.theissen@me.com>
172 lines
5.4 KiB
Rust
172 lines
5.4 KiB
Rust
use std::{
|
|
fs::{read, read_dir, ReadDir},
|
|
path::PathBuf,
|
|
};
|
|
use wasm_instrument::{
|
|
gas_metering::{self, host_function, mutable_global, ConstantCostRules},
|
|
inject_stack_limiter,
|
|
parity_wasm::{deserialize_buffer, elements::Module, serialize},
|
|
};
|
|
|
|
fn fixture_dir() -> PathBuf {
|
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
path.push("benches");
|
|
path.push("fixtures");
|
|
path
|
|
}
|
|
|
|
use gas_metering::Backend;
|
|
fn gas_metered_mod_len<B: Backend>(orig_module: Module, backend: B) -> (Module, usize) {
|
|
let module = gas_metering::inject(orig_module, backend, &ConstantCostRules::default()).unwrap();
|
|
let bytes = serialize(module.clone()).unwrap();
|
|
let len = bytes.len();
|
|
(module, len)
|
|
}
|
|
|
|
fn stack_limited_mod_len(module: Module) -> (Module, usize) {
|
|
let module = inject_stack_limiter(module, 128).unwrap();
|
|
let bytes = serialize(module.clone()).unwrap();
|
|
let len = bytes.len();
|
|
(module, len)
|
|
}
|
|
|
|
struct InstrumentedWasmResults {
|
|
filename: String,
|
|
original_module_len: usize,
|
|
stack_limited_len: usize,
|
|
gas_metered_host_fn_len: usize,
|
|
gas_metered_mut_glob_len: usize,
|
|
gas_metered_host_fn_then_stack_limited_len: usize,
|
|
gas_metered_mut_glob_then_stack_limited_len: usize,
|
|
}
|
|
|
|
fn size_overheads_all(files: ReadDir) -> Vec<InstrumentedWasmResults> {
|
|
files
|
|
.map(|entry| {
|
|
let entry = entry.unwrap();
|
|
let filename = entry.file_name().into_string().unwrap();
|
|
|
|
let (original_module_len, orig_module) = {
|
|
let bytes = match entry.path().extension().unwrap().to_str() {
|
|
Some("wasm") => read(entry.path()).unwrap(),
|
|
Some("wat") =>
|
|
wat::parse_bytes(&read(entry.path()).unwrap()).unwrap().into_owned(),
|
|
_ => panic!("expected fixture_dir containing .wasm or .wat files only"),
|
|
};
|
|
|
|
let len = bytes.len();
|
|
let module: Module = deserialize_buffer(&bytes).unwrap();
|
|
(len, module)
|
|
};
|
|
|
|
let (gm_host_fn_module, gas_metered_host_fn_len) = gas_metered_mod_len(
|
|
orig_module.clone(),
|
|
host_function::Injector::new("env", "gas"),
|
|
);
|
|
|
|
let (gm_mut_global_module, gas_metered_mut_glob_len) =
|
|
gas_metered_mod_len(orig_module.clone(), mutable_global::Injector::new("gas_left"));
|
|
|
|
let stack_limited_len = stack_limited_mod_len(orig_module).1;
|
|
|
|
let (_gm_hf_sl_mod, gas_metered_host_fn_then_stack_limited_len) =
|
|
stack_limited_mod_len(gm_host_fn_module);
|
|
|
|
let (_gm_mg_sl_module, gas_metered_mut_glob_then_stack_limited_len) =
|
|
stack_limited_mod_len(gm_mut_global_module);
|
|
|
|
InstrumentedWasmResults {
|
|
filename,
|
|
original_module_len,
|
|
stack_limited_len,
|
|
gas_metered_host_fn_len,
|
|
gas_metered_mut_glob_len,
|
|
gas_metered_host_fn_then_stack_limited_len,
|
|
gas_metered_mut_glob_then_stack_limited_len,
|
|
}
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn calc_size_overheads() -> Vec<InstrumentedWasmResults> {
|
|
let mut wasm_path = fixture_dir();
|
|
wasm_path.push("wasm");
|
|
|
|
let mut wat_path = fixture_dir();
|
|
wat_path.push("wat");
|
|
|
|
let mut results = size_overheads_all(read_dir(wasm_path).unwrap());
|
|
let results_wat = size_overheads_all(read_dir(wat_path).unwrap());
|
|
|
|
results.extend(results_wat);
|
|
|
|
results
|
|
}
|
|
|
|
/// Print the overhead of applying gas metering, stack
|
|
/// height limiting or both.
|
|
///
|
|
/// Use `cargo test print_size_overhead -- --nocapture`.
|
|
#[test]
|
|
fn print_size_overhead() {
|
|
let mut results = calc_size_overheads();
|
|
results.sort_unstable_by(|a, b| {
|
|
b.gas_metered_mut_glob_then_stack_limited_len
|
|
.cmp(&a.gas_metered_mut_glob_then_stack_limited_len)
|
|
});
|
|
|
|
for r in results {
|
|
let filename = r.filename;
|
|
let original_size = r.original_module_len / 1024;
|
|
let stack_limit = r.stack_limited_len * 100 / r.original_module_len;
|
|
let host_fn = r.gas_metered_host_fn_len * 100 / r.original_module_len;
|
|
let mut_glob = r.gas_metered_mut_glob_len * 100 / r.original_module_len;
|
|
let host_fn_sl = r.gas_metered_host_fn_then_stack_limited_len * 100 / r.original_module_len;
|
|
let mut_glob_sl =
|
|
r.gas_metered_mut_glob_then_stack_limited_len * 100 / r.original_module_len;
|
|
|
|
println!(
|
|
"{filename:30}: orig = {original_size:4} kb, stack_limiter = {stack_limit} %, \
|
|
gas_metered_host_fn = {host_fn} %, both = {host_fn_sl} %,\n \
|
|
{:69} gas_metered_mut_global = {mut_glob} %, both = {mut_glob_sl} %",
|
|
""
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Compare module size overhead of applying gas metering with two methods.
|
|
///
|
|
/// Use `cargo test print_gas_metered_sizes -- --nocapture`.
|
|
#[test]
|
|
fn print_gas_metered_sizes() {
|
|
let overheads = calc_size_overheads();
|
|
let mut results = overheads
|
|
.iter()
|
|
.map(|r| {
|
|
let diff = (r.gas_metered_mut_glob_len * 100 / r.gas_metered_host_fn_len) as i32 - 100;
|
|
(diff, r)
|
|
})
|
|
.collect::<Vec<(i32, &InstrumentedWasmResults)>>();
|
|
results.sort_unstable_by(|a, b| b.0.cmp(&a.0));
|
|
|
|
println!(
|
|
"| {:28} | {:^16} | gas metered/host fn | gas metered/mut global | size diff |",
|
|
"fixture", "original size",
|
|
);
|
|
println!("|{:-^30}|{:-^18}|{:-^21}|{:-^24}|{:-^11}|", "", "", "", "", "",);
|
|
for r in results {
|
|
let filename = &r.1.filename;
|
|
let original_size = &r.1.original_module_len / 1024;
|
|
let host_fn = &r.1.gas_metered_host_fn_len / 1024;
|
|
let mut_glob = &r.1.gas_metered_mut_glob_len / 1024;
|
|
let host_fn_percent = &r.1.gas_metered_host_fn_len * 100 / r.1.original_module_len;
|
|
let mut_glob_percent = &r.1.gas_metered_mut_glob_len * 100 / r.1.original_module_len;
|
|
let host_fn = format!("{host_fn} kb ({host_fn_percent:}%)");
|
|
let mut_glob = format!("{mut_glob} kb ({mut_glob_percent:}%)");
|
|
let diff = &r.0;
|
|
println!(
|
|
"| {filename:28} | {original_size:13} kb | {host_fn:>19} | {mut_glob:>22} | {diff:+8}% |"
|
|
);
|
|
}
|
|
}
|