Crate wasi_common

source ·
Expand description


This is Wasmtime’s legacy implementation of WASI 0.1 (Preview 1). The Wasmtime maintainers suggest all users upgrade to the implementation of WASI 0.1 and 0.2 provided by the wasmtime-wasi crate. This implementation remains in the wasmtime tree because it is required to use the wasmtime-wasi-threads crate, an implementation of the wasi-threads proposal which is not compatible with WASI 0.2.

In addition to integration with Wasmtime, this implementation may be used by other runtimes by disabling the wasmtime feature on this crate.

§The WasiFile and WasiDir traits

The WASI specification only defines one handle type, fd, on which all operations on both files and directories (aka dirfds) are defined. We believe this is a design mistake, and are architecting wasi-common to make this straightforward to correct in future snapshots of WASI. Wasi-common internally treats files and directories as two distinct resource types in the table - Box<dyn WasiFile> and Box<dyn WasiDir>. The snapshot 0 and 1 interfaces via fd will attempt to downcast a table element to one or both of these interfaces depending on what is appropriate - e.g. fd_close operates on both files and directories, fd_read only operates on files, and fd_readdir only operates on directories. The WasiFile and WasiDir traits are defined by wasi-common in terms of types defined directly in the crate’s source code (I decided it should NOT those generated by the wiggle proc macros, see snapshot architecture below), as well as the cap_std::time family of types. And, importantly, wasi-common itself provides no implementation of WasiDir, and only two trivial implementations of WasiFile on the crate::pipe::{ReadPipe, WritePipe} types, which in turn just delegate to std::io::{Read, Write}. In order for wasi-common to access the local filesystem at all, you need to provide WasiFile and WasiDir impls through either the new wasi-cap-std-sync crate found at crates/wasi-common/cap-std-sync - see the section on that crate below - or by providing your own implementation from elsewhere.

This design makes it possible for wasi-common embedders to statically reason about access to the local filesystem by examining what impls are linked into an application. We found that this separation of concerns also makes it pretty enjoyable to write alternative implementations, e.g. a virtual filesystem.

Implementations of the WasiFile and WasiDir traits are provided for synchronous embeddings (i.e. Config::async_support(false)) in wasi_common::sync and for Tokio embeddings in wasi_common::tokio.

§Traits for the rest of WASI’s features

Other aspects of a WASI implementation are not yet considered resources and accessed by handle. We plan to correct this design deficiency in WASI in the future, but for now we have designed the following traits to provide embedders with the same sort of implementation flexibility they get with WasiFile/WasiDir:

  • Timekeeping: WasiSystemClock and WasiMonotonicClock provide the two interfaces for a clock. WasiSystemClock represents time as a cap_std::time::SystemTime, and WasiMonotonicClock represents time as cap_std::time::Instant. * Randomness: we re-use the cap_rand::RngCore trait to represent a randomness source. A trivial Deterministic impl is provided. * Scheduling: The WasiSched trait abstracts over the sched_yield and poll_oneoff functions.

Users can provide implementations of each of these interfaces to the WasiCtx::builder(...) function. The wasi_cap_std_sync::WasiCtxBuilder::new() function uses this public interface to plug in its own implementations of each of these resources.



  • Virtual pipes.
  • One goal of wasi-common is for multiple WASI snapshots to provide an interface to the same underlying crate::WasiCtx. This provides us a path to evolve WASI by allowing the same WASI Command to import functions from different snapshots - e.g. the user could use Rust’s std which imports snapshot 1, but also depend directly on the wasi crate which imports some future snapshot 2. Right now, this amounts to supporting snapshot 1 and “snapshot 0” aka wasi_unstable at once.
  • The wasi-cap-std-sync crate provides impl of WasiFile and WasiDir in terms of cap_std::fs::{File, Dir}. These types provide sandboxed access to the local filesystem on both Unix and Windows.


  • An error returned from the proc_exit host syscall.
  • An Arc-wrapper around the wasi-common context to allow mutable access to the file descriptor table. This wrapper is only necessary due to the signature of fd_fdstat_set_flags; if that changes, there are a variety of improvements that can be made (TODO:



  • The core of a random number generator.


  • Exit the process with a conventional OS error code as long as Wasmtime understands the error. If the error is not an I32Exit or Trap, return the error back to the caller for it to decide what to do.