From ca6c66af87106b097a599e344d5c0cb538250abb Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 3 Apr 2026 00:36:57 +0200 Subject: feat: add resumable calls / fuel tracking Signed-off-by: Henry --- examples/resumable.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ examples/rust/Cargo.toml | 1 + examples/rust/build.sh | 15 ++++++++++----- examples/wasm-rust.rs | 14 +++++++------- 4 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 examples/resumable.rs (limited to 'examples') diff --git a/examples/resumable.rs b/examples/resumable.rs new file mode 100644 index 0000000..6838e20 --- /dev/null +++ b/examples/resumable.rs @@ -0,0 +1,46 @@ +use eyre::Result; +use tinywasm::{ExecProgress, Module, Store}; + +const WASM: &str = r#" +(module + (func (export "count_down") (param $n i32) (result i32) + (local $cur i32) + local.get $n + local.set $cur + block + loop + local.get $cur + i32.eqz + br_if 1 + local.get $cur + i32.const 1 + i32.sub + local.set $cur + br 0 + end + end + local.get $cur)) +"#; + +fn main() -> Result<()> { + let wasm = wat::parse_str(WASM)?; + let module = Module::parse_bytes(&wasm)?; + let mut store = Store::default(); + let instance = module.instantiate(&mut store, None)?; + let count_down = instance.exported_func::(&store, "count_down")?; + + let mut execution = count_down.call_resumable(&mut store, 10_000)?; + let fuel_per_round = 128; + let mut fuel_rounds = 0; + + let result = loop { + fuel_rounds += 1; + match execution.resume_with_fuel(fuel_per_round)? { + ExecProgress::Completed(value) => break value, + ExecProgress::Suspended => {} + } + }; + + println!("completed in {fuel_rounds} rounds of {fuel_per_round} fuel, result={result}"); + Ok(()) +} diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml index 430bcad..6bf8a8f 100644 --- a/examples/rust/Cargo.toml +++ b/examples/rust/Cargo.toml @@ -52,3 +52,4 @@ lto="fat" codegen-units=1 panic="abort" inherits="release" +strip=true diff --git a/examples/rust/build.sh b/examples/rust/build.sh index 9df5447..4574d23 100755 --- a/examples/rust/build.sh +++ b/examples/rust/build.sh @@ -2,11 +2,12 @@ cd "$(dirname "$0")" || exit bins=("host_fn" "hello" "fibonacci" "print" "tinywasm" "argon2id") +exclude_wat=("tinywasm") out_dir="./target/wasm32-unknown-unknown/wasm" dest_dir="out" -rust_features="+sign-ext,+simd128,+reference-types,+bulk-memory,+bulk-memory-opt,+multimemory,+call-indirect-overlong,+mutable-globals,+multivalue,+sign-ext,+nontrapping-fptoint,+extended-const,+tail-call" -# wasmopt_features="--enable-reference-types --enable-bulk-memory --enable-mutable-globals --enable-multivalue --enable-sign-ext --enable-nontrapping-float-to-int" +rust_features="+simd128,+reference-types,+bulk-memory,+mutable-globals,+multivalue,+sign-ext,+nontrapping-fptoint" +wasmopt_features="--enable-simd --enable-reference-types --enable-bulk-memory --enable-mutable-globals --enable-multivalue --enable-sign-ext --enable-nontrapping-float-to-int --duplicate-function-elimination" # ensure out dir exists mkdir -p "$dest_dir" @@ -16,8 +17,12 @@ cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profi cp "$out_dir/tinywasm_no_std.wasm" "$dest_dir/" for bin in "${bins[@]}"; do - RUSTFLAGS="-C target-feature=$rust_features -C panic=abort" cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin "$bin" + RUSTFLAGS="-Zlocation-detail=none -Zfmt-debug=none -C target-feature=$rust_features -C panic=abort" cargo build -Z build-std=std,panic_abort -Z build-std-features="optimize_for_size" --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin "$bin" cp "$out_dir/$bin.wasm" "$dest_dir/" - # wasm-opt "$dest_dir/$bin.wasm" -o "$dest_dir/$bin.opt.wasm" -O3 $wasmopt_features -done + wasm-opt "$dest_dir/$bin.wasm" -o "$dest_dir/$bin.opt.wasm" -O3 -Oz $wasmopt_features + + if [[ ! " ${exclude_wat[@]} " =~ " $bin " ]]; then + wasm2wat "$dest_dir/$bin.wasm" -o "$dest_dir/$bin.wat" + fi +done \ No newline at end of file diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs index 4d8cdf4..49792b0 100644 --- a/examples/wasm-rust.rs +++ b/examples/wasm-rust.rs @@ -72,7 +72,7 @@ fn main() -> Result<()> { } fn tinywasm() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/tinywasm.wasm")?; + let module = Module::parse_file("./examples/rust/out/tinywasm.opt.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); @@ -87,7 +87,7 @@ fn tinywasm() -> Result<()> { } fn tinywasm_no_std() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/tinywasm_no_std.wasm")?; + let module = Module::parse_file("./examples/rust/out/tinywasm_no_std.opt.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); @@ -102,7 +102,7 @@ fn tinywasm_no_std() -> Result<()> { } fn hello() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/hello.wasm")?; + let module = Module::parse_file("./examples/rust/out/hello.opt.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); @@ -131,7 +131,7 @@ fn hello() -> Result<()> { } fn host_fn() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/host_fn.wasm")?; + let module = Module::parse_file("./examples/rust/out/host_fn.opt.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); imports.define( @@ -151,7 +151,7 @@ fn host_fn() -> Result<()> { } fn printi32() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/print.wasm")?; + let module = Module::parse_file("./examples/rust/out/print.opt.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); @@ -172,7 +172,7 @@ fn printi32() -> Result<()> { } fn fibonacci() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/fibonacci.wasm")?; + let module = Module::parse_file("./examples/rust/out/fibonacci.opt.wasm")?; let mut store = Store::default(); let instance = module.instantiate(&mut store, None)?; @@ -185,7 +185,7 @@ fn fibonacci() -> Result<()> { } fn argon2id() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/argon2id.wasm")?; + let module = Module::parse_file("./examples/rust/out/argon2id.opt.wasm")?; let mut store = Store::default(); let instance = module.instantiate(&mut store, None)?; -- cgit v1.3.1