diff options
author | Guido van Rossum <guido@python.org> | 2023-08-08 04:32:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-08 04:32:42 (GMT) |
commit | 2df58dcd500dbedc61d0630374f9e94c522fe523 (patch) | |
tree | 89ef17fd39005e7c133588dead81cbed6021e4c4 | |
parent | 707018cc75558d6695e9e199a3ed0c8a4ff7cbcc (diff) | |
download | cpython-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.md | 2 | ||||
-rw-r--r-- | Tools/cases_generator/parsing.py | 4 | ||||
-rw-r--r-- | Tools/cases_generator/stacking.py | 29 |
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, ) |