Skip to main content

memlink_runtime/ffi/
loader.rs

1//! Module loader - dynamic library loading via libloading.
2
3use libloading::Library;
4use std::path::Path;
5
6use crate::error::{Error, Result};
7use crate::ffi::symbols::{LibHandle, ModuleSymbols, ModuleCallFn, ModuleInitFn, ModuleShutdownFn};
8use crate::resolver::ArtifactHandle;
9
10pub struct ModuleLoader {
11    _private: (),
12}
13
14impl ModuleLoader {
15    pub fn new() -> Self {
16        ModuleLoader { _private: () }
17    }
18
19    pub fn load(&self, artifact: ArtifactHandle) -> Result<crate::instance::ModuleInstance> {
20        let path = artifact.path().to_path_buf();
21
22        let library = unsafe { Self::dlopen(&path)? };
23        let symbols = unsafe { Self::load_symbols(library.inner())? };
24
25        Ok(crate::instance::ModuleInstance::new(
26            library.clone(),
27            symbols,
28            path,
29        ))
30    }
31
32    unsafe fn dlopen(path: &Path) -> Result<LibHandle> {
33        Library::new(path)
34            .map(LibHandle::new)
35            .map_err(|e| {
36                Error::LibraryLoadFailed(format!(
37                    "Failed to load library at '{}': {}",
38                    path.display(),
39                    e
40                ))
41            })
42    }
43
44    unsafe fn load_symbols(library: &Library) -> Result<ModuleSymbols<'_>> {
45        let memlink_init: libloading::Symbol<ModuleInitFn> = library
46            .get(b"memlink_init\0")
47            .map_err(|e| {
48                Error::SymbolNotFound(format!("memlink_init: {}", e))
49            })?;
50
51        let memlink_call: libloading::Symbol<ModuleCallFn> = library
52            .get(b"memlink_call\0")
53            .map_err(|e| {
54                Error::SymbolNotFound(format!("memlink_call: {}", e))
55            })?;
56
57        let memlink_shutdown: libloading::Symbol<ModuleShutdownFn> = library
58            .get(b"memlink_shutdown\0")
59            .map_err(|e| {
60                Error::SymbolNotFound(format!("memlink_shutdown: {}", e))
61            })?;
62
63        Ok(ModuleSymbols::new(
64            memlink_init,
65            memlink_call,
66            memlink_shutdown,
67        ))
68    }
69}
70
71impl Default for ModuleLoader {
72    fn default() -> Self {
73        Self::new()
74    }
75}