summaryrefslogtreecommitdiff
path: root/Tools
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-02-07 15:44:37 -0800
committerGitHub <noreply@github.com>2023-02-07 15:44:37 -0800
commitaacbdb0c650492756738b044e6ddf8b72f89a1a2 (patch)
treef36e5be44c5415e626b72f0255f46a1615eff29e /Tools
parentgh-101632: Add the new RETURN_CONST opcode (#101633) (diff)
downloadcpython-aacbdb0c650492756738b044e6ddf8b72f89a1a2.tar.gz
cpython-aacbdb0c650492756738b044e6ddf8b72f89a1a2.tar.bz2
cpython-aacbdb0c650492756738b044e6ddf8b72f89a1a2.zip
gh-98831: Finish the UNPACK_SEQUENCE family (#101666)
New generator feature: Generate useful glue for output arrays, so you can just write values to the output array (no bounds checking). Rewrote UNPACK_SEQUENCE_TWO_TUPLE to use this, and also UNPACK_SEQUENCE_{TUPLE,LIST}.
Diffstat (limited to 'Tools')
-rw-r--r--Tools/cases_generator/generate_cases.py25
-rw-r--r--Tools/cases_generator/test_generator.py19
2 files changed, 26 insertions, 18 deletions
diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py
index 3925583b40e..4f94b48d114 100644
--- a/Tools/cases_generator/generate_cases.py
+++ b/Tools/cases_generator/generate_cases.py
@@ -180,11 +180,8 @@ class Formatter:
stmt = f"if ({src.cond}) {{ {stmt} }}"
self.emit(stmt)
elif m := re.match(r"^&PEEK\(.*\)$", dst.name):
- # NOTE: MOVE_ITEMS() does not actually exist.
- # The only supported output array forms are:
- # - unused[...]
- # - X[...] where X[...] matches an input array exactly
- self.emit(f"MOVE_ITEMS({dst.name}, {src.name}, {src.size});")
+ # The user code is responsible for writing to the output array.
+ pass
elif m := re.match(r"^REG\(oparg(\d+)\)$", dst.name):
self.emit(f"Py_XSETREF({dst.name}, {cast}{src.name});")
else:
@@ -309,10 +306,24 @@ class Instruction:
out.declare(ieffect, src)
# Write output stack effect variable declarations
+ isize = string_effect_size(list_effect_size(self.input_effects))
input_names = {ieffect.name for ieffect in self.input_effects}
- for oeffect in self.output_effects:
+ for i, oeffect in enumerate(self.output_effects):
if oeffect.name not in input_names:
- out.declare(oeffect, None)
+ if oeffect.size:
+ osize = string_effect_size(
+ list_effect_size([oeff for oeff in self.output_effects[:i]])
+ )
+ offset = "stack_pointer"
+ if isize != osize:
+ if isize != "0":
+ offset += f" - ({isize})"
+ if osize != "0":
+ offset += f" + {osize}"
+ src = StackEffect(offset, "PyObject **")
+ out.declare(oeffect, src)
+ else:
+ out.declare(oeffect, None)
# out.emit(f"JUMPBY(OPSIZE({self.inst.name}) - 1);")
diff --git a/Tools/cases_generator/test_generator.py b/Tools/cases_generator/test_generator.py
index 9df97d24ab6..0c3d04b45dd 100644
--- a/Tools/cases_generator/test_generator.py
+++ b/Tools/cases_generator/test_generator.py
@@ -424,20 +424,18 @@ def test_array_input():
def test_array_output():
input = """
- inst(OP, (-- below, values[oparg*3], above)) {
- spam();
+ inst(OP, (unused, unused -- below, values[oparg*3], above)) {
+ spam(values, oparg);
}
"""
output = """
TARGET(OP) {
PyObject *below;
- PyObject **values;
+ PyObject **values = stack_pointer - (2) + 1;
PyObject *above;
- spam();
- STACK_GROW(2);
+ spam(values, oparg);
STACK_GROW(oparg*3);
POKE(1, above);
- MOVE_ITEMS(&PEEK(1 + oparg*3), values, oparg*3);
POKE(2 + oparg*3, below);
DISPATCH();
}
@@ -446,18 +444,17 @@ def test_array_output():
def test_array_input_output():
input = """
- inst(OP, (below, values[oparg] -- values[oparg], above)) {
- spam();
+ inst(OP, (values[oparg] -- values[oparg], above)) {
+ spam(values, oparg);
}
"""
output = """
TARGET(OP) {
PyObject **values = &PEEK(oparg);
- PyObject *below = PEEK(1 + oparg);
PyObject *above;
- spam();
+ spam(values, oparg);
+ STACK_GROW(1);
POKE(1, above);
- MOVE_ITEMS(&PEEK(1 + oparg), values, oparg);
DISPATCH();
}
"""