Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 55 additions & 11 deletions lib/src/wasm/runtime/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,18 @@ pub(crate) trait AsContextMut: AsContext {
) -> StoreContextMut<'_, Self::Data, Self::Backend>;
}

/// Storage for user data plus backend-specific runtime state.
/// Context containing the state of a WebAssembly execution, including
/// user data and backend-specific runtime state.
///
/// The `Store` is a core type in both Wasmtime and the browser shim.
/// It holds the state of the scanner (via the generic user data
/// parameter `T`, typically `ScanContext`), and registers any
/// instantiated globals, memories, or callbacks needed by the backend.
pub(crate) struct Store<T, B: RuntimeBackend> {
/// User data associated with the store.
/// User data associated with the store (e.g., `ScanContext`).
data: T,
/// Backend-specific runtime state for globals, memories and callbacks.
/// Backend-specific runtime state (e.g., references to browser memory
/// structures).
pub(crate) runtime: B::RuntimeState,
_engine: Engine,
_backend: PhantomData<B>,
Expand Down Expand Up @@ -253,10 +260,19 @@ impl<T, B: RuntimeBackend> AsContextMut for Pin<Box<Store<T, B>>> {
}
}

/// View passed to host callbacks.
/// Represents the host execution context passed as the first argument to
/// WASM host callbacks.
///
/// In both `wasmtime` and the custom browser backend, when guest WASM code calls
/// an imported host function, it yields control back to the host. The `Caller`
/// structure wraps a mutable reference to the executing [`Store`], providing
/// the host callback safe access to:
/// - The store's custom user data `T` (typically `ScanContext`), via `data()`
/// and `data_mut()`.
/// - The store context and execution backend.
#[allow(private_bounds)]
pub struct Caller<'a, T, B: RuntimeBackend> {
/// Store being used for the callback.
/// Access to the underlying `Store` context.
pub(crate) store: &'a mut Store<T, B>,
}

Expand Down Expand Up @@ -478,14 +494,25 @@ pub(crate) struct RegisteredFunc<T, B: RuntimeBackend> {
pub(crate) trampoline: HostFunc<T, B>,
}

/// Handle to a global defined in the store.
/// A backend-agnostic reference to a WebAssembly global variable defined within
/// a [`Store`].
///
/// In the browser backend, globals are backed by a JS `WebAssembly.Global`
/// object, while in the native backend they map directly to `wasmtime::Global`.
#[derive(Clone, Copy)]
pub(crate) struct Global {
/// Backend-specific global identifier.
pub(crate) id: usize,
}

/// Handle to a memory defined in the store.
/// A backend-agnostic reference to a WebAssembly linear memory defined within
/// a [`Store`].
///
/// Wasm execution relies on a primary block of linear memory for passing large
/// payloads (like the scanned file/haystack) and reading back results (like
/// matching rule bitmaps). This handle manages mutable or immutable access to
/// the memory, performing automatic synchronization with browser/JS-side
/// memory buffers when targeting the browser backend.
#[derive(Clone, Copy)]
pub(crate) struct Memory {
/// Backend-specific memory identifier.
Expand Down Expand Up @@ -522,7 +549,14 @@ pub(crate) struct DefinedExtern {
pub(crate) value: Extern,
}

/// Linker used for registering imports and instantiating modules.
/// A helper structure used to link WebAssembly modules to host functions,
/// globals, and memories.
///
/// The `Linker` serves as a registry for host imports defined in Rust (e.g.,
/// regex engines, utility functions, and global attributes). When a compiled
/// YARA-X rule module is instantiated, the `Linker` automatically links
/// these registered imports into the Wasm instance, resolving target specific
/// details behind a uniform interface.
pub(crate) struct Linker<T, B: RuntimeBackend> {
/// Functions registered in the linker.
pub(crate) functions: Vec<RegisteredFunc<T, B>>,
Expand Down Expand Up @@ -764,9 +798,14 @@ impl<B: RuntimeBackend> Module<B> {
}
}

/// Instantiated module.
/// An instantiated WebAssembly module ready for execution.
///
/// The `Instance` wraps a compiled Wasm module that has been successfully
/// linked to its host imports. It exposes exported functions, allowing the
/// caller to retrieve type-safe handles for invocation.
pub(crate) struct Instance<B: RuntimeBackend> {
/// Backend-specific instance representation.
/// Backend-specific instance representation (e.g., JS
/// `WebAssembly.Instance` or `wasmtime::Instance`).
pub(crate) inner: B::InstanceInner,
_backend: PhantomData<B>,
}
Expand All @@ -790,7 +829,12 @@ impl<B: RuntimeBackend> Instance<B> {
}
}

/// Typed function exported by an [`Instance`].
/// A strongly typed handle to a WebAssembly function exported by an
/// [`Instance`].
///
/// Calling this function invokes the compiled WASM bytecode with compile-time
/// signature checks, passing parameters and retrieving results through
/// optimized target-specific channels.
pub(crate) struct TypedFunc<P, R, B: RuntimeBackend> {
inner: B::TypedFuncHandle,
_params: PhantomData<P>,
Expand Down
42 changes: 39 additions & 3 deletions lib/src/wasm/runtime/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,43 @@
//! Runtime backend selection for generated WASM code.
//! WebAssembly execution runtime abstraction for YARA-X.
//!
//! Native builds use Wasmtime directly, while `wasm32` builds use YARA-X's
//! browser-oriented custom runtime.
//! YARA-X compiles rules into WebAssembly bytecode for high-performance
//! execution. This module provides a backend-neutral abstraction layer (shim)
//! that allows the compiler and scanner to run seamlessly on both native
//! platforms and in browser-based environments.
//!
//! ## Dual-Backend Architecture
//!
//! To support both native execution and browser sandbox environments, the
//! runtime uses a dual-backend architecture selected at compile-time:
//!
//! 1. **Native Backend (`native.rs`)**: Used for standard native targets
//! (e.g., Linux, macOS, Windows, CLI, server applications). It leverages
//! the robust, optimizing **Wasmtime** compiler and JIT engine directly.
//! 2. **Browser Backend (`browser.rs`)**: Used when compiling to WebAssembly
//! targets (e.g., `wasm32-unknown-unknown`). Since Wasmtime cannot run
//! inside the browser's Wasm sandbox, this backend provides a custom
//! implementation wrapping the host environment's built-in JavaScript
//! `WebAssembly` APIs via `wasm-bindgen`.
//!
//! ## Unified Wasmtime-like Interface
//!
//! To avoid scattering conditional compilation directives
//! (`#[cfg(target_family = "wasm")]`) throughout the compiler and scanner
//! code, this module exposes a single, unified API that matches Wasmtime's
//! standard interface. On Wasm targets, the custom shim (implemented in
//! `common.rs` and `browser.rs`) serves as a drop-in replacement for
//! Wasmtime.
//!
//! The abstraction exposes common Wasm execution types, including:
//! - [`Store`]: Manages execution state and holds user-defined data (e.g.,
//! `ScanContext`).
//! - [`Linker`]: Registers and links host-defined functions and globals into
//! Wasm modules.
//! - [`Caller`]: Exposes the execution context and mutable access to the store
//! within host callbacks.
//! - [`Memory`]: Provides structured access to Wasm linear memory.
//! - [`TypedFunc`]: Represents type-safe, callable handles to exported Wasm
//! functions.

#[cfg(target_family = "wasm")]
mod common;
Expand Down
Loading