darkfi/runtime/
memory.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19use wasmer::{MemoryView, WasmPtr};
20
21use crate::Result;
22
23pub trait MemoryManipulation {
24    fn write_slice(&self, value_slice: &[u8], mem_offset: u32) -> Result<()>;
25}
26
27impl MemoryManipulation for MemoryView<'_> {
28    fn write_slice(&self, value_slice: &[u8], mem_offset: u32) -> Result<()> {
29        // Prepare WasmPtr
30        let ptr: WasmPtr<u8> = WasmPtr::new(mem_offset);
31
32        // Write to the slice
33        let slice = ptr.slice(self, value_slice.len() as u32)?;
34
35        Ok(slice.write_slice(value_slice)?)
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42    use std::io::Cursor;
43
44    use darkfi_serial::Decodable;
45    use wasmer::{Memory, MemoryType, Store};
46
47    #[test]
48    fn test_memoryview_writeslice() {
49        let mut store = Store::default();
50        let m = Memory::new(&mut store, MemoryType::new(1, None, false)).unwrap();
51        let value: [u8; 3] = [3, 0, 1];
52        let view = m.view(&store);
53        let res = view.write_slice(&value, 0);
54        assert!(res.is_ok());
55        let ptr: WasmPtr<u8> = WasmPtr::new(0);
56        let slice = ptr.slice(&view, value.len() as u32);
57        let mut buf: [u8; 3] = [0; 3];
58        let _ = slice.expect("err").read_slice(&mut buf);
59        assert_eq!(buf, value);
60    }
61
62    #[test]
63    fn test_memoryview_allread() -> Result<()> {
64        let mut store = Store::default();
65        let m = Memory::new(&mut store, MemoryType::new(1, None, false)).unwrap();
66        let value: [u8; 3] = [3, 0, 1];
67        let view = m.view(&store);
68        let res = view.write_slice(&value, 0);
69        assert!(res.is_ok());
70        let ptr: WasmPtr<u8> = WasmPtr::new(0);
71        let slice = ptr.slice(&view, value.len() as u32)?;
72        let mut buf: [u8; 3] = [0; 3];
73        let _ = slice.read_slice(&mut buf);
74        let mut buf_reader = Cursor::new(buf);
75        let ret: [u8; 3] = Decodable::decode(&mut buf_reader)?;
76        assert!(buf.len() == (slice.len() as usize));
77        assert_eq!(ret, value);
78        assert!(buf_reader.position() == slice.len());
79        Ok(())
80    }
81}