Crate wasmtime

source ·
Expand description

§Wasmtime’s embedding API

Wasmtime is a WebAssembly engine for JIT-compiled or ahead-of-time compiled WebAssembly modules and components. More information about the Wasmtime project as a whole can be found in the documentation book whereas this documentation mostly focuses on the API reference of the wasmtime crate itself.

This crate contains an API used to interact with WebAssembly modules or WebAssembly components. For example you can compile WebAssembly, create instances, call functions, etc. As an embedder of WebAssembly you can also provide guests functionality from the host by creating host-defined functions, memories, globals, etc, which can do things that WebAssembly cannot (such as print to the screen).

The wasmtime crate is designed to be safe, efficient, and ergonomic. This enables executing WebAssembly without the embedder needing to use unsafe code, meaning that you’re guaranteed there is no undefined behavior or segfaults in either the WebAssembly guest or the host itself.

The wasmtime crate can roughly be thought of as being split into two halves:

An example of using Wasmtime to run a core WebAssembly module looks like:

use wasmtime::*;

fn main() -> wasmtime::Result<()> {
    let engine = Engine::default();

    // Modules can be compiled through either the text or binary format
    let wat = r#"
        (module
            (import "host" "host_func" (func $host_hello (param i32)))

            (func (export "hello")
                i32.const 3
                call $host_hello)
        )
    "#;
    let module = Module::new(&engine, wat)?;

    // Host functionality can be arbitrary Rust functions and is provided
    // to guests through a `Linker`.
    let mut linker = Linker::new(&engine);
    linker.func_wrap("host", "host_func", |caller: Caller<'_, u32>, param: i32| {
        println!("Got {} from WebAssembly", param);
        println!("my host state is: {}", caller.data());
    })?;

    // All wasm objects operate within the context of a "store". Each
    // `Store` has a type parameter to store host-specific data, which in
    // this case we're using `4` for.
    let mut store: Store<u32> = Store::new(&engine, 4);

    // Instantiation of a module requires specifying its imports and then
    // afterwards we can fetch exports by name, as well as asserting the
    // type signature of the function with `get_typed_func`.
    let instance = linker.instantiate(&mut store, &module)?;
    let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;

    // And finally we can call the wasm!
    hello.call(&mut store, ())?;

    Ok(())
}

§Core Concepts

There are a number of core types and concepts that are important to be aware of when using the wasmtime crate:

  • Engine - a global compilation and runtime environment for WebAssembly. An Engine is an object that can be shared concurrently across threads and is created with a Config with many knobs for configuring behavior. Compiling or executing any WebAssembly requires first configuring and creating an Engine. All Modules and Components belong to an Engine, and typically there’s one Engine per process.

  • Store - container for all information related to WebAssembly objects such as functions, instances, memories, etc. A Store<T> allows customization of the T to store arbitrary host data within a Store. This host data can be accessed through host functions via the Caller function parameter in host-defined functions. A Store is required for all WebAssembly operations, such as calling a wasm function. The Store is passed in as a “context” to methods like Func::call. Dropping a Store will deallocate all memory associated with WebAssembly objects within the Store. A Store is cheap to create and destroy and does not GC objects such as unused instances internally, so it’s intended to be short-lived (or no longer than the instances it contains).

  • Linker (or component::Linker) - host functions are defined within a linker to provide them a string-based name which can be looked up when instantiating a WebAssembly module or component. Linkers are traditionally populated at startup and then reused for all future instantiations of all instances, assuming the set of host functions does not change over time. Host functions are Fn(..) + Send + Sync and typically do not close over mutable state. Instead it’s recommended to store mutable state in the T of Store<T> which is accessed through Caller<'_, T> provided to host functions.

  • Module (or Component) - a compiled WebAssembly module or component. These structures contain compiled executable code from a WebAssembly binary which is ready to execute after being instantiated. These are expensive to create as they require compilation of the input WebAssembly. Modules and components are safe to share across threads, however. Modules and components can additionally be serialized into a list of bytes to later be deserialized quickly. This enables JIT-style compilation through constructors such as Module::new and AOT-style compilation by having the compilation process use Module::serialize and the execution process use Module::deserialize.

  • Instance (or component::Instance) - an instantiated WebAssembly module or component. An instance is where you can actually acquire a Func (or component::Func) from, for example, to call.

  • Func (or component::Func) - a WebAssembly function. This can be acquired as the export of an Instance to call WebAssembly functions, or it can be created via functions like Func::wrap to wrap host-defined functionality and give it to WebAssembly. Functions also have typed views as TypedFunc or component::TypedFunc for a more efficient calling convention.

  • Table, Global, Memory, component::Resource - other WebAssembly objects which can either be defined on the host or in wasm itself (via instances). These all have various ways of being interacted with like Func.

