Coverage Report

Created: 2026-08-27 12:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/build/source/src/lib.rs
Line
Count
Source
1
//! An in-place interpreter for WebAssembly 2.0
2
//!
3
//! # General Usage
4
//!
5
//! WebAssembly (Wasm) modules must first be decoded and validated through [`decode_and_validate`],
6
//! producing a [`Module`]. This module can then be instantiated in a [`Store`] via
7
//! [`Store::module_instantiate`], creating a module instance and returning its module address,
8
//! uniquely identifying this module instance within that store.
9
//!
10
//! When a [`Store`] is initially created through [`Store::new`], it is empty. This store exposes
11
//! many other functions besides module instantiation to interact with it and objects allocated
12
//! within it. Most notably, the [`Store::invoke_simple`] and [`Store::invoke`] methods are used to
13
//! interpret Wasm code. Refer to the examples in `examples/` for more information.
14
//!
15
//! # Example
16
//!
17
//! This is an example for how to run a function exposed from a simple Wasm module (full code in
18
//! `examples/function_invocation.rs`):
19
//!
20
//! ```
21
//! # use dlr_wasm_interpreter::{ExternVal, FuncAddr, InstantiationOutcome, Module, Store, Value, decode_and_validate};
22
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
23
//! const WAT_CODE: &str = r#"
24
//! (module
25
//!     (func (export "add_one") (param $n i32) (result i32)
26
//!         local.get $n
27
//!         i32.const 1
28
//!         i32.add))
29
//! "#;
30
//!
31
//! // Use the `wat` crate to convert from the text format to bytecode
32
//! let wasm_bytecode = wat::parse_str(WAT_CODE)?;
33
//!
34
//! // Decode and validate the module
35
//! let module = decode_and_validate(&wasm_bytecode, &mut ())?;
36
//!
37
//! // Create a new empty store
38
//! let mut store = Store::new(());
39
//!
40
//! // Instantiate the module to create a module instance, returning its address
41
//! // SAFETY: There are no extern values.
42
//! let module_addr = unsafe { store.module_instantiate(&module, vec![], None) }?.module_addr;
43
//!
44
//! // Get the function address of the exported add_one function
45
//! // SAFETY: The module address was returned from the same store.
46
//! let add_one_extern = unsafe { store.instance_export(module_addr, "add_one") }?;
47
//! let add_one = add_one_extern.as_func().ok_or("add_one is not a function")?;
48
//!
49
//! // Invoke the function
50
//! // SAFETY: The function address was returned from the same store. There are also no address
51
//! // type parameters.
52
//! let return_values = unsafe { store.invoke_simple(add_one, vec![Value::I32(16)]) }?;
53
//! assert_eq!(*return_values, [Value::I32(17)]);
54
//! # Ok(())
55
//! # }
56
//! ```
57
58
#![no_std]
59
#![cfg_attr(
60
    feature = "nightly",
61
    expect(incomplete_features),
62
    feature(explicit_tail_calls),
63
    feature(rust_preserve_none_cc)
64
)]
65
66
extern crate alloc;
67
68
pub use crate::{
69
    core::{
70
        decoding::{error::DecodingError, modules::custom_section::CustomSection},
71
        rw_spinlock,
72
        structure::instructions,
73
        structure::types::{
74
            ExternType, FuncType, GlobalType, Limits, MemType, NumType, RefType, ResultType,
75
            TableType, ValType,
76
        },
77
    },
78
    execution::{
79
        config::Config,
80
        error::{RuntimeError, TrapError},
81
        instructions::dispatch::DispatchMechanism,
82
        resumable::*,
83
        runtime_structure::{
84
            addresses::*,
85
            external_values::ExternVal,
86
            memory_instances::shared_linear_memory::{Ordering, SharedLinearMemory},
87
            store::{Hostcode, InstantiationOutcome, Store},
88
            values::{ExternAddr, Ref, Value, ValueTypeMismatchError, F32, F64},
89
        },
90
    },
91
    validation::{config::ValidationConfig, decode_and_validate, error::ValidationError, Module},
92
};
93
94
pub(crate) mod core;
95
pub(crate) mod execution;
96
pub(crate) mod validation;
97
98
/// A definition for a [`Result`] using the optional [`Error`] type.
99
pub type Result<T> = ::core::result::Result<T, Error>;
100
101
/// An opt-in error type useful for merging all error types of this crate into a single type.
102
///
103
/// Note: This crate does not use this type in any public interfaces, making it optional for downstream users.
104
#[derive(Debug, PartialEq, Eq)]
105
pub enum Error {
106
    Validation(ValidationError),
107
    RuntimeError(RuntimeError),
108
}
109
110
impl From<ValidationError> for Error {
111
1
    fn from(value: ValidationError) -> Self {
112
1
        Self::Validation(value)
113
1
    }
114
}
115
116
impl From<RuntimeError> for Error {
117
1
    fn from(value: RuntimeError) -> Self {
118
1
        Self::RuntimeError(value)
119
1
    }
120
}
121
122
#[cfg(test)]
123
mod test {
124
    use crate::{core::decoding::error::DecodingError, Error, RuntimeError, ValidationError};
125
126
    #[test]
127
1
    fn error_conversion_validation_error() {
128
1
        let validation_error = ValidationError::Decoding(DecodingError::InvalidMagic);
129
1
        let error: Error = validation_error.into();
130
131
1
        assert_eq!(
132
            error,
133
            Error::Validation(ValidationError::Decoding(DecodingError::InvalidMagic))
134
        )
135
1
    }
136
137
    #[test]
138
1
    fn error_conversion_runtime_error() {
139
1
        let runtime_error = RuntimeError::ModuleNotFound;
140
1
        let error: Error = runtime_error.into();
141
142
1
        assert_eq!(error, Error::RuntimeError(RuntimeError::ModuleNotFound))
143
1
    }
144
}