blob: 1e2c4577a78ff78014268a7ecd55d84986c7ee74 [file] [log] [blame]
Victor Stinnerf4b1e3d2019-11-04 19:48:34 +01001#ifndef Py_CPYTHON_CEVAL_H
2# error "this header file must not be included directly"
3#endif
4
5#ifdef __cplusplus
6extern "C" {
7#endif
8
9PyAPI_DATA(int) _Py_CheckRecursionLimit;
10
11#ifdef USE_STACKCHECK
12/* With USE_STACKCHECK macro defined, trigger stack checks in
13 _Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */
Victor Stinnerbe434dc2019-11-05 00:51:22 +010014static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
15 return (++tstate->recursion_depth > _Py_CheckRecursionLimit
16 || ++tstate->stackcheck_counter > 64);
17}
Victor Stinnerf4b1e3d2019-11-04 19:48:34 +010018#else
Victor Stinnerbe434dc2019-11-05 00:51:22 +010019static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
20 return (++tstate->recursion_depth > _Py_CheckRecursionLimit);
21}
Victor Stinnerf4b1e3d2019-11-04 19:48:34 +010022#endif
23
Victor Stinnerbe434dc2019-11-05 00:51:22 +010024PyAPI_FUNC(int) _Py_CheckRecursiveCall(
25 PyThreadState *tstate,
26 const char *where);
Victor Stinnerf4b1e3d2019-11-04 19:48:34 +010027
Victor Stinnerbe434dc2019-11-05 00:51:22 +010028static inline int _Py_EnterRecursiveCall(PyThreadState *tstate,
29 const char *where) {
30 return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
31}
Victor Stinnerf4b1e3d2019-11-04 19:48:34 +010032
Victor Stinnerbe434dc2019-11-05 00:51:22 +010033static inline int _Py_EnterRecursiveCall_inline(const char *where) {
34 PyThreadState *tstate = PyThreadState_GET();
35 return _Py_EnterRecursiveCall(tstate, where);
36}
37
38#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_inline(where)
Victor Stinnerf4b1e3d2019-11-04 19:48:34 +010039
40
41/* Compute the "lower-water mark" for a recursion limit. When
42 * Py_LeaveRecursiveCall() is called with a recursion depth below this mark,
43 * the overflowed flag is reset to 0. */
44#define _Py_RecursionLimitLowerWaterMark(limit) \
45 (((limit) > 200) \
46 ? ((limit) - 50) \
47 : (3 * ((limit) >> 2)))
48
49#define _Py_MakeEndRecCheck(x) \
50 (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit))
51
Victor Stinnerbe434dc2019-11-05 00:51:22 +010052static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate) {
53 if (_Py_MakeEndRecCheck(tstate->recursion_depth)) {
54 tstate->overflowed = 0;
55 }
56}
Victor Stinnerf4b1e3d2019-11-04 19:48:34 +010057
Victor Stinnerbe434dc2019-11-05 00:51:22 +010058static inline void _Py_LeaveRecursiveCall_inline(void) {
59 PyThreadState *tstate = PyThreadState_GET();
60 _Py_LeaveRecursiveCall(tstate);
61}
62
63#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_inline()
Victor Stinnerf4b1e3d2019-11-04 19:48:34 +010064
65#ifdef __cplusplus
66}
67#endif