]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39947: Move Py_EnterRecursiveCall() to internal C API (GH-18972)
authorVictor Stinner <vstinner@python.org>
Fri, 13 Mar 2020 09:19:38 +0000 (10:19 +0100)
committerGitHub <noreply@github.com>
Fri, 13 Mar 2020 09:19:38 +0000 (10:19 +0100)
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.

Include/cpython/ceval.h
Include/internal/pycore_ceval.h
Misc/NEWS.d/next/C API/2020-03-13-00-15-19.bpo-39947.w3dIru.rst [new file with mode: 0644]
Objects/abstract.c
Objects/descrobject.c
Objects/methodobject.c
Objects/object.c

index f03b53ade92983f23100adf2823632759d4c2610..00c749949c4f18427584f128a3e8c04adc4f05fd 100644 (file)
@@ -31,62 +31,6 @@ PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
 PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
 PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
 
-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
index 23d80916fde389095d3213789e9d023512fffbf7..ae6ef9aabac146164b129a91ce0c078e944a40ff 100644 (file)
@@ -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
diff --git a/Misc/NEWS.d/next/C API/2020-03-13-00-15-19.bpo-39947.w3dIru.rst b/Misc/NEWS.d/next/C API/2020-03-13-00-15-19.bpo-39947.w3dIru.rst
new file mode 100644 (file)
index 0000000..f10161c
--- /dev/null
@@ -0,0 +1,4 @@
+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.
index f9be4227890ec70720db303ac13113cb0ec3705a..02e4ad70718cd94d0838ccd80439e07ead71ca30 100644 (file)
@@ -1,6 +1,7 @@
 /* Abstract Object Interface (many thanks to Jim Fulton) */
 
 #include "Python.h"
+#include "pycore_ceval.h"   // _Py_EnterRecursiveCall()
 #include "pycore_pyerrors.h"
 #include "pycore_pystate.h"
 #include <ctype.h>
index b448ec642683c2182a7d64ceb105b077850d1085..cb7572b0d5d5e45c2264bddccf412e78f8d10ec8 100644 (file)
@@ -1,6 +1,7 @@
 /* Descriptors -- a new, flexible way to describe attributes */
 
 #include "Python.h"
+#include "pycore_ceval.h"   // _Py_EnterRecursiveCall()
 #include "pycore_object.h"
 #include "pycore_pystate.h"
 #include "pycore_tupleobject.h"
index 16abded385466403dd2788331df09687caf12539..44ae00f7e00236ef9cd2d4e2d3c138e1ee91d107 100644 (file)
@@ -2,6 +2,7 @@
 /* Method object implementation */
 
 #include "Python.h"
+#include "pycore_ceval.h"   // _Py_EnterRecursiveCall()
 #include "pycore_object.h"
 #include "pycore_pyerrors.h"
 #include "pycore_pymem.h"
index bb47cfa8585f79572b767eb260f47e7910ad2b1d..72c4189d3458cd7dcd32b74b5017f0457528942b 100644 (file)
@@ -2,6 +2,7 @@
 /* Generic object operations; and implementation of None */
 
 #include "Python.h"
+#include "pycore_ceval.h"   // _Py_EnterRecursiveCall()
 #include "pycore_context.h"
 #include "pycore_initconfig.h"
 #include "pycore_object.h"