diff options
author | Victor Stinner <vstinner@python.org> | 2020-03-13 09:19:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-13 09:19:38 (GMT) |
commit | 224481a8c988fca12f488544edd2f01c0af2a91d (patch) | |
tree | 88e6b0085773ec3591216f0f41e8ae4dcb06a5b9 /Include/internal | |
parent | 0b72b23fb0c130279f65f3bcd23521acf4a98c88 (diff) | |
download | cpython-224481a8c988fca12f488544edd2f01c0af2a91d.zip cpython-224481a8c988fca12f488544edd2f01c0af2a91d.tar.gz cpython-224481a8c988fca12f488544edd2f01c0af2a91d.tar.bz2 |
bpo-39947: Move Py_EnterRecursiveCall() to internal C API (GH-18972)
Move the static inline function flavor of Py_EnterRecursiveCall() and
Py_LeaveRecursiveCall() to the internal C API: they access
PyThreadState attributes. The limited C API provides regular
functions which hide implementation details.
Diffstat (limited to 'Include/internal')
-rw-r--r-- | Include/internal/pycore_ceval.h | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 23d8091..ae6ef9a 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -56,6 +56,66 @@ extern PyObject *_PyEval_EvalCode( extern int _PyEval_ThreadsInitialized(_PyRuntimeState *runtime); extern PyStatus _PyEval_InitThreads(PyThreadState *tstate); + +/* --- _Py_EnterRecursiveCall() ----------------------------------------- */ + +PyAPI_DATA(int) _Py_CheckRecursionLimit; + +#ifdef USE_STACKCHECK +/* With USE_STACKCHECK macro defined, trigger stack checks in + _Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */ +static inline int _Py_MakeRecCheck(PyThreadState *tstate) { + return (++tstate->recursion_depth > _Py_CheckRecursionLimit + || ++tstate->stackcheck_counter > 64); +} +#else +static inline int _Py_MakeRecCheck(PyThreadState *tstate) { + return (++tstate->recursion_depth > _Py_CheckRecursionLimit); +} +#endif + +PyAPI_FUNC(int) _Py_CheckRecursiveCall( + PyThreadState *tstate, + const char *where); + +static inline int _Py_EnterRecursiveCall(PyThreadState *tstate, + const char *where) { + return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where)); +} + +static inline int _Py_EnterRecursiveCall_inline(const char *where) { + PyThreadState *tstate = PyThreadState_GET(); + return _Py_EnterRecursiveCall(tstate, where); +} + +#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_inline(where) + + +/* Compute the "lower-water mark" for a recursion limit. When + * Py_LeaveRecursiveCall() is called with a recursion depth below this mark, + * the overflowed flag is reset to 0. */ +#define _Py_RecursionLimitLowerWaterMark(limit) \ + (((limit) > 200) \ + ? ((limit) - 50) \ + : (3 * ((limit) >> 2))) + +#define _Py_MakeEndRecCheck(x) \ + (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit)) + +static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate) { + if (_Py_MakeEndRecCheck(tstate->recursion_depth)) { + tstate->overflowed = 0; + } +} + +static inline void _Py_LeaveRecursiveCall_inline(void) { + PyThreadState *tstate = PyThreadState_GET(); + _Py_LeaveRecursiveCall(tstate); +} + +#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_inline() + + #ifdef __cplusplus } #endif |