Kaydet (Commit) 3bb71199 authored tarafından Victor Stinner's avatar Victor Stinner

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().
üst 3b3a7c01
...@@ -2715,80 +2715,77 @@ _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, ...@@ -2715,80 +2715,77 @@ _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name,
return retval; return retval;
} }
static PyObject ** static PyObject *
objargs_mkstack(PyObject **small_stack, Py_ssize_t small_stack_size, _PyObject_FastCallVa(PyObject *callable, va_list vargs)
va_list va, Py_ssize_t *p_nargs)
{ {
Py_ssize_t i, n; PyObject *small_stack[5];
va_list countva;
PyObject **stack; PyObject **stack;
Py_ssize_t nargs;
PyObject *result;
Py_ssize_t i;
va_list countva;
/* Count the number of arguments */ if (callable == NULL) {
va_copy(countva, va); return null_error();
}
n = 0; /* Count the number of arguments */
va_copy(countva, vargs);
nargs = 0;
while (1) { while (1) {
PyObject *arg = va_arg(countva, PyObject *); PyObject *arg = va_arg(countva, PyObject *);
if (arg == NULL) { if (arg == NULL) {
break; break;
} }
n++; nargs++;
} }
*p_nargs = n; va_end(countva);
/* Copy arguments */ /* Copy arguments */
if (n <= small_stack_size) { if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
stack = small_stack; stack = small_stack;
} }
else { else {
stack = PyMem_Malloc(n * sizeof(stack[0])); stack = PyMem_Malloc(nargs * sizeof(stack[0]));
if (stack == NULL) { if (stack == NULL) {
va_end(countva);
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
} }
} }
for (i = 0; i < n; ++i) { for (i = 0; i < nargs; ++i) {
stack[i] = va_arg(va, PyObject *); 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 *
PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
{ {
PyObject *small_stack[5];
PyObject **stack;
Py_ssize_t nargs;
PyObject *result;
va_list vargs; va_list vargs;
PyObject *result;
if (callable == NULL || name == NULL) { if (callable == NULL || name == NULL) {
return null_error(); return null_error();
} }
callable = PyObject_GetAttr(callable, name); callable = PyObject_GetAttr(callable, name);
if (callable == NULL) if (callable == NULL) {
return NULL; return NULL;
}
/* count the args */
va_start(vargs, name); va_start(vargs, name);
stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), result = _PyObject_FastCallVa(callable, vargs);
vargs, &nargs);
va_end(vargs); va_end(vargs);
if (stack == NULL) {
Py_DECREF(callable);
return NULL;
}
result = _PyObject_FastCall(callable, stack, nargs);
Py_DECREF(callable); Py_DECREF(callable);
if (stack != small_stack) {
PyMem_Free(stack);
}
return result; return result;
} }
...@@ -2796,66 +2793,35 @@ PyObject * ...@@ -2796,66 +2793,35 @@ PyObject *
_PyObject_CallMethodIdObjArgs(PyObject *obj, _PyObject_CallMethodIdObjArgs(PyObject *obj,
struct _Py_Identifier *name, ...) struct _Py_Identifier *name, ...)
{ {
PyObject *small_stack[5];
PyObject **stack;
PyObject *callable;
Py_ssize_t nargs;
PyObject *result;
va_list vargs; va_list vargs;
PyObject *callable, *result;
if (obj == NULL || name == NULL) { if (obj == NULL || name == NULL) {
return null_error(); return null_error();
} }
callable = _PyObject_GetAttrId(obj, name); callable = _PyObject_GetAttrId(obj, name);
if (callable == NULL) if (callable == NULL) {
return NULL; return NULL;
}
/* count the args */
va_start(vargs, name); va_start(vargs, name);
stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), result = _PyObject_FastCallVa(callable, vargs);
vargs, &nargs);
va_end(vargs); va_end(vargs);
if (stack == NULL) {
Py_DECREF(callable);
return NULL;
}
result = _PyObject_FastCall(callable, stack, nargs);
Py_DECREF(callable); Py_DECREF(callable);
if (stack != small_stack) {
PyMem_Free(stack);
}
return result; return result;
} }
PyObject * PyObject *
PyObject_CallFunctionObjArgs(PyObject *callable, ...) PyObject_CallFunctionObjArgs(PyObject *callable, ...)
{ {
PyObject *small_stack[5];
PyObject **stack;
Py_ssize_t nargs;
PyObject *result;
va_list vargs; va_list vargs;
PyObject *result;
if (callable == NULL) {
return null_error();
}
/* count the args */
va_start(vargs, callable); va_start(vargs, callable);
stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), result = _PyObject_FastCallVa(callable, vargs);
vargs, &nargs);
va_end(vargs); va_end(vargs);
if (stack == NULL) {
return NULL;
}
result = _PyObject_FastCall(callable, stack, nargs);
if (stack != small_stack) {
PyMem_Free(stack);
}
return result; return result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment