]> granicus.if.org Git - python/commitdiff
frame_clear(): Explain why it's important to make the frame
authorTim Peters <tim.peters@gmail.com>
Sat, 15 Apr 2006 03:30:08 +0000 (03:30 +0000)
committerTim Peters <tim.peters@gmail.com>
Sat, 15 Apr 2006 03:30:08 +0000 (03:30 +0000)
look dead right at the start.  Use Py_CLEAR for four more
frame members.

Objects/frameobject.c

index 217f4ba7a976d24149006c849ec19b18b282f174..9aabc7a7aa5b5a88ce52ab1a03e6810c6263a880 100644 (file)
@@ -454,36 +454,29 @@ frame_clear(PyFrameObject *f)
        PyObject **fastlocals, **p, **oldtop;
        int i, slots;
 
-       oldtop = f->f_stacktop;
-
        /* Before anything else, make sure that this frame is clearly marked
-           as being defunct! */
+         * as being defunct!  Else, e.g., a generator reachable from this
+         * frame may also point to this frame, believe itself to still be
+         * active, and try cleaning up this frame again.
+         */
+       oldtop = f->f_stacktop;
         f->f_stacktop = NULL;
 
-       Py_XDECREF(f->f_exc_type);
-       f->f_exc_type = NULL;
-
-       Py_XDECREF(f->f_exc_value);
-       f->f_exc_value = NULL;
-
-       Py_XDECREF(f->f_exc_traceback);
-       f->f_exc_traceback = NULL;
-
-       Py_XDECREF(f->f_trace);
-       f->f_trace = NULL;
+       Py_CLEAR(f->f_exc_type);
+       Py_CLEAR(f->f_exc_value);
+       Py_CLEAR(f->f_exc_traceback);
+       Py_CLEAR(f->f_trace);
 
        /* locals */
        slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
        fastlocals = f->f_localsplus;
-       for (i = slots; --i >= 0; ++fastlocals) {
+       for (i = slots; --i >= 0; ++fastlocals)
                Py_CLEAR(*fastlocals);
-       }
 
        /* stack */
        if (oldtop != NULL) {
-               for (p = f->f_valuestack; p < oldtop; p++) {
+               for (p = f->f_valuestack; p < oldtop; p++)
                        Py_CLEAR(*p);
-               }
        }
 }