1#[inline]
9pub const unsafe fn read_i16(ptr: *const u8) -> i16 {
10 read_u16(ptr) as i16
11}
12
13#[inline]
19pub const 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::RngExt;
30 use std::{vec, vec::Vec};
31
32 pub fn build_memory_input_opcodes(start_offset: U256, input: &[u8]) -> Result<Vec<u8>> {
34 let mut opcodes = vec![];
35 let mut current_offset = start_offset;
36
37 let offset_step = U256::from(32);
39 for bytes in input.chunks(32) {
40 build_push_bytes(bytes, &mut opcodes);
42
43 build_push_u256(current_offset, &mut opcodes);
45
46 opcodes.push(opcode::MSTORE);
48
49 current_offset += offset_step;
51 }
52
53 Ok(opcodes)
54 }
55
56 fn build_push_u256(value: U256, opcodes: &mut Vec<u8>) {
58 let bytes = value.to_be_bytes_trimmed_vec();
59 build_push_bytes(&bytes, opcodes);
60 }
61
62 fn build_push_bytes(bytes: &[u8], opcodes: &mut Vec<u8>) {
64 let len = bytes.len();
65 assert!(len <= 32);
66
67 let push_opcode = opcode::PUSH0 + len as u8;
68 opcodes.push(push_opcode);
69
70 opcodes.extend_from_slice(bytes);
71 }
72
73 #[test]
74 fn test_build_memory_input_opcodes() {
75 let mut rng = rand::rng();
76
77 let start_offset = rng.random_range(0x0100_0000..=(u32::MAX - 100));
79 let mut current_offset = start_offset;
80
81 let mut all_inputs = vec![];
82 let mut expected_opcodes = vec![];
83
84 let input_arr: [[u8; 32]; 3] = rng.random();
86 for input in input_arr {
87 all_inputs.extend(input);
88
89 expected_opcodes.push(opcode::PUSH32);
90 expected_opcodes.extend(input);
91 expected_opcodes.push(opcode::PUSH4);
92 expected_opcodes.extend(current_offset.to_be_bytes());
93 expected_opcodes.push(opcode::MSTORE);
94
95 current_offset += 32;
96 }
97
98 let last_input: [u8; 15] = rng.random();
99 {
100 all_inputs.extend(last_input);
101
102 expected_opcodes.push(opcode::PUSH15);
103 expected_opcodes.extend(last_input);
104 expected_opcodes.push(opcode::PUSH4);
105 expected_opcodes.extend(current_offset.to_be_bytes());
106
107 expected_opcodes.push(opcode::MSTORE);
108 }
109
110 let opcodes = build_memory_input_opcodes(U256::from(start_offset), &all_inputs).unwrap();
111 assert_eq!(opcodes, expected_opcodes);
112 }
113}