summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-08-08 04:32:42 (GMT)
committerGitHub <noreply@github.com>2023-08-08 04:32:42 (GMT)
commit2df58dcd500dbedc61d0630374f9e94c522fe523 (patch)
tree89ef17fd39005e7c133588dead81cbed6021e4c4
parent707018cc75558d6695e9e199a3ed0c8a4ff7cbcc (diff)
downloadcpython-2df58dcd500dbedc61d0630374f9e94c522fe523.zip
cpython-2df58dcd500dbedc61d0630374f9e94c522fe523.tar.gz
cpython-2df58dcd500dbedc61d0630374f9e94c522fe523.tar.bz2
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 **`).
-rw-r--r--Tools/cases_generator/interpreter_definition.md2
-rw-r--r--Tools/cases_generator/parsing.py4
-rw-r--r--Tools/cases_generator/stacking.py29
3 files changed, 15 insertions, 20 deletions
diff --git a/Tools/cases_generator/interpreter_definition.md b/Tools/cases_generator/interpreter_definition.md
index f141848..5c42387 100644
--- a/Tools/cases_generator/interpreter_definition.md
+++ b/Tools/cases_generator/interpreter_definition.md
@@ -108,7 +108,7 @@ and a piece of C code describing its semantics::
NAME [":" type] [ "if" "(" C-expression ")" ]
type:
- NAME
+ NAME ["*"]
stream:
NAME "/" size
diff --git a/Tools/cases_generator/parsing.py b/Tools/cases_generator/parsing.py
index 5610ac6..cdd20d7 100644
--- a/Tools/cases_generator/parsing.py
+++ b/Tools/cases_generator/parsing.py
@@ -252,12 +252,14 @@ class Parser(PLexer):
@contextual
def stack_effect(self) -> StackEffect | None:
- # IDENTIFIER [':' IDENTIFIER] ['if' '(' expression ')']
+ # IDENTIFIER [':' IDENTIFIER [TIMES]] ['if' '(' expression ')']
# | IDENTIFIER '[' expression ']'
if tkn := self.expect(lx.IDENTIFIER):
type_text = ""
if self.expect(lx.COLON):
type_text = self.require(lx.IDENTIFIER).text.strip()
+ if self.expect(lx.TIMES):
+ type_text += " *"
cond_text = ""
if self.expect(lx.IF):
self.require(lx.LPAREN)
diff --git a/Tools/cases_generator/stacking.py b/Tools/cases_generator/stacking.py
index 23eca30..d457ce0 100644
--- a/Tools/cases_generator/stacking.py
+++ b/Tools/cases_generator/stacking.py
@@ -120,6 +120,14 @@ class StackItem:
), f"Push or pop above current stack level: {res}"
return res
+ def as_stack_effect(self, lax: bool = False) -> StackEffect:
+ return StackEffect(
+ self.as_variable(lax=lax),
+ self.effect.type if self.effect.size else "",
+ self.effect.cond,
+ self.effect.size,
+ )
+
@dataclasses.dataclass
class CopyEffect:
@@ -356,24 +364,14 @@ def write_components(
for peek in mgr.peeks:
out.assign(
peek.effect,
- StackEffect(
- peek.as_variable(),
- peek.effect.type,
- peek.effect.cond,
- peek.effect.size,
- ),
+ peek.as_stack_effect(),
)
# Initialize array outputs
for poke in mgr.pokes:
if poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names:
out.assign(
poke.effect,
- StackEffect(
- poke.as_variable(lax=True),
- poke.effect.type,
- poke.effect.cond,
- poke.effect.size,
- ),
+ poke.as_stack_effect(lax=True),
)
if len(parts) == 1:
@@ -390,11 +388,6 @@ def write_components(
for poke in mgr.pokes:
if not poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names:
out.assign(
- StackEffect(
- poke.as_variable(),
- poke.effect.type,
- poke.effect.cond,
- poke.effect.size,
- ),
+ poke.as_stack_effect(),
poke.effect,
)