Skip to content

Commit 2dabe39

Browse files
committed
Ensure stack is consistent at end of for loops
1 parent eece9b0 commit 2dabe39

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

Lib/test/test_generated_cases.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,6 +2080,42 @@ def test_recording_uop_between_real_uops_rejected(self):
20802080
"non-recording, non-specializing uops"):
20812081
self.run_cases_test(input, "")
20822082

2083+
def test_escaping_in_loop(self):
2084+
input = """
2085+
inst(TEST_LOOP_SPILL, (a -- a)) {
2086+
int n = (int)oparg;
2087+
for (int i = 0; i < n; i++) {
2088+
escaping_inside_loop(a);
2089+
}
2090+
escaping_after_loop(a);
2091+
}
2092+
"""
2093+
output = """
2094+
TARGET(TEST_LOOP_SPILL) {
2095+
#if _Py_TAIL_CALL_INTERP
2096+
int opcode = TEST_LOOP_SPILL;
2097+
(void)(opcode);
2098+
#endif
2099+
frame->instr_ptr = next_instr;
2100+
next_instr += 1;
2101+
INSTRUCTION_STATS(TEST_LOOP_SPILL);
2102+
_PyStackRef a;
2103+
a = stack_pointer[-1];
2104+
int n = (int)oparg;
2105+
for (int i = 0; i < n; i++) {
2106+
_PyFrame_SetStackPointer(frame, stack_pointer);
2107+
_PyFrame_StackPointerValidate(frame);
2108+
escaping_inside_loop(a);
2109+
_PyFrame_StackPointerInvalidate(frame);
2110+
}
2111+
_PyFrame_SetStackPointer(frame, stack_pointer);
2112+
_PyFrame_StackPointerValidate(frame);
2113+
escaping_after_loop(a);
2114+
_PyFrame_StackPointerInvalidate(frame);
2115+
DISPATCH();
2116+
}
2117+
"""
2118+
self.run_cases_test(input, output)
20832119

20842120
class TestRecorderTableGeneration(unittest.TestCase):
20852121

Tools/cases_generator/generators_common.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,10 @@ def emit_ForStmt(
712712
self.out.emit(stmt.for_)
713713
for tkn in stmt.header:
714714
self.out.emit(tkn)
715-
return self._emit_stmt(stmt.body, uop, storage, inst)
715+
reachable, brace, body_storage = self._emit_stmt(stmt.body, uop, storage.copy(), inst)
716+
body_storage.merge(storage, self.out)
717+
self.out.emit(brace)
718+
return reachable, None, storage
716719

717720
def emit_WhileStmt(
718721
self,

0 commit comments

Comments
 (0)