From 963ddd26a89490458e31d9d553dffafe5e350e96 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 29 Jan 2024 22:38:06 +0100 Subject: chore: add more examples, refactoring Signed-off-by: Henry Gressmann --- examples/archive.rs | 29 +++++++++++++++++++++++++++++ examples/linking.rs | 41 +++++++++++++++++++++++++++++++++++++++++ examples/simple.rs | 22 ++++++++++++++++++++++ examples/wasm-rust.rs | 16 ++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 examples/archive.rs create mode 100644 examples/linking.rs create mode 100644 examples/simple.rs (limited to 'examples') diff --git a/examples/archive.rs b/examples/archive.rs new file mode 100644 index 0000000..7c93205 --- /dev/null +++ b/examples/archive.rs @@ -0,0 +1,29 @@ +use color_eyre::eyre::Result; +use tinywasm::{parser::Parser, types::TinyWasmModule, Module, Store}; + +const WASM: &str = r#" +(module + (func $add (param $lhs i32) (param $rhs i32) (result i32) + local.get $lhs + local.get $rhs + i32.add) + (export "add" (func $add))) +"#; + +fn main() -> Result<()> { + let wasm = wat::parse_str(WASM).expect("failed to parse wat"); + let module = Parser::default().parse_module_bytes(&wasm)?; + let twasm = module.serialize_twasm(); + + // now, you could e.g. write twasm to a file called `add.twasm` + // and load it later in a different program + + let module: Module = TinyWasmModule::from_twasm(&twasm)?.into(); + let mut store = Store::default(); + let instance = module.instantiate(&mut store, None)?; + let add = instance.exported_func::<(i32, i32), i32>(&store, "add")?; + + assert_eq!(add.call(&mut store, (1, 2))?, 3); + + Ok(()) +} diff --git a/examples/linking.rs b/examples/linking.rs new file mode 100644 index 0000000..f278266 --- /dev/null +++ b/examples/linking.rs @@ -0,0 +1,41 @@ +use color_eyre::eyre::Result; +use tinywasm::{Module, Store}; + +const WASM_ADD: &str = r#" +(module + (func $add (param $lhs i32) (param $rhs i32) (result i32) + local.get $lhs + local.get $rhs + i32.add) + (export "add" (func $add))) +"#; + +const WASM_IMPORT: &str = r#" +(module + (import "adder" "add" (func $add (param i32 i32) (result i32))) + (func $main (result i32) + i32.const 1 + i32.const 2 + call $add) + (export "main" (func $main)) +) +"#; + +fn main() -> Result<()> { + let wasm_add = wat::parse_str(WASM_ADD).expect("failed to parse wat"); + let wasm_import = wat::parse_str(WASM_IMPORT).expect("failed to parse wat"); + + let add_module = Module::parse_bytes(&wasm_add)?; + let import_module = Module::parse_bytes(&wasm_import)?; + + let mut store = Store::default(); + let add_instance = add_module.instantiate(&mut store, None)?; + + let mut imports = tinywasm::Imports::new(); + imports.link_module("adder", add_instance.id())?; + let import_instance = import_module.instantiate(&mut store, Some(imports))?; + + let main = import_instance.exported_func::<(), i32>(&store, "main")?; + assert_eq!(main.call(&mut store, ())?, 3); + Ok(()) +} diff --git a/examples/simple.rs b/examples/simple.rs new file mode 100644 index 0000000..6f79c0f --- /dev/null +++ b/examples/simple.rs @@ -0,0 +1,22 @@ +use color_eyre::eyre::Result; +use tinywasm::{Module, Store}; + +const WASM: &str = r#" +(module + (func $add (param $lhs i32) (param $rhs i32) (result i32) + local.get $lhs + local.get $rhs + i32.add) + (export "add" (func $add))) +"#; + +fn main() -> Result<()> { + let wasm = wat::parse_str(WASM).expect("failed to parse wat"); + let module = Module::parse_bytes(&wasm)?; + let mut store = Store::default(); + let instance = module.instantiate(&mut store, None)?; + let add = instance.exported_func::<(i32, i32), i32>(&store, "add")?; + + assert_eq!(add.call(&mut store, (1, 2))?, 3); + Ok(()) +} diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs index 112222c..b57a1da 100644 --- a/examples/wasm-rust.rs +++ b/examples/wasm-rust.rs @@ -1,6 +1,22 @@ use color_eyre::eyre::Result; use tinywasm::{Extern, FuncContext, Imports, MemoryStringExt, Module, Store}; +/// Examples of using WebAssembly compiled from Rust with tinywasm. +/// +/// These examples are meant to be run with `cargo run --example wasm-rust `. +/// For example, `cargo run --example wasm-rust hello`. +/// +/// To run these, you first need to compile the Rust examples to WebAssembly: +/// +/// ```sh +/// ./examples/rust/build.sh +/// ``` +/// +/// This requires the `wasm32-unknown-unknown` target, `binaryen` and `wabt` to be installed. +/// `rustup target add wasm32-unknown-unknown`. +/// https://github.com/WebAssembly/wabt +/// https://github.com/WebAssembly/binaryen +/// fn main() -> Result<()> { let args = std::env::args().collect::>(); if args.len() < 2 { -- cgit v1.3.1