Skip to main content

sim/loaders/
registry.rs

1use sim_kernel::{CatalogSource, LoaderRegistry, Symbol};
2#[cfg(feature = "wasm")]
3use std::sync::Arc;
4
5use sim_kernel::{Cx, Lib, LibLoader, LibSource, Result};
6
7#[cfg(all(feature = "dynamic-native", not(target_arch = "wasm32")))]
8use super::NativeDylibLoader;
9#[cfg(feature = "wasm")]
10use super::WasmLoader;
11#[cfg(feature = "codec-binary")]
12use super::binary_pack::BinaryPackLoader;
13#[cfg(feature = "codec-lisp")]
14use super::source::LispSourceLoader;
15
16/// Builds a loader registry with the standard loaders for the enabled features.
17pub fn standard_loader_registry() -> LoaderRegistry {
18    standard_loader_registry_with_sources(std::iter::empty::<(Symbol, CatalogSource)>())
19}
20
21/// Builds the standard loader registry and seeds it with catalog sources.
22pub fn standard_loader_registry_with_sources(
23    sources: impl IntoIterator<Item = (Symbol, CatalogSource)>,
24) -> LoaderRegistry {
25    let mut registry = LoaderRegistry::new().with_loader(HostLoader);
26    #[cfg(all(feature = "dynamic-native", not(target_arch = "wasm32")))]
27    {
28        registry.add_loader(NativeDylibLoader);
29    }
30    #[cfg(feature = "codec-binary")]
31    {
32        registry.add_loader(BinaryPackLoader);
33    }
34    #[cfg(feature = "codec-lisp")]
35    {
36        registry.add_loader(LispSourceLoader::default());
37    }
38    for (symbol, source) in sources {
39        registry.add_source(symbol, source);
40    }
41    registry
42}
43
44/// Builds the standard loader registry and adds a wasm loader backed by
45/// `runtime`.
46#[cfg(feature = "wasm")]
47pub fn standard_loader_registry_with_wasm(
48    runtime: Arc<dyn crate::wasm_abi::WasmRuntime>,
49) -> LoaderRegistry {
50    standard_loader_registry_with_wasm_and_sources(
51        runtime,
52        std::iter::empty::<(Symbol, CatalogSource)>(),
53    )
54}
55
56/// Builds the standard loader registry with a wasm loader and catalog sources.
57#[cfg(feature = "wasm")]
58pub fn standard_loader_registry_with_wasm_and_sources(
59    runtime: Arc<dyn crate::wasm_abi::WasmRuntime>,
60    sources: impl IntoIterator<Item = (Symbol, CatalogSource)>,
61) -> LoaderRegistry {
62    let mut registry = standard_loader_registry_with_sources(sources);
63    registry.add_loader(WasmLoader::new(runtime));
64    registry
65}
66
67/// Loader for libs supplied directly as in-process host objects.
68#[derive(Default)]
69pub struct HostLoader;
70
71impl LibLoader for HostLoader {
72    fn can_load(&self, source: &LibSource) -> bool {
73        matches!(source, LibSource::Host(_))
74    }
75
76    fn load(&self, _cx: &mut Cx, source: LibSource) -> Result<Box<dyn Lib>> {
77        match source {
78            LibSource::Host(lib) => Ok(lib),
79            _ => Err(sim_kernel::Error::HostError(
80                "host loader received non-host source".to_owned(),
81            )),
82        }
83    }
84
85    fn inspect_manifest(
86        &self,
87        _cx: &mut Cx,
88        source: &LibSource,
89    ) -> Result<Option<sim_kernel::LibManifest>> {
90        match source {
91            LibSource::Host(lib) => Ok(Some(lib.manifest())),
92            _ => Ok(None),
93        }
94    }
95}