gh-126211: Exclude preprocessor directives from statements containing escaping calls (#126213)

The cases generator inserts code to save and restore the stack pointer around
statements that contain escaping calls. To find the beginning of such statements,
we would walk backwards from the escaping call until we encountered a token that
was treated as a statement terminator. This set of terminators should include
preprocessor directives.
This commit is contained in:
mpage 2024-11-01 08:53:03 -07:00 committed by GitHub
parent 32e07fd377
commit 821759d631
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 1 deletions

View File

@ -1429,6 +1429,39 @@ class TestGeneratedCases(unittest.TestCase):
with self.assertRaisesRegex(SyntaxError, "All instructions containing a uop"):
self.run_cases_test(input, output)
def test_escaping_call_next_to_cmacro(self):
input = """
inst(OP, (--)) {
#ifdef Py_GIL_DISABLED
escaping_call();
#else
another_escaping_call();
#endif
yet_another_escaping_call();
}
"""
output = """
TARGET(OP) {
frame->instr_ptr = next_instr;
next_instr += 1;
INSTRUCTION_STATS(OP);
#ifdef Py_GIL_DISABLED
_PyFrame_SetStackPointer(frame, stack_pointer);
escaping_call();
stack_pointer = _PyFrame_GetStackPointer(frame);
#else
_PyFrame_SetStackPointer(frame, stack_pointer);
another_escaping_call();
stack_pointer = _PyFrame_GetStackPointer(frame);
#endif
_PyFrame_SetStackPointer(frame, stack_pointer);
yet_another_escaping_call();
stack_pointer = _PyFrame_GetStackPointer(frame);
DISPATCH();
}
"""
self.run_cases_test(input, output)
class TestGeneratedAbstractCases(unittest.TestCase):
def setUp(self) -> None:

View File

@ -637,7 +637,7 @@ def find_stmt_start(node: parser.InstDef, idx: int) -> lexer.Token:
assert idx < len(node.block.tokens)
while True:
tkn = node.block.tokens[idx-1]
if tkn.kind in {"SEMI", "LBRACE", "RBRACE"}:
if tkn.kind in {"SEMI", "LBRACE", "RBRACE", "CMACRO"}:
break
idx -= 1
assert idx > 0