venus_core/execute/loaded_cell.rs
1//! Loaded cell management.
2//!
3//! Handles loading compiled cell dynamic libraries and keeping them
4//! alive for execution.
5
6use libloading::Library;
7
8use crate::compile::CompiledCell;
9use crate::error::{Error, Result};
10
11/// A loaded cell library ready for execution.
12pub struct LoadedCell {
13 /// The compiled cell metadata
14 pub compiled: CompiledCell,
15 /// The loaded dynamic library (kept alive for symbol validity)
16 pub(crate) library: Library,
17 /// Number of dependencies (for FFI call construction)
18 pub(crate) dep_count: usize,
19}
20
21impl LoadedCell {
22 /// Load a compiled cell's dynamic library.
23 ///
24 /// # Arguments
25 /// * `compiled` - The compiled cell metadata with dylib path
26 /// * `dep_count` - Number of dependencies (for FFI dispatch)
27 ///
28 /// # Safety
29 /// Trusts that the compiled cell was generated by our compiler
30 /// and has the correct entry point signature.
31 pub fn load(compiled: CompiledCell, dep_count: usize) -> Result<Self> {
32 // Safety: We trust the compiled cell was generated by our compiler
33 let library = unsafe { Library::new(&compiled.dylib_path) }.map_err(|e| {
34 Error::Execution(format!(
35 "Failed to load cell library {}: {}",
36 compiled.dylib_path.display(),
37 e
38 ))
39 })?;
40
41 Ok(Self {
42 compiled,
43 library,
44 dep_count,
45 })
46 }
47
48 /// Get the cell's entry symbol name.
49 pub fn entry_symbol(&self) -> &str {
50 &self.compiled.entry_symbol
51 }
52
53 /// Get the number of dependencies.
54 pub fn dep_count(&self) -> usize {
55 self.dep_count
56 }
57
58 /// Get the cell name.
59 pub fn name(&self) -> &str {
60 &self.compiled.name
61 }
62}
63
64impl Drop for LoadedCell {
65 fn drop(&mut self) {
66 // Library unload happens automatically via libloading::Library::Drop
67 // Log for debugging memory leak issues
68 tracing::debug!(
69 "Unloading cell library: {} ({})",
70 self.compiled.name,
71 self.compiled.dylib_path.display()
72 );
73 }
74}