[Python-checkins] gh-106812: Small stack effect fixes (#107759)

gvanrossum webhook-mailer at python.org
Tue Aug 8 00:32:46 EDT 2023


https://github.com/python/cpython/commit/2df58dcd500dbedc61d0630374f9e94c522fe523
commit: 2df58dcd500dbedc61d0630374f9e94c522fe523
branch: main
author: Guido van Rossum <guido at python.org>
committer: gvanrossum <gvanrossum at gmail.com>
date: 2023-08-07T21:32:42-07:00
summary:

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 **`).

files:
M Tools/cases_generator/interpreter_definition.md
M Tools/cases_generator/parsing.py
M Tools/cases_generator/stacking.py

diff --git a/Tools/cases_generator/interpreter_definition.md b/Tools/cases_generator/interpreter_definition.md
index f141848631d04..5c4238756748a 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 5610ac661a894..cdd20d7a0b3f5 100644
--- a/Tools/cases_generator/parsing.py
+++ b/Tools/cases_generator/parsing.py
@@ -252,12 +252,14 @@ def cache_effect(self) -> CacheEffect | None:
 
     @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 23eca3037f896..d457ce01a8f43 100644
--- a/Tools/cases_generator/stacking.py
+++ b/Tools/cases_generator/stacking.py
@@ -120,6 +120,14 @@ def as_variable(self, lax: bool = False) -> str:
             ), 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,
                 )



More information about the Python-checkins mailing list