Skip to content
Snippets Groups Projects
Unverified Commit 3f61db47 authored by Brandt Bucher's avatar Brandt Bucher Committed by GitHub
Browse files

gh-90997: Move `CACHE` handling into `_unpack_opargs` (#92409)

* Move CACHE handling into _unpack_opargs

* Remove auto-added import

* blurb add
parent 50210643
Branches
Tags
No related merge requests found
...@@ -440,11 +440,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None, ...@@ -440,11 +440,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
for i in range(start, end): for i in range(start, end):
labels.add(target) labels.add(target)
starts_line = None starts_line = None
cache_counter = 0
for offset, op, arg in _unpack_opargs(code): for offset, op, arg in _unpack_opargs(code):
if cache_counter > 0:
cache_counter -= 1
continue
if linestarts is not None: if linestarts is not None:
starts_line = linestarts.get(offset, None) starts_line = linestarts.get(offset, None)
if starts_line is not None: if starts_line is not None:
...@@ -454,7 +450,6 @@ def _get_instructions_bytes(code, varname_from_oparg=None, ...@@ -454,7 +450,6 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
argrepr = '' argrepr = ''
positions = Positions(*next(co_positions, ())) positions = Positions(*next(co_positions, ()))
deop = _deoptop(op) deop = _deoptop(op)
cache_counter = _inline_cache_entries[deop]
if arg is not None: if arg is not None:
# Set argval to the dereferenced value of the argument when # Set argval to the dereferenced value of the argument when
# available, and argrepr to the string representation of argval. # available, and argrepr to the string representation of argval.
...@@ -497,7 +492,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None, ...@@ -497,7 +492,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
yield Instruction(_all_opname[op], op, yield Instruction(_all_opname[op], op,
arg, argval, argrepr, arg, argval, argrepr,
offset, starts_line, is_jump_target, positions) offset, starts_line, is_jump_target, positions)
if show_caches and cache_counter: if show_caches and _inline_cache_entries[deop]:
for name, caches in _cache_format[opname[deop]].items(): for name, caches in _cache_format[opname[deop]].items():
data = code[offset + 2: offset + 2 + caches * 2] data = code[offset + 2: offset + 2 + caches * 2]
argrepr = f"{name}: {int.from_bytes(data, sys.byteorder)}" argrepr = f"{name}: {int.from_bytes(data, sys.byteorder)}"
...@@ -586,9 +581,16 @@ def _disassemble_str(source, **kwargs): ...@@ -586,9 +581,16 @@ def _disassemble_str(source, **kwargs):
def _unpack_opargs(code): def _unpack_opargs(code):
extended_arg = 0 extended_arg = 0
caches = 0
for i in range(0, len(code), 2): for i in range(0, len(code), 2):
# Skip inline CACHE entries:
if caches:
caches -= 1
continue
op = code[i] op = code[i]
if _deoptop(op) >= HAVE_ARGUMENT: deop = _deoptop(op)
caches = _inline_cache_entries[deop]
if deop >= HAVE_ARGUMENT:
arg = code[i+1] | extended_arg arg = code[i+1] | extended_arg
extended_arg = (arg << 8) if op == EXTENDED_ARG else 0 extended_arg = (arg << 8) if op == EXTENDED_ARG else 0
# The oparg is stored as a signed integer # The oparg is stored as a signed integer
......
Fix an issue where :mod:`dis` utilities may interpret populated inline cache
entries as valid instructions.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment