[Python-checkins] gh-98831: rewrite MAKE_FUNCTION and BUILD_SLICE in the instruction definition DSL (#101529)

iritkatriel webhook-mailer at python.org
Fri Feb 3 09:40:56 EST 2023


https://github.com/python/cpython/commit/433fb3ef08c71b97a0d08e522df56e0afaf3747a
commit: 433fb3ef08c71b97a0d08e522df56e0afaf3747a
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2023-02-03T14:40:45Z
summary:

gh-98831: rewrite MAKE_FUNCTION and BUILD_SLICE in the instruction definition DSL (#101529)

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 74c53ad1579f..8993567ac822 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -2972,36 +2972,39 @@ dummy_func(
             CHECK_EVAL_BREAKER();
         }
 
-        // error: MAKE_FUNCTION has irregular stack effect
-        inst(MAKE_FUNCTION) {
-            PyObject *codeobj = POP();
-            PyFunctionObject *func = (PyFunctionObject *)
+        inst(MAKE_FUNCTION, (defaults    if (oparg & 0x01),
+                             kwdefaults  if (oparg & 0x02),
+                             annotations if (oparg & 0x04),
+                             closure     if (oparg & 0x08),
+                             codeobj -- func)) {
+
+            PyFunctionObject *func_obj = (PyFunctionObject *)
                 PyFunction_New(codeobj, GLOBALS());
 
             Py_DECREF(codeobj);
-            if (func == NULL) {
+            if (func_obj == NULL) {
                 goto error;
             }
 
             if (oparg & 0x08) {
-                assert(PyTuple_CheckExact(TOP()));
-                func->func_closure = POP();
+                assert(PyTuple_CheckExact(closure));
+                func_obj->func_closure = closure;
             }
             if (oparg & 0x04) {
-                assert(PyTuple_CheckExact(TOP()));
-                func->func_annotations = POP();
+                assert(PyTuple_CheckExact(annotations));
+                func_obj->func_annotations = annotations;
             }
             if (oparg & 0x02) {
-                assert(PyDict_CheckExact(TOP()));
-                func->func_kwdefaults = POP();
+                assert(PyDict_CheckExact(kwdefaults));
+                func_obj->func_kwdefaults = kwdefaults;
             }
             if (oparg & 0x01) {
-                assert(PyTuple_CheckExact(TOP()));
-                func->func_defaults = POP();
+                assert(PyTuple_CheckExact(defaults));
+                func_obj->func_defaults = defaults;
             }
 
-            func->func_version = ((PyCodeObject *)codeobj)->co_version;
-            PUSH((PyObject *)func);
+            func_obj->func_version = ((PyCodeObject *)codeobj)->co_version;
+            func = (PyObject *)func_obj;
         }
 
         inst(RETURN_GENERATOR, (--)) {
@@ -3027,22 +3030,12 @@ dummy_func(
             goto resume_frame;
         }
 
-        // error: BUILD_SLICE has irregular stack effect
-        inst(BUILD_SLICE) {
-            PyObject *start, *stop, *step, *slice;
-            if (oparg == 3)
-                step = POP();
-            else
-                step = NULL;
-            stop = POP();
-            start = TOP();
+        inst(BUILD_SLICE, (start, stop, step if (oparg == 3) -- slice)) {
             slice = PySlice_New(start, stop, step);
             Py_DECREF(start);
             Py_DECREF(stop);
             Py_XDECREF(step);
-            SET_TOP(slice);
-            if (slice == NULL)
-                goto error;
+            ERROR_IF(slice == NULL, error);
         }
 
         // error: FORMAT_VALUE has irregular stack effect
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 6f90d9ca4a59..e524bfcb99d4 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -3584,34 +3584,42 @@
         }
 
         TARGET(MAKE_FUNCTION) {
-            PyObject *codeobj = POP();
-            PyFunctionObject *func = (PyFunctionObject *)
+            PyObject *codeobj = PEEK(1);
+            PyObject *closure = (oparg & 0x08) ? PEEK(1 + ((oparg & 0x08) ? 1 : 0)) : NULL;
+            PyObject *annotations = (oparg & 0x04) ? PEEK(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0)) : NULL;
+            PyObject *kwdefaults = (oparg & 0x02) ? PEEK(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0)) : NULL;
+            PyObject *defaults = (oparg & 0x01) ? PEEK(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0)) : NULL;
+            PyObject *func;
+
+            PyFunctionObject *func_obj = (PyFunctionObject *)
                 PyFunction_New(codeobj, GLOBALS());
 
             Py_DECREF(codeobj);
-            if (func == NULL) {
+            if (func_obj == NULL) {
                 goto error;
             }
 
             if (oparg & 0x08) {
-                assert(PyTuple_CheckExact(TOP()));
-                func->func_closure = POP();
+                assert(PyTuple_CheckExact(closure));
+                func_obj->func_closure = closure;
             }
             if (oparg & 0x04) {
-                assert(PyTuple_CheckExact(TOP()));
-                func->func_annotations = POP();
+                assert(PyTuple_CheckExact(annotations));
+                func_obj->func_annotations = annotations;
             }
             if (oparg & 0x02) {
-                assert(PyDict_CheckExact(TOP()));
-                func->func_kwdefaults = POP();
+                assert(PyDict_CheckExact(kwdefaults));
+                func_obj->func_kwdefaults = kwdefaults;
             }
             if (oparg & 0x01) {
-                assert(PyTuple_CheckExact(TOP()));
-                func->func_defaults = POP();
+                assert(PyTuple_CheckExact(defaults));
+                func_obj->func_defaults = defaults;
             }
 
-            func->func_version = ((PyCodeObject *)codeobj)->co_version;
-            PUSH((PyObject *)func);
+            func_obj->func_version = ((PyCodeObject *)codeobj)->co_version;
+            func = (PyObject *)func_obj;
+            STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0));
+            POKE(1, func);
             DISPATCH();
         }
 
@@ -3639,20 +3647,18 @@
         }
 
         TARGET(BUILD_SLICE) {
-            PyObject *start, *stop, *step, *slice;
-            if (oparg == 3)
-                step = POP();
-            else
-                step = NULL;
-            stop = POP();
-            start = TOP();
+            PyObject *step = (oparg == 3) ? PEEK(((oparg == 3) ? 1 : 0)) : NULL;
+            PyObject *stop = PEEK(1 + ((oparg == 3) ? 1 : 0));
+            PyObject *start = PEEK(2 + ((oparg == 3) ? 1 : 0));
+            PyObject *slice;
             slice = PySlice_New(start, stop, step);
             Py_DECREF(start);
             Py_DECREF(stop);
             Py_XDECREF(step);
-            SET_TOP(slice);
-            if (slice == NULL)
-                goto error;
+            if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; }
+            STACK_SHRINK(((oparg == 3) ? 1 : 0));
+            STACK_SHRINK(1);
+            POKE(1, slice);
             DISPATCH();
         }
 
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index 256f81a89fcd..857526c35aa5 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -325,11 +325,11 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
         case CALL_FUNCTION_EX:
             return -1;
         case MAKE_FUNCTION:
-            return -1;
+            return ((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0) + 1;
         case RETURN_GENERATOR:
             return 0;
         case BUILD_SLICE:
-            return -1;
+            return ((oparg == 3) ? 1 : 0) + 2;
         case FORMAT_VALUE:
             return -1;
         case COPY:
@@ -671,11 +671,11 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
         case CALL_FUNCTION_EX:
             return -1;
         case MAKE_FUNCTION:
-            return -1;
+            return 1;
         case RETURN_GENERATOR:
             return 0;
         case BUILD_SLICE:
-            return -1;
+            return 1;
         case FORMAT_VALUE:
             return -1;
         case COPY:



More information about the Python-checkins mailing list