diff options
| author | Victor Stinner <vstinner@python.org> | 2019-11-04 18:48:34 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-04 18:48:34 (GMT) |
| commit | f4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613 (patch) | |
| tree | b42e4aaf30370f71b5622f8a41976ac71706d8e8 /Include/cpython | |
| parent | 6552563b3d5061816720a5a6c7d4ffd6ba35b98b (diff) | |
| download | cpython-f4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613.zip cpython-f4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613.tar.gz cpython-f4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613.tar.bz2 | |
bpo-38644: Add Py_EnterRecursiveCall() to the limited API (GH-17046)
Provide Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() as
regular functions for the limited API. Previously, there were defined
as macros, but these macros didn't work with the limited API which
cannot access PyThreadState.recursion_depth field.
Remove _Py_CheckRecursionLimit from the stable ABI.
Add Include/cpython/ceval.h header file.
Diffstat (limited to 'Include/cpython')
| -rw-r--r-- | Include/cpython/ceval.h | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h new file mode 100644 index 0000000..61bbc4f --- /dev/null +++ b/Include/cpython/ceval.h @@ -0,0 +1,50 @@ +#ifndef Py_CPYTHON_CEVAL_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +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. */ +# define _Py_MakeRecCheck(x) \ + (++(x) > _Py_CheckRecursionLimit || \ + ++(PyThreadState_GET()->stackcheck_counter) > 64) +#else +# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) +#endif + +PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); + +#define _Py_EnterRecursiveCall_macro(where) \ + (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ + _Py_CheckRecursiveCall(where)) + +#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_macro(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)) + +#define _Py_LeaveRecursiveCall_macro() \ + do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \ + PyThreadState_GET()->overflowed = 0; \ + } while(0) + +#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_macro() + +#ifdef __cplusplus +} +#endif |
