summaryrefslogtreecommitdiffstats
path: root/Modules/_ctypes
diff options
context:
space:
mode:
authorDong-hee Na <donghee.na@python.org>2022-02-09 18:10:11 (GMT)
committerGitHub <noreply@github.com>2022-02-09 18:10:11 (GMT)
commitd18120cd67b4297f78bfc9bf7b36774cf0bf15f2 (patch)
treeecf47ddfca44e517e5400c89f6d5fa13fe14e459 /Modules/_ctypes
parentbf2d44ffb06e8f49aacc6b1c140a6717df5cf897 (diff)
downloadcpython-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.c35
-rw-r--r--Modules/_ctypes/callproc.c6
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