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