wahgex_core/compile/
state.rs

1//! This module contains type and functions related to the entire runtime state
2//! of the engine.
3
4use std::alloc::{Layout, LayoutError};
5
6use super::{
7    epsilon_closure::EpsilonClosureFunctions,
8    lookaround::{LookFunctions, LookLayout},
9    pattern::{PatternFunctions, PatternLayout},
10    sparse_set::{SparseSetFunctions, SparseSetLayout},
11    transition::{TransitionFunctions, TransitionLayout},
12    BuildError, CompileContext,
13};
14
15/// This type will be used to plan the WASM memory layout and precompute the
16/// ptr/offsets of various data structures.
17#[derive(Debug)]
18pub struct StateLayout {
19    /// The overall memory layout encompassing all state-related data
20    /// structures.
21    pub overall: Layout,
22    transition: TransitionLayout,
23    pub first_sparse_set: SparseSetLayout,
24    pub second_sparse_set: SparseSetLayout,
25    pattern: PatternLayout,
26    look: LookLayout,
27}
28
29impl StateLayout {
30    /// Creates a new `StateLayout` by sequentially arranging layouts for
31    /// various components.
32    pub fn new(ctx: &mut CompileContext) -> Result<Self, LayoutError> {
33        // Using a ZST to start the layout so that we have minimal alignment
34        // requirements
35        let overall = Layout::new::<()>();
36        let (overall, transition) = TransitionLayout::new(ctx, overall)?;
37        let (overall, first_sparse_set) = SparseSetLayout::new(ctx, overall)?;
38        let (overall, second_sparse_set) = SparseSetLayout::new(ctx, overall)?;
39        let (overall, pattern) = PatternLayout::new(ctx, overall)?;
40        let (overall, look) = LookLayout::new(ctx, overall)?;
41
42        let overall = overall.pad_to_align();
43
44        Ok(Self {
45            overall,
46            transition,
47            first_sparse_set,
48            second_sparse_set,
49            pattern,
50            look,
51        })
52    }
53}
54
55/// This struct contains all the functions for manipulating the built-in
56/// data structures.
57#[derive(Debug)]
58pub struct StateFunctions {
59    #[expect(dead_code)]
60    sparse_set: SparseSetFunctions,
61    pub epsilon_closure: EpsilonClosureFunctions,
62    pub transition: TransitionFunctions,
63    pub pattern: PatternFunctions,
64}
65
66impl StateFunctions {
67    /// Creates and registers all WebAssembly functions required for managing
68    /// the NFA runtime state.
69    pub fn new(ctx: &mut CompileContext, layout: &StateLayout) -> Result<Self, BuildError> {
70        // It shouldn't matter if we pass the first or the second sparse set, since they
71        // have the same
72        let sparse_set = SparseSetFunctions::new(ctx, &layout.first_sparse_set);
73        let look_funcs = LookFunctions::new(ctx, &layout.look)?;
74        let epsilon_closure = EpsilonClosureFunctions::new(ctx, sparse_set.insert, &look_funcs)?;
75        let transition = TransitionFunctions::new(ctx, &epsilon_closure, &layout.transition);
76        let pattern = PatternFunctions::new(ctx, &layout.pattern);
77
78        Ok(Self {
79            sparse_set,
80            epsilon_closure,
81            transition,
82            pattern,
83        })
84    }
85}