[Python-checkins] gh-98831: rewrite RERAISE and CLEANUP_THROW in the instruction definition DSL (#101511)

iritkatriel webhook-mailer at python.org
Thu Feb 2 05:03:17 EST 2023


https://github.com/python/cpython/commit/0675b8f032c69d265468b31d5cadac6a7ce4bd9c
commit: 0675b8f032c69d265468b31d5cadac6a7ce4bd9c
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2023-02-02T10:02:57Z
summary:

gh-98831: rewrite RERAISE and CLEANUP_THROW in the instruction definition DSL (#101511)

files:
M Python/bytecodes.c
M Python/generated_cases.c.h
M Python/opcode_metadata.h

diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index fb41c8387ccc..169a2647866b 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -739,10 +739,10 @@ dummy_func(
             Py_XSETREF(exc_info->exc_value, exc_value);
         }
 
-        // stack effect: (__0 -- )
-        inst(RERAISE) {
+        inst(RERAISE, (values[oparg], exc -- values[oparg])) {
+            assert(oparg >= 0 && oparg <= 2);
             if (oparg) {
-                PyObject *lasti = PEEK(oparg + 1);
+                PyObject *lasti = values[0];
                 if (PyLong_Check(lasti)) {
                     frame->prev_instr = _PyCode_CODE(frame->f_code) + PyLong_AsLong(lasti);
                     assert(!_PyErr_Occurred(tstate));
@@ -753,11 +753,11 @@ dummy_func(
                     goto error;
                 }
             }
-            PyObject *val = POP();
-            assert(val && PyExceptionInstance_Check(val));
-            PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val));
-            PyObject *tb = PyException_GetTraceback(val);
-            _PyErr_Restore(tstate, exc, val, tb);
+            assert(exc && PyExceptionInstance_Check(exc));
+            Py_INCREF(exc);
+            PyObject *typ = Py_NewRef(PyExceptionInstance_Class(exc));
+            PyObject *tb = PyException_GetTraceback(exc);
+            _PyErr_Restore(tstate, typ, exc, tb);
             goto exception_unwind;
         }
 
@@ -784,18 +784,12 @@ dummy_func(
             }
         }
 
-        // stack effect: (__0, __1 -- )
-        inst(CLEANUP_THROW) {
+        inst(CLEANUP_THROW, (sub_iter, last_sent_val, exc_value -- value)) {
             assert(throwflag);
-            PyObject *exc_value = TOP();
             assert(exc_value && PyExceptionInstance_Check(exc_value));
             if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) {
-                PyObject *value = ((PyStopIterationObject *)exc_value)->value;
-                Py_INCREF(value);
-                Py_DECREF(POP());  // The StopIteration.
-                Py_DECREF(POP());  // The last sent value.
-                Py_DECREF(POP());  // The delegated sub-iterator.
-                PUSH(value);
+                value = Py_NewRef(((PyStopIterationObject *)exc_value)->value);
+                DECREF_INPUTS();
             }
             else {
                 PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value));
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 77f9b00c4f0a..97263866fe91 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -945,8 +945,11 @@
         }
 
         TARGET(RERAISE) {
+            PyObject *exc = PEEK(1);
+            PyObject **values = &PEEK(1 + oparg);
+            assert(oparg >= 0 && oparg <= 2);
             if (oparg) {
-                PyObject *lasti = PEEK(oparg + 1);
+                PyObject *lasti = values[0];
                 if (PyLong_Check(lasti)) {
                     frame->prev_instr = _PyCode_CODE(frame->f_code) + PyLong_AsLong(lasti);
                     assert(!_PyErr_Occurred(tstate));
@@ -957,11 +960,11 @@
                     goto error;
                 }
             }
-            PyObject *val = POP();
-            assert(val && PyExceptionInstance_Check(val));
-            PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val));
-            PyObject *tb = PyException_GetTraceback(val);
-            _PyErr_Restore(tstate, exc, val, tb);
+            assert(exc && PyExceptionInstance_Check(exc));
+            Py_INCREF(exc);
+            PyObject *typ = Py_NewRef(PyExceptionInstance_Class(exc));
+            PyObject *tb = PyException_GetTraceback(exc);
+            _PyErr_Restore(tstate, typ, exc, tb);
             goto exception_unwind;
         }
 
@@ -1001,16 +1004,17 @@
         }
 
         TARGET(CLEANUP_THROW) {
+            PyObject *exc_value = PEEK(1);
+            PyObject *last_sent_val = PEEK(2);
+            PyObject *sub_iter = PEEK(3);
+            PyObject *value;
             assert(throwflag);
-            PyObject *exc_value = TOP();
             assert(exc_value && PyExceptionInstance_Check(exc_value));
             if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) {
-                PyObject *value = ((PyStopIterationObject *)exc_value)->value;
-                Py_INCREF(value);
-                Py_DECREF(POP());  // The StopIteration.
-                Py_DECREF(POP());  // The last sent value.
-                Py_DECREF(POP());  // The delegated sub-iterator.
-                PUSH(value);
+                value = Py_NewRef(((PyStopIterationObject *)exc_value)->value);
+                Py_DECREF(sub_iter);
+                Py_DECREF(last_sent_val);
+                Py_DECREF(exc_value);
             }
             else {
                 PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value));
@@ -1018,6 +1022,8 @@
                 _PyErr_Restore(tstate, exc_type, Py_NewRef(exc_value), exc_traceback);
                 goto exception_unwind;
             }
+            STACK_SHRINK(2);
+            POKE(1, value);
             DISPATCH();
         }
 
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index f0bdedeb667d..ca3dde363bfd 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -105,13 +105,13 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
         case POP_EXCEPT:
             return 1;
         case RERAISE:
-            return -1;
+            return oparg + 1;
         case PREP_RERAISE_STAR:
             return 2;
         case END_ASYNC_FOR:
             return 2;
         case CLEANUP_THROW:
-            return -1;
+            return 3;
         case LOAD_ASSERTION_ERROR:
             return 0;
         case LOAD_BUILD_CLASS:
@@ -451,13 +451,13 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
         case POP_EXCEPT:
             return 0;
         case RERAISE:
-            return -1;
+            return oparg;
         case PREP_RERAISE_STAR:
             return 1;
         case END_ASYNC_FOR:
             return 0;
         case CLEANUP_THROW:
-            return -1;
+            return 1;
         case LOAD_ASSERTION_ERROR:
             return 1;
         case LOAD_BUILD_CLASS:



More information about the Python-checkins mailing list