makepad_stitch/
engine.rs

1use {
2    crate::{
3        code::{CompiledCode, UncompiledCode},
4        compile::Compiler,
5        decode::DecodeError,
6        func::{Func, FuncType},
7        instance::Instance,
8        module::ModuleBuilder,
9        store::Store,
10        validate::Validator,
11    },
12    std::sync::{Arc, Mutex},
13};
14
15/// A Wasm engine.
16#[derive(Clone, Debug)]
17pub struct Engine {
18    inner: Arc<EngineInner>,
19}
20
21impl Engine {
22    /// Creates a new [`Engine`].
23    pub fn new() -> Engine {
24        Engine {
25            inner: Arc::new(EngineInner {
26                validators: Mutex::new(Pool::new()),
27                compilers: Mutex::new(Pool::new()),
28            }),
29        }
30    }
31
32    pub(crate) fn validate(
33        &self,
34        type_: &FuncType,
35        module: &ModuleBuilder,
36        code: &UncompiledCode,
37    ) -> Result<(), DecodeError> {
38        let mut validator = self.inner.validators.lock().unwrap().pop_or_default();
39        let result = validator.validate(type_, module, code);
40        self.inner.validators.lock().unwrap().push(validator);
41        result
42    }
43
44    pub(crate) fn compile(
45        &self,
46        store: &mut Store,
47        func: Func,
48        instance: &Instance,
49        code: &UncompiledCode,
50    ) -> CompiledCode {
51        let mut compiler = self.inner.compilers.lock().unwrap().pop_or_default();
52        let result = compiler.compile(store, func, instance, code);
53        self.inner.compilers.lock().unwrap().push(compiler);
54        result
55    }
56}
57
58impl Default for Engine {
59    fn default() -> Self {
60        Self::new()
61    }
62}
63
64#[derive(Debug)]
65struct EngineInner {
66    validators: Mutex<Pool<Validator>>,
67    compilers: Mutex<Pool<Compiler>>,
68}
69
70#[derive(Debug)]
71struct Pool<T> {
72    items: Vec<T>,
73}
74
75impl<T> Pool<T>
76where
77    T: Default,
78{
79    fn new() -> Self {
80        Self { items: Vec::new() }
81    }
82
83    fn pop_or_default(&mut self) -> T {
84        self.items.pop().unwrap_or_default()
85    }
86
87    fn push(&mut self, item: T) {
88        self.items.push(item);
89    }
90}