]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-90997: Move `CACHE` handling into `_unpack_opargs` (#92409)
authorBrandt Bucher <brandtbucher@gmail.com>
Fri, 6 May 2022 17:57:08 +0000 (10:57 -0700)
committerGitHub <noreply@github.com>
Fri, 6 May 2022 17:57:08 +0000 (18:57 +0100)
* Move CACHE handling into _unpack_opargs

* Remove auto-added import

* blurb add

Lib/dis.py
Misc/NEWS.d/next/Library/2022-05-06-09-48-07.gh-issue-90997.4PmCgX.rst [new file with mode: 0644]

index 53c62694decaa04dfcdeb5e32840a53d94eda15d..046013120b000de0e58b17e4f4f924fbe777a91a 100644 (file)
@@ -440,11 +440,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
         for i in range(start, end):
             labels.add(target)
     starts_line = None
-    cache_counter = 0
     for offset, op, arg in _unpack_opargs(code):
-        if cache_counter > 0:
-            cache_counter -= 1
-            continue
         if linestarts is not None:
             starts_line = linestarts.get(offset, None)
             if starts_line is not None:
@@ -454,7 +450,6 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
         argrepr = ''
         positions = Positions(*next(co_positions, ()))
         deop = _deoptop(op)
-        cache_counter = _inline_cache_entries[deop]
         if arg is not None:
             #  Set argval to the dereferenced value of the argument when
             #  available, and argrepr to the string representation of argval.
@@ -497,7 +492,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
         yield Instruction(_all_opname[op], op,
                           arg, argval, argrepr,
                           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():
                 data = code[offset + 2: offset + 2 + caches * 2]
                 argrepr = f"{name}: {int.from_bytes(data, sys.byteorder)}"
@@ -586,9 +581,16 @@ _INT_OVERFLOW = 2 ** (_INT_BITS - 1)
 
 def _unpack_opargs(code):
     extended_arg = 0
+    caches = 0
     for i in range(0, len(code), 2):
+        # Skip inline CACHE entries:
+        if caches:
+            caches -= 1
+            continue
         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
             extended_arg = (arg << 8) if op == EXTENDED_ARG else 0
             # The oparg is stored as a signed integer
diff --git a/Misc/NEWS.d/next/Library/2022-05-06-09-48-07.gh-issue-90997.4PmCgX.rst b/Misc/NEWS.d/next/Library/2022-05-06-09-48-07.gh-issue-90997.4PmCgX.rst
new file mode 100644 (file)
index 0000000..0e68307
--- /dev/null
@@ -0,0 +1,2 @@
+Fix an issue where :mod:`dis` utilities may interpret populated inline cache
+entries as valid instructions.