1#[inline]
9pub unsafe fn read_i16(ptr: *const u8) -> i16 {
10 read_u16(ptr) as i16
11}
12
13#[inline]
19pub unsafe fn read_u16(ptr: *const u8) -> u16 {
20 u16::from_be_bytes(unsafe { ptr.cast::<[u8; 2]>().read() })
21}
22
23#[cfg(test)]
25pub mod test {
26 use crate::opcode;
27 use anyhow::Result;
28 use primitives::U256;
29 use rand::Rng;
30
31 pub fn build_memory_input_opcodes(start_offset: U256, input: &[u8]) -> Result<Vec<u8>> {
33 let mut opcodes = vec![];
34 let mut current_offset = start_offset;
35
36 let offset_step = U256::from(32);
38 for bytes in input.chunks(32) {
39 build_push_bytes(bytes, &mut opcodes);
41
42 build_push_u256(current_offset, &mut opcodes);
44
45 opcodes.push(opcode::MSTORE);
47
48 current_offset += offset_step;
50 }
51
52 Ok(opcodes)
53 }
54
55 fn build_push_u256(value: U256, opcodes: &mut Vec<u8>) {
57 let bytes = value.to_be_bytes_trimmed_vec();
58 build_push_bytes(&bytes, opcodes);
59 }
60
61 fn build_push_bytes(bytes: &[u8], opcodes: &mut Vec<u8>) {
63 let len = bytes.len();
64 assert!(len <= 32);
65
66 let push_opcode = opcode::PUSH0 + len as u8;
67 opcodes.push(push_opcode);
68
69 opcodes.extend_from_slice(bytes);
70 }
71
72 #[test]
73 fn test_build_memory_input_opcodes() {
74 let mut rng = rand::rng();
75
76 let start_offset = rng.random_range(0x0100_0000..=(u32::MAX - 100));
78 let mut current_offset = start_offset;
79
80 let mut all_inputs = vec![];
81 let mut expected_opcodes = vec![];
82
83 let input_arr: [[u8; 32]; 3] = rng.random();
85 for input in input_arr {
86 all_inputs.extend(input);
87
88 expected_opcodes.push(opcode::PUSH32);
89 expected_opcodes.extend(input);
90 expected_opcodes.push(opcode::PUSH4);
91 expected_opcodes.extend(current_offset.to_be_bytes());
92 expected_opcodes.push(opcode::MSTORE);
93
94 current_offset += 32;
95 }
96
97 let last_input: [u8; 15] = rng.random();
98 {
99 all_inputs.extend(last_input);
100
101 expected_opcodes.push(opcode::PUSH15);
102 expected_opcodes.extend(last_input);
103 expected_opcodes.push(opcode::PUSH4);
104 expected_opcodes.extend(current_offset.to_be_bytes());
105
106 expected_opcodes.push(opcode::MSTORE);
107 }
108
109 let opcodes = build_memory_input_opcodes(U256::from(start_offset), &all_inputs).unwrap();
110 assert_eq!(opcodes, expected_opcodes);
111 }
112}