Browse Source
bpo-38644: Add Py_EnterRecursiveCall() to the limited API (GH-17046)
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.pull/16997/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 101 additions and 38 deletions
-
12Doc/c-api/exceptions.rst
-
6Doc/whatsnew/3.9.rst
-
43Include/ceval.h
-
50Include/cpython/ceval.h
-
1Makefile.pre.in
-
5Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst
-
1PCbuild/pythoncore.vcxproj
-
3PCbuild/pythoncore.vcxproj.filters
-
18Python/ceval.c
@ -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 |
|||
@ -0,0 +1,5 @@ |
|||
Provide :c:func:`Py_EnterRecursiveCall` and :c:func:`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. |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue