Skip to main content

herkos_runtime/
lib.rs

1//! `herkos-runtime` — Runtime library for herkos transpiled output.
2//!
3//! This crate is `#![no_std]` by default. It provides:
4//! - `IsolatedMemory<const MAX_PAGES: usize>` for Wasm linear memory
5//! - `WasmTrap` / `WasmResult<T>` for Wasm trap handling
6//! - Trait definitions for capability-based host imports (Phase 3+)
7
8#![no_std]
9
10#[cfg(feature = "alloc")]
11extern crate alloc;
12
13/// WebAssembly page size: 64 KiB per the Wasm specification.
14pub const PAGE_SIZE: usize = 65536;
15
16mod memory;
17pub use memory::IsolatedMemory;
18
19mod table;
20pub use table::{FuncRef, Table};
21
22mod module;
23pub use module::{LibraryModule, Module};
24
25mod ops;
26pub use ops::{
27    i32_div_s, i32_div_u, i32_rem_s, i32_rem_u, i32_trunc_f32_s, i32_trunc_f32_u, i32_trunc_f64_s,
28    i32_trunc_f64_u, i64_div_s, i64_div_u, i64_rem_s, i64_rem_u, i64_trunc_f32_s, i64_trunc_f32_u,
29    i64_trunc_f64_s, i64_trunc_f64_u,
30};
31
32/// Wasm execution errors — no panics, no unwinding.
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum WasmTrap {
35    /// Memory access out of bounds.
36    OutOfBounds,
37    /// Integer division by zero.
38    DivisionByZero,
39    /// Integer overflow (e.g., `i32.trunc_f64_s` on out-of-range float).
40    IntegerOverflow,
41    /// Unreachable instruction executed.
42    Unreachable,
43    /// Indirect call type mismatch (`call_indirect` signature check).
44    IndirectCallTypeMismatch,
45    /// Table access out of bounds.
46    TableOutOfBounds,
47    /// Undefined element in table.
48    UndefinedElement,
49}
50
51/// Result type for Wasm operations — `Result<T, WasmTrap>`.
52pub type WasmResult<T> = Result<T, WasmTrap>;
53
54/// Sentinel type for modules with no host imports.
55///
56/// Zero-sized — the compiler eliminates it entirely. Used as the generic parameter `H`
57/// in `Env<H>` for modules that have no host imports.
58#[derive(Clone, Copy)]
59pub struct NoHost;
60
61/// Errors that occur during module/memory/table construction.
62///
63/// These are programming errors in the transpiler, not runtime Wasm traps.
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum ConstructionError {
66    /// Initial pages exceeds MAX_PAGES for memory.
67    MemoryInitialPagesExceedsMax { initial: usize, max: usize },
68    /// Initial size exceeds MAX_SIZE for table.
69    TableInitialSizeExceedsMax { initial: usize, max: usize },
70}
71
72impl From<ConstructionError> for WasmTrap {
73    fn from(_: ConstructionError) -> Self {
74        // Construction errors are programming errors, but we map them to
75        // OutOfBounds for compatibility with the error propagation chain.
76        WasmTrap::OutOfBounds
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn wasm_trap_is_copy() {
86        let trap = WasmTrap::OutOfBounds;
87        let trap2 = trap; // Copy
88        assert_eq!(trap, trap2);
89    }
90
91    #[test]
92    fn wasm_result_ok() {
93        let result: WasmResult<i32> = Ok(42);
94        assert!(result.is_ok());
95        assert_eq!(result, Ok(42));
96    }
97
98    #[test]
99    fn wasm_result_err() {
100        let result: WasmResult<i32> = Err(WasmTrap::DivisionByZero);
101        assert!(result.is_err());
102        assert_eq!(result, Err(WasmTrap::DivisionByZero));
103    }
104}