All “store-connected” types such as Func, Memory, etc, require the store to be passed in as a context to each method. Methods in wasmtime frequently have their first parameter as either impl AsContext or impl AsContextMut. These traits are implemented for a variety of types, allowing you to, for example, pass the following types into methods:

  • &Store<T>
  • &mut Store<T>
  • &Caller<'_, T>
  • &mut Caller<'_, T>
  • StoreContext<'_, T>
  • StoreContextMut<'_, T>

A Store is the sole owner of all WebAssembly internals. Types like Func point within the Store and require the Store to be provided to actually access the internals of the WebAssembly function, for instance.

§WASI

The wasmtime crate does not natively provide support for WASI, but you can use the wasmtime-wasi crate for that purpose. With wasmtime-wasi all WASI functions can be added to a Linker and then used to instantiate WASI-using modules. For more information see the WASI example in the documentation.

§Crate Features

The wasmtime crate comes with a number of compile-time features that can be used to customize what features it supports. Some of these features are just internal details, but some affect the public API of the wasmtime crate. Wasmtime APIs gated behind a Cargo feature should be indicated as such in the documentation.

  • runtime - Enabled by default, this feature enables executing WebAssembly modules and components. If a compiler is not available (such as cranelift) then Module::deserialize must be used, for example, to provide an ahead-of-time compiled artifact to execute WebAssembly.

  • cranelift - Enabled by default, this features enables using Cranelift at runtime to compile a WebAssembly module to native code. This feature is required to process and compile new WebAssembly modules and components.

  • cache - Enabled by default, this feature adds support for wasmtime to perform internal caching of modules in a global location. This must still be enabled explicitly through Config::cache_config_load or Config::cache_config_load_default.

  • wat - Enabled by default, this feature adds support for accepting the text format of WebAssembly in Module::new and Component::new. The text format will be automatically recognized and translated to binary when compiling a module.

  • parallel-compilation - Enabled by default, this feature enables support for compiling functions in parallel with rayon.

  • async - Enabled by default, this feature enables APIs and runtime support for defining asynchronous host functions and calling WebAssembly asynchronously. For more information see Config::async_support.

  • profiling - Enabled by default, this feature compiles in support for profiling guest code via a number of possible strategies. See Config::profiler for more information.

  • all-arch - Not enabled by default. This feature compiles in support for all architectures for both the JIT compiler and the wasmtime compile CLI command. This can be combined with Config::target to precompile modules for a different platform than the host.

  • pooling-allocator - Enabled by default, this feature adds support for PoolingAllocationConfig to pass to Config::allocation_strategy. The pooling allocator can enable efficient reuse of resources for high-concurrency and high-instantiation-count scenarios.

  • demangle - Enabled by default, this will affect how backtraces are printed and whether symbol names from WebAssembly are attempted to be demangled. Rust and C++ demanglings are currently supported.

  • coredump - Enabled by default, this will provide support for generating a core dump when a trap happens. This can be configured via Config::coredump_on_trap.

  • addr2line - Enabled by default, this feature configures whether traps will attempt to parse DWARF debug information and convert WebAssembly addresses to source filenames and line numbers.

  • debug-builtins - Enabled by default, this feature includes some built-in debugging utilities and symbols for native debuggers such as GDB and LLDB to attach to the process Wasmtime is used within. The intrinsics provided will enable debugging guest code compiled to WebAssembly. This must also be enabled via Config::debug_info as well for guests.

  • component-model - Enabled by default, this enables support for the wasmtime::component API for working with components.

  • gc - Enabled by default, this enables support for a number of WebAssembly proposals such as reference-types, function-references, and gc. Note that the implementation of the gc proposal itself is not yet complete at this time.

  • threads - Enabled by default, this enables compile-time support for the WebAssembly threads proposal, notably shared memories.

  • call-hook - Disabled by default, this enables support for the [Store::call_hook] API. This incurs a small overhead on all entries/exits from WebAssembly and may want to be disabled by some embedders.

  • memory-protection-keys - Disabled by default, this enables support for the [PoolingAllocationConfig::memory_protection_keys] API. This feature currently only works on x64 Linux and can enable compacting the virtual memory allocation for linear memories in the pooling allocator. This comes with the same overhead as the call-hook feature where entries/exits into WebAssembly will have more overhead than before.

