static void Nuitka_Generator_tp_del( struct Nuitka_GeneratorObject *generator ) { if ( generator->m_status != status_Running ) { return; } PyObject *error_type, *error_value; PyTracebackObject *error_traceback; FETCH_ERROR_OCCURRED( &error_type, &error_value, &error_traceback ); PyObject *close_result = Nuitka_Generator_close( generator, NULL ); if (unlikely( close_result == NULL )) { PyErr_WriteUnraisable( (PyObject *)generator ); } else { Py_DECREF( close_result ); } /* Restore the saved exception if any. */ RESTORE_ERROR_OCCURRED( error_type, error_value, error_traceback ); }
static void Nuitka_Generator_tp_dealloc( struct Nuitka_GeneratorObject *generator ) { // Revive temporarily. assert( Py_REFCNT( generator ) == 0 ); Py_REFCNT( generator ) = 1; // Save the current exception, if any, we must preserve it. PyObject *save_exception_type, *save_exception_value; PyTracebackObject *save_exception_tb; FETCH_ERROR_OCCURRED( &save_exception_type, &save_exception_value, &save_exception_tb ); if ( generator->m_status == status_Running ) { PyObject *close_result = Nuitka_Generator_close( generator, NULL ); if (unlikely( close_result == NULL )) { PyErr_WriteUnraisable( (PyObject *)generator ); } else { Py_DECREF( close_result ); } } Nuitka_Generator_release_closure( generator ); Py_XDECREF( generator->m_frame ); assert( Py_REFCNT( generator ) == 1 ); Py_REFCNT( generator ) = 0; releaseFiber( &generator->m_yielder_context ); // Now it is safe to release references and memory for it. Nuitka_GC_UnTrack( generator ); if ( generator->m_weakrefs != NULL ) { PyObject_ClearWeakRefs( (PyObject *)generator ); assert( !ERROR_OCCURRED() ); } Py_DECREF( generator->m_name ); #if PYTHON_VERSION >= 350 Py_DECREF( generator->m_qualname ); #endif PyObject_GC_Del( generator ); RESTORE_ERROR_OCCURRED( save_exception_type, save_exception_value, save_exception_tb ); }
static PyObject *Nuitka_Frame_clear( PyFrameObject *frame ) { if ( frame->f_executing ) { PyErr_Format( PyExc_RuntimeError, "cannot clear an executing frame" ); return NULL; } #if PYTHON_VERSION >= 340 // For frames that are closed, we also need to close the generator. if ( frame->f_gen != NULL ) { Py_INCREF( frame ); assert( Nuitka_Generator_Check( frame->f_gen ) ); Nuitka_GeneratorObject *generator = (Nuitka_GeneratorObject *)frame->f_gen; frame->f_gen = NULL; PyObject *close_result = Nuitka_Generator_close( generator, NULL ); if (unlikely( close_result == NULL )) { PyErr_WriteUnraisable( (PyObject *)frame->f_gen ); } else { Py_DECREF( close_result ); } Py_DECREF( frame ); } #endif Nuitka_Frame_tp_clear( frame ); Py_RETURN_NONE; }
static void Nuitka_Generator_tp_dealloc( Nuitka_GeneratorObject *generator ) { assert( Py_REFCNT( generator ) == 0 ); Py_REFCNT( generator ) = 1; // Save the current exception, if any, we must preserve it. PyObject *save_exception_type, *save_exception_value, *save_exception_tb; PyErr_Fetch(&save_exception_type, &save_exception_value, &save_exception_tb); PyObject *close_result = Nuitka_Generator_close( generator, NULL ); if (unlikely( close_result == NULL )) { PyErr_WriteUnraisable( (PyObject *)generator ); } else { Py_DECREF( close_result ); } assert( Py_REFCNT( generator ) == 1 ); Py_REFCNT( generator ) = 0; releaseFiber( &generator->m_yielder_context ); // Now it is safe to release references and memory for it. Nuitka_GC_UnTrack( generator ); if ( generator->m_weakrefs != NULL ) { PyObject_ClearWeakRefs( (PyObject *)generator ); } if ( generator->m_context ) { generator->m_cleanup( generator->m_context ); } Py_DECREF( generator->m_name ); Py_XDECREF( generator->m_frame ); PyObject_GC_Del( generator ); PyErr_Restore( save_exception_type, save_exception_value, save_exception_tb ); }
static void Nuitka_Generator_tp_del( Nuitka_GeneratorObject *generator ) { if ( generator->m_status != status_Running ) { return; } // Revive temporarily. assert( Py_REFCNT( generator ) == 0 ); Py_REFCNT( generator ) = 1; PyObject *error_type, *error_value, *error_traceback; PyErr_Fetch( &error_type, &error_value, &error_traceback ); PyObject *result = Nuitka_Generator_close( generator, NULL ); if (unlikely( result == NULL )) { PyErr_WriteUnraisable( (PyObject *)generator ); } else { Py_DECREF( result ); } /* Restore the saved exception. */ PyErr_Restore( error_type, error_value, error_traceback ); assert( Py_REFCNT( generator ) > 0 ); Py_REFCNT( generator ) -= 1; Py_ssize_t refcnt = Py_REFCNT( generator ); if (unlikely( refcnt != 0 )) { _Py_NewReference( (PyObject *)generator ); Py_REFCNT( generator ) = refcnt; _Py_DEC_REFTOTAL; } }
static void Nuitka_Generator_tp_dealloc( Nuitka_GeneratorObject *generator ) { assert( Py_REFCNT( generator ) == 0 ); Py_REFCNT( generator ) = 1; PyObject *close_result = Nuitka_Generator_close( generator, NULL ); if (unlikely( close_result == NULL )) { PyErr_WriteUnraisable( (PyObject *)generator ); } else { Py_DECREF( close_result ); } assert( Py_REFCNT( generator ) == 1 ); Py_REFCNT( generator ) = 0; releaseFiber( &generator->m_yielder_context ); // Now it is safe to release references and memory for it. Nuitka_GC_UnTrack( generator ); if ( generator->m_weakrefs != NULL ) { PyObject_ClearWeakRefs( (PyObject *)generator ); } if ( generator->m_context ) { generator->m_cleanup( generator->m_context ); } Py_DECREF( generator->m_name ); Py_XDECREF( generator->m_frame ); PyObject_GC_Del( generator ); }
static PyObject *Nuitka_Frame_clear(struct Nuitka_FrameObject *frame) { if (frame->m_frame.f_executing) { PyErr_Format(PyExc_RuntimeError, "cannot clear an executing frame"); return NULL; } #if PYTHON_VERSION >= 340 // For frames that are closed, we also need to close the generator. if (frame->m_frame.f_gen != NULL) { Py_INCREF(frame); CHECK_OBJECT(frame->m_frame.f_gen); PyObject *f_gen = frame->m_frame.f_gen; PyObject *close_result; if (Nuitka_Generator_Check(frame->m_frame.f_gen)) { struct Nuitka_GeneratorObject *generator = (struct Nuitka_GeneratorObject *)frame->m_frame.f_gen; frame->m_frame.f_gen = NULL; close_result = Nuitka_Generator_close(generator, NULL); } #if PYTHON_VERSION >= 350 else if (Nuitka_Coroutine_Check(frame->m_frame.f_gen)) { struct Nuitka_CoroutineObject *coroutine = (struct Nuitka_CoroutineObject *)frame->m_frame.f_gen; frame->m_frame.f_gen = NULL; close_result = Nuitka_Coroutine_close(coroutine, NULL); } #endif #if PYTHON_VERSION >= 360 else if (Nuitka_Asyncgen_Check(frame->m_frame.f_gen)) { struct Nuitka_AsyncgenObject *asyncgen = (struct Nuitka_AsyncgenObject *)frame->m_frame.f_gen; frame->m_frame.f_gen = NULL; close_result = Nuitka_Asyncgen_close(asyncgen, NULL); } #endif else { // Compiled frames should only have our types. assert(false); frame->m_frame.f_gen = NULL; close_result = Py_None; Py_INCREF(close_result); } if (unlikely(close_result == NULL)) { PyErr_WriteUnraisable(f_gen); } else { Py_DECREF(close_result); } Py_DECREF(frame); } #endif Nuitka_Frame_tp_clear(frame); Py_RETURN_NONE; }