Disassembles the image into a textual representation for debugging.
(&self)
| 255 | |
| 256 | /// Disassembles the image into a textual representation for debugging. |
| 257 | pub fn disasm(&self) -> Vec<String> { |
| 258 | let mut lines = Vec::with_capacity(self.code.len()); |
| 259 | |
| 260 | for ((i, instr), meta) in |
| 261 | self.code.iter().copied().enumerate().zip(self.debug_info.instrs.iter()) |
| 262 | { |
| 263 | let pos = meta.linecol; |
| 264 | if let Some((key, is_start)) = self.debug_info.callables.get(&i) { |
| 265 | if *is_start { |
| 266 | lines.push("".to_owned()); |
| 267 | lines.push(format!(";; {} (BEGIN)", key)); |
| 268 | } else { |
| 269 | lines.push(format!(";; {} (END)", key)); |
| 270 | lines.push("".to_owned()); |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | let mut line = format!("{:04}: {}", i, format_instr(instr)); |
| 275 | |
| 276 | while line.len() < 40 { |
| 277 | line.push(' '); |
| 278 | } |
| 279 | line.push_str(&format!("; {}", pos)); |
| 280 | |
| 281 | match opcode_of(instr) { |
| 282 | Opcode::Call => { |
| 283 | let (_reg, target) = bytecode::parse_call(instr); |
| 284 | let target = usize::from(target); |
| 285 | let (name, _is_start) = self |
| 286 | .debug_info |
| 287 | .callables |
| 288 | .get(&target) |
| 289 | .expect("All CALL targets must be defined"); |
| 290 | line.push_str(&format!(", {}", name)) |
| 291 | } |
| 292 | |
| 293 | Opcode::Upcall => { |
| 294 | let (index, _first_reg) = bytecode::parse_upcall(instr); |
| 295 | let name = &self.upcalls[usize::from(index)]; |
| 296 | line.push_str(&format!(", {}", name)) |
| 297 | } |
| 298 | |
| 299 | Opcode::LoadConstant => { |
| 300 | let (_reg, index) = bytecode::parse_load_constant(instr); |
| 301 | let constant = &self.constants[usize::from(index)]; |
| 302 | line.push_str(&format!(", {}", constant.as_disassembly())) |
| 303 | } |
| 304 | |
| 305 | Opcode::UpcallAsync => { |
| 306 | let (index, _first_reg) = bytecode::parse_upcall_async(instr); |
| 307 | let name = &self.upcalls[usize::from(index)]; |
| 308 | line.push_str(&format!(", {}", name)) |
| 309 | } |
| 310 | |
| 311 | _ => (), |
| 312 | } |
| 313 | |
| 314 | lines.push(line); |