Skip to content

Commit 2df58dc

Browse files
authored
gh-106812: Small stack effect fixes (#107759)
- Generalize the syntax for the type of a stack effect to allow a trailing `*`, so we can declare something as e.g. `PyCodeObject *`. - When generating assignments for stack effects, the type of the value on the stack should be the default (i.e., `PyObject *`) even when the variable copied to/from it has a different type, so that an appropriate cast is generated However, not when the variable is an array -- then the type is taken from the variable (as it is always `PyObject **`).
1 parent 707018c commit 2df58dc

File tree

3 files changed

+15
-20
lines changed

3 files changed

+15
-20
lines changed

Tools/cases_generator/interpreter_definition.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ and a piece of C code describing its semantics::
108108
NAME [":" type] [ "if" "(" C-expression ")" ]
109109
110110
type:
111-
NAME
111+
NAME ["*"]
112112
113113
stream:
114114
NAME "/" size

Tools/cases_generator/parsing.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,14 @@ def cache_effect(self) -> CacheEffect | None:
252252

253253
@contextual
254254
def stack_effect(self) -> StackEffect | None:
255-
# IDENTIFIER [':' IDENTIFIER] ['if' '(' expression ')']
255+
# IDENTIFIER [':' IDENTIFIER [TIMES]] ['if' '(' expression ')']
256256
# | IDENTIFIER '[' expression ']'
257257
if tkn := self.expect(lx.IDENTIFIER):
258258
type_text = ""
259259
if self.expect(lx.COLON):
260260
type_text = self.require(lx.IDENTIFIER).text.strip()
261+
if self.expect(lx.TIMES):
262+
type_text += " *"
261263
cond_text = ""
262264
if self.expect(lx.IF):
263265
self.require(lx.LPAREN)

Tools/cases_generator/stacking.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ def as_variable(self, lax: bool = False) -> str:
120120
), f"Push or pop above current stack level: {res}"
121121
return res
122122

123+
def as_stack_effect(self, lax: bool = False) -> StackEffect:
124+
return StackEffect(
125+
self.as_variable(lax=lax),
126+
self.effect.type if self.effect.size else "",
127+
self.effect.cond,
128+
self.effect.size,
129+
)
130+
123131

124132
@dataclasses.dataclass
125133
class CopyEffect:
@@ -356,24 +364,14 @@ def write_components(
356364
for peek in mgr.peeks:
357365
out.assign(
358366
peek.effect,
359-
StackEffect(
360-
peek.as_variable(),
361-
peek.effect.type,
362-
peek.effect.cond,
363-
peek.effect.size,
364-
),
367+
peek.as_stack_effect(),
365368
)
366369
# Initialize array outputs
367370
for poke in mgr.pokes:
368371
if poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names:
369372
out.assign(
370373
poke.effect,
371-
StackEffect(
372-
poke.as_variable(lax=True),
373-
poke.effect.type,
374-
poke.effect.cond,
375-
poke.effect.size,
376-
),
374+
poke.as_stack_effect(lax=True),
377375
)
378376

379377
if len(parts) == 1:
@@ -390,11 +388,6 @@ def write_components(
390388
for poke in mgr.pokes:
391389
if not poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names:
392390
out.assign(
393-
StackEffect(
394-
poke.as_variable(),
395-
poke.effect.type,
396-
poke.effect.cond,
397-
poke.effect.size,
398-
),
391+
poke.as_stack_effect(),
399392
poke.effect,
400393
)

0 commit comments

Comments
 (0)