From 8adce672578683dcc7ab62e5492e0f5dbc07a0b4 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 26 Jan 2024 18:03:59 +0100 Subject: docs: string example Signed-off-by: Henry Gressmann --- examples/rust/Cargo.toml | 4 ++++ examples/rust/build.sh | 4 ++-- examples/rust/src/hello.rs | 30 ++++++++++++++++++++---------- examples/rust/src/print.rs | 18 ++++++++++++++++++ examples/rust/src/tinywasm.rs | 2 +- examples/wasm-rust.rs | 35 ++++++++++++++++++++++++++++++++++- 6 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 examples/rust/src/print.rs (limited to 'examples') diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml index d557392..837f7f3 100644 --- a/examples/rust/Cargo.toml +++ b/examples/rust/Cargo.toml @@ -16,6 +16,10 @@ tinywasm={path="../../crates/tinywasm", features=["parser", "std"]} name="hello" path="src/hello.rs" +[[bin]] +name="print" +path="src/print.rs" + [[bin]] name="tinywasm" path="src/tinywasm.rs" diff --git a/examples/rust/build.sh b/examples/rust/build.sh index a8c587a..a13357d 100755 --- a/examples/rust/build.sh +++ b/examples/rust/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$0")" -bins=("hello" "tinywasm" "fibonacci") +bins=("hello" "fibonacci" "print" "tinywasm") exclude_wat=("tinywasm") out_dir="./target/wasm32-unknown-unknown/wasm" dest_dir="out" @@ -10,7 +10,7 @@ dest_dir="out" mkdir -p "$dest_dir" for bin in "${bins[@]}"; do - cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin "$bin" + RUSTFLAGS="-C target-feature=+reference-types -C panic=abort" cargo build --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.wasm" -O --intrinsic-lowering -O diff --git a/examples/rust/src/hello.rs b/examples/rust/src/hello.rs index 34f3c7f..6bb6d97 100644 --- a/examples/rust/src/hello.rs +++ b/examples/rust/src/hello.rs @@ -1,18 +1,28 @@ -#![no_std] #![no_main] -#[cfg(not(test))] -#[panic_handler] -fn panic(_info: &core::panic::PanicInfo) -> ! { - core::arch::wasm32::unreachable() -} - #[link(wasm_import_module = "env")] extern "C" { - fn printi32(x: i32); + fn print_utf8(location: i32, len: i32); +} + +const ARG: &[u8] = &[0u8; 100]; + +#[no_mangle] +pub unsafe extern "C" fn arg_ptr() -> i32 { + ARG.as_ptr() as i32 } #[no_mangle] -pub unsafe extern "C" fn add_and_print(lh: i32, rh: i32) { - printi32(lh + rh); +pub unsafe extern "C" fn arg_size() -> i32 { + ARG.len() as i32 +} + +#[no_mangle] +pub unsafe extern "C" fn hello(len: i32) { + let arg = core::str::from_utf8(&ARG[0..len as usize]).unwrap(); + let res = format!("Hello, {}!", arg).as_bytes().to_vec(); + + let len = res.len() as i32; + let ptr = res.leak().as_ptr() as i32; + print_utf8(ptr, len); } diff --git a/examples/rust/src/print.rs b/examples/rust/src/print.rs new file mode 100644 index 0000000..34f3c7f --- /dev/null +++ b/examples/rust/src/print.rs @@ -0,0 +1,18 @@ +#![no_std] +#![no_main] + +#[cfg(not(test))] +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + core::arch::wasm32::unreachable() +} + +#[link(wasm_import_module = "env")] +extern "C" { + fn printi32(x: i32); +} + +#[no_mangle] +pub unsafe extern "C" fn add_and_print(lh: i32, rh: i32) { + printi32(lh + rh); +} diff --git a/examples/rust/src/tinywasm.rs b/examples/rust/src/tinywasm.rs index 0fb9261..08c8135 100644 --- a/examples/rust/src/tinywasm.rs +++ b/examples/rust/src/tinywasm.rs @@ -12,7 +12,7 @@ pub extern "C" fn hello() { } fn run() -> tinywasm::Result<()> { - let module = tinywasm::Module::parse_bytes(include_bytes!("../out/hello.wasm"))?; + let module = tinywasm::Module::parse_bytes(include_bytes!("../out/print.wasm"))?; let mut store = tinywasm::Store::default(); let mut imports = tinywasm::Imports::new(); diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs index 3b26863..6580bd5 100644 --- a/examples/wasm-rust.rs +++ b/examples/wasm-rust.rs @@ -7,12 +7,15 @@ fn main() -> Result<()> { println!("Usage: cargo run --example wasm-rust "); println!("Available examples:"); println!(" hello"); - println!(" tinywasm"); + println!(" printi32"); + println!(" fibonacci - calculate fibonacci(30)"); + println!(" tinywasm - run printi32 inside of tinywasm inside of itself"); return Ok(()); } match args[1].as_str() { "hello" => hello()?, + "printi32" => printi32()?, "fibonacci" => fibonacci()?, "tinywasm" => tinywasm()?, _ => {} @@ -48,6 +51,36 @@ fn hello() -> Result<()> { let module = Module::parse_bytes(&HELLO_WASM)?; let mut store = Store::default(); + let mut imports = Imports::new(); + imports.define( + "env", + "print_utf8", + Extern::typed_func(|mut ctx: FuncContext<'_>, args: (i32, i32)| { + let mem = ctx.memory("memory")?; + let ptr = args.1 as usize; + let len = args.0 as usize; + let string = mem.load_string(ptr, len)?; + println!("{}", string); + Ok(()) + }), + )?; + + let instance = module.instantiate(&mut store, Some(imports))?; + let arg_ptr = instance.exported_func::<(), i32>(&mut store, "arg_ptr")?.call(&mut store, ())?; + let arg = b"world"; + + instance.exported_memory(&mut store, "memory")?.store(arg_ptr as usize, arg.len(), arg)?; + let hello = instance.exported_func::(&mut store, "hello")?; + hello.call(&mut store, arg.len() as i32)?; + + Ok(()) +} + +fn printi32() -> Result<()> { + const HELLO_WASM: &[u8] = include_bytes!("./rust/out/print.wasm"); + let module = Module::parse_bytes(&HELLO_WASM)?; + let mut store = Store::default(); + let mut imports = Imports::new(); imports.define( "env", -- cgit v1.3.1