@@ -170,9 +170,11 @@ green_clear_exc(PyGreenlet* g)
170
170
{
171
171
#if GREENLET_PY37
172
172
g -> exc_info = NULL ;
173
- g -> exc_state .exc_type = NULL ;
174
173
g -> exc_state .exc_value = NULL ;
174
+ #if !GREENLET_PY311
175
+ g -> exc_state .exc_type = NULL ;
175
176
g -> exc_state .exc_traceback = NULL ;
177
+ #endif
176
178
g -> exc_state .previous_item = NULL ;
177
179
#else
178
180
g -> exc_type = NULL ;
@@ -525,8 +527,13 @@ g_switchstack(void)
525
527
{ /* save state */
526
528
PyGreenlet * current = ts_current ;
527
529
PyThreadState * tstate = PyThreadState_GET ();
530
+ #if GREENLET_PY311
531
+ current -> recursion_depth = (tstate -> recursion_limit
532
+ - tstate -> recursion_remaining );
533
+ #else
528
534
current -> recursion_depth = tstate -> recursion_depth ;
529
535
current -> top_frame = tstate -> frame ;
536
+ #endif
530
537
#if GREENLET_PY37
531
538
current -> context = tstate -> context ;
532
539
#endif
@@ -551,6 +558,15 @@ g_switchstack(void)
551
558
*/
552
559
current -> cframe = tstate -> cframe ;
553
560
ts__g_switchstack_use_tracing = tstate -> cframe -> use_tracing ;
561
+ #if GREENLET_PY311
562
+ current -> current_frame = tstate -> cframe -> current_frame ;
563
+ current -> datastack_chunk = tstate -> datastack_chunk ;
564
+ current -> datastack_top = tstate -> datastack_top ;
565
+ current -> datastack_limit = tstate -> datastack_limit ;
566
+ PyFrameObject * frame = PyThreadState_GetFrame (tstate );
567
+ Py_XDECREF (frame ); /* PyThreadState_GetFrame gives us a new reference. */
568
+ current -> top_frame = frame ;
569
+ #endif
554
570
#endif
555
571
}
556
572
@@ -574,9 +590,6 @@ g_switchstack(void)
574
590
PyGreenlet * target = ts_target ;
575
591
PyGreenlet * origin = ts_current ;
576
592
PyThreadState * tstate = PyThreadState_GET ();
577
- tstate -> recursion_depth = target -> recursion_depth ;
578
- tstate -> frame = target -> top_frame ;
579
- target -> top_frame = NULL ;
580
593
581
594
#if GREENLET_PY37
582
595
tstate -> context = target -> context ;
@@ -607,7 +620,18 @@ g_switchstack(void)
607
620
*/
608
621
tstate -> cframe -> use_tracing = ts__g_switchstack_use_tracing ;
609
622
#endif
610
-
623
+ #if GREENLET_PY311
624
+ tstate -> recursion_remaining = (tstate -> recursion_limit
625
+ - target -> recursion_depth );
626
+ tstate -> cframe -> current_frame = target -> current_frame ;
627
+ tstate -> datastack_chunk = target -> datastack_chunk ;
628
+ tstate -> datastack_top = target -> datastack_top ;
629
+ tstate -> datastack_limit = target -> datastack_limit ;
630
+ #else
631
+ tstate -> recursion_depth = target -> recursion_depth ;
632
+ tstate -> frame = target -> top_frame ;
633
+ #endif
634
+ target -> top_frame = NULL ;
611
635
assert (ts_origin == NULL );
612
636
Py_INCREF (target );
613
637
ts_current = target ;
@@ -810,7 +834,7 @@ static int GREENLET_NOINLINE(g_initialstub)(void* mark)
810
834
We want to defer copying the state info until we're sure
811
835
we need it and are in a stable place to do so.
812
836
*/
813
- CFrame trace_info ;
837
+ _PyCFrame trace_info ;
814
838
#endif
815
839
/* save exception in case getattr clears it */
816
840
PyErr_Fetch (& exc , & val , & tb );
@@ -875,7 +899,12 @@ static int GREENLET_NOINLINE(g_initialstub)(void* mark)
875
899
}
876
900
self -> top_frame = NULL ;
877
901
green_clear_exc (self );
902
+ #if GREENLET_PY311
903
+ self -> recursion_depth = (PyThreadState_GET ()-> recursion_limit
904
+ - PyThreadState_GET ()-> recursion_remaining );
905
+ #else
878
906
self -> recursion_depth = PyThreadState_GET ()-> recursion_depth ;
907
+ #endif
879
908
880
909
/* restore arguments in case they are clobbered */
881
910
ts_target = self ;
@@ -1006,13 +1035,13 @@ green_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
1006
1035
it uses the ``root_cframe`` just to have something to put there.
1007
1036
However, once the greenlet is actually switched to for the first
1008
1037
time, ``g_initialstub`` (which doesn't actually "return" while the
1009
- greenlet is running) stores a new CFrame on its local stack, and
1038
+ greenlet is running) stores a new _PyCFrame on its local stack, and
1010
1039
copies the appropriate values from the currently running CFrame;
1011
- this is then made the CFrame for the newly-minted greenlet.
1040
+ this is then made the _PyCFrame for the newly-minted greenlet.
1012
1041
``g_initialstub`` then proceeds to call ``glet.run()``, which
1013
- results in ``PyEval_...`` adding the CFrame to the list. Switches
1042
+ results in ``PyEval_...`` adding the _PyCFrame to the list. Switches
1014
1043
continue as normal. Finally, when the greenlet finishes, the call to
1015
- ``glet.run()`` returns and the CFrame is taken out of the linked
1044
+ ``glet.run()`` returns and the _PyCFrame is taken out of the linked
1016
1045
list and the stack value is now unused and free to expire.
1017
1046
*/
1018
1047
((PyGreenlet * )o )-> cframe = & PyThreadState_GET ()-> root_cframe ;
@@ -1121,9 +1150,11 @@ green_traverse(PyGreenlet* self, visitproc visit, void* arg)
1121
1150
Py_VISIT (self -> context );
1122
1151
#endif
1123
1152
#if GREENLET_PY37
1124
- Py_VISIT (self -> exc_state .exc_type );
1125
1153
Py_VISIT (self -> exc_state .exc_value );
1154
+ #if !GREENLET_PY311
1155
+ Py_VISIT (self -> exc_state .exc_type );
1126
1156
Py_VISIT (self -> exc_state .exc_traceback );
1157
+ #endif
1127
1158
#else
1128
1159
Py_VISIT (self -> exc_type );
1129
1160
Py_VISIT (self -> exc_value );
@@ -1159,9 +1190,11 @@ green_clear(PyGreenlet* self)
1159
1190
Py_CLEAR (self -> context );
1160
1191
#endif
1161
1192
#if GREENLET_PY37
1162
- Py_CLEAR (self -> exc_state .exc_type );
1163
1193
Py_CLEAR (self -> exc_state .exc_value );
1194
+ #if !GREENLET_PY311
1195
+ Py_CLEAR (self -> exc_state .exc_type );
1164
1196
Py_CLEAR (self -> exc_state .exc_traceback );
1197
+ #endif
1165
1198
#else
1166
1199
Py_CLEAR (self -> exc_type );
1167
1200
Py_CLEAR (self -> exc_value );
@@ -1253,9 +1286,11 @@ green_dealloc(PyGreenlet* self)
1253
1286
Py_CLEAR (self -> context );
1254
1287
#endif
1255
1288
#if GREENLET_PY37
1256
- Py_CLEAR (self -> exc_state .exc_type );
1257
1289
Py_CLEAR (self -> exc_state .exc_value );
1290
+ #if !GREENLET_PY311
1291
+ Py_CLEAR (self -> exc_state .exc_type );
1258
1292
Py_CLEAR (self -> exc_state .exc_traceback );
1293
+ #endif
1259
1294
#else
1260
1295
Py_CLEAR (self -> exc_type );
1261
1296
Py_CLEAR (self -> exc_value );
0 commit comments