Using WebAssembly from Rust
This document shows an example of how to embed Wasmtime using the Rust
API to execute a simple wasm program. Be sure to also check out the
full API documentation for a full listing of what the wasmtime
crate has to offer.
Creating the WebAssembly to execute
We'll just assume that you've already got a wasm file on hand for the rest of
this tutorial. To make things simple we'll also just assume you've got a
hello.wat
file which looks like this:
(module
(func (export "answer") (result i32)
i32.const 42
)
)
Here we're just exporting one function which returns an integer that we'll read from Rust.
Hello, World!
First up let's create a rust project
$ cargo new --bin wasmtime_hello
$ cd wasmtime_hello
Next you'll want to add hello.wat
to the root of your project.
We will be using the wasmtime
crate to run the wasm file. Please execute the command cargo add wasmtime
to use the latest version of the crate. The dependencies
block in the Cargo.toml
file will appear as follows:
[dependencies]
wasmtime = "19.0.0"
Next up let's write the code that we need to execute this wasm file. The simplest version of this looks like so:
We can build and execute our example with cargo run
. Note that by depending on
wasmtime
you're depending on a JIT compiler, so it may take a moment to build
all of its dependencies:
$ cargo run
Compiling ...
...
Finished dev [unoptimized + debuginfo] target(s) in 42.32s
Running `wasmtime_hello/target/debug/wasmtime_hello`
Answer: 42
and there we go! We've now executed our first WebAssembly in wasmtime
and
gotten the result back.
Importing Host Functionality
What we've just seen is a pretty small example of how to call a wasm function and take a look at the result. Most interesting wasm modules, however, are going to import some functions to do something a bit more interesting. For that you'll need to provide imported functions from Rust for wasm to call!
Let's take a look at a wasm module which imports a logging function as well as some simple arithmetic from the environment.
(module
(import "" "log" (func $log (param i32)))
(import "" "double" (func $double (param i32) (result i32)))
(func (export "run")
i32.const 0
call $log
i32.const 1
call $log
i32.const 2
call $double
call $log
)
)
This wasm module will call our "log"
import a few times and then also call the
"double"
import. We can compile and instantiate this module with code that
looks like this:
Note that there's a number of ways to define a Func
, be sure to consult its
documentation for other ways to create a host-defined function.