Skip to main content

ic_memory/runtime/
backing.rs

1use ic_stable_structures::{Memory, memory_manager::VirtualMemory};
2use std::rc::Rc;
3
4///
5/// RuntimeMemory
6///
7/// Cloneable virtual memory opened through a runtime's committed authority.
8/// Implements [`Memory`] for stable structures without exposing the backing
9/// memory or an alternate manager. Cloning does not require `M: Clone`.
10/// Reads delegate to the upstream memory implementation, including its
11/// optimized support for uninitialized destinations through `Memory::read_unsafe`.
12///
13
14pub struct RuntimeMemory<M: Memory>(pub(super) VirtualMemory<Rc<M>>);
15
16impl<M: Memory> Clone for RuntimeMemory<M> {
17    fn clone(&self) -> Self {
18        Self(self.0.clone())
19    }
20}
21
22impl<M: Memory> Memory for RuntimeMemory<M> {
23    fn size(&self) -> u64 {
24        self.0.size()
25    }
26    fn grow(&self, pages: u64) -> i64 {
27        self.0.grow(pages)
28    }
29    fn read(&self, offset: u64, dst: &mut [u8]) {
30        self.0.read(offset, dst);
31    }
32    #[allow(
33        unsafe_code,
34        reason = "delegate the upstream raw-read contract unchanged"
35    )]
36    unsafe fn read_unsafe(&self, offset: u64, dst: *mut u8, count: usize) {
37        // SAFETY: The caller supplies a valid destination disjoint from this
38        // memory and its backing. Forwarding preserves the pointer and count;
39        // VirtualMemory owns bucket translation and initializes the destination
40        // on success. After a panic, initialization must not be assumed.
41        unsafe { self.0.read_unsafe(offset, dst, count) }
42    }
43    fn write(&self, offset: u64, src: &[u8]) {
44        self.0.write(offset, src);
45    }
46}