summaryrefslogtreecommitdiffstats
path: root/Lib/dis.py
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2021-06-07 18:22:26 (GMT)
committerGitHub <noreply@github.com>2021-06-07 18:22:26 (GMT)
commit2ab27c4af4ddf7528e1375e77c787c7fbb09b5e6 (patch)
treed3983e5282f575560cb7449fae4785447fdfff14 /Lib/dis.py
parent001eb520b5757294dc455c900d94b7b153de6cdd (diff)
downloadcpython-2ab27c4af4ddf7528e1375e77c787c7fbb09b5e6.zip
cpython-2ab27c4af4ddf7528e1375e77c787c7fbb09b5e6.tar.gz
cpython-2ab27c4af4ddf7528e1375e77c787c7fbb09b5e6.tar.bz2
bpo-43693: Un-revert commits 2c1e258 and b2bf2bc. (gh-26577)
These were reverted in gh-26530 (commit 17c4edc) due to refleaks. * 2c1e258 - Compute deref offsets in compiler (gh-25152) * b2bf2bc - Add new internal code objects fields: co_fastlocalnames and co_fastlocalkinds. (gh-26388) This change fixes the refleaks. https://bugs.python.org/issue43693
Diffstat (limited to 'Lib/dis.py')
-rw-r--r--Lib/dis.py53
1 files changed, 27 insertions, 26 deletions
diff --git a/Lib/dis.py b/Lib/dis.py
index bc7c4d4..48a6ab8 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -273,15 +273,15 @@ def get_instructions(x, *, first_line=None):
the disassembled code object.
"""
co = _get_code_object(x)
- cell_names = co.co_cellvars + co.co_freevars
linestarts = dict(findlinestarts(co))
if first_line is not None:
line_offset = first_line - co.co_firstlineno
else:
line_offset = 0
- return _get_instructions_bytes(co.co_code, co.co_varnames, co.co_names,
- co.co_consts, cell_names, linestarts,
- line_offset)
+ return _get_instructions_bytes(co.co_code,
+ co._varname_from_oparg,
+ co.co_names, co.co_consts,
+ linestarts, line_offset)
def _get_const_info(const_index, const_list):
"""Helper to get optional details about const references
@@ -295,7 +295,7 @@ def _get_const_info(const_index, const_list):
argval = const_list[const_index]
return argval, repr(argval)
-def _get_name_info(name_index, name_list):
+def _get_name_info(name_index, get_name, **extrainfo):
"""Helper to get optional details about named references
Returns the dereferenced name as both value and repr if the name
@@ -303,8 +303,8 @@ def _get_name_info(name_index, name_list):
Otherwise returns the name index and its repr().
"""
argval = name_index
- if name_list is not None:
- argval = name_list[name_index]
+ if get_name is not None:
+ argval = get_name(name_index, **extrainfo)
argrepr = argval
else:
argrepr = repr(argval)
@@ -336,8 +336,10 @@ def parse_exception_table(code):
except StopIteration:
return entries
-def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
- cells=None, linestarts=None, line_offset=0, exception_entries=()):
+def _get_instructions_bytes(code, varname_from_oparg=None,
+ names=None, constants=None,
+ linestarts=None, line_offset=0,
+ exception_entries=()):
"""Iterate over the instructions in a bytecode string.
Generates a sequence of Instruction namedtuples giving the details of each
@@ -346,6 +348,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
arguments.
"""
+ get_name = None if names is None else names.__getitem__
labels = set(findlabels(code))
for start, end, target, _, _ in exception_entries:
for i in range(start, end):
@@ -368,20 +371,18 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
if op in hasconst:
argval, argrepr = _get_const_info(arg, constants)
elif op in hasname:
- argval, argrepr = _get_name_info(arg, names)
+ argval, argrepr = _get_name_info(arg, get_name)
elif op in hasjabs:
argval = arg*2
argrepr = "to " + repr(argval)
elif op in hasjrel:
argval = offset + 2 + arg*2
argrepr = "to " + repr(argval)
- elif op in haslocal:
- argval, argrepr = _get_name_info(arg, varnames)
+ elif op in haslocal or op in hasfree:
+ argval, argrepr = _get_name_info(arg, varname_from_oparg)
elif op in hascompare:
argval = cmp_op[arg]
argrepr = argval
- elif op in hasfree:
- argval, argrepr = _get_name_info(arg, cells)
elif op == FORMAT_VALUE:
argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3]
argval = (argval, bool(arg & 0x4))
@@ -398,11 +399,11 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
def disassemble(co, lasti=-1, *, file=None):
"""Disassemble a code object."""
- cell_names = co.co_cellvars + co.co_freevars
linestarts = dict(findlinestarts(co))
exception_entries = parse_exception_table(co)
- _disassemble_bytes(co.co_code, lasti, co.co_varnames, co.co_names,
- co.co_consts, cell_names, linestarts, file=file,
+ _disassemble_bytes(co.co_code, lasti,
+ co._varname_from_oparg,
+ co.co_names, co.co_consts, linestarts, file=file,
exception_entries=exception_entries)
def _disassemble_recursive(co, *, file=None, depth=None):
@@ -416,8 +417,8 @@ def _disassemble_recursive(co, *, file=None, depth=None):
print("Disassembly of %r:" % (x,), file=file)
_disassemble_recursive(x, file=file, depth=depth)
-def _disassemble_bytes(code, lasti=-1, varnames=None, names=None,
- constants=None, cells=None, linestarts=None,
+def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None,
+ names=None, constants=None, linestarts=None,
*, file=None, line_offset=0, exception_entries=()):
# Omit the line number column entirely if we have no line number info
show_lineno = bool(linestarts)
@@ -434,8 +435,8 @@ def _disassemble_bytes(code, lasti=-1, varnames=None, names=None,
offset_width = len(str(maxoffset))
else:
offset_width = 4
- for instr in _get_instructions_bytes(code, varnames, names,
- constants, cells, linestarts,
+ for instr in _get_instructions_bytes(code, varname_from_oparg, names,
+ constants, linestarts,
line_offset=line_offset, exception_entries=exception_entries):
new_source_line = (show_lineno and
instr.starts_line is not None and
@@ -517,7 +518,6 @@ class Bytecode:
else:
self.first_line = first_line
self._line_offset = first_line - co.co_firstlineno
- self._cell_names = co.co_cellvars + co.co_freevars
self._linestarts = dict(findlinestarts(co))
self._original_object = x
self.current_offset = current_offset
@@ -525,8 +525,9 @@ class Bytecode:
def __iter__(self):
co = self.codeobj
- return _get_instructions_bytes(co.co_code, co.co_varnames, co.co_names,
- co.co_consts, self._cell_names,
+ return _get_instructions_bytes(co.co_code,
+ co._varname_from_oparg,
+ co.co_names, co.co_consts,
self._linestarts,
line_offset=self._line_offset,
exception_entries=self.exception_entries)
@@ -554,9 +555,9 @@ class Bytecode:
else:
offset = -1
with io.StringIO() as output:
- _disassemble_bytes(co.co_code, varnames=co.co_varnames,
+ _disassemble_bytes(co.co_code,
+ varname_from_oparg=co._varname_from_oparg,
names=co.co_names, constants=co.co_consts,
- cells=self._cell_names,
linestarts=self._linestarts,
line_offset=self._line_offset,
file=output,