b3_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 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}