mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
gh-112962: in dis module, put cache information in the Instruction instead of creating fake Instructions to represent it (#113016)
This commit is contained in:
parent
3531ea441b
commit
428c9812cb
7 changed files with 115 additions and 47 deletions
75
Lib/dis.py
75
Lib/dis.py
|
|
@ -267,9 +267,10 @@ _Instruction = collections.namedtuple(
|
|||
'starts_line',
|
||||
'line_number',
|
||||
'label',
|
||||
'positions'
|
||||
'positions',
|
||||
'cache_info',
|
||||
],
|
||||
defaults=[None, None]
|
||||
defaults=[None, None, None]
|
||||
)
|
||||
|
||||
_Instruction.opname.__doc__ = "Human readable name for operation"
|
||||
|
|
@ -286,6 +287,7 @@ _Instruction.starts_line.__doc__ = "True if this opcode starts a source line, ot
|
|||
_Instruction.line_number.__doc__ = "source line number associated with this opcode (if any), otherwise None"
|
||||
_Instruction.label.__doc__ = "A label (int > 0) if this instruction is a jump target, otherwise None"
|
||||
_Instruction.positions.__doc__ = "dis.Positions object holding the span of source code covered by this instruction"
|
||||
_Instruction.cache_info.__doc__ = "list of (name, size, data), one for each cache entry of the instruction"
|
||||
|
||||
_ExceptionTableEntryBase = collections.namedtuple("_ExceptionTableEntryBase",
|
||||
"start end target depth lasti")
|
||||
|
|
@ -334,6 +336,8 @@ class Instruction(_Instruction):
|
|||
label - A label if this instruction is a jump target, otherwise None
|
||||
positions - Optional dis.Positions object holding the span of source code
|
||||
covered by this instruction
|
||||
cache_info - information about the format and content of the instruction's cache
|
||||
entries (if any)
|
||||
"""
|
||||
|
||||
@property
|
||||
|
|
@ -570,7 +574,6 @@ def get_instructions(x, *, first_line=None, show_caches=False, adaptive=False):
|
|||
linestarts=linestarts,
|
||||
line_offset=line_offset,
|
||||
co_positions=co.co_positions(),
|
||||
show_caches=show_caches,
|
||||
original_code=original_code,
|
||||
arg_resolver=arg_resolver)
|
||||
|
||||
|
|
@ -645,8 +648,7 @@ def _is_backward_jump(op):
|
|||
'ENTER_EXECUTOR')
|
||||
|
||||
def _get_instructions_bytes(code, linestarts=None, line_offset=0, co_positions=None,
|
||||
show_caches=False, original_code=None, labels_map=None,
|
||||
arg_resolver=None):
|
||||
original_code=None, labels_map=None, arg_resolver=None):
|
||||
"""Iterate over the instructions in a bytecode string.
|
||||
|
||||
Generates a sequence of Instruction namedtuples giving the details of each
|
||||
|
|
@ -682,32 +684,28 @@ def _get_instructions_bytes(code, linestarts=None, line_offset=0, co_positions=N
|
|||
else:
|
||||
argval, argrepr = arg, repr(arg)
|
||||
|
||||
yield Instruction(_all_opname[op], op, arg, argval, argrepr,
|
||||
offset, start_offset, starts_line, line_number,
|
||||
labels_map.get(offset, None), positions)
|
||||
instr = Instruction(_all_opname[op], op, arg, argval, argrepr,
|
||||
offset, start_offset, starts_line, line_number,
|
||||
labels_map.get(offset, None), positions)
|
||||
|
||||
caches = _get_cache_size(_all_opname[deop])
|
||||
if not caches:
|
||||
continue
|
||||
if not show_caches:
|
||||
# We still need to advance the co_positions iterator:
|
||||
for _ in range(caches):
|
||||
next(co_positions, ())
|
||||
continue
|
||||
for name, size in _cache_format[opname[deop]].items():
|
||||
for i in range(size):
|
||||
offset += 2
|
||||
# Only show the fancy argrepr for a CACHE instruction when it's
|
||||
# the first entry for a particular cache value:
|
||||
if i == 0:
|
||||
data = code[offset: offset + 2 * size]
|
||||
argrepr = f"{name}: {int.from_bytes(data, sys.byteorder)}"
|
||||
else:
|
||||
argrepr = ""
|
||||
yield Instruction(
|
||||
"CACHE", CACHE, 0, None, argrepr, offset, offset, False, None, None,
|
||||
Positions(*next(co_positions, ()))
|
||||
)
|
||||
# Advance the co_positions iterator:
|
||||
for _ in range(caches):
|
||||
next(co_positions, ())
|
||||
|
||||
if caches:
|
||||
cache_info = []
|
||||
for name, size in _cache_format[opname[deop]].items():
|
||||
data = code[offset + 2: offset + 2 + 2 * size]
|
||||
cache_info.append((name, size, data))
|
||||
else:
|
||||
cache_info = None
|
||||
|
||||
yield Instruction(_all_opname[op], op, arg, argval, argrepr,
|
||||
offset, start_offset, starts_line, line_number,
|
||||
labels_map.get(offset, None), positions, cache_info)
|
||||
|
||||
|
||||
|
||||
def disassemble(co, lasti=-1, *, file=None, show_caches=False, adaptive=False,
|
||||
show_offsets=False):
|
||||
|
|
@ -787,7 +785,6 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None,
|
|||
instrs = _get_instructions_bytes(code, linestarts=linestarts,
|
||||
line_offset=line_offset,
|
||||
co_positions=co_positions,
|
||||
show_caches=show_caches,
|
||||
original_code=original_code,
|
||||
labels_map=labels_map,
|
||||
arg_resolver=arg_resolver)
|
||||
|
|
@ -805,6 +802,23 @@ def print_instructions(instrs, exception_entries, formatter, show_caches=False,
|
|||
is_current_instr = instr.offset <= lasti \
|
||||
<= instr.offset + 2 * _get_cache_size(_all_opname[_deoptop(instr.opcode)])
|
||||
formatter.print_instruction(instr, is_current_instr)
|
||||
deop = _deoptop(instr.opcode)
|
||||
if show_caches and instr.cache_info:
|
||||
offset = instr.offset
|
||||
for name, size, data in instr.cache_info:
|
||||
for i in range(size):
|
||||
offset += 2
|
||||
# Only show the fancy argrepr for a CACHE instruction when it's
|
||||
# the first entry for a particular cache value:
|
||||
if i == 0:
|
||||
argrepr = f"{name}: {int.from_bytes(data, sys.byteorder)}"
|
||||
else:
|
||||
argrepr = ""
|
||||
formatter.print_instruction(
|
||||
Instruction("CACHE", CACHE, 0, None, argrepr, offset, offset,
|
||||
False, None, None, instr.positions),
|
||||
is_current_instr)
|
||||
|
||||
formatter.print_exception_table(exception_entries)
|
||||
|
||||
def _disassemble_str(source, **kwargs):
|
||||
|
|
@ -952,7 +966,6 @@ class Bytecode:
|
|||
linestarts=self._linestarts,
|
||||
line_offset=self._line_offset,
|
||||
co_positions=co.co_positions(),
|
||||
show_caches=self.show_caches,
|
||||
original_code=original_code,
|
||||
labels_map=labels_map,
|
||||
arg_resolver=arg_resolver)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue