gh-125063: Emit slices as constants in the bytecode compiler (#125064)

* Make slices marshallable

* Emit slices as constants

* Update Python/marshal.c

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>

* Refactor codegen_slice into two functions so it
always has the same net effect

* Fix for free-threaded builds

* Simplify marshal loading of slices

* Only return SUCCESS/ERROR from codegen_slice

---------

Co-authored-by: Mark Shannon <mark@hotpy.org>
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
This commit is contained in:
Michael Droettboom 2024-10-08 13:18:39 -04:00 committed by GitHub
parent 7dca7322cc
commit c6127af868
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 122 additions and 23 deletions

View file

@ -1386,6 +1386,14 @@ class TestSpecifics(unittest.TestCase):
actual += 1
self.assertEqual(actual, expected)
def check_consts(func, typ, expected):
slice_consts = 0
consts = func.__code__.co_consts
for instr in dis.Bytecode(func):
if instr.opname == "LOAD_CONST" and isinstance(consts[instr.oparg], typ):
slice_consts += 1
self.assertEqual(slice_consts, expected)
def load():
return x[a:b] + x [a:] + x[:b] + x[:]
@ -1401,15 +1409,30 @@ class TestSpecifics(unittest.TestCase):
def aug():
x[a:b] += y
check_op_count(load, "BINARY_SLICE", 4)
def aug_const():
x[1:2] += y
def compound_const_slice():
x[1:2:3, 4:5:6] = y
check_op_count(load, "BINARY_SLICE", 3)
check_op_count(load, "BUILD_SLICE", 0)
check_op_count(store, "STORE_SLICE", 4)
check_consts(load, slice, 1)
check_op_count(store, "STORE_SLICE", 3)
check_op_count(store, "BUILD_SLICE", 0)
check_consts(store, slice, 1)
check_op_count(long_slice, "BUILD_SLICE", 1)
check_op_count(long_slice, "BINARY_SLICE", 0)
check_op_count(aug, "BINARY_SLICE", 1)
check_op_count(aug, "STORE_SLICE", 1)
check_op_count(aug, "BUILD_SLICE", 0)
check_op_count(aug_const, "BINARY_SLICE", 0)
check_op_count(aug_const, "STORE_SLICE", 0)
check_consts(aug_const, slice, 1)
check_op_count(compound_const_slice, "BINARY_SLICE", 0)
check_op_count(compound_const_slice, "BUILD_SLICE", 0)
check_consts(compound_const_slice, slice, 0)
check_consts(compound_const_slice, tuple, 1)
def test_compare_positions(self):
for opname_prefix, op in [