Format instruction details for inclusion in disassembly output.
(self, instr, mark_as_current)
| 480 | False) |
| 481 | |
| 482 | def print_instruction_line(self, instr, mark_as_current): |
| 483 | """Format instruction details for inclusion in disassembly output.""" |
| 484 | lineno_width = self.lineno_width |
| 485 | offset_width = self.offset_width |
| 486 | label_width = self.label_width |
| 487 | |
| 488 | new_source_line = (lineno_width > 0 and |
| 489 | instr.starts_line and |
| 490 | instr.offset > 0) |
| 491 | if new_source_line: |
| 492 | print(file=self.file) |
| 493 | |
| 494 | fields = [] |
| 495 | # Column: Source code locations information |
| 496 | if lineno_width: |
| 497 | if self.show_positions: |
| 498 | # reporting positions instead of just line numbers |
| 499 | if instr_positions := instr.positions: |
| 500 | if all(p is None for p in instr_positions): |
| 501 | positions_str = _NO_LINENO |
| 502 | else: |
| 503 | ps = tuple('?' if p is None else p for p in instr_positions) |
| 504 | positions_str = f"{ps[0]}:{ps[2]}-{ps[1]}:{ps[3]}" |
| 505 | fields.append(f'{positions_str:{lineno_width}}') |
| 506 | else: |
| 507 | fields.append(' ' * lineno_width) |
| 508 | else: |
| 509 | if instr.starts_line: |
| 510 | lineno_fmt = "%%%dd" if instr.line_number is not None else "%%%ds" |
| 511 | lineno_fmt = lineno_fmt % lineno_width |
| 512 | lineno = _NO_LINENO if instr.line_number is None else instr.line_number |
| 513 | fields.append(lineno_fmt % lineno) |
| 514 | else: |
| 515 | fields.append(' ' * lineno_width) |
| 516 | # Column: Label |
| 517 | if instr.label is not None: |
| 518 | lbl = f"L{instr.label}:" |
| 519 | fields.append(f"{lbl:>{label_width}}") |
| 520 | else: |
| 521 | fields.append(' ' * label_width) |
| 522 | # Column: Instruction offset from start of code sequence |
| 523 | if offset_width > 0: |
| 524 | fields.append(f"{repr(instr.offset):>{offset_width}} ") |
| 525 | # Column: Current instruction indicator |
| 526 | if mark_as_current: |
| 527 | fields.append('-->') |
| 528 | else: |
| 529 | fields.append(' ') |
| 530 | # Column: Opcode name |
| 531 | fields.append(instr.opname.ljust(_OPNAME_WIDTH)) |
| 532 | # Column: Opcode argument |
| 533 | if instr.arg is not None: |
| 534 | # If opname is longer than _OPNAME_WIDTH, we allow it to overflow into |
| 535 | # the space reserved for oparg. This results in fewer misaligned opargs |
| 536 | # in the disassembly output. |
| 537 | opname_excess = max(0, len(instr.opname) - _OPNAME_WIDTH) |
| 538 | fields.append(repr(instr.arg).rjust(_OPARG_WIDTH - opname_excess)) |
| 539 | # Column: Opcode argument details |