@@ -785,42 +785,49 @@ Py_GetRecursionLimit(void)
785785void
786786Py_SetRecursionLimit (int new_limit )
787787{
788- PyThreadState * tstate = _PyThreadState_GET ();
789- tstate -> interp -> ceval .recursion_limit = new_limit ;
788+ PyInterpreterState * interp = _PyInterpreterState_GET ();
789+ interp -> ceval .recursion_limit = new_limit ;
790+ for (PyThreadState * p = interp -> tstate_head ; p != NULL ; p = p -> next ) {
791+ int depth = p -> recursion_limit - p -> recursion_remaining ;
792+ p -> recursion_limit = new_limit ;
793+ p -> recursion_remaining = new_limit - depth ;
794+ }
790795}
791796
792797/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
793- if the recursion_depth reaches recursion_limit.
794- If USE_STACKCHECK, the macro decrements recursion_limit
795- to guarantee that _Py_CheckRecursiveCall() is regularly called.
796- Without USE_STACKCHECK, there is no need for this. */
798+ if the recursion_depth reaches recursion_limit. */
797799int
798800_Py_CheckRecursiveCall (PyThreadState * tstate , const char * where )
799801{
800- int recursion_limit = tstate -> interp -> ceval .recursion_limit ;
801-
802+ /* Check against global limit first. */
803+ int depth = tstate -> recursion_limit - tstate -> recursion_remaining ;
804+ if (depth < tstate -> interp -> ceval .recursion_limit ) {
805+ tstate -> recursion_limit = tstate -> interp -> ceval .recursion_limit ;
806+ tstate -> recursion_remaining = tstate -> recursion_limit - depth ;
807+ assert (tstate -> recursion_remaining > 0 );
808+ return 0 ;
809+ }
802810#ifdef USE_STACKCHECK
803- tstate -> stackcheck_counter = 0 ;
804811 if (PyOS_CheckStack ()) {
805- -- tstate -> recursion_depth ;
812+ ++ tstate -> recursion_remaining ;
806813 _PyErr_SetString (tstate , PyExc_MemoryError , "Stack overflow" );
807814 return -1 ;
808815 }
809816#endif
810817 if (tstate -> recursion_headroom ) {
811- if (tstate -> recursion_depth > recursion_limit + 50 ) {
818+ if (tstate -> recursion_remaining < - 50 ) {
812819 /* Overflowing while handling an overflow. Give up. */
813820 Py_FatalError ("Cannot recover from stack overflow." );
814821 }
815822 }
816823 else {
817- if (tstate -> recursion_depth > recursion_limit ) {
824+ if (tstate -> recursion_remaining <= 0 ) {
818825 tstate -> recursion_headroom ++ ;
819826 _PyErr_Format (tstate , PyExc_RecursionError ,
820827 "maximum recursion depth exceeded%s" ,
821828 where );
822829 tstate -> recursion_headroom -- ;
823- -- tstate -> recursion_depth ;
830+ ++ tstate -> recursion_remaining ;
824831 return -1 ;
825832 }
826833 }
@@ -1582,7 +1589,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
15821589
15831590start_frame :
15841591 if (_Py_EnterRecursiveCall (tstate , "" )) {
1585- tstate -> recursion_depth ++ ;
1592+ tstate -> recursion_remaining -- ;
15861593 goto exit_eval_frame ;
15871594 }
15881595
@@ -5688,13 +5695,13 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con,
56885695static int
56895696_PyEvalFrameClearAndPop (PyThreadState * tstate , InterpreterFrame * frame )
56905697{
5691- ++ tstate -> recursion_depth ;
5698+ -- tstate -> recursion_remaining ;
56925699 assert (frame -> frame_obj == NULL || frame -> frame_obj -> f_own_locals_memory == 0 );
56935700 if (_PyFrame_Clear (frame , 0 )) {
5694- -- tstate -> recursion_depth ;
5701+ ++ tstate -> recursion_remaining ;
56955702 return -1 ;
56965703 }
5697- -- tstate -> recursion_depth ;
5704+ ++ tstate -> recursion_remaining ;
56985705 _PyThreadState_PopFrame (tstate , frame );
56995706 return 0 ;
57005707}
0 commit comments