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