Skip to content

Commit e3cfa51

Browse files
Move stackref buffer to per-interpreter. Check for C recursion limit in testcapi
1 parent b87590f commit e3cfa51

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed

Modules/_testcapi/vectorcall.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,15 @@ _testcapi_pyobject_vectorcall_impl(PyObject *module, PyObject *func,
9898
PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple");
9999
return NULL;
100100
}
101-
return PyObject_Vectorcall(func, stack, nargs, kwnames);
101+
PyObject *res;
102+
// The CPython interpreter does not guarantee that vectorcalls are
103+
// checked for recursion limit. It's thus up to the C extension themselves to check.
104+
if (Py_EnterRecursiveCall("in _testcapi.pyobject_vectorcall")) {
105+
return NULL;
106+
}
107+
res = PyObject_Vectorcall(func, stack, nargs, kwnames);
108+
Py_LeaveRecursiveCall();
109+
return res;
102110
}
103111

104112
static PyObject *

Python/ceval.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11681168
return NULL;
11691169
}
11701170

1171+
/* +1 because vectorcall might use -1 to write self */
1172+
/* gh-138115: This must not be in individual cases for
1173+
non-tail-call interpreters, as it results in excessive
1174+
stack usage in some compilers.
1175+
*/
1176+
PyObject *STACKREF_SCRATCH[MAX_STACKREF_SCRATCH+1];
1177+
11711178
/* Local "register" variables.
11721179
* These are cached values from the frame and code object. */
11731180
_Py_CODEUNIT *next_instr;

Python/ceval_macros.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,7 @@ do { \
428428
#define MAX_STACKREF_SCRATCH 10
429429

430430
#define STACKREFS_TO_PYOBJECTS(ARGS, ARG_COUNT, NAME) \
431-
/* +1 because vectorcall might use -1 to write self */ \
432-
PyObject *NAME##_temp[MAX_STACKREF_SCRATCH+1]; \
431+
PyObject **NAME##_temp = (PyObject **)&STACKREF_SCRATCH; \
433432
PyObject **NAME = _PyObjectArray_FromStackRefArray(ARGS, ARG_COUNT, NAME##_temp + 1);
434433

435434
#define STACKREFS_TO_PYOBJECTS_CLEANUP(NAME) \

0 commit comments

Comments
 (0)