[Python-checkins] cpython: Add _PyObject_FastCallVa() helper

victor.stinner python-checkins at python.org
Thu Dec 8 20:16:59 EST 2016


https://hg.python.org/cpython/rev/b771cf37714b
changeset:   105532:b771cf37714b
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Fri Dec 09 00:21:55 2016 +0100
summary:
  Add _PyObject_FastCallVa() helper

Issue #28915: Add _PyObject_FastCallVa() helper to factorize code of functions:

* PyObject_CallFunctionObjArgs()
* PyObject_CallMethodObjArgs()
* _PyObject_CallMethodIdObjArgs()

Inline objargs_mkstack() into _PyObject_FastCallVa(), remove
objargs_mkstack().

files:
  Objects/abstract.c |  118 +++++++++++---------------------
  1 files changed, 42 insertions(+), 76 deletions(-)


diff --git a/Objects/abstract.c b/Objects/abstract.c
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -2715,80 +2715,77 @@
     return retval;
 }
 
-static PyObject **
-objargs_mkstack(PyObject **small_stack, Py_ssize_t small_stack_size,
-                va_list va, Py_ssize_t *p_nargs)
+static PyObject *
+_PyObject_FastCallVa(PyObject *callable, va_list vargs)
 {
-    Py_ssize_t i, n;
+    PyObject *small_stack[5];
+    PyObject **stack;
+    Py_ssize_t nargs;
+    PyObject *result;
+    Py_ssize_t i;
     va_list countva;
-    PyObject **stack;
+
+    if (callable == NULL) {
+        return null_error();
+    }
 
     /* Count the number of arguments */
-    va_copy(countva, va);
-
-    n = 0;
+    va_copy(countva, vargs);
+    nargs = 0;
     while (1) {
         PyObject *arg = va_arg(countva, PyObject *);
         if (arg == NULL) {
             break;
         }
-        n++;
+        nargs++;
     }
-    *p_nargs = n;
+    va_end(countva);
 
     /* Copy arguments */
-    if (n <= small_stack_size) {
+    if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
         stack = small_stack;
     }
     else {
-        stack = PyMem_Malloc(n * sizeof(stack[0]));
+        stack = PyMem_Malloc(nargs * sizeof(stack[0]));
         if (stack == NULL) {
-            va_end(countva);
             PyErr_NoMemory();
             return NULL;
         }
     }
 
-    for (i = 0; i < n; ++i) {
-        stack[i] = va_arg(va, PyObject *);
+    for (i = 0; i < nargs; ++i) {
+        stack[i] = va_arg(vargs, PyObject *);
     }
-    va_end(countva);
-    return stack;
+
+    /* Call the function */
+    result = _PyObject_FastCall(callable, stack, nargs);
+
+    if (stack != small_stack) {
+        PyMem_Free(stack);
+    }
+    return result;
 }
 
 PyObject *
 PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
 {
-    PyObject *small_stack[5];
-    PyObject **stack;
-    Py_ssize_t nargs;
+    va_list vargs;
     PyObject *result;
-    va_list vargs;
 
     if (callable == NULL || name == NULL) {
         return null_error();
     }
 
     callable = PyObject_GetAttr(callable, name);
-    if (callable == NULL)
-        return NULL;
-
-    /* count the args */
-    va_start(vargs, name);
-    stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
-                            vargs, &nargs);
-    va_end(vargs);
-    if (stack == NULL) {
-        Py_DECREF(callable);
+    if (callable == NULL) {
         return NULL;
     }
 
-    result = _PyObject_FastCall(callable, stack, nargs);
+    va_start(vargs, name);
+    result = _PyObject_FastCallVa(callable, vargs);
+    va_end(vargs);
+
     Py_DECREF(callable);
-    if (stack != small_stack) {
-        PyMem_Free(stack);
-    }
-
     return result;
 }
 
@@ -2796,66 +2793,35 @@
 _PyObject_CallMethodIdObjArgs(PyObject *obj,
                               struct _Py_Identifier *name, ...)
 {
-    PyObject *small_stack[5];
-    PyObject **stack;
-    PyObject *callable;
-    Py_ssize_t nargs;
-    PyObject *result;
     va_list vargs;
+    PyObject *callable, *result;
 
     if (obj == NULL || name == NULL) {
         return null_error();
     }
 
     callable = _PyObject_GetAttrId(obj, name);
-    if (callable == NULL)
-        return NULL;
-
-    /* count the args */
-    va_start(vargs, name);
-    stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
-                            vargs, &nargs);
-    va_end(vargs);
-    if (stack == NULL) {
-        Py_DECREF(callable);
+    if (callable == NULL) {
         return NULL;
     }
 
-    result = _PyObject_FastCall(callable, stack, nargs);
+    va_start(vargs, name);
+    result = _PyObject_FastCallVa(callable, vargs);
+    va_end(vargs);
+
     Py_DECREF(callable);
-    if (stack != small_stack) {
-        PyMem_Free(stack);
-    }
-
     return result;
 }
 
 PyObject *
 PyObject_CallFunctionObjArgs(PyObject *callable, ...)
 {
-    PyObject *small_stack[5];
-    PyObject **stack;
-    Py_ssize_t nargs;
+    va_list vargs;
     PyObject *result;
-    va_list vargs;
-
-    if (callable == NULL) {
-        return null_error();
-    }
-
-    /* count the args */
+
     va_start(vargs, callable);
-    stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
-                            vargs, &nargs);
+    result = _PyObject_FastCallVa(callable, vargs);
     va_end(vargs);
-    if (stack == NULL) {
-        return NULL;
-    }
-
-    result = _PyObject_FastCall(callable, stack, nargs);
-    if (stack != small_stack) {
-        PyMem_Free(stack);
-    }
 
     return result;
 }

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list