mirror of https://github.com/python/cpython
bpo-46323: Reduce stack usage of ctypes python callback function. (GH-31224)
This commit is contained in:
parent
bf2d44ffb0
commit
d18120cd67
|
@ -0,0 +1,3 @@
|
|||
:mod:`ctypes` now allocates memory on the stack instead of on the heap
|
||||
to pass arguments while calling a Python callback function.
|
||||
Patch by Dong-hee Na.
|
|
@ -14,9 +14,18 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef MS_WIN32
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include <ffi.h>
|
||||
#include "ctypes.h"
|
||||
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
/* AIX needs alloca.h for alloca() */
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
static void
|
||||
|
@ -148,7 +157,6 @@ static void _CallPythonObject(void *mem,
|
|||
void **pArgs)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
PyObject **args = NULL;
|
||||
Py_ssize_t i = 0, j = 0, nargs = 0;
|
||||
PyObject *error_object = NULL;
|
||||
int *space;
|
||||
|
@ -156,24 +164,10 @@ static void _CallPythonObject(void *mem,
|
|||
|
||||
assert(PyTuple_Check(converters));
|
||||
nargs = PyTuple_GET_SIZE(converters);
|
||||
/* Hm. What to return in case of error?
|
||||
For COM, 0xFFFFFFFF seems better than 0.
|
||||
*/
|
||||
if (nargs < 0) {
|
||||
PrintError("BUG: PySequence_Length");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
PyObject *args_stack[CTYPES_MAX_ARGCOUNT];
|
||||
if (nargs <= CTYPES_MAX_ARGCOUNT) {
|
||||
args = args_stack;
|
||||
}
|
||||
else {
|
||||
args = PyMem_Malloc(nargs * sizeof(PyObject *));
|
||||
if (args == NULL) {
|
||||
PyErr_NoMemory();
|
||||
goto Done;
|
||||
}
|
||||
assert(nargs <= CTYPES_MAX_ARGCOUNT);
|
||||
PyObject **args = NULL;
|
||||
if (nargs > 0) {
|
||||
args = alloca(nargs * sizeof(PyObject *));
|
||||
}
|
||||
|
||||
PyObject **cnvs = PySequence_Fast_ITEMS(converters);
|
||||
|
@ -310,9 +304,6 @@ static void _CallPythonObject(void *mem,
|
|||
for (j = 0; j < i; j++) {
|
||||
Py_DECREF(args[j]);
|
||||
}
|
||||
if (args != args_stack) {
|
||||
PyMem_Free(args);
|
||||
}
|
||||
PyGILState_Release(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -1162,11 +1162,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
args = (struct argument *)alloca(sizeof(struct argument) * argcount);
|
||||
if (!args) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
args = alloca(sizeof(struct argument) * argcount);
|
||||
memset(args, 0, sizeof(struct argument) * argcount);
|
||||
argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0;
|
||||
#ifdef MS_WIN32
|
||||
|
|
Loading…
Reference in New Issue