@@ -49,6 +49,20 @@ _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count)
4949#endif
5050}
5151
52+ void
53+ _Py_EnterRecursiveCallUnchecked (PyThreadState * tstate )
54+ {
55+ uintptr_t here_addr = _Py_get_machine_stack_pointer ();
56+ _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
57+ #if _Py_STACK_GROWS_DOWN
58+ if (here_addr < _tstate -> c_stack_hard_limit ) {
59+ #else
60+ if (here_addr > _tstate -> c_stack_hard_limit ) {
61+ #endif
62+ Py_FatalError ("Unchecked stack overflow." );
63+ }
64+ }
65+
5266#if defined(__s390x__ )
5367# define Py_C_STACK_SIZE 320000
5468#elif defined(_WIN32 )
@@ -264,7 +278,7 @@ PyUnstable_ThreadState_ResetStackProtection(PyThreadState *tstate)
264278
265279
266280/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
267- if the stack pointer is beyond c_stack_soft_limit . */
281+ if the stack pointer is between the stack base and c_stack_hard_limit . */
268282int
269283_Py_CheckRecursiveCall (PyThreadState * tstate , const char * where )
270284{
@@ -273,21 +287,16 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
273287 assert (_tstate -> c_stack_soft_limit != 0 );
274288 assert (_tstate -> c_stack_hard_limit != 0 );
275289#if _Py_STACK_GROWS_DOWN
290+ assert (here_addr >= _tstate -> c_stack_hard_limit - _PyOS_STACK_MARGIN_BYTES );
276291 if (here_addr < _tstate -> c_stack_hard_limit ) {
277- if (here_addr < _tstate -> c_stack_hard_limit - _PyOS_STACK_MARGIN_BYTES ) {
278- // Far out of bounds -- Assume stack switching has occurred
279- return 0 ;
280- }
292+ /* Overflowing while handling an overflow. Give up. */
281293 int kbytes_used = (int )(_tstate -> c_stack_top - here_addr )/1024 ;
282294#else
295+ assert (here_addr <= _tstate -> c_stack_hard_limit + _PyOS_STACK_MARGIN_BYTES );
283296 if (here_addr > _tstate -> c_stack_hard_limit ) {
284- if (here_addr > _tstate -> c_stack_hard_limit + _PyOS_STACK_MARGIN_BYTES ) {
285- // Far out of bounds -- Assume stack switching has occurred
286- return 0 ;
287- }
297+ /* Overflowing while handling an overflow. Give up. */
288298 int kbytes_used = (int )(here_addr - _tstate -> c_stack_top )/1024 ;
289299#endif
290- /* Too much stack used to safely raise an exception. Give up. */
291300 char buffer [80 ];
292301 snprintf (buffer , 80 , "Unrecoverable stack overflow (used %d kB)%s" , kbytes_used , where );
293302 Py_FatalError (buffer );
@@ -1192,6 +1201,19 @@ _PyEval_GetIter(_PyStackRef iterable, _PyStackRef *index_or_null, int yield_from
11921201 return PyStackRef_FromPyObjectSteal (iter_o );
11931202}
11941203
1204+ Py_NO_INLINE int
1205+ _Py_ReachedRecursionLimit (PyThreadState * tstate ) {
1206+ uintptr_t here_addr = _Py_get_machine_stack_pointer ();
1207+ _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
1208+ assert (_tstate -> c_stack_hard_limit != 0 );
1209+ #if _Py_STACK_GROWS_DOWN
1210+ return here_addr <= _tstate -> c_stack_soft_limit ;
1211+ #else
1212+ return here_addr >= _tstate -> c_stack_soft_limit ;
1213+ #endif
1214+ }
1215+
1216+
11951217#if (defined(__GNUC__ ) && __GNUC__ >= 10 && !defined(__clang__ )) && defined(__x86_64__ )
11961218/*
11971219 * gh-129987: The SLP autovectorizer can cause poor code generation for
0 commit comments