summaryrefslogtreecommitdiffstats
path: root/Lib
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
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')
-rw-r--r--Lib/ctypes/test/test_values.py6
-rw-r--r--Lib/dis.py53
-rw-r--r--Lib/importlib/_bootstrap_external.py4
-rw-r--r--Lib/test/test_dis.py40
4 files changed, 53 insertions, 50 deletions
diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py
index 92c3c28..5aa0d75 100644
--- a/Lib/ctypes/test/test_values.py
+++ b/Lib/ctypes/test/test_values.py
@@ -80,9 +80,9 @@ class PythonValuesTestCase(unittest.TestCase):
continue
items.append((entry.name.decode("ascii"), entry.size))
- expected = [("__hello__", 138),
- ("__phello__", -138),
- ("__phello__.spam", 138),
+ expected = [("__hello__", 128),
+ ("__phello__", -128),
+ ("__phello__.spam", 128),
]
self.assertEqual(items, expected, "PyImport_FrozenModules example "
"in Doc/library/ctypes.rst may be out of date")
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,
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index ee720f8..3955218 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -355,6 +355,8 @@ _code_type = type(_write_atomic.__code__)
# Python 3.11a1 3450 Use exception table for unwinding ("zero cost" exception handling)
# Python 3.11a1 3451 (Add CALL_METHOD_KW)
# Python 3.11a1 3452 (drop nlocals from marshaled code objects)
+# Python 3.11a1 3453 (add co_fastlocalnames and co_fastlocalkinds)
+# Python 3.11a1 3454 (compute cell offsets relative to locals bpo-43693)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
@@ -364,7 +366,7 @@ _code_type = type(_write_atomic.__code__)
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.
-MAGIC_NUMBER = (3452).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3454).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__'
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index f341a3e..b119d18 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -427,7 +427,7 @@ def _h(y):
return foo
dis_nested_0 = """\
-%3d 0 LOAD_CLOSURE 0 (y)
+%3d 0 LOAD_CLOSURE 2 (y)
2 BUILD_TUPLE 1
4 LOAD_CONST 1 (<code object foo at 0x..., file "%s", line %d>)
6 LOAD_CONST 2 ('_h.<locals>.foo')
@@ -444,12 +444,12 @@ dis_nested_0 = """\
dis_nested_1 = """%s
Disassembly of <code object foo at 0x..., file "%s", line %d>:
-%3d 0 LOAD_CLOSURE 0 (x)
+%3d 0 LOAD_CLOSURE 1 (x)
2 BUILD_TUPLE 1
4 LOAD_CONST 1 (<code object <listcomp> at 0x..., file "%s", line %d>)
6 LOAD_CONST 2 ('_h.<locals>.foo.<locals>.<listcomp>')
8 MAKE_FUNCTION 8 (closure)
- 10 LOAD_DEREF 1 (y)
+ 10 LOAD_DEREF 2 (y)
12 GET_ITER
14 CALL_FUNCTION 1
16 RETURN_VALUE
@@ -467,7 +467,7 @@ Disassembly of <code object <listcomp> at 0x..., file "%s", line %d>:
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 6 (to 18)
6 STORE_FAST 1 (z)
- 8 LOAD_DEREF 0 (x)
+ 8 LOAD_DEREF 2 (x)
10 LOAD_FAST 1 (z)
12 BINARY_ADD
14 LIST_APPEND 2
@@ -962,16 +962,16 @@ expected_jumpy_line = 1
Instruction = dis.Instruction
expected_opinfo_outer = [
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False),
- Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_CLOSURE', opcode=135, arg=4, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=6, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=10, starts_line=None, is_jump_target=False),
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=12, starts_line=None, is_jump_target=False),
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=14, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=16, starts_line=7, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=4, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='', argrepr="''", offset=22, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=1, argrepr='1', offset=24, starts_line=None, is_jump_target=False),
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=26, starts_line=None, is_jump_target=False),
@@ -985,20 +985,20 @@ expected_opinfo_outer = [
expected_opinfo_f = [
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False),
- Instruction(opname='LOAD_CLOSURE', opcode=135, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_CLOSURE', opcode=135, arg=5, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_CLOSURE', opcode=135, arg=6, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_CLOSURE', opcode=135, arg=4, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=10, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=14, starts_line=None, is_jump_target=False),
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=16, starts_line=None, is_jump_target=False),
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=18, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=20, starts_line=5, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='a', argrepr='a', offset=22, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='b', argrepr='b', offset=24, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='c', argrepr='c', offset=26, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='d', argrepr='d', offset=28, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=5, argval='a', argrepr='a', offset=22, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=6, argval='b', argrepr='b', offset=24, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='c', argrepr='c', offset=26, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=4, argval='d', argrepr='d', offset=28, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='', offset=30, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=32, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=34, starts_line=6, is_jump_target=False),
@@ -1007,10 +1007,10 @@ expected_opinfo_f = [
expected_opinfo_inner = [
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=0, starts_line=4, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
- Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=4, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
+ Instruction(opname='LOAD_DEREF', opcode=136, arg=5, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=10, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=12, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=6, argval=6, argrepr='', offset=14, starts_line=None, is_jump_target=False),