ic_stable_structures/
vec_mem.rs1use crate::{Memory, WASM_PAGE_SIZE};
2use std::cell::RefCell;
3use std::ops::Deref;
4use std::rc::Rc;
5
6const MAX_PAGES: u64 = i64::MAX as u64 / WASM_PAGE_SIZE;
7
8pub type VectorMemory = Rc<RefCell<Vec<u8>>>;
10
11impl Memory for RefCell<Vec<u8>> {
12 fn size(&self) -> u64 {
13 self.borrow().len() as u64 / WASM_PAGE_SIZE
14 }
15
16 fn grow(&self, pages: u64) -> i64 {
17 let size = self.size();
18 match size.checked_add(pages) {
19 Some(n) => {
20 if n > MAX_PAGES {
21 return -1;
22 }
23 self.borrow_mut().resize((n * WASM_PAGE_SIZE) as usize, 0);
24 size as i64
25 }
26 None => -1,
27 }
28 }
29
30 fn read(&self, offset: u64, dst: &mut [u8]) {
31 let n = offset
32 .checked_add(dst.len() as u64)
33 .expect("read: out of bounds");
34
35 if n as usize > self.borrow().len() {
36 panic!("read: out of bounds");
37 }
38
39 dst.copy_from_slice(&self.borrow()[offset as usize..n as usize]);
40 }
41
42 unsafe fn read_unsafe(&self, offset: u64, dst: *mut u8, count: usize) {
43 let n = offset
44 .checked_add(count as u64)
45 .expect("read: out of bounds");
46
47 if n as usize > self.borrow().len() {
48 panic!("read: out of bounds");
49 }
50
51 std::ptr::copy(self.borrow().as_ptr().add(offset as usize), dst, count);
56 }
57
58 fn write(&self, offset: u64, src: &[u8]) {
59 let n = offset
60 .checked_add(src.len() as u64)
61 .expect("write: out of bounds");
62
63 if n as usize > self.borrow().len() {
64 panic!("write: out of bounds");
65 }
66 self.borrow_mut()[offset as usize..n as usize].copy_from_slice(src);
67 }
68}
69
70impl<M: Memory> Memory for Rc<M> {
71 fn size(&self) -> u64 {
72 self.deref().size()
73 }
74 fn grow(&self, pages: u64) -> i64 {
75 self.deref().grow(pages)
76 }
77 fn read(&self, offset: u64, dst: &mut [u8]) {
78 self.deref().read(offset, dst)
79 }
80 unsafe fn read_unsafe(&self, offset: u64, dst: *mut u8, count: usize) {
81 self.deref().read_unsafe(offset, dst, count)
82 }
83 fn write(&self, offset: u64, src: &[u8]) {
84 self.deref().write(offset, src)
85 }
86}