### Concurrent Function Call Example Setup Source: https://docs.wasmtime.dev/api/src/wasmtime/runtime/component/concurrent/func.rs.html Example setup for using StoreContextMut::run_concurrent to obtain an Accessor for concurrent calls. ```rust 89 /// # use { 90 /// # wasmtime::{ 91 /// # error::{Result}, 92 /// # component::{Component, Linker, ResourceTable}, 93 /// # Config, Engine, Store 94 /// # }, 95 /// # }; 96 /// # 97 /// # struct Ctx { table: ResourceTable } 98 /// # 99 /// # async fn foo() -> Result<()> { 100 /// # let mut config = Config::new(); 101 /// # let engine = Engine::new(&config)?; 102 /// # let mut store = Store::new(&engine, Ctx { table: ResourceTable::new() }); 103 /// # let mut linker = Linker::new(&engine); ``` -------------------------------- ### start method: error path and pipe setup Source: https://docs.wasmtime.dev/api/src/wasmtime_wasi_tls/p3/host.rs.html Handles the error case in the start method by returning a ready result with the error, and sets up pipes and channels for the TLS connection, spawning a task to combine results. ```rust let result = ResultProducer::ready(getter, Err(err)); return Ok(( StreamReader::new(&mut store, cleartext)?, FutureReader::new(&mut store, result)?, )); } } let (ciphertext_reader, ciphertext_writer) = pipe::pipe(); let (ciphertext_result_tx, ciphertext_result_rx) = oneshot::channel(); let (cleartext_result_tx, cleartext_result_rx) = oneshot::channel(); let (recv_result_tx, recv_result_rx) = oneshot::channel(); let connection = { let ctx = store.get(); let connector = ctx.table.get_mut(&this)?; connector.recv = Some(ciphertext_reader); connector.connection.clone() }; ciphertext.pipe( &mut store, AsyncWriteConsumer::new(ciphertext_writer, ciphertext_result_tx), )?; let cleartext = AsyncReadProducer::new(connection, cleartext_result_tx); store.spawn(FnTask(async move || { let ciphertext_result = match ciphertext_result_rx.await? { // Let the TLS implementation know the transport is closed. // Most likely, `shutdown` will be entirely synchronous and // complete immediately, but awaiting it anyway to adhere to // the AsyncWrite contract: Ok(mut inner) => inner.shutdown().await, Err(e) => Err(e), }; let cleartext_result = cleartext_result_rx.await?.map(drop); let combined_result = cleartext_result .and(ciphertext_result) .map_err(|e| Error::from(e)); _ = recv_result_tx.send(combined_result); Ok(()) }))?; let result = ResultProducer::new(getter, recv_result_rx); Ok(( StreamReader::new(&mut store, cleartext)?, FutureReader::new(&mut store, result)?, )) } ``` -------------------------------- ### get example Source: https://docs.wasmtime.dev/api/cranelift_codegen/type.FxHashMap.html Returns a reference to the value corresponding to the key. The example inserts a key-value pair and asserts that get returns the correct value or None for missing keys. ```rust use std::collections::HashMap; let mut map = HashMap::new(); map.insert(1, "a"); assert_eq!(map.get(&1), Some(&"a")); assert_eq!(map.get(&2), None); ``` -------------------------------- ### Test Setup for Run Command Source: https://docs.wasmtime.dev/api/src/cranelift_reader/run_command.rs.html Example of setting up a function signature for testing a run command. ```rust #[test] fn run_a_command() { let mut signature = Signature::new(CallConv::Fast); signature.returns.push(AbiParam::new(types::I32)); ``` -------------------------------- ### Exported resources: setup with Engine, Component, Linker, Store Source: https://docs.wasmtime.dev/api/src/wasmtime/runtime/component/bindgen_examples/mod.rs.html Shows the beginning of an example that uses a world exporting a resource. It imports `Level` from the generated `exports::example::exported_resources::logging` module and includes the bindgen-generated code via `include_str!`. The example sets up an `Engine`, loads a component, creates a `Linker`, and creates a `Store` with `MyState`; the rest of the example is truncated in the source. ```rust use wasmtime::{Result, Engine, Store}; use wasmtime::component::{bindgen, Component, Linker}; use self::exports::example::exported_resources::logging::Level; #[doc = include_str!("./_6_exported_resources.rs")] struct MyState; fn main() -> Result<()> { # if true { return Ok(()) } let engine = Engine::default(); let component = Component::from_file(&engine, "./your-component.wasm")?; let linker = Linker::new(&engine); // ... this small example has no imports so nothing is added here, but // if you had imports this is where they'd go. let mut store = Store::new(&engine, MyState); ``` -------------------------------- ### Example using wasm_bench_create, wasm_bench_compile, wasm_bench_instantiate, wasm_bench_execute, and wasm_bench_free Source: https://docs.wasmtime.dev/api/wasmtime_bench_api/index.html Rust example demonstrating the full benchmark lifecycle: creating a WasmBenchConfig with timer callbacks, parsing a Wasm module, and calling compile/instantiate/execute/free. Shows that 'compilation_{start,end}' timing functions are called on successful compile, 'instantiation_{start,end}' on successful instantiate, and 'execution_{start,end}' on successful execute. Error codes use OK constant and non-null assertions. ```rust use std::ptr; use wasmtime_bench_api::*; let working_dir = std::env::current_dir().unwrap().display().to_string(); let stdout_path = "./stdout.log"; let stderr_path = "./stderr.log"; // Functions to start/end timers for compilation. // // The `compilation_timer` pointer configured in the `WasmBenchConfig` is // passed through. extern "C" fn compilation_start(timer: *mut u8) { // Start your compilation timer here. } extern "C" fn compilation_end(timer: *mut u8) { // End your compilation timer here. } // Similar for instantiation. extern "C" fn instantiation_start(timer: *mut u8) { // Start your instantiation timer here. } extern "C" fn instantiation_end(timer: *mut u8) { // End your instantiation timer here. } // Similar for execution. extern "C" fn execution_start(timer: *mut u8) { // Start your execution timer here. } extern "C" fn execution_end(timer: *mut u8) { // End your execution timer here. } let config = WasmBenchConfig { working_dir_ptr: working_dir.as_ptr(), working_dir_len: working_dir.len(), stdout_path_ptr: stdout_path.as_ptr(), stdout_path_len: stdout_path.len(), stderr_path_ptr: stderr_path.as_ptr(), stderr_path_len: stderr_path.len(), stdin_path_ptr: ptr::null(), stdin_path_len: 0, compilation_timer: ptr::null_mut(), compilation_start, compilation_end, instantiation_timer: ptr::null_mut(), instantiation_start, instantiation_end, execution_timer: ptr::null_mut(), execution_start, execution_end, execution_flags_ptr: ptr::null(), execution_flags_len: 0, }; let mut bench_api = ptr::null_mut(); unsafe { let code = wasm_bench_create(config, &mut bench_api); assert_eq!(code, OK); assert!(!bench_api.is_null()); }; let wasm = wat::parse_bytes(br#" (module (func $bench_start (import "bench" "start")) (func $bench_end (import "bench" "end")) (func $start (export "_start") call $bench_start i32.const 1 i32.const 2 i32.add drop call $bench_end ) ) "#).unwrap(); // This will call the `compilation_{start,end}` timing functions on success. let code = unsafe { wasm_bench_compile(bench_api, wasm.as_ptr(), wasm.len()) }; assert_eq!(code, OK); // This will call the `instantiation_{start,end}` timing functions on success. let code = unsafe { wasm_bench_instantiate(bench_api) }; assert_eq!(code, OK); // This will call the `execution_{start,end}` timing functions on success. let code = unsafe { wasm_bench_execute(bench_api) }; assert_eq!(code, OK); unsafe { wasm_bench_free(bench_api); } ``` -------------------------------- ### Basic Slab usage example Source: https://docs.wasmtime.dev/api/wasmtime_internal_core/slab/index.html Shows how to create a `Slab`, allocate values, access them via indexing and `get`/`get_mut`, deallocate an entry, and allocate a new one. Note that indexing panics on missing or deallocated entries, while `get` and `get_mut` provide fallible lookup. ```rust use wasmtime_internal_core::slab::Slab; let mut slab = Slab::new(); // Insert some values into the slab. let rza = slab.alloc("Robert Fitzgerald Diggs")?; let gza = slab.alloc("Gary Grice")?; let bill = slab.alloc("Bill Gates")?; // Allocated elements can be accessed infallibly via indexing (and missing and // deallocated entries will panic). assert_eq!(slab[rza], "Robert Fitzgerald Diggs"); // Alternatively, the `get` and `get_mut` methods provide fallible lookup. if let Some(genius) = slab.get(gza) { println!("The gza gza genius: {}", genius); } if let Some(val) = slab.get_mut(bill) { *val = "Bill Gates doesn't belong in this set..."; } // We can remove values from the slab. slab.dealloc(bill); // Allocate a new entry. let bill = slab.alloc("Bill Murray")?; ``` -------------------------------- ### WasiHttpView standalone server example Source: https://docs.wasmtime.dev/api/wasmtime_wasi_http/p2/index.html Standalone example that implements WasiHttpView, adds WASI HTTP interfaces to a Linker, pre-instantiates a component with ProxyPre, and serves HTTP/1.1 requests over a TCP listener. Requires a MyServer type with a ProxyPre field and a handle_request method; the example only shows the main setup and connection loop. ```rust use wasmtime::bail; use hyper::server::conn::http1; use std::sync::Arc; use tokio::net::TcpListener; use wasmtime::component::{Component, Linker, ResourceTable}; use wasmtime::{Engine, Result, Store}; use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView}; use wasmtime_wasi_http::p2::bindings::ProxyPre; use wasmtime_wasi_http::p2::bindings::http::types::Scheme; use wasmtime_wasi_http::p2::body::HyperOutgoingBody; use wasmtime_wasi_http::io::TokioIo; use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView, WasiHttpCtxView}; #[tokio::main] async fn main() -> Result<()> { let component = std::env::args().nth(1).unwrap(); // Prepare the `Engine` for Wasmtime let engine = Engine::default(); // Compile the component on the command line to machine code let component = Component::from_file(&engine, &component)?; // Prepare the `ProxyPre` which is a pre-instantiated version of the // component that we have. This will make per-request instantiation // much quicker. let mut linker = Linker::new(&engine); wasmtime_wasi::p2::add_to_linker_async(&mut linker)?; wasmtime_wasi_http::p2::add_only_http_to_linker_async(&mut linker)?; let pre = ProxyPre::new(linker.instantiate(&component)?)?; // Prepare our server state and start listening for connections. let server = Arc::new(MyServer { pre }); let listener = TcpListener::bind("127.0.0.1:8000").await?; println!("Listening on {}", listener.local_addr()?); loop { // Accept a TCP connection and serve all of its requests in a separate // tokio task. Note that for now this only works with HTTP/1.1. let (client, addr) = listener.accept().await?; println!("serving new client from {addr}"); let server = server.clone(); tokio::task::spawn(async move { if let Err(e) = http1::Builder::new() .keep_alive(true) .serve_connection( TokioIo::new(client), hyper::service::service_fn(move |req| { let server = server.clone(); async move { server.handle_request(req).await } }), ) .await { eprintln!("error serving client[{addr}]: {e:?}"); } }); } } struct MyServer { pre: ProxyPre, } ``` -------------------------------- ### Install QEMU user-mode emulation Source: https://docs.wasmtime.dev/contributing-cross-compiling.html Install qemu-user to enable running tests for cross-compiled binaries. ```bash sudo apt install qemu-user ``` -------------------------------- ### C multi-value example (multi.c) Source: https://docs.wasmtime.dev/examples-multi-value.html C example that instantiates the WebAssembly module and invokes its exported functions. Build with `cmake -B build -S examples`, `cmake --build build --target wasmtime-multi`, then `./build/wasmtime-multi`. Defines a `callback` and a `closure_callback` that set result values. ```c /* Example of instantiating of the WebAssembly module and invoking its exported function. You can build and run this example using cmake: cmake -B build -S examples cmake --build build --target wasmtime-multi ./build/wasmtime-multi Also note that this example was taken from https://github.com/WebAssembly/wasm-c-api/blob/master/example/multi.c originally */ #include #include #include #include #include #include static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap); // A function to be called from Wasm code. wasm_trap_t *callback(void *env, wasmtime_caller_t *caller, const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *results, size_t nresults) { (void)env; (void)caller; (void)nargs; (void)nresults; printf("Calling back...\n"); printf("> %" PRIu32 " %" PRIu64 "\n", args[0].of.i32, args[1].of.i64); printf("\n"); results[0] = args[1]; results[1] = args[0]; return NULL; } // A function closure. wasm_trap_t *closure_callback(void *env, wasmtime_caller_t *caller, const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *results, size_t nresults) { (void)caller; (void)args; (void)nargs; (void)nresults; int i = *(int *)env; printf("Calling back closure...\n"); printf("> %d\n", i); results[0].kind = WASMTIME_I32; results[0].of.i32 = (int32_t)i; return NULL; } int main() { // Initialize. printf("Initializing...\n"); wasm_engine_t *engine = wasm_engine_new(); wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL); wasmtime_context_t *context = wasmtime_store_context(store); ``` -------------------------------- ### C Memory Interaction Setup Source: https://docs.wasmtime.dev/examples-memory.html Initial setup for a C program to instantiate a WebAssembly module and invoke exported functions, including helper functions for error checking. ```c /* Example of instantiating of the WebAssembly module and invoking its exported function. You can build and run this example using cmake: cmake -B build -S examples cmake --build build --target wasmtime-memory ./build/wasmtime-memory Also note that this example was taken from https://github.com/WebAssembly/wasm-c-api/blob/master/example/memory.c originally */ #include #include #include #include #include #include static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap); void check(bool success) { if (!success) { printf("> Error, expected success\n"); exit(1); } } void check_call(wasmtime_context_t *store, wasmtime_func_t *func, const wasmtime_val_t *args, size_t nargs, int32_t expected) { wasmtime_val_t results[1]; wasm_trap_t *trap = NULL; wasmtime_error_t *error = wasmtime_func_call(store, func, args, nargs, results, 1, &trap); if (error != NULL || trap != NULL) exit_with_error("failed to call function", error, trap); if (results[0].of.i32 != expected) { printf("> Error on result\n"); exit(1); } } ``` -------------------------------- ### Build and run WASI example with CMake Source: https://docs.wasmtime.dev/examples-wasip1.html Commands to build and run the WASI example using CMake. ```bash cargo build --target wasm32-wasip1 -p example-wasi-wasm cmake -B build -S examples cmake --build build --target wasmtime-wasip1 ./build/wasmtime-wasip1 ``` -------------------------------- ### Build and run WASI example with Cargo and CC Source: https://docs.wasmtime.dev/examples-wasip1.html Commands to compile the WASI example on Linux using cargo and the C compiler. ```bash cargo build --target wasm32-wasip1 -p example-wasi-wasm cargo build --release -p wasmtime-c-api cc examples/wasip1/main.c \ -I crates/c-api/include \ target/release/libwasmtime.a \ -lpthread -ldl -lm \ -o wasip1 ./wasip1 ``` -------------------------------- ### Build and Run Multithreaded Wasmtime Example Source: https://docs.wasmtime.dev/examples-multithreaded-embedding.html Commands to build and execute the multithreaded C++ example using CMake. ```bash cmake -B build -S examples cmake --build build --target wasmtime-threads-cpp ./build/wasmtime-threads-cpp ``` -------------------------------- ### Standalone example: setting up WASI HTTP with ProxyPre Source: https://docs.wasmtime.dev/api/src/wasmtime_wasi_http/p2/mod.rs.html Shows how to implement `WasiHttpView`, add WASI HTTP interfaces to a linker, pre-instantiate a component with `ProxyPre`, and serve requests. Requires a component file path as a command-line argument. ```rust use wasmtime::bail; use hyper::server::conn::http1; use std::sync::Arc; use tokio::net::TcpListener; use wasmtime::component::{Component, Linker, ResourceTable}; use wasmtime::{Engine, Result, Store}; use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView}; use wasmtime_wasi_http::p2::bindings::ProxyPre; use wasmtime_wasi_http::p2::bindings::http::types::Scheme; use wasmtime_wasi_http::p2::body::HyperOutgoingBody; use wasmtime_wasi_http::io::TokioIo; use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView, WasiHttpCtxView}; #[tokio::main] async fn main() -> Result<()> { let component = std::env::args().nth(1).unwrap(); // Prepare the `Engine` for Wasmtime let engine = Engine::default(); // Compile the component on the command line to machine code let component = Component::from_file(&engine, &component)?; // Prepare the `ProxyPre` which is a pre-instantiated version of the // component that we have. This will make per-request instantiation // much quicker. let mut linker = Linker::new(&engine); wasmtime_wasi::p2::add_to_linker_async(&mut linker)?; wasmtime_wasi_http::p2::add_only_http_to_linker_async(&mut linker)?; ``` -------------------------------- ### Example: Using StoreContextMut::run_concurrent to get an Accessor Source: https://docs.wasmtime.dev/api/src/wasmtime/runtime/component/concurrent/func.rs.html?search= This example shows the setup for using StoreContextMut::run_concurrent to obtain an Accessor for concurrent calls. It includes the necessary imports and a basic store setup with a resource table. ```rust # use { # wasmtime::{ # error::{Result}, # component::{Component, Linker, ResourceTable}, # Config, Engine, Store # }, # }; # # struct Ctx { table: ResourceTable } # # async fn foo() -> Result<()> { # let mut config = Config::new(); # let engine = Engine::new(&config)?; # let mut store = Store::new(&engine, Ctx { table: ResourceTable::new() }); # let mut linker = Linker::new(&engine); ``` -------------------------------- ### Rust host example: instantiate and call wasm module Source: https://docs.wasmtime.dev/examples-hello-world.html Rust example that compiles the wasm module, creates a Store with host state, defines an imported function that prints the state and increments a counter, instantiates the module, and calls the exported 'run' function. Run with `cargo run --example hello`. ```rust //! Small example of how to instantiate a wasm module that imports one function, //! showing how you can fill in host functionality for a wasm module. // You can execute this example with `cargo run --example hello` use wasmtime::*; struct MyState { name: String, count: usize, } fn main() -> Result<()> { // First the wasm module needs to be compiled. This is done with a global // "compilation environment" within an `Engine`. Note that engines can be // further configured through `Config` if desired instead of using the // default like this is here. println!("Compiling module..."); let engine = Engine::default(); let module = Module::from_file(&engine, "examples/hello.wat")?; // After a module is compiled we create a `Store` which will contain // instantiated modules and other items like host functions. A Store // contains an arbitrary piece of host information, and we use `MyState` // here. println!("Initializing..."); let mut store = Store::new( &engine, MyState { name: "hello, world!".to_string(), count: 0, }, ); // Our wasm module we'll be instantiating requires one imported function. // the function takes no parameters and returns no results. We create a host // implementation of that function here, and the `caller` parameter here is // used to get access to our original `MyState` value. println!("Creating callback..."); let hello_func = Func::wrap(&mut store, |mut caller: Caller<'_, MyState>| { println!("Calling back..."); println!("> {}", caller.data().name); caller.data_mut().count += 1; }); // Once we've got that all set up we can then move to the instantiation // phase, pairing together a compiled module as well as a set of imports. // Note that this is where the wasm `start` function, if any, would run. println!("Instantiating module..."); let imports = [hello_func.into()]; let instance = Instance::new(&mut store, &module, &imports)?; // Next we poke around a bit to extract the `run` function from the module. println!("Extracting export..."); let run = instance.get_typed_func::<(), ()>(&mut store, "run")?; // And last but not least we can call it! println!("Calling export..."); run.call(&mut store, ())?; println!("Done."); Ok(()) } ``` -------------------------------- ### get example Source: https://docs.wasmtime.dev/api/cranelift_codegen/type.FxHashSet.html?search= Returns a reference to the value in the set if it exists. The example gets Some(&2) for 2 and None for 4. ```rust use std::collections::HashSet; let set = HashSet::from([1, 2, 3]); assert_eq!(set.get(&2), Some(&2)); assert_eq!(set.get(&4), None); ``` -------------------------------- ### Full example with main function Source: https://docs.wasmtime.dev/api/src/wasmtime_wasi_io/lib.rs.html?search= Complete example showing how to set up a linker and store with the wasi-io implementation. It creates an Engine, a Linker, and a Store with a MyState that implements IoView, then calls add_to_linker_async. The example is intended to be used in a main function that returns a Result. ```rust use wasmtime::{Engine, Result, Store}; use wasmtime::component::{ResourceTable, Linker}; use wasmtime_wasi_io::IoView; fn main() -> Result<()> { let engine = Engine::default(); let mut linker = Linker::::new(&engine); wasmtime_wasi_io::add_to_linker_async(&mut linker)?; // ... add any further functionality to `linker` if desired ... let mut store = Store::new( &engine, MyState { table: ResourceTable::new(), }, ); // ... use `linker` to instantiate within `store` ... Ok(()) } struct MyState { table: ResourceTable, } impl IoView for MyState { fn table(&mut self) -> &mut ResourceTable { &mut self.table } } ``` -------------------------------- ### Install Wasmtime via cargo-binstall Source: https://docs.wasmtime.dev/cli-install.html Use cargo-binstall to automatically fetch and install the appropriate precompiled binary for your system. ```bash cargo binstall wasmtime-cli ``` -------------------------------- ### Hello World Component Bindings Example Source: https://docs.wasmtime.dev/api/src/wasmtime/runtime/component/bindgen_examples/mod.rs.html?search= Shows how to instantiate a component with generated bindings and call a greet export. Uses HasSelf to avoid a custom projection and passes state through the linker. ```rust let mut linker = Linker::new(&engine); HelloWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; // As with the core wasm API of Wasmtime instantiation occurs within a // `Store`. The bindings structure contains an `instantiate` method which // takes the store, component, and linker. This returns the `bindings` // structure which is an instance of `HelloWorld` and supports typed access // to the exports of the component. let mut store = Store::new( &engine, MyState { name: "me".to_string(), }, ); let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?; // Here our `greet` function doesn't take any parameters for the component, // but in the Wasmtime embedding API the first argument is always a `Store`. bindings.call_greet(&mut store)?; Ok(()) } ``` -------------------------------- ### Compile, record, and inject for fib example Source: https://docs.wasmtime.dev/examples-profiling-perf.html Compiles the Fibonacci example to wasm, records it with perf and jitdump, then injects the jit data. The output shows the program result and perf record statistics. ```bash $ rustc --target wasm32-wasip1 fib.rs -O $ perf record -k mono wasmtime --profile=jitdump fib.wasm fib(42) = 267914296 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.147 MB perf.data (3435 samples) ] $ perf inject --jit --input perf.data --output perf.jit.data ``` -------------------------------- ### Instantiate and call a WebAssembly module with Wasmtime C API Source: https://docs.wasmtime.dev/examples-hello-world.html This example demonstrates the complete process of instantiating a WebAssembly module and invoking its exported function using the Wasmtime C API. It reads a .wat file, compiles it, creates a callback function, instantiates the module, and calls the 'run' export. The example includes error handling and cleanup. Build with cmake: cmake -B build -S examples, cmake --build build --target wasmtime-hello, ./build/wasmtime-hello. ```C /* Example of instantiating of the WebAssembly module and invoking its exported function. You can build and run this example using cmake: cmake -B build -S examples cmake --build build --target wasmtime-hello ./build/wasmtime-hello */ #include #include #include #include #include static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap); static wasm_trap_t *hello_callback(void *env, wasmtime_caller_t *caller, const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *results, size_t nresults) { (void)env; (void)caller; (void)args; (void)nargs; (void)results; (void)nresults; printf("Calling back...\n"); printf("> Hello World!\n"); return NULL; } int main() { int ret = 0; // Set up our compilation context. Note that we could also work with a // `wasm_config_t` here to configure what feature are enabled and various // compilation settings. printf("Initializing...\n"); wasm_engine_t *engine = wasm_engine_new(); assert(engine != NULL); // With an engine we can create a *store* which is a long-lived group of wasm // modules. Note that we allocate some custom data here to live in the store, // but here we skip that and specify NULL. wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL); assert(store != NULL); wasmtime_context_t *context = wasmtime_store_context(store); // Read our input file, which in this case is a wasm text file. FILE *file = fopen("examples/hello.wat", "r"); assert(file != NULL); fseek(file, 0L, SEEK_END); size_t file_size = ftell(file); fseek(file, 0L, SEEK_SET); wasm_byte_vec_t wat; wasm_byte_vec_new_uninitialized(&wat, file_size); if (fread(wat.data, file_size, 1, file) != 1) { printf("> Error loading module!\n"); return 1; } fclose(file); // Parse the wat into the binary wasm format wasm_byte_vec_t wasm; wasmtime_error_t *error = wasmtime_wat2wasm(wat.data, wat.size, &wasm); if (error != NULL) exit_with_error("failed to parse wat", error, NULL); wasm_byte_vec_delete(&wat); // Now that we've got our binary webassembly we can compile our module. printf("Compiling module...\n"); wasmtime_module_t *module = NULL; error = wasmtime_module_new(engine, (uint8_t *)wasm.data, wasm.size, &module); wasm_byte_vec_delete(&wasm); if (error != NULL) exit_with_error("failed to compile module", error, NULL); // Next up we need to create the function that the wasm module imports. Here // we'll be hooking up a thunk function to the `hello_callback` native // function above. Note that we can assign custom data, but we just use NULL // for now). printf("Creating callback...\n"); wasm_functype_t *hello_ty = wasm_functype_new_0_0(); wasmtime_func_t hello; wasmtime_func_new(context, hello_ty, hello_callback, NULL, NULL, &hello); wasm_functype_delete(hello_ty); // With our callback function we can now instantiate the compiled module, // giving us an instance we can then execute exports from. Note that // instantiation can trap due to execution of the `start` function, so we need // to handle that here too. printf("Instantiating module...\n"); wasm_trap_t *trap = NULL; wasmtime_instance_t instance; wasmtime_extern_t import; import.kind = WASMTIME_EXTERN_FUNC; import.of.func = hello; error = wasmtime_instance_new(context, module, &import, 1, &instance, &trap); if (error != NULL || trap != NULL) exit_with_error("failed to instantiate", error, trap); // Lookup our `run` export function printf("Extracting export...\n"); wasmtime_extern_t run; bool ok = wasmtime_instance_export_get(context, &instance, "run", 3, &run); assert(ok); assert(run.kind == WASMTIME_EXTERN_FUNC); // And call it! printf("Calling export...\n"); error = wasmtime_func_call(context, &run.of.func, NULL, 0, NULL, 0, &trap); if (error != NULL || trap != NULL) exit_with_error("failed to call function", error, trap); // Clean up after ourselves at this point printf("All finished!\n"); ret = 0; wasmtime_module_delete(module); wasmtime_store_delete(store); wasm_engine_delete(engine); return ret; } static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap) { fprintf(stderr, "error: %s\n", message); wasm_byte_vec_t error_message; if (error != NULL) { wasmtime_error_message(error, &error_message); wasmtime_error_delete(error); } else { wasm_trap_message(trap, &error_message); wasm_trap_delete(trap); } fprintf(stderr, "%.*s\n", (int)error_message.size, error_message.data); wasm_byte_vec_delete(&error_message); exit(1); } ``` -------------------------------- ### allow_unknown_exports example Source: https://docs.wasmtime.dev/api/src/wasmtime/runtime/linker.rs.html?search= Example usage of allow_unknown_exports: creates a Linker, enables unknown exports, and links a module. The example is wrapped in a doc-test with hidden setup lines. ```rust # use wasmtime::*; # fn main() -> Result<()> { # let engine = Engine::default(); # let module = Module::new(&engine, "(module)")?; # let mut store = Store::new(&engine, ()); let mut linker = Linker::new(&engine); linker.allow_unknown_exports(true); linker.module(&mut store, "mod", &module)?; # Ok(()) # } ``` -------------------------------- ### Rust multi-value example (multi.rs) Source: https://docs.wasmtime.dev/examples-multi-value.html Rust example that compiles `examples/multi.wat`, creates a host callback returning two values, and calls the exported `g` and `round_trip_many` functions. Run with `cargo run --example multi`. Uses `Func::wrap` for the callback and `get_typed_func` for multi-value calls. ```rust //! This is an example of working with multi-value modules and dealing with //! multi-value functions. //! //! Note that the `Func::wrap*` interfaces cannot be used to return multiple //! values just yet, so we need to use the more dynamic `Func::new` and //! `Func::call` methods. // You can execute this example with `cargo run --example multi` use wasmtime::Result; fn main() -> Result<()> { use wasmtime::*; println!("Initializing..."); let engine = Engine::default(); let mut store = Store::new(&engine, ()); // Compile. println!("Compiling module..."); let module = Module::from_file(&engine, "examples/multi.wat")?; // Create a host function which takes multiple parameters and returns // multiple results. println!("Creating callback..."); let callback_func = Func::wrap(&mut store, |a: i32, b: i64| -> (i64, i32) { (b + 1, a + 1) }); // Instantiate. println!("Instantiating module..."); let instance = Instance::new(&mut store, &module, &[callback_func.into()])?; // Extract exports. println!("Extracting export..."); let g = instance.get_typed_func::<(i32, i64), (i64, i32)>(&mut store, "g")?; // Call `$g`. println!("Calling export \"g\"..."); let (a, b) = g.call(&mut store, (1, 3))?; println!("Printing result..."); println!("> {a} {b}"); assert_eq!(a, 4); assert_eq!(b, 2); // Call `$round_trip_many`. println!("Calling export \"round_trip_many\"..."); let round_trip_many = instance .get_typed_func::< (i64, i64, i64, i64, i64, i64, i64, i64, i64, i64), (i64, i64, i64, i64, i64, i64, i64, i64, i64, i64), > (&mut store, "round_trip_many")?; let results = round_trip_many.call(&mut store, (0, 1, 2, 3, 4, 5, 6, 7, 8, 9))?; println!("Printing result..."); println!("> {results:?}"); assert_eq!(results, (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); Ok(()) } ``` -------------------------------- ### Main Execution Entry Point Source: https://docs.wasmtime.dev/api/src/veri/veri.rs.html?search= Initializes the environment, parses arguments with optional configuration file expansion, sets up the Rayon thread pool, and prepares the working directory. ```rust fn main() -> Result<()> { env_logger::builder().format_target(false).init(); // Expand any `--config` files into the argument list before parsing. // Configuration arguments are placed ahead of the arguments given on the // command line so that the command line takes precedence. // No configuration file is applied unless one is asked for: a run should // only ever have the filters and exclusions that are visible in its own // command line. let raw: Vec = std::env::args().collect(); let config_paths = collect_config_paths(&raw[1..]); let opts = if config_paths.is_empty() { Opts::parse() } else { let mut combined = vec![raw[0].clone()]; for path in &config_paths { combined.extend(read_config_args(path)?); } combined.extend(raw[1..].iter().cloned()); Opts::parse_from(combined) }; // Setup thread pool. // // Recursively evaluating complex spec encodings (e.g., `clz`) can overflow // the default Rayon worker thread stack size, so default to a larger stack. const DEFAULT_STACK_SIZE: usize = 256 * 1024 * 1024; let stack_size = std::env::var("ISLE_VERI_STACK_SIZE") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(DEFAULT_STACK_SIZE); rayon::ThreadPoolBuilder::new() .num_threads(opts.num_threads) .stack_size(stack_size) .build_global()?; log::info!("num theads: {}", rayon::current_num_threads()); // Resolve the working directory, defaulting to a fresh temporary directory // that lives for the duration of the run. let temp_dir = match &opts.work_dir { Some(_) => None, None => Some(tempfile::tempdir()?), }; let work_dir: &std::path::Path = match (&opts.work_dir, &temp_dir) { (Some(dir), _) => dir, (None, Some(temp)) => temp.path(), (None, None) => unreachable!(), }; // Read ISLE inputs. let inputs = opts.isle_input_files(work_dir)?; let mut runner = Runner::from_files(&inputs)?; // Scope expansion to a single root term, if requested. Otherwise the // default is to expand from every term that has rules. if let Some(root) = &opts.only_root { runner.set_root_term(root); } // Scope verification to a single named rule, if requested. This seeds ``` -------------------------------- ### starts_with example Source: https://docs.wasmtime.dev/api/cranelift_codegen/ir/instructions/struct.VariableArgs.html Checks whether the slice starts with a given prefix. The example shows true for prefixes and the slice itself, and false for non-prefixes. ```rust let v = [10, 40, 30]; assert!(v.starts_with(&[10])); assert!(v.starts_with(&[10, 40])); assert!(v.starts_with(&v)); assert!(!v.starts_with(&[50])); assert!(!v.starts_with(&[10, 50])); ``` -------------------------------- ### Install Wasmtime via Cargo Source: https://docs.wasmtime.dev/cli-install.html Compile and install the Wasmtime CLI from crates.io using Cargo. ```bash cargo install wasmtime-cli ``` -------------------------------- ### Install wasm32 targets Source: https://docs.wasmtime.dev/contributing-testing.html Install the required wasm32-wasip1 and wasm32-unknown-unknown targets using rustup to enable test compilation. ```bash rustup target add wasm32-wasip1 wasm32-unknown-unknown ``` -------------------------------- ### hello.cc: Compile, instantiate, and run a WebAssembly module with Wasmtime C++ API Source: https://docs.wasmtime.dev/c-api/hello_8cc-example.html This example reads a WebAssembly text file (examples/hello.wat), compiles it with Module::compile, creates a Store, defines a host function that prints "Calling back...", instantiates the module, extracts the exported "run" function, and calls it. It prints progress messages to stdout. Requires the wasmtime.hh header and a C++ compiler. ```cpp #include #include #include #include using namespace wasmtime; std::string readFile(const char *name) { std::ifstream watFile; watFile.open(name); std::stringstream strStream; strStream << watFile.rdbuf(); return strStream.str(); } int main() { // First the wasm module needs to be compiled. This is done with a global // "compilation environment" within an `Engine`. Note that engines can be // further configured through `Config` if desired instead of using the // default like this is here. std::cout << "Compiling module\n"; Engine engine; auto module = Module::compile(engine, readFile("examples/hello.wat")).unwrap(); // After a module is compiled we create a `Store` which will contain // instantiated modules and other items like host functions. A Store // contains an arbitrary piece of host information, and we use `MyState` // here. std::cout << "Initializing...\n"; Store store(engine); // Our wasm module we'll be instantiating requires one imported function. // the function takes no parameters and returns no results. We create a host // implementation of that function here. std::cout << "Creating callback...\n"; Func host_func = Func::wrap(store, []() { std::cout << "Calling back...\n"; }); // Once we've got that all set up we can then move to the instantiation // phase, pairing together a compiled module as well as a set of imports. // Note that this is where the wasm `start` function, if any, would run. std::cout << "Instantiating module...\n"; auto instance = Instance::create(store, module, {host_func}).unwrap(); // Next we poke around a bit to extract the `run` function from the module. std::cout << "Extracting export...\n"; auto run = std::get(*instance.get(store, "run")); // And last but not least we can call it! std::cout << "Calling export...\n"; run.call(store, {}).unwrap(); std::cout << "Done\n"; } ``` -------------------------------- ### ScalarBitSet::len example Source: https://docs.wasmtime.dev/api/cranelift_bitset/scalar/struct.ScalarBitSet.html Getting the number of elements in the set. ```rust use cranelift_bitset::ScalarBitSet; let mut bitset = ScalarBitSet::::new(); assert_eq!(bitset.len(), 0); bitset.insert(24); bitset.insert(13); bitset.insert(36); assert_eq!(bitset.len(), 3); ``` -------------------------------- ### Get OperandKind from Location Source: https://docs.wasmtime.dev/api/cranelift_assembler_x64_meta/dsl/format/enum.OperandKind.html Example of retrieving the OperandKind from a Location. ```rust let k: OperandKind = Location::imm32.kind(); ``` -------------------------------- ### HelloWorldPre::instantiate_async Source: https://docs.wasmtime.dev/api/wasmtime/component/bindgen_examples/_0_hello_world/struct.HelloWorldPre.html?search= Same as `Self::instantiate`, except with `async`. ```APIDOC ## HelloWorldPre::instantiate_async ### Description Same as `Self::instantiate`, except with `async`. ### Method `pub async fn instantiate_async(&self, store: impl AsContextMut) -> Result` ### Parameters - **store** (`impl AsContextMut`) - Required - The store to instantiate the component into. ### Returns - `Result` - The instantiated `HelloWorld` bindings, or an error if instantiation fails. ```