mirror of
https://github.com/python/cpython.git
synced 2025-10-17 04:08:28 +00:00
GH-125837: Split LOAD_CONST
into three. (GH-125972)
* Add LOAD_CONST_IMMORTAL opcode * Add LOAD_SMALL_INT opcode * Remove RETURN_CONST opcode
This commit is contained in:
parent
67f5c5bd6f
commit
faa3272fb8
33 changed files with 706 additions and 538 deletions
|
@ -775,7 +775,6 @@ class TestSpecifics(unittest.TestCase):
|
|||
self.assertEqual(repr(f1()), repr(const))
|
||||
|
||||
check_same_constant(None)
|
||||
check_same_constant(0)
|
||||
check_same_constant(0.0)
|
||||
check_same_constant(b'abc')
|
||||
check_same_constant('abc')
|
||||
|
@ -853,9 +852,9 @@ class TestSpecifics(unittest.TestCase):
|
|||
eval(compile(code, "file.py", "exec"), g)
|
||||
exec(code, g)
|
||||
f = g['f']
|
||||
expected = tuple([None, '', 1] + [f't{i}' for i in range(N)])
|
||||
expected = tuple([None, ''] + [f't{i}' for i in range(N)])
|
||||
self.assertEqual(f.__code__.co_consts, expected)
|
||||
expected = "".join(expected[3:])
|
||||
expected = "".join(expected[2:])
|
||||
self.assertEqual(expected, f())
|
||||
|
||||
# Stripping unused constants is not a strict requirement for the
|
||||
|
@ -867,7 +866,7 @@ class TestSpecifics(unittest.TestCase):
|
|||
def f1():
|
||||
"docstring"
|
||||
return 42
|
||||
self.assertEqual(f1.__code__.co_consts, (f1.__doc__, 42))
|
||||
self.assertEqual(f1.__code__.co_consts, (f1.__doc__,))
|
||||
|
||||
# This is a regression test for a CPython specific peephole optimizer
|
||||
# implementation bug present in a few releases. It's assertion verifies
|
||||
|
@ -884,7 +883,7 @@ class TestSpecifics(unittest.TestCase):
|
|||
# RETURN_VALUE opcode. This does not always crash an interpreter.
|
||||
# When you build with the clang memory sanitizer it reliably aborts.
|
||||
self.assertEqual(
|
||||
'RETURN_CONST',
|
||||
'RETURN_VALUE',
|
||||
list(dis.get_instructions(unused_code_at_end))[-1].opname)
|
||||
|
||||
@support.cpython_only
|
||||
|
@ -982,7 +981,6 @@ class TestSpecifics(unittest.TestCase):
|
|||
self.assertEqual(repr(f1()), repr(const1))
|
||||
self.assertEqual(repr(f2()), repr(const2))
|
||||
|
||||
check_different_constants(0, 0.0)
|
||||
check_different_constants(+0.0, -0.0)
|
||||
check_different_constants((0,), (0.0,))
|
||||
check_different_constants('a', b'a')
|
||||
|
@ -1045,8 +1043,8 @@ class TestSpecifics(unittest.TestCase):
|
|||
|
||||
for func in funcs:
|
||||
opcodes = list(dis.get_instructions(func))
|
||||
self.assertLessEqual(len(opcodes), 3)
|
||||
self.assertEqual('RETURN_CONST', opcodes[-1].opname)
|
||||
self.assertLessEqual(len(opcodes), 4)
|
||||
self.assertEqual('RETURN_VALUE', opcodes[-1].opname)
|
||||
self.assertEqual(None, opcodes[-1].argval)
|
||||
|
||||
def test_false_while_loop(self):
|
||||
|
@ -1063,8 +1061,8 @@ class TestSpecifics(unittest.TestCase):
|
|||
# Check that we did not raise but we also don't generate bytecode
|
||||
for func in funcs:
|
||||
opcodes = list(dis.get_instructions(func))
|
||||
self.assertEqual(2, len(opcodes))
|
||||
self.assertEqual('RETURN_CONST', opcodes[1].opname)
|
||||
self.assertEqual(3, len(opcodes))
|
||||
self.assertEqual('RETURN_VALUE', opcodes[-1].opname)
|
||||
self.assertEqual(None, opcodes[1].argval)
|
||||
|
||||
def test_consts_in_conditionals(self):
|
||||
|
@ -1738,7 +1736,7 @@ class TestSourcePositions(unittest.TestCase):
|
|||
line=1, end_line=3, column=0, end_column=36, occurrence=1)
|
||||
# The "error msg":
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_CONST',
|
||||
line=3, end_line=3, column=25, end_column=36, occurrence=4)
|
||||
line=3, end_line=3, column=25, end_column=36, occurrence=2)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL',
|
||||
line=1, end_line=3, column=0, end_column=36, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RAISE_VARARGS',
|
||||
|
@ -1760,7 +1758,7 @@ class TestSourcePositions(unittest.TestCase):
|
|||
line=1, end_line=2, column=1, end_column=8, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD',
|
||||
line=1, end_line=2, column=1, end_column=8, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST',
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE',
|
||||
line=4, end_line=4, column=7, end_column=14, occurrence=1)
|
||||
|
||||
def test_multiline_async_generator_expression(self):
|
||||
|
@ -1777,7 +1775,7 @@ class TestSourcePositions(unittest.TestCase):
|
|||
self.assertIsInstance(compiled_code, types.CodeType)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE',
|
||||
line=1, end_line=2, column=1, end_column=8, occurrence=2)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST',
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE',
|
||||
line=1, end_line=6, column=0, end_column=32, occurrence=1)
|
||||
|
||||
def test_multiline_list_comprehension(self):
|
||||
|
@ -1815,7 +1813,7 @@ class TestSourcePositions(unittest.TestCase):
|
|||
line=2, end_line=3, column=5, end_column=12, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD',
|
||||
line=2, end_line=3, column=5, end_column=12, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST',
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE',
|
||||
line=2, end_line=7, column=4, end_column=36, occurrence=1)
|
||||
|
||||
def test_multiline_set_comprehension(self):
|
||||
|
@ -1853,7 +1851,7 @@ class TestSourcePositions(unittest.TestCase):
|
|||
line=2, end_line=3, column=5, end_column=12, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD',
|
||||
line=2, end_line=3, column=5, end_column=12, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST',
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE',
|
||||
line=2, end_line=7, column=4, end_column=36, occurrence=1)
|
||||
|
||||
def test_multiline_dict_comprehension(self):
|
||||
|
@ -1891,7 +1889,7 @@ class TestSourcePositions(unittest.TestCase):
|
|||
line=2, end_line=3, column=5, end_column=11, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD',
|
||||
line=2, end_line=3, column=5, end_column=11, occurrence=1)
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST',
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE',
|
||||
line=2, end_line=7, column=4, end_column=36, occurrence=1)
|
||||
|
||||
def test_matchcase_sequence(self):
|
||||
|
@ -2204,8 +2202,8 @@ class TestSourcePositions(unittest.TestCase):
|
|||
start_line, end_line, _, _ = instr.positions
|
||||
self.assertEqual(start_line, end_line)
|
||||
|
||||
# Expect three load None instructions for the no-exception __exit__ call,
|
||||
# and one RETURN_VALUE.
|
||||
# Expect four `LOAD_CONST None` instructions:
|
||||
# three for the no-exception __exit__ call, and one for the return.
|
||||
# They should all have the locations of the context manager ('xyz').
|
||||
|
||||
load_none = [instr for instr in dis.get_instructions(f) if
|
||||
|
@ -2213,8 +2211,8 @@ class TestSourcePositions(unittest.TestCase):
|
|||
return_value = [instr for instr in dis.get_instructions(f) if
|
||||
instr.opname == 'RETURN_VALUE']
|
||||
|
||||
self.assertEqual(len(load_none), 3)
|
||||
self.assertEqual(len(return_value), 1)
|
||||
self.assertEqual(len(load_none), 4)
|
||||
self.assertEqual(len(return_value), 2)
|
||||
for instr in load_none + return_value:
|
||||
start_line, end_line, start_col, end_col = instr.positions
|
||||
self.assertEqual(start_line, f.__code__.co_firstlineno + 1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue