canic_core/ops/runtime/
memory.rs

1pub use canic_memory::{MemoryRange, MemoryRegistryEntry, MemoryRegistryView};
2
3use crate::{
4    CRATE_NAME, Error, ThisError, log,
5    log::Topic,
6    model::memory::{CANIC_MEMORY_MAX, CANIC_MEMORY_MIN},
7    ops::runtime::RuntimeOpsError,
8};
9use canic_memory::{
10    MemoryRegistryError,
11    ops::{MemoryRegistryOps as BaseRegistryOps, MemoryRegistrySummary},
12};
13
14///
15/// MemoryRegistryOpsError
16///
17
18#[derive(Debug, ThisError)]
19pub enum MemoryRegistryOpsError {
20    #[error(transparent)]
21    MemoryRegistryOpsError(#[from] MemoryRegistryError),
22}
23
24impl From<MemoryRegistryOpsError> for Error {
25    fn from(err: MemoryRegistryOpsError) -> Self {
26        RuntimeOpsError::from(err).into()
27    }
28}
29
30///
31/// MemoryRegistryOps
32/// Ops wrapper around the global memory registry.
33///
34
35pub struct MemoryRegistryOps;
36
37impl MemoryRegistryOps {
38    /// Initialise all registered memory segments and ranges.
39    ///
40    /// - Reserves the internal canic range.
41    /// - Applies all deferred range reservations.
42    /// - Applies all deferred registrations (sorted by ID).
43    /// - Emits summary logs per range.
44    pub fn init_memory() -> Result<(), Error> {
45        let summary =
46            BaseRegistryOps::init_memory(Some((CRATE_NAME, CANIC_MEMORY_MIN, CANIC_MEMORY_MAX)))
47                .map_err(MemoryRegistryOpsError::from)?;
48
49        Self::log_summary(&summary);
50
51        Ok(())
52    }
53
54    fn log_summary(summary: &MemoryRegistrySummary) {
55        if !crate::log::is_ready() {
56            // During early init, logging may not be ready; avoid accidental traps.
57            return;
58        }
59
60        let entries = &summary.entries;
61
62        for (crate_name, range) in &summary.ranges {
63            let count = entries.iter().filter(|(id, _)| range.contains(*id)).count();
64
65            log!(
66                Topic::Memory,
67                Info,
68                "💾 memory.range: {} [{}-{}] ({}/{} slots used)",
69                crate_name,
70                range.start,
71                range.end,
72                count,
73                range.end - range.start + 1,
74            );
75        }
76    }
77
78    #[must_use]
79    pub fn export() -> MemoryRegistryView {
80        BaseRegistryOps::export()
81    }
82
83    #[must_use]
84    pub fn export_ranges() -> Vec<(String, MemoryRange)> {
85        BaseRegistryOps::export_ranges()
86    }
87
88    #[must_use]
89    pub fn get(id: u8) -> Option<MemoryRegistryEntry> {
90        BaseRegistryOps::get(id)
91    }
92}