@@ -749,6 +749,9 @@ enum why_code {
749749 WHY_SILENCED = 0x0080 /* Exception silenced by 'with' */
750750};
751751
752+ static void save_exc_state (PyThreadState * , PyFrameObject * );
753+ static void swap_exc_state (PyThreadState * , PyFrameObject * );
754+ static void restore_and_clear_exc_state (PyThreadState * , PyFrameObject * );
752755static enum why_code do_raise (PyObject * , PyObject * );
753756static int unpack_iterable (PyObject * , int , int , PyObject * * );
754757
@@ -1110,54 +1113,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
11101113 Py_XDECREF(traceback); \
11111114 }
11121115
1113- #define SAVE_EXC_STATE () \
1114- { \
1115- PyObject *type, *value, *traceback; \
1116- Py_XINCREF(tstate->exc_type); \
1117- Py_XINCREF(tstate->exc_value); \
1118- Py_XINCREF(tstate->exc_traceback); \
1119- type = f->f_exc_type; \
1120- value = f->f_exc_value; \
1121- traceback = f->f_exc_traceback; \
1122- f->f_exc_type = tstate->exc_type; \
1123- f->f_exc_value = tstate->exc_value; \
1124- f->f_exc_traceback = tstate->exc_traceback; \
1125- Py_XDECREF(type); \
1126- Py_XDECREF(value); \
1127- Py_XDECREF(traceback); \
1128- }
1129-
1130- #define SWAP_EXC_STATE () \
1131- { \
1132- PyObject *tmp; \
1133- tmp = tstate->exc_type; \
1134- tstate->exc_type = f->f_exc_type; \
1135- f->f_exc_type = tmp; \
1136- tmp = tstate->exc_value; \
1137- tstate->exc_value = f->f_exc_value; \
1138- f->f_exc_value = tmp; \
1139- tmp = tstate->exc_traceback; \
1140- tstate->exc_traceback = f->f_exc_traceback; \
1141- f->f_exc_traceback = tmp; \
1142- }
1143-
1144- #define RESTORE_AND_CLEAR_EXC_STATE () \
1145- { \
1146- PyObject *type, *value, *tb; \
1147- type = tstate->exc_type; \
1148- value = tstate->exc_value; \
1149- tb = tstate->exc_traceback; \
1150- tstate->exc_type = f->f_exc_type; \
1151- tstate->exc_value = f->f_exc_value; \
1152- tstate->exc_traceback = f->f_exc_traceback; \
1153- f->f_exc_type = NULL; \
1154- f->f_exc_value = NULL; \
1155- f->f_exc_traceback = NULL; \
1156- Py_XDECREF(type); \
1157- Py_XDECREF(value); \
1158- Py_XDECREF(tb); \
1159- }
1160-
11611116/* Start of code */
11621117
11631118 if (f == NULL )
@@ -1236,11 +1191,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
12361191 /* We were in an except handler when we left,
12371192 restore the exception state which was put aside
12381193 (see YIELD_VALUE). */
1239- SWAP_EXC_STATE ();
1240- }
1241- else {
1242- SAVE_EXC_STATE ();
1194+ swap_exc_state (tstate , f );
12431195 }
1196+ else
1197+ save_exc_state (tstate , f );
12441198 }
12451199
12461200#ifdef LLTRACE
@@ -3033,9 +2987,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
30332987 break ;
30342988 if (i == f -> f_iblock )
30352989 /* We did not create this exception. */
3036- RESTORE_AND_CLEAR_EXC_STATE ()
2990+ restore_and_clear_exc_state ( tstate , f );
30372991 else
3038- SWAP_EXC_STATE ()
2992+ swap_exc_state ( tstate , f );
30392993 }
30402994
30412995 if (tstate -> use_tracing ) {
@@ -3453,6 +3407,60 @@ special_lookup(PyObject *o, char *meth, PyObject **cache)
34533407}
34543408
34553409
3410+ /* These 3 functions deal with the exception state of generators. */
3411+
3412+ static void
3413+ save_exc_state (PyThreadState * tstate , PyFrameObject * f )
3414+ {
3415+ PyObject * type , * value , * traceback ;
3416+ Py_XINCREF (tstate -> exc_type );
3417+ Py_XINCREF (tstate -> exc_value );
3418+ Py_XINCREF (tstate -> exc_traceback );
3419+ type = f -> f_exc_type ;
3420+ value = f -> f_exc_value ;
3421+ traceback = f -> f_exc_traceback ;
3422+ f -> f_exc_type = tstate -> exc_type ;
3423+ f -> f_exc_value = tstate -> exc_value ;
3424+ f -> f_exc_traceback = tstate -> exc_traceback ;
3425+ Py_XDECREF (type );
3426+ Py_XDECREF (value );
3427+ Py_XDECREF (traceback );
3428+ }
3429+
3430+ static void
3431+ swap_exc_state (PyThreadState * tstate , PyFrameObject * f )
3432+ {
3433+ PyObject * tmp ;
3434+ tmp = tstate -> exc_type ;
3435+ tstate -> exc_type = f -> f_exc_type ;
3436+ f -> f_exc_type = tmp ;
3437+ tmp = tstate -> exc_value ;
3438+ tstate -> exc_value = f -> f_exc_value ;
3439+ f -> f_exc_value = tmp ;
3440+ tmp = tstate -> exc_traceback ;
3441+ tstate -> exc_traceback = f -> f_exc_traceback ;
3442+ f -> f_exc_traceback = tmp ;
3443+ }
3444+
3445+ static void
3446+ restore_and_clear_exc_state (PyThreadState * tstate , PyFrameObject * f )
3447+ {
3448+ PyObject * type , * value , * tb ;
3449+ type = tstate -> exc_type ;
3450+ value = tstate -> exc_value ;
3451+ tb = tstate -> exc_traceback ;
3452+ tstate -> exc_type = f -> f_exc_type ;
3453+ tstate -> exc_value = f -> f_exc_value ;
3454+ tstate -> exc_traceback = f -> f_exc_traceback ;
3455+ f -> f_exc_type = NULL ;
3456+ f -> f_exc_value = NULL ;
3457+ f -> f_exc_traceback = NULL ;
3458+ Py_XDECREF (type );
3459+ Py_XDECREF (value );
3460+ Py_XDECREF (tb );
3461+ }
3462+
3463+
34563464/* Logic for the raise statement (too complicated for inlining).
34573465 This *consumes* a reference count to each of its arguments. */
34583466static enum why_code
0 commit comments