@@ -979,43 +979,48 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f)
979
979
980
980
PyObject * name = PyTuple_GET_ITEM (co -> co_localsplusnames , i );
981
981
PyObject * value = fast [i ];
982
- int cellargoffset = CO_CELL_NOT_AN_ARG ;
983
- if (co -> co_cell2arg != NULL ) {
984
- cellargoffset = co -> co_cell2arg [i - co -> co_nlocals ];
985
- }
986
- if (kind & CO_FAST_FREE ) {
987
- // The cell was set by _PyEval_MakeFrameVector() from
988
- // the function's closure.
989
- assert (value != NULL && PyCell_Check (value ));
990
- value = PyCell_GET (value );
991
- }
992
- else if (kind & CO_FAST_CELL ) {
993
- // Note that no *_DEREF ops can happen before MAKE_CELL
994
- // executes. So there's no need to duplicate the work
995
- // that MAKE_CELL would otherwise do later, if it hasn't
996
- // run yet.
997
- if (value != NULL ) {
998
- if (PyCell_Check (value ) &&
999
- _PyFrame_OpAlreadyRan (f , MAKE_CELL , i )) {
1000
- // (likely) MAKE_CELL must have executed already.
1001
- value = PyCell_GET (value );
1002
- }
1003
- // (unlikely) Otherwise it must be an initial value set
1004
- // by an earlier call to PyFrame_FastToLocals().
982
+ if (f -> f_state != FRAME_CLEARED ) {
983
+ int cellargoffset = CO_CELL_NOT_AN_ARG ;
984
+ if (co -> co_cell2arg != NULL ) {
985
+ cellargoffset = co -> co_cell2arg [i - co -> co_nlocals ];
1005
986
}
1006
- else {
1007
- // (unlikely) MAKE_CELL hasn't executed yet.
1008
- if (cellargoffset != CO_CELL_NOT_AN_ARG ) {
1009
- // It is an arg that escapes into an inner
1010
- // function so we use the initial value that
1011
- // was already set by _PyEval_MakeFrameVector().
1012
- // Normally the arg value would always be set.
1013
- // However, it can be NULL if it was deleted via
1014
- // PyFrame_LocalsToFast().
1015
- value = fast [cellargoffset ];
987
+ if (kind & CO_FAST_FREE ) {
988
+ // The cell was set by _PyEval_MakeFrameVector() from
989
+ // the function's closure.
990
+ assert (value != NULL && PyCell_Check (value ));
991
+ value = PyCell_GET (value );
992
+ }
993
+ else if (kind & CO_FAST_CELL ) {
994
+ // Note that no *_DEREF ops can happen before MAKE_CELL
995
+ // executes. So there's no need to duplicate the work
996
+ // that MAKE_CELL would otherwise do later, if it hasn't
997
+ // run yet.
998
+ if (value != NULL ) {
999
+ if (PyCell_Check (value ) &&
1000
+ _PyFrame_OpAlreadyRan (f , MAKE_CELL , i )) {
1001
+ // (likely) MAKE_CELL must have executed already.
1002
+ value = PyCell_GET (value );
1003
+ }
1004
+ // (unlikely) Otherwise it must be an initial value set
1005
+ // by an earlier call to PyFrame_FastToLocals().
1006
+ }
1007
+ else {
1008
+ // (unlikely) MAKE_CELL hasn't executed yet.
1009
+ if (cellargoffset != CO_CELL_NOT_AN_ARG ) {
1010
+ // It is an arg that escapes into an inner
1011
+ // function so we use the initial value that
1012
+ // was already set by _PyEval_MakeFrameVector().
1013
+ // Normally the arg value would always be set.
1014
+ // However, it can be NULL if it was deleted via
1015
+ // PyFrame_LocalsToFast().
1016
+ value = fast [cellargoffset ];
1017
+ }
1016
1018
}
1017
1019
}
1018
1020
}
1021
+ else {
1022
+ assert (value == NULL );
1023
+ }
1019
1024
if (value == NULL ) {
1020
1025
if (PyObject_DelItem (locals , name ) != 0 ) {
1021
1026
if (PyErr_ExceptionMatches (PyExc_KeyError )) {
@@ -1055,8 +1060,9 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
1055
1060
PyObject * * fast ;
1056
1061
PyObject * error_type , * error_value , * error_traceback ;
1057
1062
PyCodeObject * co ;
1058
- if (f == NULL )
1063
+ if (f == NULL || f -> f_state == FRAME_CLEARED ) {
1059
1064
return ;
1065
+ }
1060
1066
locals = _PyFrame_Specials (f )[FRAME_SPECIALS_LOCALS_OFFSET ];
1061
1067
if (locals == NULL )
1062
1068
return ;
@@ -1114,7 +1120,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
1114
1120
}
1115
1121
}
1116
1122
if (cell != NULL ) {
1117
- PyObject * oldvalue = PyCell_GET (cell );
1123
+ oldvalue = PyCell_GET (cell );
1118
1124
if (value != oldvalue ) {
1119
1125
Py_XDECREF (oldvalue );
1120
1126
Py_XINCREF (value );
0 commit comments