neo_solidity/cli/bytecode/bytecode_disasm/
helpers.rs

1fn take<'a>(bytecode: &'a [u8], pc: &mut usize, len: usize) -> Option<&'a [u8]> {
2    if pc.saturating_add(len) > bytecode.len() {
3        return None;
4    }
5    let slice = &bytecode[*pc..*pc + len];
6    *pc += len;
7    Some(slice)
8}
9
10fn take_u8(bytecode: &[u8], pc: &mut usize) -> Option<u8> {
11    take(bytecode, pc, 1).map(|b| b[0])
12}
13
14fn take_i8(bytecode: &[u8], pc: &mut usize) -> Option<i8> {
15    take_u8(bytecode, pc).map(|b| b as i8)
16}
17
18fn take_u16(bytecode: &[u8], pc: &mut usize) -> Option<u16> {
19    let bytes = take(bytecode, pc, 2)?;
20    Some(u16::from_le_bytes([bytes[0], bytes[1]]))
21}
22
23fn take_i16(bytecode: &[u8], pc: &mut usize) -> Option<i16> {
24    take_u16(bytecode, pc).map(|v| v as i16)
25}
26
27fn take_u32(bytecode: &[u8], pc: &mut usize) -> Option<u32> {
28    let bytes = take(bytecode, pc, 4)?;
29    Some(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
30}
31
32fn take_i32(bytecode: &[u8], pc: &mut usize) -> Option<i32> {
33    take_u32(bytecode, pc).map(|v| v as i32)
34}
35
36fn take_i64(bytecode: &[u8], pc: &mut usize) -> Option<i64> {
37    let bytes = take(bytecode, pc, 8)?;
38    Some(i64::from_le_bytes([
39        bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
40    ]))
41}
42
43fn fmt_target(bytecode_len: usize, base: usize, rel: i32) -> String {
44    let base_i64 = base as i64;
45    let rel_i64 = rel as i64;
46    let target = base_i64.checked_add(rel_i64);
47    match target {
48        Some(t) if (0..bytecode_len as i64).contains(&t) => format!("0x{t:06X}"),
49        _ => format!("(out of bounds: base=0x{base:06X} rel={rel})"),
50    }
51}