b3_stable_structures/
vec_mem.rs

1use 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
8/// A `Memory` that is based on a vector.
9pub 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    fn write(&self, offset: u64, src: &[u8]) {
43        let n = offset
44            .checked_add(src.len() as u64)
45            .expect("write: out of bounds");
46
47        if n as usize > self.borrow().len() {
48            panic!("write: out of bounds");
49        }
50        self.borrow_mut()[offset as usize..n as usize].copy_from_slice(src);
51    }
52}
53
54impl<M: Memory> Memory for Rc<M> {
55    fn size(&self) -> u64 {
56        self.deref().size()
57    }
58    fn grow(&self, pages: u64) -> i64 {
59        self.deref().grow(pages)
60    }
61    fn read(&self, offset: u64, dst: &mut [u8]) {
62        self.deref().read(offset, dst)
63    }
64    fn write(&self, offset: u64, src: &[u8]) {
65        self.deref().write(offset, src)
66    }
67}