@@ -488,7 +488,7 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
488488}
489489
490490static void
491- frame_clear (PyFrameObject * f )
491+ frame_tp_clear (PyFrameObject * f )
492492{
493493 PyObject * * fastlocals , * * p , * * oldtop ;
494494 Py_ssize_t i , slots ;
@@ -500,6 +500,7 @@ frame_clear(PyFrameObject *f)
500500 */
501501 oldtop = f -> f_stacktop ;
502502 f -> f_stacktop = NULL ;
503+ f -> f_executing = 0 ;
503504
504505 Py_CLEAR (f -> f_exc_type );
505506 Py_CLEAR (f -> f_exc_value );
@@ -519,6 +520,25 @@ frame_clear(PyFrameObject *f)
519520 }
520521}
521522
523+ static PyObject *
524+ frame_clear (PyFrameObject * f )
525+ {
526+ if (f -> f_executing ) {
527+ PyErr_SetString (PyExc_RuntimeError ,
528+ "cannot clear an executing frame" );
529+ return NULL ;
530+ }
531+ if (f -> f_gen ) {
532+ _PyGen_Finalize (f -> f_gen );
533+ assert (f -> f_gen == NULL );
534+ }
535+ frame_tp_clear (f );
536+ Py_RETURN_NONE ;
537+ }
538+
539+ PyDoc_STRVAR (clear__doc__ ,
540+ "F.clear(): clear most references held by the frame" );
541+
522542static PyObject *
523543frame_sizeof (PyFrameObject * f )
524544{
@@ -538,6 +558,8 @@ PyDoc_STRVAR(sizeof__doc__,
538558"F.__sizeof__() -> size of F in memory, in bytes" );
539559
540560static PyMethodDef frame_methods [] = {
561+ {"clear" , (PyCFunction )frame_clear , METH_NOARGS ,
562+ clear__doc__ },
541563 {"__sizeof__" , (PyCFunction )frame_sizeof , METH_NOARGS ,
542564 sizeof__doc__ },
543565 {NULL , NULL } /* sentinel */
@@ -566,7 +588,7 @@ PyTypeObject PyFrame_Type = {
566588 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC ,/* tp_flags */
567589 0 , /* tp_doc */
568590 (traverseproc )frame_traverse , /* tp_traverse */
569- (inquiry )frame_clear , /* tp_clear */
591+ (inquiry )frame_tp_clear , /* tp_clear */
570592 0 , /* tp_richcompare */
571593 0 , /* tp_weaklistoffset */
572594 0 , /* tp_iter */
@@ -708,6 +730,8 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
708730 f -> f_lasti = -1 ;
709731 f -> f_lineno = code -> co_firstlineno ;
710732 f -> f_iblock = 0 ;
733+ f -> f_executing = 0 ;
734+ f -> f_gen = NULL ;
711735
712736 _PyObject_GC_TRACK (f );
713737 return f ;
0 commit comments