revm_bytecode/eof/
printer.rs1#![cfg(feature = "std")]
7
8pub fn print(code: &[u8]) {
10 use crate::{opcode::*, utils::read_i16};
11 use primitives::hex;
12
13 let mut i = 0;
15 while i < code.len() {
16 let op = code[i];
17 let opcode = &OPCODE_INFO[op as usize];
18
19 let Some(opcode) = opcode else {
20 println!("Unknown opcode: 0x{:02X}", op);
21 i += 1;
22 continue;
23 };
24
25 if opcode.immediate_size() != 0 {
26 if i + opcode.immediate_size() as usize >= code.len() {
28 println!("Malformed code: immediate out of bounds");
29 break;
30 }
31 }
32
33 print!("{}", opcode.name());
34 if opcode.immediate_size() != 0 {
35 let immediate = &code[i + 1..i + 1 + opcode.immediate_size() as usize];
36 print!(" : 0x{:}", hex::encode(immediate));
37 if opcode.immediate_size() == 2 {
38 print!(" ({})", i16::from_be_bytes(immediate.try_into().unwrap()));
39 }
40 }
41 println!();
42
43 let mut rjumpv_additional_immediates = 0;
44 if op == RJUMPV {
45 let max_index = code[i + 1] as usize;
46 let len = max_index + 1;
47 rjumpv_additional_immediates = len * 2;
49
50 if i + 1 + rjumpv_additional_immediates >= code.len() {
52 println!("Malformed code: immediate out of bounds");
53 break;
54 }
55
56 for vtablei in 0..len {
57 let offset = unsafe { read_i16(code.as_ptr().add(i + 2 + 2 * vtablei)) } as isize;
58 println!("RJUMPV[{vtablei}]: 0x{offset:04X} ({offset})");
59 }
60 }
61
62 i += 1 + opcode.immediate_size() as usize + rjumpv_additional_immediates;
63 }
64}
65
66#[cfg(test)]
67mod test {
68 use primitives::hex;
69
70 #[test]
71 fn sanity_test() {
72 super::print(&hex!("6001e200ffff00"));
73 }
74}