Expand description
wasi_virt_layer provides a virtualization layer for WebAssembly System Interface (WASI).
This crate facilitates merging a Virtual File System (VFS) and threading mechanisms into standard WASI modules without modifying their source code in complex ways. It allows a host environment (like browsers via JavaScript bindings) to seamlessly interact with in-memory Wasm modules.
§Core Concepts
- Virtual File System (VFS): Overrides filesystem-related WASI calls to a custom virtualized implementation.
- Threading: Provides components that patch how Wasm spawns and manages threads using shared memory.
- Memory Bridge: Manages memory boundaries and host-guest interaction.
§WASI callback re-entrancy
A host-routed WASI call must not synchronously call back into the same virtualized WASI path.
For example, a virtual fd_write implementation that forwards to std::io::stderr() can
re-enter fd_write when that stderr is itself connected to the VFS. This creates an unbounded
call cycle and commonly appears as a hang or lockup.
Route such output to a terminal or host sink that bypasses the virtualized WASI ABI. During
diagnosis, enable the detect-wasi-reentrancy feature. It adds a thread-local guard around
non_recursive_wasi_snapshot_preview1! calls and traps immediately when the host path
synchronously re-enters this boundary.
Modules§
- clock
- Clock and time operations.
- file
- Virtual File System operations and definitions.
- memory
- Memory operations to bridge host and WebAssembly memory models.
- poll
- I/O polling and event waiting mechanisms.
- prelude
- Common traits, structs, and macros representing the core functionality.
- process
- Process execution and lifecycle virtualization.
- random
- Random number generation and virtualization.
- sched
- Scheduler operations.
- shared_
memory - Shared memory management for zero-copy inter-module memory access. Shared memory ABI for zero-copy inter-module memory access.
- simple_
debug - Simple, fast debugging utilities for WebAssembly execution.
- stack
- Export-stack isolation ABI and shared handoff state. Shared ABI state used by generated export-stack isolation wrappers.
- thread
- Threading support for WASI.
- wasi
- WebAssembly System Interface (WASI) modules and utilities.
- wasip1_
derive - Procedural macros for generating WASIP1 boilerplate.
Macros§
- Embedded
Files - Macro for defining constant file systems.
- __as_t
- Internal helper macro for handle
selfand other identifiers. - configure_
wasm_ stack - Configures export-stack isolation for the current module.
- export_
pseudo_ wasm - Expose a function in the generated Wasm to register structures that implement PseudoWasmTraits.
- export_
shared_ memory_ manager - Export a shared memory manager implementation. This macro creates an extern “C” function that target modules can call to register their shared memory configuration with the VFS.
- import_
wasm - By entering the names of the files to be combined, a bridge for the combination is created. You need to prepare as many Wasip1 instances on the virtual file system as the number of files to be combined.
- non_
recursive_ wasi_ snapshot_ preview1 - Typically, WASI ABI calls are made using plug!. However, there may be cases where you want to call the ABI directly from within plug!. Doing so would result in recursion. To address this, call the function through this macro. When calling a function through this macro, it becomes a proper WASI ABI call after plug is connected. This allows you to call the ABI without causing recursion.
- own_
memory - A macro to explicitly manage memory growth for multiple WebAssembly targets when the automatic memory expansion is disabled (
--own-memorymode). - plug_
args - @embedded or @dynamic Whether to import JavaScript runtime args from vfs, args is automatically imported even if you are not using it, so that you can block it
- plug_
clock - Plugs the clock ecosystem by defining necessary handlers for clock operations.
- plug_
env - @embedded or @dynamic Whether to import JavaScript runtime env from vfs, env is automatically imported even if you are not using it, so that you can block it
- plug_fs
- Plugs the file system ecosystem by defining necessary handlers. It ensures that the provided Wasm uses the given virtual file system. If self is passed, file operations performed within the VFS will also use the virtual file system. If used properly, it can even be wrapped as a component without imports. On the other hand, if plug_fs is not applied to self, file access in the VFS will use the WASI p1 ABI to access the external file system.
- plug_
poll - Plugs the poll ecosystem by defining necessary handlers.
- plug_
process - Plugs the process exit ecosystem by defining necessary handlers.
- plug_
random - Plugs the random ecosystem by defining necessary handlers.
- plug_
sched - Plugs the sched ecosystem by defining necessary handlers.
- plug_
thread - Plugs the thread ecosystem by defining necessary accessor enums and hooks. Other plug_* macros can be split and used separately, but due to the internal branching logic of this macro, only one instance of this macro can be defined per VirtualThread.
- protect_
wasm_ exports - Marks specific exports for stack protection.
- wrap_
unreachable - A macro to explicitly wrap WebAssembly’s unreachable instructions for a given Target module.
This generates internal markers interpreted by
wasi_virt_layer-cliduring generation. If you use this macro, unreachable will no longer be invoked; instead, execution immediately unwinds back to the main function or the thread entry point. This prevents the VFS from being affected by the target’s abort. By using get_flag, you can retrieve the value (the exit_code) once the unwinding is complete and control has returned to the VFS code. The value for unreachable is 1. This value is maintained per thread. For example, if you call set_flag inside proc_exit, then at the moment control returns from the VFS code (proc_exit) back to the target code, execution will immediately unwind to main. By combining these mechanisms, you can return control to the VFS at the exact moment the target WASM performs a proc_exit, and obtain the exit code.