@@ -193,18 +193,28 @@ extern void _PyEval_DeactivateOpCache(void);
193193
194194/* --- _Py_EnterRecursiveCall() ----------------------------------------- */ 
195195
196- #ifdef  USE_STACKCHECK 
197- /* With USE_STACKCHECK macro defined, trigger stack checks in 
198-    _Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */ 
199- static  inline  int  _Py_MakeRecCheck (PyThreadState  * tstate )  {
200-     return  (tstate -> c_recursion_remaining --  <  0 
201-             ||  (tstate -> c_recursion_remaining  &  63 ) ==  0 );
196+ #if  !_Py__has_builtin (__builtin_frame_address )
197+ static  uintptr_t  return_pointer_as_int (char *  p ) {
198+     return  (uintptr_t )p ;
202199}
200+ #endif 
201+ 
202+ static  inline  uintptr_t 
203+ _Py_get_machine_stack_pointer (void ) {
204+ #if  _Py__has_builtin (__builtin_frame_address )
205+     return  (uintptr_t )__builtin_frame_address (0 );
203206#else 
204- static   inline   int   _Py_MakeRecCheck ( PyThreadState   * tstate ) { 
205-     return   tstate -> c_recursion_remaining --   <   0 ; 
206- } 
207+      char   here ; 
208+     /* Avoid compiler warning about returning stack address */ 
209+      return   return_pointer_as_int ( & here ); 
207210#endif 
211+ }
212+ 
213+ static  inline  int  _Py_MakeRecCheck (PyThreadState  * tstate )  {
214+     uintptr_t  here_addr  =  _Py_get_machine_stack_pointer ();
215+     _PyThreadStateImpl  * _tstate  =  (_PyThreadStateImpl  * )tstate ;
216+     return  here_addr  <  _tstate -> c_stack_soft_limit ;
217+ }
208218
209219// Export for '_json' shared extension, used via _Py_EnterRecursiveCall() 
210220// static inline function. 
@@ -220,23 +230,30 @@ static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate,
220230    return  (_Py_MakeRecCheck (tstate ) &&  _Py_CheckRecursiveCall (tstate , where ));
221231}
222232
223- static  inline  void  _Py_EnterRecursiveCallTstateUnchecked (PyThreadState  * tstate )  {
224-     assert (tstate -> c_recursion_remaining  >  0 );
225-     tstate -> c_recursion_remaining -- ;
226- }
227- 
228233static  inline  int  _Py_EnterRecursiveCall (const  char  * where ) {
229234    PyThreadState  * tstate  =  _PyThreadState_GET ();
230235    return  _Py_EnterRecursiveCallTstate (tstate , where );
231236}
232237
233- static  inline  void  _Py_LeaveRecursiveCallTstate (PyThreadState  * tstate )  {
234-     tstate -> c_recursion_remaining ++ ;
238+ static  inline  void  _Py_LeaveRecursiveCallTstate (PyThreadState  * tstate ) {
239+     (void )tstate ;
240+ }
241+ 
242+ PyAPI_FUNC (void ) _Py_InitializeRecursionLimits (PyThreadState  * tstate );
243+ 
244+ static  inline  int  _Py_ReachedRecursionLimit (PyThreadState  * tstate )  {
245+     uintptr_t  here_addr  =  _Py_get_machine_stack_pointer ();
246+     _PyThreadStateImpl  * _tstate  =  (_PyThreadStateImpl  * )tstate ;
247+     if  (here_addr  >  _tstate -> c_stack_soft_limit ) {
248+         return  0 ;
249+     }
250+     if  (_tstate -> c_stack_hard_limit  ==  0 ) {
251+         _Py_InitializeRecursionLimits (tstate );
252+     }
253+     return  here_addr  <= _tstate -> c_stack_soft_limit ;
235254}
236255
237256static  inline  void  _Py_LeaveRecursiveCall (void )  {
238-     PyThreadState  * tstate  =  _PyThreadState_GET ();
239-     _Py_LeaveRecursiveCallTstate (tstate );
240257}
241258
242259extern  struct  _PyInterpreterFrame *  _PyEval_GetFrame (void );
@@ -327,7 +344,6 @@ void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
327344
328345PyAPI_FUNC (PyObject  * ) _PyFloat_FromDouble_ConsumeInputs (_PyStackRef  left , _PyStackRef  right , double  value );
329346
330- 
331347#ifdef  __cplusplus 
332348}
333349#endif 
0 commit comments