multiversx_sc_scenario/executor/debug/
contract_debug_instance_state.rs1use multiversx_chain_vm_executor::{
2 BreakpointValue, ExecutorError, InstanceState, MemLength, MemPtr, VMHooksEarlyExit,
3};
4
5#[derive(Clone, Debug)]
6pub struct ContractDebugInstanceState;
7
8impl ContractDebugInstanceState {
9 pub unsafe fn main_memory_load(mem_ptr: MemPtr, mem_length: MemLength) -> &'static [u8] {
15 unsafe {
16 let bytes_ptr =
17 std::ptr::slice_from_raw_parts(mem_ptr as *const u8, mem_length as usize);
18 &*bytes_ptr
19 }
20 }
21
22 pub unsafe fn main_memory_store(offset: MemPtr, data: &[u8]) {
28 unsafe {
29 std::ptr::copy(data.as_ptr(), offset as *mut u8, data.len());
30 }
31 }
32
33 pub fn main_memory_ptr(bytes: &[u8]) -> (MemPtr, MemLength) {
34 (bytes.as_ptr() as MemPtr, bytes.len() as MemLength)
35 }
36
37 pub fn main_memory_mut_ptr(bytes: &mut [u8]) -> (MemPtr, MemLength) {
38 (bytes.as_ptr() as MemPtr, bytes.len() as MemLength)
39 }
40
41 pub fn early_exit_panic(early_exit: VMHooksEarlyExit) -> ! {
42 std::panic::panic_any(early_exit)
43 }
44
45 pub fn breakpoint_panic(breakpoint_value: BreakpointValue) -> ! {
46 std::panic::panic_any(breakpoint_value)
47 }
48}
49
50impl InstanceState for ContractDebugInstanceState {
51 fn get_points_used(&mut self) -> Result<u64, ExecutorError> {
52 Ok(0)
53 }
54
55 fn set_points_used(&mut self, _points: u64) -> Result<(), ExecutorError> {
56 Ok(())
57 }
58
59 fn memory_load_to_slice(&self, mem_ptr: MemPtr, dest: &mut [u8]) -> Result<(), ExecutorError> {
60 let data = unsafe { Self::main_memory_load(mem_ptr, dest.len() as MemLength) };
61 dest.copy_from_slice(data);
62 Ok(())
63 }
64
65 fn memory_load_owned(
66 &self,
67 mem_ptr: MemPtr,
68 mem_length: MemLength,
69 ) -> Result<Vec<u8>, ExecutorError> {
70 let data = unsafe { Self::main_memory_load(mem_ptr, mem_length) };
71 Ok(data.to_vec())
72 }
73
74 fn memory_store(&self, mem_ptr: MemPtr, data: &[u8]) -> Result<(), ExecutorError> {
75 unsafe {
76 Self::main_memory_store(mem_ptr, data);
77 }
78 Ok(())
79 }
80}
81
82#[cfg(test)]
83#[allow(deprecated)]
84mod test {
85 use super::*;
86
87 #[test]
88 fn test_mem_ptr_conversion() {
89 assert_mem_load_sound(vec![]);
90 assert_mem_load_sound(vec![1]);
91 assert_mem_load_sound(vec![1, 2, 3]);
92
93 assert_mem_store_sound(vec![]);
94 assert_mem_store_sound(vec![1]);
95 assert_mem_store_sound(vec![1, 2, 3]);
96 }
97
98 fn assert_mem_load_sound(data: Vec<u8>) {
99 let (offset, length) = ContractDebugInstanceState::main_memory_ptr(&data);
100 let re_slice = unsafe { ContractDebugInstanceState::main_memory_load(offset, length) };
101 let cloned = re_slice.to_vec();
102 assert_eq!(data, cloned);
103 }
104
105 fn assert_mem_store_sound(mut data: Vec<u8>) {
106 let new_data: Vec<u8> = data.iter().map(|x| x * 2).collect();
107 let (offset, length) = ContractDebugInstanceState::main_memory_mut_ptr(&mut data);
108 assert_eq!(length, data.len() as isize);
109 unsafe {
110 ContractDebugInstanceState::main_memory_store(offset, &new_data);
111 }
112 assert_eq!(data, new_data);
113 }
114}