changeset: 105532:b771cf37714b user: Victor Stinner date: Fri Dec 09 00:21:55 2016 +0100 files: Objects/abstract.c description: 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(). diff -r 5376b3a168c8 -r b771cf37714b Objects/abstract.c --- a/Objects/abstract.c Thu Dec 08 09:01:39 2016 -0800 +++ b/Objects/abstract.c Fri Dec 09 00:21:55 2016 +0100 @@ -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; }