[Python-checkins] gh-98831: rewrite GET_LEN, GET_ITER, BEFORE_WITH and a few simple opcodes in the instruction definition DSL (#101443)

iritkatriel webhook-mailer at python.org
Tue Jan 31 05:23:37 EST 2023


https://github.com/python/cpython/commit/29a858b85f4c6479474b8d82c8995bde1166352b
commit: 29a858b85f4c6479474b8d82c8995bde1166352b
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2023-01-31T10:23:15Z
summary:

gh-98831: rewrite GET_LEN, GET_ITER, BEFORE_WITH and a few simple opcodes in the instruction definition DSL (#101443)

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 d1e59f7908b5..5b3bf4ec7ba7 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -2053,8 +2053,7 @@ dummy_func(
             }
         }
 
-        // stack effect: ( -- )
-        inst(JUMP_BACKWARD_NO_INTERRUPT) {
+        inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) {
             /* This bytecode is used in the `yield from` or `await` loop.
              * If there is an interrupt, we want it handled in the innermost
              * generator or coroutine, so we deliberately do not check it here.
@@ -2063,18 +2062,12 @@ dummy_func(
             JUMPBY(-oparg);
         }
 
-        // stack effect: ( -- __0)
-        inst(GET_LEN) {
+        inst(GET_LEN, (obj -- obj, len_o)) {
             // PUSH(len(TOS))
-            Py_ssize_t len_i = PyObject_Length(TOP());
-            if (len_i < 0) {
-                goto error;
-            }
-            PyObject *len_o = PyLong_FromSsize_t(len_i);
-            if (len_o == NULL) {
-                goto error;
-            }
-            PUSH(len_o);
+            Py_ssize_t len_i = PyObject_Length(obj);
+            ERROR_IF(len_i < 0, error);
+            len_o = PyLong_FromSsize_t(len_i);
+            ERROR_IF(len_o == NULL, error);
         }
 
         inst(MATCH_CLASS, (subject, type, names -- attrs)) {
@@ -2110,15 +2103,11 @@ dummy_func(
             ERROR_IF(values_or_none == NULL, error);
         }
 
-        // stack effect: ( -- )
-        inst(GET_ITER) {
+        inst(GET_ITER, (iterable -- iter)) {
             /* before: [obj]; after [getiter(obj)] */
-            PyObject *iterable = TOP();
-            PyObject *iter = PyObject_GetIter(iterable);
-            Py_DECREF(iterable);
-            SET_TOP(iter);
-            if (iter == NULL)
-                goto error;
+            iter = PyObject_GetIter(iterable);
+            DECREF_INPUTS();
+            ERROR_IF(iter == NULL, error);
         }
 
         // stack effect: ( -- )
@@ -2313,10 +2302,10 @@ dummy_func(
             PREDICT(GET_AWAITABLE);
         }
 
-        // stack effect: ( -- __0)
-        inst(BEFORE_WITH) {
-            PyObject *mgr = TOP();
-            PyObject *res;
+        inst(BEFORE_WITH, (mgr -- exit, res)) {
+            /* pop the context manager, push its __exit__ and the
+             * value returned from calling its __enter__
+             */
             PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__));
             if (enter == NULL) {
                 if (!_PyErr_Occurred(tstate)) {
@@ -2327,7 +2316,7 @@ dummy_func(
                 }
                 goto error;
             }
-            PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__));
+            exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__));
             if (exit == NULL) {
                 if (!_PyErr_Occurred(tstate)) {
                     _PyErr_Format(tstate, PyExc_TypeError,
@@ -2339,14 +2328,13 @@ dummy_func(
                 Py_DECREF(enter);
                 goto error;
             }
-            SET_TOP(exit);
-            Py_DECREF(mgr);
+            DECREF_INPUTS();
             res = _PyObject_CallNoArgs(enter);
             Py_DECREF(enter);
             if (res == NULL) {
-                goto error;
+                Py_DECREF(exit);
+                ERROR_IF(true, error);
             }
-            PUSH(res);
         }
 
         inst(WITH_EXCEPT_START, (exit_func, lasti, unused, val -- exit_func, lasti, unused, val, res)) {
@@ -2469,8 +2457,7 @@ dummy_func(
             GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS);
         }
 
-        // stack effect: ( -- )
-        inst(KW_NAMES) {
+        inst(KW_NAMES, (--)) {
             assert(kwnames == NULL);
             assert(oparg < PyTuple_GET_SIZE(consts));
             kwnames = GETITEM(consts, oparg);
@@ -3252,8 +3239,7 @@ dummy_func(
             PEEK(oparg) = top;
         }
 
-        // stack effect: ( -- )
-        inst(EXTENDED_ARG) {
+        inst(EXTENDED_ARG, (--)) {
             assert(oparg);
             assert(cframe.use_tracing == 0);
             opcode = _Py_OPCODE(*next_instr);
@@ -3262,8 +3248,7 @@ dummy_func(
             DISPATCH_GOTO();
         }
 
-        // stack effect: ( -- )
-        inst(CACHE) {
+        inst(CACHE, (--)) {
             Py_UNREACHABLE();
         }
 
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 3ee30ae8df9e..661fe27f327b 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -2460,16 +2460,15 @@
         }
 
         TARGET(GET_LEN) {
+            PyObject *obj = PEEK(1);
+            PyObject *len_o;
             // PUSH(len(TOS))
-            Py_ssize_t len_i = PyObject_Length(TOP());
-            if (len_i < 0) {
-                goto error;
-            }
-            PyObject *len_o = PyLong_FromSsize_t(len_i);
-            if (len_o == NULL) {
-                goto error;
-            }
-            PUSH(len_o);
+            Py_ssize_t len_i = PyObject_Length(obj);
+            if (len_i < 0) goto error;
+            len_o = PyLong_FromSsize_t(len_i);
+            if (len_o == NULL) goto error;
+            STACK_GROW(1);
+            POKE(1, len_o);
             DISPATCH();
         }
 
@@ -2532,13 +2531,13 @@
         }
 
         TARGET(GET_ITER) {
+            PyObject *iterable = PEEK(1);
+            PyObject *iter;
             /* before: [obj]; after [getiter(obj)] */
-            PyObject *iterable = TOP();
-            PyObject *iter = PyObject_GetIter(iterable);
+            iter = PyObject_GetIter(iterable);
             Py_DECREF(iterable);
-            SET_TOP(iter);
-            if (iter == NULL)
-                goto error;
+            if (iter == NULL) goto pop_1_error;
+            POKE(1, iter);
             DISPATCH();
         }
 
@@ -2736,8 +2735,12 @@
         }
 
         TARGET(BEFORE_WITH) {
-            PyObject *mgr = TOP();
+            PyObject *mgr = PEEK(1);
+            PyObject *exit;
             PyObject *res;
+            /* pop the context manager, push its __exit__ and the
+             * value returned from calling its __enter__
+             */
             PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__));
             if (enter == NULL) {
                 if (!_PyErr_Occurred(tstate)) {
@@ -2748,7 +2751,7 @@
                 }
                 goto error;
             }
-            PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__));
+            exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__));
             if (exit == NULL) {
                 if (!_PyErr_Occurred(tstate)) {
                     _PyErr_Format(tstate, PyExc_TypeError,
@@ -2760,14 +2763,16 @@
                 Py_DECREF(enter);
                 goto error;
             }
-            SET_TOP(exit);
             Py_DECREF(mgr);
             res = _PyObject_CallNoArgs(enter);
             Py_DECREF(enter);
             if (res == NULL) {
-                goto error;
+                Py_DECREF(exit);
+                if (true) goto pop_1_error;
             }
-            PUSH(res);
+            STACK_GROW(1);
+            POKE(1, res);
+            POKE(2, exit);
             DISPATCH();
         }
 
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index e76ddda2f029..c40e40ff324d 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -245,9 +245,9 @@ _PyOpcode_num_popped(int opcode, int oparg) {
         case JUMP_IF_TRUE_OR_POP:
             return -1;
         case JUMP_BACKWARD_NO_INTERRUPT:
-            return -1;
+            return 0;
         case GET_LEN:
-            return -1;
+            return 1;
         case MATCH_CLASS:
             return 3;
         case MATCH_MAPPING:
@@ -257,7 +257,7 @@ _PyOpcode_num_popped(int opcode, int oparg) {
         case MATCH_KEYS:
             return 2;
         case GET_ITER:
-            return -1;
+            return 1;
         case GET_YIELD_FROM_ITER:
             return -1;
         case FOR_ITER:
@@ -273,7 +273,7 @@ _PyOpcode_num_popped(int opcode, int oparg) {
         case BEFORE_ASYNC_WITH:
             return -1;
         case BEFORE_WITH:
-            return -1;
+            return 1;
         case WITH_EXCEPT_START:
             return 4;
         case PUSH_EXC_INFO:
@@ -287,7 +287,7 @@ _PyOpcode_num_popped(int opcode, int oparg) {
         case CALL_BOUND_METHOD_EXACT_ARGS:
             return -1;
         case KW_NAMES:
-            return -1;
+            return 0;
         case CALL:
             return -1;
         case CALL_PY_EXACT_ARGS:
@@ -339,9 +339,9 @@ _PyOpcode_num_popped(int opcode, int oparg) {
         case SWAP:
             return -1;
         case EXTENDED_ARG:
-            return -1;
+            return 0;
         case CACHE:
-            return -1;
+            return 0;
         default:
             Py_UNREACHABLE();
     }
@@ -591,9 +591,9 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
         case JUMP_IF_TRUE_OR_POP:
             return -1;
         case JUMP_BACKWARD_NO_INTERRUPT:
-            return -1;
+            return 0;
         case GET_LEN:
-            return -1;
+            return 2;
         case MATCH_CLASS:
             return 1;
         case MATCH_MAPPING:
@@ -603,7 +603,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
         case MATCH_KEYS:
             return 3;
         case GET_ITER:
-            return -1;
+            return 1;
         case GET_YIELD_FROM_ITER:
             return -1;
         case FOR_ITER:
@@ -619,7 +619,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
         case BEFORE_ASYNC_WITH:
             return -1;
         case BEFORE_WITH:
-            return -1;
+            return 2;
         case WITH_EXCEPT_START:
             return 5;
         case PUSH_EXC_INFO:
@@ -633,7 +633,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
         case CALL_BOUND_METHOD_EXACT_ARGS:
             return -1;
         case KW_NAMES:
-            return -1;
+            return 0;
         case CALL:
             return -1;
         case CALL_PY_EXACT_ARGS:
@@ -685,9 +685,9 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
         case SWAP:
             return -1;
         case EXTENDED_ARG:
-            return -1;
+            return 0;
         case CACHE:
-            return -1;
+            return 0;
         default:
             Py_UNREACHABLE();
     }



More information about the Python-checkins mailing list