More crate features can be found in the manifest of Wasmtime itself for seeing what can be enabled and disabled.

Re-exports§

Modules§

  • Embedding API for the Component Model
  • Unix-specific extension for the wasmtime crate.

Structs§

Enums§

  • Passed to the argument of [Store::call_hook] to indicate a state transition in the WebAssembly VM.
  • Return value of CodeBuilder::hint
  • An external item to a WebAssembly module, or a list of what can possibly be exported from a wasm module.
  • A list of all possible types which can be externally referenced from a WebAssembly module.
  • Indicator of whether a type is final or not.
  • The heap types that can Wasm can have references to.
  • Represents the module instance allocation strategy to use.
  • Configure the strategy used for versioning in serializing and deserializing crate::Module.
  • Describe the tri-state configuration of memory protection keys (MPK).
  • Indicator of whether a global value, struct’s field, or array type’s elements are mutable or not.
  • Possible optimization levels for the Cranelift codegen backend.
  • Return value from the Engine::detect_precompiled API.
  • Select which profiling technique to support.
  • A reference.
  • The storage type of a struct field or array element.
  • Possible Compilation strategies for a wasm module.
  • Representation of a WebAssembly trap and what caused it to occur.
  • What to do after returning from a callback when the engine epoch reaches the deadline for a Store during execution of a function using that store.
  • Possible runtime values that a WebAssembly module can either consume or produce.
  • A list of all possible value types in WebAssembly.
  • Result of Memory::atomic_wait32 and Memory::atomic_wait64
  • Select how wasm backtrace detailed information is handled.

Constants§

Traits§

  • A trait used to get shared access to a Store in Wasmtime.
  • A trait used to get exclusive mutable access to a Store in Wasmtime.
  • A common trait implemented by all garbage-collected reference types.
  • Internal trait implemented for all arguments that can be passed to Func::wrap and Linker::func_wrap.
  • A linear memory. This trait provides an interface for raw memory buffers which are used by wasmtime, e.g. inside [‘Memory’]. Such buffers are in principle not thread safe. By implementing this trait together with MemoryCreator, one can supply wasmtime with custom allocated host managed memory.
  • A memory creator. Can be used to provide a memory creator to wasmtime which supplies host managed memory.
  • Used by hosts to limit resource consumption of instances.
  • Used by hosts to limit resource consumption of instances, blocking asynchronously if necessary.
  • A trait implemented for GC references that are guaranteed to be rooted:
  • A stack creator. Can be used to provide a stack creator to wasmtime which supplies stacks for async support.
  • A stack memory. This trait provides an interface for raw memory buffers which are used by wasmtime inside of stacks which wasmtime executes WebAssembly in for async support. By implementing this trait together with StackCreator, one can supply wasmtime with custom allocated host managed stacks.
  • A trait used for Func::typed and with TypedFunc to represent the set of parameters for wasm functions.
  • A trait used for Func::typed and with TypedFunc to represent the set of results for wasm functions.
  • A trait implemented for types which can be returned from closures passed to Func::wrap and friends.
  • A trait implemented for types which can be arguments and results for closures passed to Func::wrap as well as parameters to Func::typed.
  • Trait implemented for various tuples made up of types which implement WasmTy that can be passed to Func::wrap_inner and [HostContext::from_closure].

Unions§

  • A “raw” and unsafe representation of a WebAssembly value.