diff -r 8f258245c391 Objects/abstract.c --- a/Objects/abstract.c Thu Dec 01 14:51:04 2016 +0100 +++ b/Objects/abstract.c Fri Dec 02 09:30:40 2016 +0200 @@ -2678,17 +2678,30 @@ PyObject * return retval; } -static PyObject ** -objargs_mkstack(PyObject **small_stack, Py_ssize_t small_stack_size, - va_list va, Py_ssize_t *p_nargs) +#define SMALL_STACK_SIZE 5 + +static PyObject * +call_small_stack(PyObject *callable, va_list va, Py_ssize_t n) +{ + PyObject *stack[SMALL_STACK_SIZE]; + Py_ssize_t i; + + /* Copy arguments */ + for (i = 0; i < n; ++i) { + stack[i] = va_arg(va, PyObject *); + } + return _PyObject_FastCall(callable, stack, n); +} + +static PyObject * +vcall(PyObject *callable, va_list va) { Py_ssize_t i, n; va_list countva; - PyObject **stack; + PyObject *result; /* Count the number of arguments */ va_copy(countva, va); - n = 0; while (1) { PyObject *arg = va_arg(countva, PyObject *); @@ -2697,34 +2710,38 @@ objargs_mkstack(PyObject **small_stack, } n++; } - *p_nargs = n; - - /* Copy arguments */ - if (n <= small_stack_size) { - stack = small_stack; + va_end(countva); + + if (n == 0) { + result = _PyObject_CallNoArg(callable); + } + else if (n == 1) { + PyObject *arg = va_arg(va, PyObject *); + result = _PyObject_CallArg1(callable, arg); + } + else if (n <= SMALL_STACK_SIZE) { + result = call_small_stack(callable, va, n); } else { - stack = PyMem_Malloc(n * sizeof(stack[0])); + /* Copy arguments */ + PyObject **stack = PyMem_Malloc(n * sizeof(PyObject *)); if (stack == NULL) { - va_end(countva); PyErr_NoMemory(); return NULL; } + for (i = 0; i < n; ++i) { + stack[i] = va_arg(va, PyObject *); + } + result = _PyObject_FastCall(callable, stack, n); + PyMem_Free(stack); } - for (i = 0; i < n; ++i) { - stack[i] = va_arg(va, PyObject *); - } - va_end(countva); - return stack; + return result; } PyObject * PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) { - PyObject *small_stack[5]; - PyObject **stack; - Py_ssize_t nargs; PyObject *result; va_list vargs; @@ -2736,22 +2753,10 @@ PyObject_CallMethodObjArgs(PyObject *cal if (callable == NULL) return NULL; - /* count the args */ va_start(vargs, name); - stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), - vargs, &nargs); + result = vcall(callable, vargs); va_end(vargs); - if (stack == NULL) { - Py_DECREF(callable); - return NULL; - } - - result = _PyObject_FastCall(callable, stack, nargs); Py_DECREF(callable); - if (stack != small_stack) { - PyMem_Free(stack); - } - return result; } @@ -2759,9 +2764,6 @@ PyObject * _PyObject_CallMethodIdObjArgs(PyObject *callable, struct _Py_Identifier *name, ...) { - PyObject *small_stack[5]; - PyObject **stack; - Py_ssize_t nargs; PyObject *result; va_list vargs; @@ -2773,31 +2775,16 @@ PyObject * if (callable == NULL) return NULL; - /* count the args */ va_start(vargs, name); - stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), - vargs, &nargs); + result = vcall(callable, vargs); va_end(vargs); - if (stack == NULL) { - Py_DECREF(callable); - return NULL; - } - - result = _PyObject_FastCall(callable, stack, nargs); 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; PyObject *result; va_list vargs; @@ -2805,20 +2792,9 @@ PyObject_CallFunctionObjArgs(PyObject *c return null_error(); } - /* count the args */ va_start(vargs, callable); - stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), - vargs, &nargs); + result = vcall(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; }