diff options
author | Dong-hee Na <donghee.na@python.org> | 2022-02-09 18:10:11 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-09 18:10:11 (GMT) |
commit | d18120cd67b4297f78bfc9bf7b36774cf0bf15f2 (patch) | |
tree | ecf47ddfca44e517e5400c89f6d5fa13fe14e459 /Modules/_ctypes | |
parent | bf2d44ffb06e8f49aacc6b1c140a6717df5cf897 (diff) | |
download | cpython-d18120cd67b4297f78bfc9bf7b36774cf0bf15f2.zip cpython-d18120cd67b4297f78bfc9bf7b36774cf0bf15f2.tar.gz cpython-d18120cd67b4297f78bfc9bf7b36774cf0bf15f2.tar.bz2 |
bpo-46323: Reduce stack usage of ctypes python callback function. (GH-31224)
Diffstat (limited to 'Modules/_ctypes')
-rw-r--r-- | Modules/_ctypes/callbacks.c | 35 | ||||
-rw-r--r-- | Modules/_ctypes/callproc.c | 6 |
2 files changed, 14 insertions, 27 deletions
diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index f2d9a53..591b944 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -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); } diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 6dba0ff..4a6b8ec 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -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 |