@@ -785,42 +785,49 @@ Py_GetRecursionLimit(void)
785
785
void
786
786
Py_SetRecursionLimit (int new_limit )
787
787
{
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
+ }
790
795
}
791
796
792
797
/* 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. */
797
799
int
798
800
_Py_CheckRecursiveCall (PyThreadState * tstate , const char * where )
799
801
{
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
+ }
802
810
#ifdef USE_STACKCHECK
803
- tstate -> stackcheck_counter = 0 ;
804
811
if (PyOS_CheckStack ()) {
805
- -- tstate -> recursion_depth ;
812
+ ++ tstate -> recursion_remaining ;
806
813
_PyErr_SetString (tstate , PyExc_MemoryError , "Stack overflow" );
807
814
return -1 ;
808
815
}
809
816
#endif
810
817
if (tstate -> recursion_headroom ) {
811
- if (tstate -> recursion_depth > recursion_limit + 50 ) {
818
+ if (tstate -> recursion_remaining < - 50 ) {
812
819
/* Overflowing while handling an overflow. Give up. */
813
820
Py_FatalError ("Cannot recover from stack overflow." );
814
821
}
815
822
}
816
823
else {
817
- if (tstate -> recursion_depth > recursion_limit ) {
824
+ if (tstate -> recursion_remaining <= 0 ) {
818
825
tstate -> recursion_headroom ++ ;
819
826
_PyErr_Format (tstate , PyExc_RecursionError ,
820
827
"maximum recursion depth exceeded%s" ,
821
828
where );
822
829
tstate -> recursion_headroom -- ;
823
- -- tstate -> recursion_depth ;
830
+ ++ tstate -> recursion_remaining ;
824
831
return -1 ;
825
832
}
826
833
}
@@ -1582,7 +1589,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
1582
1589
1583
1590
start_frame :
1584
1591
if (_Py_EnterRecursiveCall (tstate , "" )) {
1585
- tstate -> recursion_depth ++ ;
1592
+ tstate -> recursion_remaining -- ;
1586
1593
goto exit_eval_frame ;
1587
1594
}
1588
1595
@@ -5688,13 +5695,13 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con,
5688
5695
static int
5689
5696
_PyEvalFrameClearAndPop (PyThreadState * tstate , InterpreterFrame * frame )
5690
5697
{
5691
- ++ tstate -> recursion_depth ;
5698
+ -- tstate -> recursion_remaining ;
5692
5699
assert (frame -> frame_obj == NULL || frame -> frame_obj -> f_own_locals_memory == 0 );
5693
5700
if (_PyFrame_Clear (frame , 0 )) {
5694
- -- tstate -> recursion_depth ;
5701
+ ++ tstate -> recursion_remaining ;
5695
5702
return -1 ;
5696
5703
}
5697
- -- tstate -> recursion_depth ;
5704
+ ++ tstate -> recursion_remaining ;
5698
5705
_PyThreadState_PopFrame (tstate , frame );
5699
5706
return 0 ;
5700
5707
}
0 commit comments