Example #1
0
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 );
}
Example #2
0
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 );
}
Example #3
0
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;
    }
}
Example #6
0
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 );
}
Example #7
0
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;
}