multiversx_chain_vm/
mem_conv.rs1use multiversx_chain_vm_executor::{MemLength, MemPtr};
2
3pub fn with_mem_ptr<F, R>(bytes: &[u8], f: F) -> R
4where
5 F: FnOnce(MemPtr, MemLength) -> R,
6{
7 f(bytes.as_ptr() as MemPtr, bytes.len() as MemLength)
8}
9
10pub fn with_mem_ptr_mut<F, R>(bytes: &mut [u8], f: F) -> R
11where
12 F: FnOnce(MemPtr, MemLength) -> R,
13{
14 f(bytes.as_ptr() as MemPtr, bytes.len() as MemLength)
15}
16
17pub unsafe fn with_bytes<F, R>(offset: MemPtr, length: MemLength, f: F) -> R
23where
24 F: FnOnce(&[u8]) -> R,
25{
26 let bytes = std::ptr::slice_from_raw_parts(offset as *const u8, length as usize);
27 f(&*bytes)
28}
29
30pub unsafe fn with_bytes_mut<F, R>(offset: MemPtr, length: MemLength, f: F) -> R
36where
37 F: FnOnce(&mut [u8]) -> R,
38{
39 let bytes = std::ptr::slice_from_raw_parts_mut(offset as *mut u8, length as usize);
40 f(&mut *bytes)
41}
42
43#[cfg(test)]
44mod test {
45 use super::*;
46
47 #[test]
48 fn test_mem_ptr_conversion() {
49 assert_mem_conv_sound(vec![]);
50 assert_mem_conv_sound(vec![1]);
51 assert_mem_conv_sound(vec![1, 2, 3]);
52 }
53
54 fn assert_mem_conv_sound(data: Vec<u8>) {
55 let cloned = with_mem_ptr(data.as_slice(), |offset, length| unsafe {
56 with_bytes(offset, length, |bytes| bytes.to_vec())
57 });
58 assert_eq!(data, cloned);
59 }
60
61 #[test]
62 fn test_mem_ptr_mut() {
63 let mut data = vec![1, 2, 3];
64 with_mem_ptr_mut(data.as_mut_slice(), |offset, length| unsafe {
65 with_bytes_mut(offset, length, |bytes| {
66 for b in bytes {
67 *b += 1;
68 }
69 })
70 });
71 assert_eq!(data, vec![2, 3, 4]);
72 }
73}