xref: /third_party/python/Objects/genobject.c (revision 7db96d56)
17db96d56Sopenharmony_ci/* Generator object implementation */
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci#include "Python.h"
47db96d56Sopenharmony_ci#include "pycore_call.h"          // _PyObject_CallNoArgs()
57db96d56Sopenharmony_ci#include "pycore_ceval.h"         // _PyEval_EvalFrame()
67db96d56Sopenharmony_ci#include "pycore_frame.h"         // _PyInterpreterFrame
77db96d56Sopenharmony_ci#include "pycore_genobject.h"     // struct _Py_async_gen_state
87db96d56Sopenharmony_ci#include "pycore_object.h"        // _PyObject_GC_UNTRACK()
97db96d56Sopenharmony_ci#include "pycore_opcode.h"        // _PyOpcode_Deopt
107db96d56Sopenharmony_ci#include "pycore_pyerrors.h"      // _PyErr_ClearExcState()
117db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyThreadState_GET()
127db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
137db96d56Sopenharmony_ci#include "opcode.h"               // SEND
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_cistatic PyObject *gen_close(PyGenObject *, PyObject *);
167db96d56Sopenharmony_cistatic PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *);
177db96d56Sopenharmony_cistatic PyObject *async_gen_athrow_new(PyAsyncGenObject *, PyObject *);
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_cistatic const char *NON_INIT_CORO_MSG = "can't send non-None value to a "
207db96d56Sopenharmony_ci                                 "just-started coroutine";
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_cistatic const char *ASYNC_GEN_IGNORED_EXIT_MSG =
237db96d56Sopenharmony_ci                                 "async generator ignored GeneratorExit";
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_cistatic inline int
267db96d56Sopenharmony_ciexc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg)
277db96d56Sopenharmony_ci{
287db96d56Sopenharmony_ci    Py_VISIT(exc_state->exc_value);
297db96d56Sopenharmony_ci    return 0;
307db96d56Sopenharmony_ci}
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_cistatic int
337db96d56Sopenharmony_cigen_traverse(PyGenObject *gen, visitproc visit, void *arg)
347db96d56Sopenharmony_ci{
357db96d56Sopenharmony_ci    Py_VISIT(gen->gi_code);
367db96d56Sopenharmony_ci    Py_VISIT(gen->gi_name);
377db96d56Sopenharmony_ci    Py_VISIT(gen->gi_qualname);
387db96d56Sopenharmony_ci    if (gen->gi_frame_state < FRAME_CLEARED) {
397db96d56Sopenharmony_ci        _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe);
407db96d56Sopenharmony_ci        assert(frame->frame_obj == NULL ||
417db96d56Sopenharmony_ci               frame->frame_obj->f_frame->owner == FRAME_OWNED_BY_GENERATOR);
427db96d56Sopenharmony_ci        int err = _PyFrame_Traverse(frame, visit, arg);
437db96d56Sopenharmony_ci        if (err) {
447db96d56Sopenharmony_ci            return err;
457db96d56Sopenharmony_ci        }
467db96d56Sopenharmony_ci    }
477db96d56Sopenharmony_ci    /* No need to visit cr_origin, because it's just tuples/str/int, so can't
487db96d56Sopenharmony_ci       participate in a reference cycle. */
497db96d56Sopenharmony_ci    return exc_state_traverse(&gen->gi_exc_state, visit, arg);
507db96d56Sopenharmony_ci}
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_civoid
537db96d56Sopenharmony_ci_PyGen_Finalize(PyObject *self)
547db96d56Sopenharmony_ci{
557db96d56Sopenharmony_ci    PyGenObject *gen = (PyGenObject *)self;
567db96d56Sopenharmony_ci    PyObject *res = NULL;
577db96d56Sopenharmony_ci    PyObject *error_type, *error_value, *error_traceback;
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci    if (gen->gi_frame_state >= FRAME_COMPLETED) {
607db96d56Sopenharmony_ci        /* Generator isn't paused, so no need to close */
617db96d56Sopenharmony_ci        return;
627db96d56Sopenharmony_ci    }
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_ci    if (PyAsyncGen_CheckExact(self)) {
657db96d56Sopenharmony_ci        PyAsyncGenObject *agen = (PyAsyncGenObject*)self;
667db96d56Sopenharmony_ci        PyObject *finalizer = agen->ag_origin_or_finalizer;
677db96d56Sopenharmony_ci        if (finalizer && !agen->ag_closed) {
687db96d56Sopenharmony_ci            /* Save the current exception, if any. */
697db96d56Sopenharmony_ci            PyErr_Fetch(&error_type, &error_value, &error_traceback);
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci            res = PyObject_CallOneArg(finalizer, self);
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci            if (res == NULL) {
747db96d56Sopenharmony_ci                PyErr_WriteUnraisable(self);
757db96d56Sopenharmony_ci            } else {
767db96d56Sopenharmony_ci                Py_DECREF(res);
777db96d56Sopenharmony_ci            }
787db96d56Sopenharmony_ci            /* Restore the saved exception. */
797db96d56Sopenharmony_ci            PyErr_Restore(error_type, error_value, error_traceback);
807db96d56Sopenharmony_ci            return;
817db96d56Sopenharmony_ci        }
827db96d56Sopenharmony_ci    }
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci    /* Save the current exception, if any. */
857db96d56Sopenharmony_ci    PyErr_Fetch(&error_type, &error_value, &error_traceback);
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci    /* If `gen` is a coroutine, and if it was never awaited on,
887db96d56Sopenharmony_ci       issue a RuntimeWarning. */
897db96d56Sopenharmony_ci    if (gen->gi_code != NULL &&
907db96d56Sopenharmony_ci        ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE &&
917db96d56Sopenharmony_ci        gen->gi_frame_state == FRAME_CREATED)
927db96d56Sopenharmony_ci    {
937db96d56Sopenharmony_ci        _PyErr_WarnUnawaitedCoroutine((PyObject *)gen);
947db96d56Sopenharmony_ci    }
957db96d56Sopenharmony_ci    else {
967db96d56Sopenharmony_ci        res = gen_close(gen, NULL);
977db96d56Sopenharmony_ci    }
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci    if (res == NULL) {
1007db96d56Sopenharmony_ci        if (PyErr_Occurred()) {
1017db96d56Sopenharmony_ci            PyErr_WriteUnraisable(self);
1027db96d56Sopenharmony_ci        }
1037db96d56Sopenharmony_ci    }
1047db96d56Sopenharmony_ci    else {
1057db96d56Sopenharmony_ci        Py_DECREF(res);
1067db96d56Sopenharmony_ci    }
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ci    /* Restore the saved exception. */
1097db96d56Sopenharmony_ci    PyErr_Restore(error_type, error_value, error_traceback);
1107db96d56Sopenharmony_ci}
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_cistatic void
1137db96d56Sopenharmony_cigen_dealloc(PyGenObject *gen)
1147db96d56Sopenharmony_ci{
1157db96d56Sopenharmony_ci    PyObject *self = (PyObject *) gen;
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK(gen);
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci    if (gen->gi_weakreflist != NULL)
1207db96d56Sopenharmony_ci        PyObject_ClearWeakRefs(self);
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ci    _PyObject_GC_TRACK(self);
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_ci    if (PyObject_CallFinalizerFromDealloc(self))
1257db96d56Sopenharmony_ci        return;                     /* resurrected.  :( */
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK(self);
1287db96d56Sopenharmony_ci    if (PyAsyncGen_CheckExact(gen)) {
1297db96d56Sopenharmony_ci        /* We have to handle this case for asynchronous generators
1307db96d56Sopenharmony_ci           right here, because this code has to be between UNTRACK
1317db96d56Sopenharmony_ci           and GC_Del. */
1327db96d56Sopenharmony_ci        Py_CLEAR(((PyAsyncGenObject*)gen)->ag_origin_or_finalizer);
1337db96d56Sopenharmony_ci    }
1347db96d56Sopenharmony_ci    if (gen->gi_frame_state < FRAME_CLEARED) {
1357db96d56Sopenharmony_ci        _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
1367db96d56Sopenharmony_ci        gen->gi_frame_state = FRAME_CLEARED;
1377db96d56Sopenharmony_ci        frame->previous = NULL;
1387db96d56Sopenharmony_ci        _PyFrame_Clear(frame);
1397db96d56Sopenharmony_ci    }
1407db96d56Sopenharmony_ci    if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) {
1417db96d56Sopenharmony_ci        Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer);
1427db96d56Sopenharmony_ci    }
1437db96d56Sopenharmony_ci    Py_CLEAR(gen->gi_code);
1447db96d56Sopenharmony_ci    Py_CLEAR(gen->gi_name);
1457db96d56Sopenharmony_ci    Py_CLEAR(gen->gi_qualname);
1467db96d56Sopenharmony_ci    _PyErr_ClearExcState(&gen->gi_exc_state);
1477db96d56Sopenharmony_ci    PyObject_GC_Del(gen);
1487db96d56Sopenharmony_ci}
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_cistatic PySendResult
1517db96d56Sopenharmony_cigen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult,
1527db96d56Sopenharmony_ci             int exc, int closing)
1537db96d56Sopenharmony_ci{
1547db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
1557db96d56Sopenharmony_ci    _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
1567db96d56Sopenharmony_ci    PyObject *result;
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_ci    *presult = NULL;
1597db96d56Sopenharmony_ci    if (gen->gi_frame_state == FRAME_CREATED && arg && arg != Py_None) {
1607db96d56Sopenharmony_ci        const char *msg = "can't send non-None value to a "
1617db96d56Sopenharmony_ci                            "just-started generator";
1627db96d56Sopenharmony_ci        if (PyCoro_CheckExact(gen)) {
1637db96d56Sopenharmony_ci            msg = NON_INIT_CORO_MSG;
1647db96d56Sopenharmony_ci        }
1657db96d56Sopenharmony_ci        else if (PyAsyncGen_CheckExact(gen)) {
1667db96d56Sopenharmony_ci            msg = "can't send non-None value to a "
1677db96d56Sopenharmony_ci                    "just-started async generator";
1687db96d56Sopenharmony_ci        }
1697db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, msg);
1707db96d56Sopenharmony_ci        return PYGEN_ERROR;
1717db96d56Sopenharmony_ci    }
1727db96d56Sopenharmony_ci    if (gen->gi_frame_state == FRAME_EXECUTING) {
1737db96d56Sopenharmony_ci        const char *msg = "generator already executing";
1747db96d56Sopenharmony_ci        if (PyCoro_CheckExact(gen)) {
1757db96d56Sopenharmony_ci            msg = "coroutine already executing";
1767db96d56Sopenharmony_ci        }
1777db96d56Sopenharmony_ci        else if (PyAsyncGen_CheckExact(gen)) {
1787db96d56Sopenharmony_ci            msg = "async generator already executing";
1797db96d56Sopenharmony_ci        }
1807db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, msg);
1817db96d56Sopenharmony_ci        return PYGEN_ERROR;
1827db96d56Sopenharmony_ci    }
1837db96d56Sopenharmony_ci    if (gen->gi_frame_state >= FRAME_COMPLETED) {
1847db96d56Sopenharmony_ci        if (PyCoro_CheckExact(gen) && !closing) {
1857db96d56Sopenharmony_ci            /* `gen` is an exhausted coroutine: raise an error,
1867db96d56Sopenharmony_ci               except when called from gen_close(), which should
1877db96d56Sopenharmony_ci               always be a silent method. */
1887db96d56Sopenharmony_ci            PyErr_SetString(
1897db96d56Sopenharmony_ci                PyExc_RuntimeError,
1907db96d56Sopenharmony_ci                "cannot reuse already awaited coroutine");
1917db96d56Sopenharmony_ci        }
1927db96d56Sopenharmony_ci        else if (arg && !exc) {
1937db96d56Sopenharmony_ci            /* `gen` is an exhausted generator:
1947db96d56Sopenharmony_ci               only return value if called from send(). */
1957db96d56Sopenharmony_ci            *presult = Py_None;
1967db96d56Sopenharmony_ci            Py_INCREF(*presult);
1977db96d56Sopenharmony_ci            return PYGEN_RETURN;
1987db96d56Sopenharmony_ci        }
1997db96d56Sopenharmony_ci        return PYGEN_ERROR;
2007db96d56Sopenharmony_ci    }
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci    assert(gen->gi_frame_state < FRAME_EXECUTING);
2037db96d56Sopenharmony_ci    /* Push arg onto the frame's value stack */
2047db96d56Sopenharmony_ci    result = arg ? arg : Py_None;
2057db96d56Sopenharmony_ci    Py_INCREF(result);
2067db96d56Sopenharmony_ci    _PyFrame_StackPush(frame, result);
2077db96d56Sopenharmony_ci
2087db96d56Sopenharmony_ci    frame->previous = tstate->cframe->current_frame;
2097db96d56Sopenharmony_ci
2107db96d56Sopenharmony_ci    gen->gi_exc_state.previous_item = tstate->exc_info;
2117db96d56Sopenharmony_ci    tstate->exc_info = &gen->gi_exc_state;
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ci    if (exc) {
2147db96d56Sopenharmony_ci        assert(_PyErr_Occurred(tstate));
2157db96d56Sopenharmony_ci        _PyErr_ChainStackItem(NULL);
2167db96d56Sopenharmony_ci    }
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci    gen->gi_frame_state = FRAME_EXECUTING;
2197db96d56Sopenharmony_ci    result = _PyEval_EvalFrame(tstate, frame, exc);
2207db96d56Sopenharmony_ci    if (gen->gi_frame_state == FRAME_EXECUTING) {
2217db96d56Sopenharmony_ci        gen->gi_frame_state = FRAME_COMPLETED;
2227db96d56Sopenharmony_ci    }
2237db96d56Sopenharmony_ci    tstate->exc_info = gen->gi_exc_state.previous_item;
2247db96d56Sopenharmony_ci    gen->gi_exc_state.previous_item = NULL;
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ci    assert(tstate->cframe->current_frame == frame->previous);
2277db96d56Sopenharmony_ci    /* Don't keep the reference to previous any longer than necessary.  It
2287db96d56Sopenharmony_ci     * may keep a chain of frames alive or it could create a reference
2297db96d56Sopenharmony_ci     * cycle. */
2307db96d56Sopenharmony_ci    frame->previous = NULL;
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_ci    /* If the generator just returned (as opposed to yielding), signal
2337db96d56Sopenharmony_ci     * that the generator is exhausted. */
2347db96d56Sopenharmony_ci    if (result) {
2357db96d56Sopenharmony_ci        if (gen->gi_frame_state == FRAME_SUSPENDED) {
2367db96d56Sopenharmony_ci            *presult = result;
2377db96d56Sopenharmony_ci            return PYGEN_NEXT;
2387db96d56Sopenharmony_ci        }
2397db96d56Sopenharmony_ci        assert(result == Py_None || !PyAsyncGen_CheckExact(gen));
2407db96d56Sopenharmony_ci        if (result == Py_None && !PyAsyncGen_CheckExact(gen) && !arg) {
2417db96d56Sopenharmony_ci            /* Return NULL if called by gen_iternext() */
2427db96d56Sopenharmony_ci            Py_CLEAR(result);
2437db96d56Sopenharmony_ci        }
2447db96d56Sopenharmony_ci    }
2457db96d56Sopenharmony_ci    else {
2467db96d56Sopenharmony_ci        if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
2477db96d56Sopenharmony_ci            const char *msg = "generator raised StopIteration";
2487db96d56Sopenharmony_ci            if (PyCoro_CheckExact(gen)) {
2497db96d56Sopenharmony_ci                msg = "coroutine raised StopIteration";
2507db96d56Sopenharmony_ci            }
2517db96d56Sopenharmony_ci            else if (PyAsyncGen_CheckExact(gen)) {
2527db96d56Sopenharmony_ci                msg = "async generator raised StopIteration";
2537db96d56Sopenharmony_ci            }
2547db96d56Sopenharmony_ci            _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
2557db96d56Sopenharmony_ci        }
2567db96d56Sopenharmony_ci        else if (PyAsyncGen_CheckExact(gen) &&
2577db96d56Sopenharmony_ci                PyErr_ExceptionMatches(PyExc_StopAsyncIteration))
2587db96d56Sopenharmony_ci        {
2597db96d56Sopenharmony_ci            /* code in `gen` raised a StopAsyncIteration error:
2607db96d56Sopenharmony_ci               raise a RuntimeError.
2617db96d56Sopenharmony_ci            */
2627db96d56Sopenharmony_ci            const char *msg = "async generator raised StopAsyncIteration";
2637db96d56Sopenharmony_ci            _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
2647db96d56Sopenharmony_ci        }
2657db96d56Sopenharmony_ci    }
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ci    /* generator can't be rerun, so release the frame */
2687db96d56Sopenharmony_ci    /* first clean reference cycle through stored exception traceback */
2697db96d56Sopenharmony_ci    _PyErr_ClearExcState(&gen->gi_exc_state);
2707db96d56Sopenharmony_ci
2717db96d56Sopenharmony_ci    gen->gi_frame_state = FRAME_CLEARED;
2727db96d56Sopenharmony_ci    _PyFrame_Clear(frame);
2737db96d56Sopenharmony_ci    *presult = result;
2747db96d56Sopenharmony_ci    return result ? PYGEN_RETURN : PYGEN_ERROR;
2757db96d56Sopenharmony_ci}
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_cistatic PySendResult
2787db96d56Sopenharmony_ciPyGen_am_send(PyGenObject *gen, PyObject *arg, PyObject **result)
2797db96d56Sopenharmony_ci{
2807db96d56Sopenharmony_ci    return gen_send_ex2(gen, arg, result, 0, 0);
2817db96d56Sopenharmony_ci}
2827db96d56Sopenharmony_ci
2837db96d56Sopenharmony_cistatic PyObject *
2847db96d56Sopenharmony_cigen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
2857db96d56Sopenharmony_ci{
2867db96d56Sopenharmony_ci    PyObject *result;
2877db96d56Sopenharmony_ci    if (gen_send_ex2(gen, arg, &result, exc, closing) == PYGEN_RETURN) {
2887db96d56Sopenharmony_ci        if (PyAsyncGen_CheckExact(gen)) {
2897db96d56Sopenharmony_ci            assert(result == Py_None);
2907db96d56Sopenharmony_ci            PyErr_SetNone(PyExc_StopAsyncIteration);
2917db96d56Sopenharmony_ci        }
2927db96d56Sopenharmony_ci        else if (result == Py_None) {
2937db96d56Sopenharmony_ci            PyErr_SetNone(PyExc_StopIteration);
2947db96d56Sopenharmony_ci        }
2957db96d56Sopenharmony_ci        else {
2967db96d56Sopenharmony_ci            _PyGen_SetStopIterationValue(result);
2977db96d56Sopenharmony_ci        }
2987db96d56Sopenharmony_ci        Py_CLEAR(result);
2997db96d56Sopenharmony_ci    }
3007db96d56Sopenharmony_ci    return result;
3017db96d56Sopenharmony_ci}
3027db96d56Sopenharmony_ci
3037db96d56Sopenharmony_ciPyDoc_STRVAR(send_doc,
3047db96d56Sopenharmony_ci"send(arg) -> send 'arg' into generator,\n\
3057db96d56Sopenharmony_cireturn next yielded value or raise StopIteration.");
3067db96d56Sopenharmony_ci
3077db96d56Sopenharmony_cistatic PyObject *
3087db96d56Sopenharmony_cigen_send(PyGenObject *gen, PyObject *arg)
3097db96d56Sopenharmony_ci{
3107db96d56Sopenharmony_ci    return gen_send_ex(gen, arg, 0, 0);
3117db96d56Sopenharmony_ci}
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ciPyDoc_STRVAR(close_doc,
3147db96d56Sopenharmony_ci"close() -> raise GeneratorExit inside generator.");
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_ci/*
3177db96d56Sopenharmony_ci *   This helper function is used by gen_close and gen_throw to
3187db96d56Sopenharmony_ci *   close a subiterator being delegated to by yield-from.
3197db96d56Sopenharmony_ci */
3207db96d56Sopenharmony_ci
3217db96d56Sopenharmony_cistatic int
3227db96d56Sopenharmony_cigen_close_iter(PyObject *yf)
3237db96d56Sopenharmony_ci{
3247db96d56Sopenharmony_ci    PyObject *retval = NULL;
3257db96d56Sopenharmony_ci
3267db96d56Sopenharmony_ci    if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) {
3277db96d56Sopenharmony_ci        retval = gen_close((PyGenObject *)yf, NULL);
3287db96d56Sopenharmony_ci        if (retval == NULL)
3297db96d56Sopenharmony_ci            return -1;
3307db96d56Sopenharmony_ci    }
3317db96d56Sopenharmony_ci    else {
3327db96d56Sopenharmony_ci        PyObject *meth;
3337db96d56Sopenharmony_ci        if (_PyObject_LookupAttr(yf, &_Py_ID(close), &meth) < 0) {
3347db96d56Sopenharmony_ci            PyErr_WriteUnraisable(yf);
3357db96d56Sopenharmony_ci        }
3367db96d56Sopenharmony_ci        if (meth) {
3377db96d56Sopenharmony_ci            retval = _PyObject_CallNoArgs(meth);
3387db96d56Sopenharmony_ci            Py_DECREF(meth);
3397db96d56Sopenharmony_ci            if (retval == NULL)
3407db96d56Sopenharmony_ci                return -1;
3417db96d56Sopenharmony_ci        }
3427db96d56Sopenharmony_ci    }
3437db96d56Sopenharmony_ci    Py_XDECREF(retval);
3447db96d56Sopenharmony_ci    return 0;
3457db96d56Sopenharmony_ci}
3467db96d56Sopenharmony_ci
3477db96d56Sopenharmony_ciPyObject *
3487db96d56Sopenharmony_ci_PyGen_yf(PyGenObject *gen)
3497db96d56Sopenharmony_ci{
3507db96d56Sopenharmony_ci    PyObject *yf = NULL;
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ci    if (gen->gi_frame_state < FRAME_CLEARED) {
3537db96d56Sopenharmony_ci        _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_ci        if (gen->gi_frame_state == FRAME_CREATED) {
3567db96d56Sopenharmony_ci            /* Return immediately if the frame didn't start yet. SEND
3577db96d56Sopenharmony_ci               always come after LOAD_CONST: a code object should not start
3587db96d56Sopenharmony_ci               with SEND */
3597db96d56Sopenharmony_ci            assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND);
3607db96d56Sopenharmony_ci            return NULL;
3617db96d56Sopenharmony_ci        }
3627db96d56Sopenharmony_ci        _Py_CODEUNIT next = frame->prev_instr[1];
3637db96d56Sopenharmony_ci        if (_PyOpcode_Deopt[_Py_OPCODE(next)] != RESUME || _Py_OPARG(next) < 2)
3647db96d56Sopenharmony_ci        {
3657db96d56Sopenharmony_ci            /* Not in a yield from */
3667db96d56Sopenharmony_ci            return NULL;
3677db96d56Sopenharmony_ci        }
3687db96d56Sopenharmony_ci        yf = _PyFrame_StackPeek(frame);
3697db96d56Sopenharmony_ci        Py_INCREF(yf);
3707db96d56Sopenharmony_ci    }
3717db96d56Sopenharmony_ci
3727db96d56Sopenharmony_ci    return yf;
3737db96d56Sopenharmony_ci}
3747db96d56Sopenharmony_ci
3757db96d56Sopenharmony_cistatic PyObject *
3767db96d56Sopenharmony_cigen_close(PyGenObject *gen, PyObject *args)
3777db96d56Sopenharmony_ci{
3787db96d56Sopenharmony_ci    PyObject *retval;
3797db96d56Sopenharmony_ci    PyObject *yf = _PyGen_yf(gen);
3807db96d56Sopenharmony_ci    int err = 0;
3817db96d56Sopenharmony_ci
3827db96d56Sopenharmony_ci    if (yf) {
3837db96d56Sopenharmony_ci        PyFrameState state = gen->gi_frame_state;
3847db96d56Sopenharmony_ci        gen->gi_frame_state = FRAME_EXECUTING;
3857db96d56Sopenharmony_ci        err = gen_close_iter(yf);
3867db96d56Sopenharmony_ci        gen->gi_frame_state = state;
3877db96d56Sopenharmony_ci        Py_DECREF(yf);
3887db96d56Sopenharmony_ci    }
3897db96d56Sopenharmony_ci    if (err == 0)
3907db96d56Sopenharmony_ci        PyErr_SetNone(PyExc_GeneratorExit);
3917db96d56Sopenharmony_ci    retval = gen_send_ex(gen, Py_None, 1, 1);
3927db96d56Sopenharmony_ci    if (retval) {
3937db96d56Sopenharmony_ci        const char *msg = "generator ignored GeneratorExit";
3947db96d56Sopenharmony_ci        if (PyCoro_CheckExact(gen)) {
3957db96d56Sopenharmony_ci            msg = "coroutine ignored GeneratorExit";
3967db96d56Sopenharmony_ci        } else if (PyAsyncGen_CheckExact(gen)) {
3977db96d56Sopenharmony_ci            msg = ASYNC_GEN_IGNORED_EXIT_MSG;
3987db96d56Sopenharmony_ci        }
3997db96d56Sopenharmony_ci        Py_DECREF(retval);
4007db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError, msg);
4017db96d56Sopenharmony_ci        return NULL;
4027db96d56Sopenharmony_ci    }
4037db96d56Sopenharmony_ci    if (PyErr_ExceptionMatches(PyExc_StopIteration)
4047db96d56Sopenharmony_ci        || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
4057db96d56Sopenharmony_ci        PyErr_Clear();          /* ignore these errors */
4067db96d56Sopenharmony_ci        Py_RETURN_NONE;
4077db96d56Sopenharmony_ci    }
4087db96d56Sopenharmony_ci    return NULL;
4097db96d56Sopenharmony_ci}
4107db96d56Sopenharmony_ci
4117db96d56Sopenharmony_ci
4127db96d56Sopenharmony_ciPyDoc_STRVAR(throw_doc,
4137db96d56Sopenharmony_ci"throw(value)\n\
4147db96d56Sopenharmony_cithrow(type[,value[,tb]])\n\
4157db96d56Sopenharmony_ci\n\
4167db96d56Sopenharmony_ciRaise exception in generator, return next yielded value or raise\n\
4177db96d56Sopenharmony_ciStopIteration.");
4187db96d56Sopenharmony_ci
4197db96d56Sopenharmony_cistatic PyObject *
4207db96d56Sopenharmony_ci_gen_throw(PyGenObject *gen, int close_on_genexit,
4217db96d56Sopenharmony_ci           PyObject *typ, PyObject *val, PyObject *tb)
4227db96d56Sopenharmony_ci{
4237db96d56Sopenharmony_ci    PyObject *yf = _PyGen_yf(gen);
4247db96d56Sopenharmony_ci
4257db96d56Sopenharmony_ci    if (yf) {
4267db96d56Sopenharmony_ci        _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
4277db96d56Sopenharmony_ci        PyObject *ret;
4287db96d56Sopenharmony_ci        int err;
4297db96d56Sopenharmony_ci        if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) &&
4307db96d56Sopenharmony_ci            close_on_genexit
4317db96d56Sopenharmony_ci        ) {
4327db96d56Sopenharmony_ci            /* Asynchronous generators *should not* be closed right away.
4337db96d56Sopenharmony_ci               We have to allow some awaits to work it through, hence the
4347db96d56Sopenharmony_ci               `close_on_genexit` parameter here.
4357db96d56Sopenharmony_ci            */
4367db96d56Sopenharmony_ci            PyFrameState state = gen->gi_frame_state;
4377db96d56Sopenharmony_ci            gen->gi_frame_state = FRAME_EXECUTING;
4387db96d56Sopenharmony_ci            err = gen_close_iter(yf);
4397db96d56Sopenharmony_ci            gen->gi_frame_state = state;
4407db96d56Sopenharmony_ci            Py_DECREF(yf);
4417db96d56Sopenharmony_ci            if (err < 0)
4427db96d56Sopenharmony_ci                return gen_send_ex(gen, Py_None, 1, 0);
4437db96d56Sopenharmony_ci            goto throw_here;
4447db96d56Sopenharmony_ci        }
4457db96d56Sopenharmony_ci        if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) {
4467db96d56Sopenharmony_ci            /* `yf` is a generator or a coroutine. */
4477db96d56Sopenharmony_ci            PyThreadState *tstate = _PyThreadState_GET();
4487db96d56Sopenharmony_ci            /* Since we are fast-tracking things by skipping the eval loop,
4497db96d56Sopenharmony_ci               we need to update the current frame so the stack trace
4507db96d56Sopenharmony_ci               will be reported correctly to the user. */
4517db96d56Sopenharmony_ci            /* XXX We should probably be updating the current frame
4527db96d56Sopenharmony_ci               somewhere in ceval.c. */
4537db96d56Sopenharmony_ci            _PyInterpreterFrame *prev = tstate->cframe->current_frame;
4547db96d56Sopenharmony_ci            frame->previous = prev;
4557db96d56Sopenharmony_ci            tstate->cframe->current_frame = frame;
4567db96d56Sopenharmony_ci            /* Close the generator that we are currently iterating with
4577db96d56Sopenharmony_ci               'yield from' or awaiting on with 'await'. */
4587db96d56Sopenharmony_ci            PyFrameState state = gen->gi_frame_state;
4597db96d56Sopenharmony_ci            gen->gi_frame_state = FRAME_EXECUTING;
4607db96d56Sopenharmony_ci            ret = _gen_throw((PyGenObject *)yf, close_on_genexit,
4617db96d56Sopenharmony_ci                             typ, val, tb);
4627db96d56Sopenharmony_ci            gen->gi_frame_state = state;
4637db96d56Sopenharmony_ci            tstate->cframe->current_frame = prev;
4647db96d56Sopenharmony_ci            frame->previous = NULL;
4657db96d56Sopenharmony_ci        } else {
4667db96d56Sopenharmony_ci            /* `yf` is an iterator or a coroutine-like object. */
4677db96d56Sopenharmony_ci            PyObject *meth;
4687db96d56Sopenharmony_ci            if (_PyObject_LookupAttr(yf, &_Py_ID(throw), &meth) < 0) {
4697db96d56Sopenharmony_ci                Py_DECREF(yf);
4707db96d56Sopenharmony_ci                return NULL;
4717db96d56Sopenharmony_ci            }
4727db96d56Sopenharmony_ci            if (meth == NULL) {
4737db96d56Sopenharmony_ci                Py_DECREF(yf);
4747db96d56Sopenharmony_ci                goto throw_here;
4757db96d56Sopenharmony_ci            }
4767db96d56Sopenharmony_ci            PyFrameState state = gen->gi_frame_state;
4777db96d56Sopenharmony_ci            gen->gi_frame_state = FRAME_EXECUTING;
4787db96d56Sopenharmony_ci            ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL);
4797db96d56Sopenharmony_ci            gen->gi_frame_state = state;
4807db96d56Sopenharmony_ci            Py_DECREF(meth);
4817db96d56Sopenharmony_ci        }
4827db96d56Sopenharmony_ci        Py_DECREF(yf);
4837db96d56Sopenharmony_ci        if (!ret) {
4847db96d56Sopenharmony_ci            PyObject *val;
4857db96d56Sopenharmony_ci            /* Pop subiterator from stack */
4867db96d56Sopenharmony_ci            assert(gen->gi_frame_state < FRAME_CLEARED);
4877db96d56Sopenharmony_ci            ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe);
4887db96d56Sopenharmony_ci            assert(ret == yf);
4897db96d56Sopenharmony_ci            Py_DECREF(ret);
4907db96d56Sopenharmony_ci            // XXX: Performing this jump ourselves is awkward and problematic.
4917db96d56Sopenharmony_ci            // See https://github.com/python/cpython/pull/31968.
4927db96d56Sopenharmony_ci            /* Termination repetition of SEND loop */
4937db96d56Sopenharmony_ci            assert(_PyInterpreterFrame_LASTI(frame) >= 0);
4947db96d56Sopenharmony_ci            /* Backup to SEND */
4957db96d56Sopenharmony_ci            assert(_Py_OPCODE(frame->prev_instr[-1]) == SEND);
4967db96d56Sopenharmony_ci            int jump = _Py_OPARG(frame->prev_instr[-1]);
4977db96d56Sopenharmony_ci            frame->prev_instr += jump - 1;
4987db96d56Sopenharmony_ci            if (_PyGen_FetchStopIterationValue(&val) == 0) {
4997db96d56Sopenharmony_ci                ret = gen_send(gen, val);
5007db96d56Sopenharmony_ci                Py_DECREF(val);
5017db96d56Sopenharmony_ci            } else {
5027db96d56Sopenharmony_ci                ret = gen_send_ex(gen, Py_None, 1, 0);
5037db96d56Sopenharmony_ci            }
5047db96d56Sopenharmony_ci        }
5057db96d56Sopenharmony_ci        return ret;
5067db96d56Sopenharmony_ci    }
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_cithrow_here:
5097db96d56Sopenharmony_ci    /* First, check the traceback argument, replacing None with
5107db96d56Sopenharmony_ci       NULL. */
5117db96d56Sopenharmony_ci    if (tb == Py_None) {
5127db96d56Sopenharmony_ci        tb = NULL;
5137db96d56Sopenharmony_ci    }
5147db96d56Sopenharmony_ci    else if (tb != NULL && !PyTraceBack_Check(tb)) {
5157db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
5167db96d56Sopenharmony_ci            "throw() third argument must be a traceback object");
5177db96d56Sopenharmony_ci        return NULL;
5187db96d56Sopenharmony_ci    }
5197db96d56Sopenharmony_ci
5207db96d56Sopenharmony_ci    Py_INCREF(typ);
5217db96d56Sopenharmony_ci    Py_XINCREF(val);
5227db96d56Sopenharmony_ci    Py_XINCREF(tb);
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ci    if (PyExceptionClass_Check(typ))
5257db96d56Sopenharmony_ci        PyErr_NormalizeException(&typ, &val, &tb);
5267db96d56Sopenharmony_ci
5277db96d56Sopenharmony_ci    else if (PyExceptionInstance_Check(typ)) {
5287db96d56Sopenharmony_ci        /* Raising an instance.  The value should be a dummy. */
5297db96d56Sopenharmony_ci        if (val && val != Py_None) {
5307db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError,
5317db96d56Sopenharmony_ci              "instance exception may not have a separate value");
5327db96d56Sopenharmony_ci            goto failed_throw;
5337db96d56Sopenharmony_ci        }
5347db96d56Sopenharmony_ci        else {
5357db96d56Sopenharmony_ci            /* Normalize to raise <class>, <instance> */
5367db96d56Sopenharmony_ci            Py_XDECREF(val);
5377db96d56Sopenharmony_ci            val = typ;
5387db96d56Sopenharmony_ci            typ = PyExceptionInstance_Class(typ);
5397db96d56Sopenharmony_ci            Py_INCREF(typ);
5407db96d56Sopenharmony_ci
5417db96d56Sopenharmony_ci            if (tb == NULL)
5427db96d56Sopenharmony_ci                /* Returns NULL if there's no traceback */
5437db96d56Sopenharmony_ci                tb = PyException_GetTraceback(val);
5447db96d56Sopenharmony_ci        }
5457db96d56Sopenharmony_ci    }
5467db96d56Sopenharmony_ci    else {
5477db96d56Sopenharmony_ci        /* Not something you can raise.  throw() fails. */
5487db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
5497db96d56Sopenharmony_ci                     "exceptions must be classes or instances "
5507db96d56Sopenharmony_ci                     "deriving from BaseException, not %s",
5517db96d56Sopenharmony_ci                     Py_TYPE(typ)->tp_name);
5527db96d56Sopenharmony_ci            goto failed_throw;
5537db96d56Sopenharmony_ci    }
5547db96d56Sopenharmony_ci
5557db96d56Sopenharmony_ci    PyErr_Restore(typ, val, tb);
5567db96d56Sopenharmony_ci    return gen_send_ex(gen, Py_None, 1, 0);
5577db96d56Sopenharmony_ci
5587db96d56Sopenharmony_cifailed_throw:
5597db96d56Sopenharmony_ci    /* Didn't use our arguments, so restore their original refcounts */
5607db96d56Sopenharmony_ci    Py_DECREF(typ);
5617db96d56Sopenharmony_ci    Py_XDECREF(val);
5627db96d56Sopenharmony_ci    Py_XDECREF(tb);
5637db96d56Sopenharmony_ci    return NULL;
5647db96d56Sopenharmony_ci}
5657db96d56Sopenharmony_ci
5667db96d56Sopenharmony_ci
5677db96d56Sopenharmony_cistatic PyObject *
5687db96d56Sopenharmony_cigen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs)
5697db96d56Sopenharmony_ci{
5707db96d56Sopenharmony_ci    PyObject *typ;
5717db96d56Sopenharmony_ci    PyObject *tb = NULL;
5727db96d56Sopenharmony_ci    PyObject *val = NULL;
5737db96d56Sopenharmony_ci
5747db96d56Sopenharmony_ci    if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) {
5757db96d56Sopenharmony_ci        return NULL;
5767db96d56Sopenharmony_ci    }
5777db96d56Sopenharmony_ci    typ = args[0];
5787db96d56Sopenharmony_ci    if (nargs == 3) {
5797db96d56Sopenharmony_ci        val = args[1];
5807db96d56Sopenharmony_ci        tb = args[2];
5817db96d56Sopenharmony_ci    }
5827db96d56Sopenharmony_ci    else if (nargs == 2) {
5837db96d56Sopenharmony_ci        val = args[1];
5847db96d56Sopenharmony_ci    }
5857db96d56Sopenharmony_ci    return _gen_throw(gen, 1, typ, val, tb);
5867db96d56Sopenharmony_ci}
5877db96d56Sopenharmony_ci
5887db96d56Sopenharmony_ci
5897db96d56Sopenharmony_cistatic PyObject *
5907db96d56Sopenharmony_cigen_iternext(PyGenObject *gen)
5917db96d56Sopenharmony_ci{
5927db96d56Sopenharmony_ci    PyObject *result;
5937db96d56Sopenharmony_ci    assert(PyGen_CheckExact(gen) || PyCoro_CheckExact(gen));
5947db96d56Sopenharmony_ci    if (gen_send_ex2(gen, NULL, &result, 0, 0) == PYGEN_RETURN) {
5957db96d56Sopenharmony_ci        if (result != Py_None) {
5967db96d56Sopenharmony_ci            _PyGen_SetStopIterationValue(result);
5977db96d56Sopenharmony_ci        }
5987db96d56Sopenharmony_ci        Py_CLEAR(result);
5997db96d56Sopenharmony_ci    }
6007db96d56Sopenharmony_ci    return result;
6017db96d56Sopenharmony_ci}
6027db96d56Sopenharmony_ci
6037db96d56Sopenharmony_ci/*
6047db96d56Sopenharmony_ci * Set StopIteration with specified value.  Value can be arbitrary object
6057db96d56Sopenharmony_ci * or NULL.
6067db96d56Sopenharmony_ci *
6077db96d56Sopenharmony_ci * Returns 0 if StopIteration is set and -1 if any other exception is set.
6087db96d56Sopenharmony_ci */
6097db96d56Sopenharmony_ciint
6107db96d56Sopenharmony_ci_PyGen_SetStopIterationValue(PyObject *value)
6117db96d56Sopenharmony_ci{
6127db96d56Sopenharmony_ci    PyObject *e;
6137db96d56Sopenharmony_ci
6147db96d56Sopenharmony_ci    if (value == NULL ||
6157db96d56Sopenharmony_ci        (!PyTuple_Check(value) && !PyExceptionInstance_Check(value)))
6167db96d56Sopenharmony_ci    {
6177db96d56Sopenharmony_ci        /* Delay exception instantiation if we can */
6187db96d56Sopenharmony_ci        PyErr_SetObject(PyExc_StopIteration, value);
6197db96d56Sopenharmony_ci        return 0;
6207db96d56Sopenharmony_ci    }
6217db96d56Sopenharmony_ci    /* Construct an exception instance manually with
6227db96d56Sopenharmony_ci     * PyObject_CallOneArg and pass it to PyErr_SetObject.
6237db96d56Sopenharmony_ci     *
6247db96d56Sopenharmony_ci     * We do this to handle a situation when "value" is a tuple, in which
6257db96d56Sopenharmony_ci     * case PyErr_SetObject would set the value of StopIteration to
6267db96d56Sopenharmony_ci     * the first element of the tuple.
6277db96d56Sopenharmony_ci     *
6287db96d56Sopenharmony_ci     * (See PyErr_SetObject/_PyErr_CreateException code for details.)
6297db96d56Sopenharmony_ci     */
6307db96d56Sopenharmony_ci    e = PyObject_CallOneArg(PyExc_StopIteration, value);
6317db96d56Sopenharmony_ci    if (e == NULL) {
6327db96d56Sopenharmony_ci        return -1;
6337db96d56Sopenharmony_ci    }
6347db96d56Sopenharmony_ci    PyErr_SetObject(PyExc_StopIteration, e);
6357db96d56Sopenharmony_ci    Py_DECREF(e);
6367db96d56Sopenharmony_ci    return 0;
6377db96d56Sopenharmony_ci}
6387db96d56Sopenharmony_ci
6397db96d56Sopenharmony_ci/*
6407db96d56Sopenharmony_ci *   If StopIteration exception is set, fetches its 'value'
6417db96d56Sopenharmony_ci *   attribute if any, otherwise sets pvalue to None.
6427db96d56Sopenharmony_ci *
6437db96d56Sopenharmony_ci *   Returns 0 if no exception or StopIteration is set.
6447db96d56Sopenharmony_ci *   If any other exception is set, returns -1 and leaves
6457db96d56Sopenharmony_ci *   pvalue unchanged.
6467db96d56Sopenharmony_ci */
6477db96d56Sopenharmony_ci
6487db96d56Sopenharmony_ciint
6497db96d56Sopenharmony_ci_PyGen_FetchStopIterationValue(PyObject **pvalue)
6507db96d56Sopenharmony_ci{
6517db96d56Sopenharmony_ci    PyObject *et, *ev, *tb;
6527db96d56Sopenharmony_ci    PyObject *value = NULL;
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci    if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
6557db96d56Sopenharmony_ci        PyErr_Fetch(&et, &ev, &tb);
6567db96d56Sopenharmony_ci        if (ev) {
6577db96d56Sopenharmony_ci            /* exception will usually be normalised already */
6587db96d56Sopenharmony_ci            if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
6597db96d56Sopenharmony_ci                value = ((PyStopIterationObject *)ev)->value;
6607db96d56Sopenharmony_ci                Py_INCREF(value);
6617db96d56Sopenharmony_ci                Py_DECREF(ev);
6627db96d56Sopenharmony_ci            } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) {
6637db96d56Sopenharmony_ci                /* Avoid normalisation and take ev as value.
6647db96d56Sopenharmony_ci                 *
6657db96d56Sopenharmony_ci                 * Normalization is required if the value is a tuple, in
6667db96d56Sopenharmony_ci                 * that case the value of StopIteration would be set to
6677db96d56Sopenharmony_ci                 * the first element of the tuple.
6687db96d56Sopenharmony_ci                 *
6697db96d56Sopenharmony_ci                 * (See _PyErr_CreateException code for details.)
6707db96d56Sopenharmony_ci                 */
6717db96d56Sopenharmony_ci                value = ev;
6727db96d56Sopenharmony_ci            } else {
6737db96d56Sopenharmony_ci                /* normalisation required */
6747db96d56Sopenharmony_ci                PyErr_NormalizeException(&et, &ev, &tb);
6757db96d56Sopenharmony_ci                if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
6767db96d56Sopenharmony_ci                    PyErr_Restore(et, ev, tb);
6777db96d56Sopenharmony_ci                    return -1;
6787db96d56Sopenharmony_ci                }
6797db96d56Sopenharmony_ci                value = ((PyStopIterationObject *)ev)->value;
6807db96d56Sopenharmony_ci                Py_INCREF(value);
6817db96d56Sopenharmony_ci                Py_DECREF(ev);
6827db96d56Sopenharmony_ci            }
6837db96d56Sopenharmony_ci        }
6847db96d56Sopenharmony_ci        Py_XDECREF(et);
6857db96d56Sopenharmony_ci        Py_XDECREF(tb);
6867db96d56Sopenharmony_ci    } else if (PyErr_Occurred()) {
6877db96d56Sopenharmony_ci        return -1;
6887db96d56Sopenharmony_ci    }
6897db96d56Sopenharmony_ci    if (value == NULL) {
6907db96d56Sopenharmony_ci        value = Py_None;
6917db96d56Sopenharmony_ci        Py_INCREF(value);
6927db96d56Sopenharmony_ci    }
6937db96d56Sopenharmony_ci    *pvalue = value;
6947db96d56Sopenharmony_ci    return 0;
6957db96d56Sopenharmony_ci}
6967db96d56Sopenharmony_ci
6977db96d56Sopenharmony_cistatic PyObject *
6987db96d56Sopenharmony_cigen_repr(PyGenObject *gen)
6997db96d56Sopenharmony_ci{
7007db96d56Sopenharmony_ci    return PyUnicode_FromFormat("<generator object %S at %p>",
7017db96d56Sopenharmony_ci                                gen->gi_qualname, gen);
7027db96d56Sopenharmony_ci}
7037db96d56Sopenharmony_ci
7047db96d56Sopenharmony_cistatic PyObject *
7057db96d56Sopenharmony_cigen_get_name(PyGenObject *op, void *Py_UNUSED(ignored))
7067db96d56Sopenharmony_ci{
7077db96d56Sopenharmony_ci    Py_INCREF(op->gi_name);
7087db96d56Sopenharmony_ci    return op->gi_name;
7097db96d56Sopenharmony_ci}
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_cistatic int
7127db96d56Sopenharmony_cigen_set_name(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored))
7137db96d56Sopenharmony_ci{
7147db96d56Sopenharmony_ci    /* Not legal to del gen.gi_name or to set it to anything
7157db96d56Sopenharmony_ci     * other than a string object. */
7167db96d56Sopenharmony_ci    if (value == NULL || !PyUnicode_Check(value)) {
7177db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
7187db96d56Sopenharmony_ci                        "__name__ must be set to a string object");
7197db96d56Sopenharmony_ci        return -1;
7207db96d56Sopenharmony_ci    }
7217db96d56Sopenharmony_ci    Py_INCREF(value);
7227db96d56Sopenharmony_ci    Py_XSETREF(op->gi_name, value);
7237db96d56Sopenharmony_ci    return 0;
7247db96d56Sopenharmony_ci}
7257db96d56Sopenharmony_ci
7267db96d56Sopenharmony_cistatic PyObject *
7277db96d56Sopenharmony_cigen_get_qualname(PyGenObject *op, void *Py_UNUSED(ignored))
7287db96d56Sopenharmony_ci{
7297db96d56Sopenharmony_ci    Py_INCREF(op->gi_qualname);
7307db96d56Sopenharmony_ci    return op->gi_qualname;
7317db96d56Sopenharmony_ci}
7327db96d56Sopenharmony_ci
7337db96d56Sopenharmony_cistatic int
7347db96d56Sopenharmony_cigen_set_qualname(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored))
7357db96d56Sopenharmony_ci{
7367db96d56Sopenharmony_ci    /* Not legal to del gen.__qualname__ or to set it to anything
7377db96d56Sopenharmony_ci     * other than a string object. */
7387db96d56Sopenharmony_ci    if (value == NULL || !PyUnicode_Check(value)) {
7397db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
7407db96d56Sopenharmony_ci                        "__qualname__ must be set to a string object");
7417db96d56Sopenharmony_ci        return -1;
7427db96d56Sopenharmony_ci    }
7437db96d56Sopenharmony_ci    Py_INCREF(value);
7447db96d56Sopenharmony_ci    Py_XSETREF(op->gi_qualname, value);
7457db96d56Sopenharmony_ci    return 0;
7467db96d56Sopenharmony_ci}
7477db96d56Sopenharmony_ci
7487db96d56Sopenharmony_cistatic PyObject *
7497db96d56Sopenharmony_cigen_getyieldfrom(PyGenObject *gen, void *Py_UNUSED(ignored))
7507db96d56Sopenharmony_ci{
7517db96d56Sopenharmony_ci    PyObject *yf = _PyGen_yf(gen);
7527db96d56Sopenharmony_ci    if (yf == NULL)
7537db96d56Sopenharmony_ci        Py_RETURN_NONE;
7547db96d56Sopenharmony_ci    return yf;
7557db96d56Sopenharmony_ci}
7567db96d56Sopenharmony_ci
7577db96d56Sopenharmony_ci
7587db96d56Sopenharmony_cistatic PyObject *
7597db96d56Sopenharmony_cigen_getrunning(PyGenObject *gen, void *Py_UNUSED(ignored))
7607db96d56Sopenharmony_ci{
7617db96d56Sopenharmony_ci    if (gen->gi_frame_state == FRAME_EXECUTING) {
7627db96d56Sopenharmony_ci        Py_RETURN_TRUE;
7637db96d56Sopenharmony_ci    }
7647db96d56Sopenharmony_ci    Py_RETURN_FALSE;
7657db96d56Sopenharmony_ci}
7667db96d56Sopenharmony_ci
7677db96d56Sopenharmony_cistatic PyObject *
7687db96d56Sopenharmony_cigen_getsuspended(PyGenObject *gen, void *Py_UNUSED(ignored))
7697db96d56Sopenharmony_ci{
7707db96d56Sopenharmony_ci    return PyBool_FromLong(gen->gi_frame_state == FRAME_SUSPENDED);
7717db96d56Sopenharmony_ci}
7727db96d56Sopenharmony_ci
7737db96d56Sopenharmony_cistatic PyObject *
7747db96d56Sopenharmony_ci_gen_getframe(PyGenObject *gen, const char *const name)
7757db96d56Sopenharmony_ci{
7767db96d56Sopenharmony_ci    if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) {
7777db96d56Sopenharmony_ci        return NULL;
7787db96d56Sopenharmony_ci    }
7797db96d56Sopenharmony_ci    if (gen->gi_frame_state == FRAME_CLEARED) {
7807db96d56Sopenharmony_ci        Py_RETURN_NONE;
7817db96d56Sopenharmony_ci    }
7827db96d56Sopenharmony_ci    return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe));
7837db96d56Sopenharmony_ci}
7847db96d56Sopenharmony_ci
7857db96d56Sopenharmony_cistatic PyObject *
7867db96d56Sopenharmony_cigen_getframe(PyGenObject *gen, void *Py_UNUSED(ignored))
7877db96d56Sopenharmony_ci{
7887db96d56Sopenharmony_ci    return _gen_getframe(gen, "gi_frame");
7897db96d56Sopenharmony_ci}
7907db96d56Sopenharmony_ci
7917db96d56Sopenharmony_cistatic PyGetSetDef gen_getsetlist[] = {
7927db96d56Sopenharmony_ci    {"__name__", (getter)gen_get_name, (setter)gen_set_name,
7937db96d56Sopenharmony_ci     PyDoc_STR("name of the generator")},
7947db96d56Sopenharmony_ci    {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
7957db96d56Sopenharmony_ci     PyDoc_STR("qualified name of the generator")},
7967db96d56Sopenharmony_ci    {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL,
7977db96d56Sopenharmony_ci     PyDoc_STR("object being iterated by yield from, or None")},
7987db96d56Sopenharmony_ci    {"gi_running", (getter)gen_getrunning, NULL, NULL},
7997db96d56Sopenharmony_ci    {"gi_frame", (getter)gen_getframe,  NULL, NULL},
8007db96d56Sopenharmony_ci    {"gi_suspended", (getter)gen_getsuspended,  NULL, NULL},
8017db96d56Sopenharmony_ci    {NULL} /* Sentinel */
8027db96d56Sopenharmony_ci};
8037db96d56Sopenharmony_ci
8047db96d56Sopenharmony_cistatic PyMemberDef gen_memberlist[] = {
8057db96d56Sopenharmony_ci    {"gi_code",      T_OBJECT, offsetof(PyGenObject, gi_code),     READONLY|PY_AUDIT_READ},
8067db96d56Sopenharmony_ci    {NULL}      /* Sentinel */
8077db96d56Sopenharmony_ci};
8087db96d56Sopenharmony_ci
8097db96d56Sopenharmony_cistatic PyObject *
8107db96d56Sopenharmony_cigen_sizeof(PyGenObject *gen, PyObject *Py_UNUSED(ignored))
8117db96d56Sopenharmony_ci{
8127db96d56Sopenharmony_ci    Py_ssize_t res;
8137db96d56Sopenharmony_ci    res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus);
8147db96d56Sopenharmony_ci    PyCodeObject *code = gen->gi_code;
8157db96d56Sopenharmony_ci    res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *);
8167db96d56Sopenharmony_ci    return PyLong_FromSsize_t(res);
8177db96d56Sopenharmony_ci}
8187db96d56Sopenharmony_ci
8197db96d56Sopenharmony_ciPyDoc_STRVAR(sizeof__doc__,
8207db96d56Sopenharmony_ci"gen.__sizeof__() -> size of gen in memory, in bytes");
8217db96d56Sopenharmony_ci
8227db96d56Sopenharmony_cistatic PyMethodDef gen_methods[] = {
8237db96d56Sopenharmony_ci    {"send",(PyCFunction)gen_send, METH_O, send_doc},
8247db96d56Sopenharmony_ci    {"throw",_PyCFunction_CAST(gen_throw), METH_FASTCALL, throw_doc},
8257db96d56Sopenharmony_ci    {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
8267db96d56Sopenharmony_ci    {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
8277db96d56Sopenharmony_ci    {NULL, NULL}        /* Sentinel */
8287db96d56Sopenharmony_ci};
8297db96d56Sopenharmony_ci
8307db96d56Sopenharmony_cistatic PyAsyncMethods gen_as_async = {
8317db96d56Sopenharmony_ci    0,                                          /* am_await */
8327db96d56Sopenharmony_ci    0,                                          /* am_aiter */
8337db96d56Sopenharmony_ci    0,                                          /* am_anext */
8347db96d56Sopenharmony_ci    (sendfunc)PyGen_am_send,                    /* am_send  */
8357db96d56Sopenharmony_ci};
8367db96d56Sopenharmony_ci
8377db96d56Sopenharmony_ci
8387db96d56Sopenharmony_ciPyTypeObject PyGen_Type = {
8397db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
8407db96d56Sopenharmony_ci    "generator",                                /* tp_name */
8417db96d56Sopenharmony_ci    offsetof(PyGenObject, gi_iframe) +
8427db96d56Sopenharmony_ci    offsetof(_PyInterpreterFrame, localsplus),       /* tp_basicsize */
8437db96d56Sopenharmony_ci    sizeof(PyObject *),                         /* tp_itemsize */
8447db96d56Sopenharmony_ci    /* methods */
8457db96d56Sopenharmony_ci    (destructor)gen_dealloc,                    /* tp_dealloc */
8467db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
8477db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
8487db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
8497db96d56Sopenharmony_ci    &gen_as_async,                              /* tp_as_async */
8507db96d56Sopenharmony_ci    (reprfunc)gen_repr,                         /* tp_repr */
8517db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
8527db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
8537db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
8547db96d56Sopenharmony_ci    0,                                          /* tp_hash */
8557db96d56Sopenharmony_ci    0,                                          /* tp_call */
8567db96d56Sopenharmony_ci    0,                                          /* tp_str */
8577db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
8587db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
8597db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
8607db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
8617db96d56Sopenharmony_ci    0,                                          /* tp_doc */
8627db96d56Sopenharmony_ci    (traverseproc)gen_traverse,                 /* tp_traverse */
8637db96d56Sopenharmony_ci    0,                                          /* tp_clear */
8647db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
8657db96d56Sopenharmony_ci    offsetof(PyGenObject, gi_weakreflist),      /* tp_weaklistoffset */
8667db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* tp_iter */
8677db96d56Sopenharmony_ci    (iternextfunc)gen_iternext,                 /* tp_iternext */
8687db96d56Sopenharmony_ci    gen_methods,                                /* tp_methods */
8697db96d56Sopenharmony_ci    gen_memberlist,                             /* tp_members */
8707db96d56Sopenharmony_ci    gen_getsetlist,                             /* tp_getset */
8717db96d56Sopenharmony_ci    0,                                          /* tp_base */
8727db96d56Sopenharmony_ci    0,                                          /* tp_dict */
8737db96d56Sopenharmony_ci
8747db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
8757db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
8767db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
8777db96d56Sopenharmony_ci    0,                                          /* tp_init */
8787db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
8797db96d56Sopenharmony_ci    0,                                          /* tp_new */
8807db96d56Sopenharmony_ci    0,                                          /* tp_free */
8817db96d56Sopenharmony_ci    0,                                          /* tp_is_gc */
8827db96d56Sopenharmony_ci    0,                                          /* tp_bases */
8837db96d56Sopenharmony_ci    0,                                          /* tp_mro */
8847db96d56Sopenharmony_ci    0,                                          /* tp_cache */
8857db96d56Sopenharmony_ci    0,                                          /* tp_subclasses */
8867db96d56Sopenharmony_ci    0,                                          /* tp_weaklist */
8877db96d56Sopenharmony_ci    0,                                          /* tp_del */
8887db96d56Sopenharmony_ci    0,                                          /* tp_version_tag */
8897db96d56Sopenharmony_ci    _PyGen_Finalize,                            /* tp_finalize */
8907db96d56Sopenharmony_ci};
8917db96d56Sopenharmony_ci
8927db96d56Sopenharmony_cistatic PyObject *
8937db96d56Sopenharmony_cimake_gen(PyTypeObject *type, PyFunctionObject *func)
8947db96d56Sopenharmony_ci{
8957db96d56Sopenharmony_ci    PyCodeObject *code = (PyCodeObject *)func->func_code;
8967db96d56Sopenharmony_ci    int slots = code->co_nlocalsplus + code->co_stacksize;
8977db96d56Sopenharmony_ci    PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, slots);
8987db96d56Sopenharmony_ci    if (gen == NULL) {
8997db96d56Sopenharmony_ci        return NULL;
9007db96d56Sopenharmony_ci    }
9017db96d56Sopenharmony_ci    gen->gi_frame_state = FRAME_CLEARED;
9027db96d56Sopenharmony_ci    gen->gi_code = (PyCodeObject *)func->func_code;
9037db96d56Sopenharmony_ci    Py_INCREF(gen->gi_code);
9047db96d56Sopenharmony_ci    gen->gi_weakreflist = NULL;
9057db96d56Sopenharmony_ci    gen->gi_exc_state.exc_value = NULL;
9067db96d56Sopenharmony_ci    gen->gi_exc_state.previous_item = NULL;
9077db96d56Sopenharmony_ci    assert(func->func_name != NULL);
9087db96d56Sopenharmony_ci    gen->gi_name = Py_NewRef(func->func_name);
9097db96d56Sopenharmony_ci    assert(func->func_qualname != NULL);
9107db96d56Sopenharmony_ci    gen->gi_qualname = Py_NewRef(func->func_qualname);
9117db96d56Sopenharmony_ci    _PyObject_GC_TRACK(gen);
9127db96d56Sopenharmony_ci    return (PyObject *)gen;
9137db96d56Sopenharmony_ci}
9147db96d56Sopenharmony_ci
9157db96d56Sopenharmony_cistatic PyObject *
9167db96d56Sopenharmony_cicompute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame);
9177db96d56Sopenharmony_ci
9187db96d56Sopenharmony_ciPyObject *
9197db96d56Sopenharmony_ci_Py_MakeCoro(PyFunctionObject *func)
9207db96d56Sopenharmony_ci{
9217db96d56Sopenharmony_ci    int coro_flags = ((PyCodeObject *)func->func_code)->co_flags &
9227db96d56Sopenharmony_ci        (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR);
9237db96d56Sopenharmony_ci    assert(coro_flags);
9247db96d56Sopenharmony_ci    if (coro_flags == CO_GENERATOR) {
9257db96d56Sopenharmony_ci        return make_gen(&PyGen_Type, func);
9267db96d56Sopenharmony_ci    }
9277db96d56Sopenharmony_ci    if (coro_flags == CO_ASYNC_GENERATOR) {
9287db96d56Sopenharmony_ci        PyAsyncGenObject *o;
9297db96d56Sopenharmony_ci        o = (PyAsyncGenObject *)make_gen(&PyAsyncGen_Type, func);
9307db96d56Sopenharmony_ci        if (o == NULL) {
9317db96d56Sopenharmony_ci            return NULL;
9327db96d56Sopenharmony_ci        }
9337db96d56Sopenharmony_ci        o->ag_origin_or_finalizer = NULL;
9347db96d56Sopenharmony_ci        o->ag_closed = 0;
9357db96d56Sopenharmony_ci        o->ag_hooks_inited = 0;
9367db96d56Sopenharmony_ci        o->ag_running_async = 0;
9377db96d56Sopenharmony_ci        return (PyObject*)o;
9387db96d56Sopenharmony_ci    }
9397db96d56Sopenharmony_ci    assert (coro_flags == CO_COROUTINE);
9407db96d56Sopenharmony_ci    PyObject *coro = make_gen(&PyCoro_Type, func);
9417db96d56Sopenharmony_ci    if (!coro) {
9427db96d56Sopenharmony_ci        return NULL;
9437db96d56Sopenharmony_ci    }
9447db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
9457db96d56Sopenharmony_ci    int origin_depth = tstate->coroutine_origin_tracking_depth;
9467db96d56Sopenharmony_ci
9477db96d56Sopenharmony_ci    if (origin_depth == 0) {
9487db96d56Sopenharmony_ci        ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL;
9497db96d56Sopenharmony_ci    } else {
9507db96d56Sopenharmony_ci        assert(_PyEval_GetFrame());
9517db96d56Sopenharmony_ci        PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame()->previous);
9527db96d56Sopenharmony_ci        ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin;
9537db96d56Sopenharmony_ci        if (!cr_origin) {
9547db96d56Sopenharmony_ci            Py_DECREF(coro);
9557db96d56Sopenharmony_ci            return NULL;
9567db96d56Sopenharmony_ci        }
9577db96d56Sopenharmony_ci    }
9587db96d56Sopenharmony_ci    return coro;
9597db96d56Sopenharmony_ci}
9607db96d56Sopenharmony_ci
9617db96d56Sopenharmony_cistatic PyObject *
9627db96d56Sopenharmony_cigen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
9637db96d56Sopenharmony_ci                      PyObject *name, PyObject *qualname)
9647db96d56Sopenharmony_ci{
9657db96d56Sopenharmony_ci    PyCodeObject *code = f->f_frame->f_code;
9667db96d56Sopenharmony_ci    int size = code->co_nlocalsplus + code->co_stacksize;
9677db96d56Sopenharmony_ci    PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, size);
9687db96d56Sopenharmony_ci    if (gen == NULL) {
9697db96d56Sopenharmony_ci        Py_DECREF(f);
9707db96d56Sopenharmony_ci        return NULL;
9717db96d56Sopenharmony_ci    }
9727db96d56Sopenharmony_ci    /* Copy the frame */
9737db96d56Sopenharmony_ci    assert(f->f_frame->frame_obj == NULL);
9747db96d56Sopenharmony_ci    assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT);
9757db96d56Sopenharmony_ci    _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
9767db96d56Sopenharmony_ci    _PyFrame_Copy((_PyInterpreterFrame *)f->_f_frame_data, frame);
9777db96d56Sopenharmony_ci    gen->gi_frame_state = FRAME_CREATED;
9787db96d56Sopenharmony_ci    assert(frame->frame_obj == f);
9797db96d56Sopenharmony_ci    f->f_frame = frame;
9807db96d56Sopenharmony_ci    frame->owner = FRAME_OWNED_BY_GENERATOR;
9817db96d56Sopenharmony_ci    assert(PyObject_GC_IsTracked((PyObject *)f));
9827db96d56Sopenharmony_ci    gen->gi_code = PyFrame_GetCode(f);
9837db96d56Sopenharmony_ci    Py_INCREF(gen->gi_code);
9847db96d56Sopenharmony_ci    Py_DECREF(f);
9857db96d56Sopenharmony_ci    gen->gi_weakreflist = NULL;
9867db96d56Sopenharmony_ci    gen->gi_exc_state.exc_value = NULL;
9877db96d56Sopenharmony_ci    gen->gi_exc_state.previous_item = NULL;
9887db96d56Sopenharmony_ci    if (name != NULL)
9897db96d56Sopenharmony_ci        gen->gi_name = name;
9907db96d56Sopenharmony_ci    else
9917db96d56Sopenharmony_ci        gen->gi_name = gen->gi_code->co_name;
9927db96d56Sopenharmony_ci    Py_INCREF(gen->gi_name);
9937db96d56Sopenharmony_ci    if (qualname != NULL)
9947db96d56Sopenharmony_ci        gen->gi_qualname = qualname;
9957db96d56Sopenharmony_ci    else
9967db96d56Sopenharmony_ci        gen->gi_qualname = gen->gi_code->co_qualname;
9977db96d56Sopenharmony_ci    Py_INCREF(gen->gi_qualname);
9987db96d56Sopenharmony_ci    _PyObject_GC_TRACK(gen);
9997db96d56Sopenharmony_ci    return (PyObject *)gen;
10007db96d56Sopenharmony_ci}
10017db96d56Sopenharmony_ci
10027db96d56Sopenharmony_ciPyObject *
10037db96d56Sopenharmony_ciPyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
10047db96d56Sopenharmony_ci{
10057db96d56Sopenharmony_ci    return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
10067db96d56Sopenharmony_ci}
10077db96d56Sopenharmony_ci
10087db96d56Sopenharmony_ciPyObject *
10097db96d56Sopenharmony_ciPyGen_New(PyFrameObject *f)
10107db96d56Sopenharmony_ci{
10117db96d56Sopenharmony_ci    return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);
10127db96d56Sopenharmony_ci}
10137db96d56Sopenharmony_ci
10147db96d56Sopenharmony_ci/* Coroutine Object */
10157db96d56Sopenharmony_ci
10167db96d56Sopenharmony_citypedef struct {
10177db96d56Sopenharmony_ci    PyObject_HEAD
10187db96d56Sopenharmony_ci    PyCoroObject *cw_coroutine;
10197db96d56Sopenharmony_ci} PyCoroWrapper;
10207db96d56Sopenharmony_ci
10217db96d56Sopenharmony_cistatic int
10227db96d56Sopenharmony_cigen_is_coroutine(PyObject *o)
10237db96d56Sopenharmony_ci{
10247db96d56Sopenharmony_ci    if (PyGen_CheckExact(o)) {
10257db96d56Sopenharmony_ci        PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
10267db96d56Sopenharmony_ci        if (code->co_flags & CO_ITERABLE_COROUTINE) {
10277db96d56Sopenharmony_ci            return 1;
10287db96d56Sopenharmony_ci        }
10297db96d56Sopenharmony_ci    }
10307db96d56Sopenharmony_ci    return 0;
10317db96d56Sopenharmony_ci}
10327db96d56Sopenharmony_ci
10337db96d56Sopenharmony_ci/*
10347db96d56Sopenharmony_ci *   This helper function returns an awaitable for `o`:
10357db96d56Sopenharmony_ci *     - `o` if `o` is a coroutine-object;
10367db96d56Sopenharmony_ci *     - `type(o)->tp_as_async->am_await(o)`
10377db96d56Sopenharmony_ci *
10387db96d56Sopenharmony_ci *   Raises a TypeError if it's not possible to return
10397db96d56Sopenharmony_ci *   an awaitable and returns NULL.
10407db96d56Sopenharmony_ci */
10417db96d56Sopenharmony_ciPyObject *
10427db96d56Sopenharmony_ci_PyCoro_GetAwaitableIter(PyObject *o)
10437db96d56Sopenharmony_ci{
10447db96d56Sopenharmony_ci    unaryfunc getter = NULL;
10457db96d56Sopenharmony_ci    PyTypeObject *ot;
10467db96d56Sopenharmony_ci
10477db96d56Sopenharmony_ci    if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
10487db96d56Sopenharmony_ci        /* 'o' is a coroutine. */
10497db96d56Sopenharmony_ci        Py_INCREF(o);
10507db96d56Sopenharmony_ci        return o;
10517db96d56Sopenharmony_ci    }
10527db96d56Sopenharmony_ci
10537db96d56Sopenharmony_ci    ot = Py_TYPE(o);
10547db96d56Sopenharmony_ci    if (ot->tp_as_async != NULL) {
10557db96d56Sopenharmony_ci        getter = ot->tp_as_async->am_await;
10567db96d56Sopenharmony_ci    }
10577db96d56Sopenharmony_ci    if (getter != NULL) {
10587db96d56Sopenharmony_ci        PyObject *res = (*getter)(o);
10597db96d56Sopenharmony_ci        if (res != NULL) {
10607db96d56Sopenharmony_ci            if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
10617db96d56Sopenharmony_ci                /* __await__ must return an *iterator*, not
10627db96d56Sopenharmony_ci                   a coroutine or another awaitable (see PEP 492) */
10637db96d56Sopenharmony_ci                PyErr_SetString(PyExc_TypeError,
10647db96d56Sopenharmony_ci                                "__await__() returned a coroutine");
10657db96d56Sopenharmony_ci                Py_CLEAR(res);
10667db96d56Sopenharmony_ci            } else if (!PyIter_Check(res)) {
10677db96d56Sopenharmony_ci                PyErr_Format(PyExc_TypeError,
10687db96d56Sopenharmony_ci                             "__await__() returned non-iterator "
10697db96d56Sopenharmony_ci                             "of type '%.100s'",
10707db96d56Sopenharmony_ci                             Py_TYPE(res)->tp_name);
10717db96d56Sopenharmony_ci                Py_CLEAR(res);
10727db96d56Sopenharmony_ci            }
10737db96d56Sopenharmony_ci        }
10747db96d56Sopenharmony_ci        return res;
10757db96d56Sopenharmony_ci    }
10767db96d56Sopenharmony_ci
10777db96d56Sopenharmony_ci    PyErr_Format(PyExc_TypeError,
10787db96d56Sopenharmony_ci                 "object %.100s can't be used in 'await' expression",
10797db96d56Sopenharmony_ci                 ot->tp_name);
10807db96d56Sopenharmony_ci    return NULL;
10817db96d56Sopenharmony_ci}
10827db96d56Sopenharmony_ci
10837db96d56Sopenharmony_cistatic PyObject *
10847db96d56Sopenharmony_cicoro_repr(PyCoroObject *coro)
10857db96d56Sopenharmony_ci{
10867db96d56Sopenharmony_ci    return PyUnicode_FromFormat("<coroutine object %S at %p>",
10877db96d56Sopenharmony_ci                                coro->cr_qualname, coro);
10887db96d56Sopenharmony_ci}
10897db96d56Sopenharmony_ci
10907db96d56Sopenharmony_cistatic PyObject *
10917db96d56Sopenharmony_cicoro_await(PyCoroObject *coro)
10927db96d56Sopenharmony_ci{
10937db96d56Sopenharmony_ci    PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
10947db96d56Sopenharmony_ci    if (cw == NULL) {
10957db96d56Sopenharmony_ci        return NULL;
10967db96d56Sopenharmony_ci    }
10977db96d56Sopenharmony_ci    Py_INCREF(coro);
10987db96d56Sopenharmony_ci    cw->cw_coroutine = coro;
10997db96d56Sopenharmony_ci    _PyObject_GC_TRACK(cw);
11007db96d56Sopenharmony_ci    return (PyObject *)cw;
11017db96d56Sopenharmony_ci}
11027db96d56Sopenharmony_ci
11037db96d56Sopenharmony_cistatic PyObject *
11047db96d56Sopenharmony_cicoro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored))
11057db96d56Sopenharmony_ci{
11067db96d56Sopenharmony_ci    PyObject *yf = _PyGen_yf((PyGenObject *) coro);
11077db96d56Sopenharmony_ci    if (yf == NULL)
11087db96d56Sopenharmony_ci        Py_RETURN_NONE;
11097db96d56Sopenharmony_ci    return yf;
11107db96d56Sopenharmony_ci}
11117db96d56Sopenharmony_ci
11127db96d56Sopenharmony_cistatic PyObject *
11137db96d56Sopenharmony_cicr_getsuspended(PyCoroObject *coro, void *Py_UNUSED(ignored))
11147db96d56Sopenharmony_ci{
11157db96d56Sopenharmony_ci    if (coro->cr_frame_state == FRAME_SUSPENDED) {
11167db96d56Sopenharmony_ci        Py_RETURN_TRUE;
11177db96d56Sopenharmony_ci    }
11187db96d56Sopenharmony_ci    Py_RETURN_FALSE;
11197db96d56Sopenharmony_ci}
11207db96d56Sopenharmony_ci
11217db96d56Sopenharmony_cistatic PyObject *
11227db96d56Sopenharmony_cicr_getrunning(PyCoroObject *coro, void *Py_UNUSED(ignored))
11237db96d56Sopenharmony_ci{
11247db96d56Sopenharmony_ci    if (coro->cr_frame_state == FRAME_EXECUTING) {
11257db96d56Sopenharmony_ci        Py_RETURN_TRUE;
11267db96d56Sopenharmony_ci    }
11277db96d56Sopenharmony_ci    Py_RETURN_FALSE;
11287db96d56Sopenharmony_ci}
11297db96d56Sopenharmony_ci
11307db96d56Sopenharmony_cistatic PyObject *
11317db96d56Sopenharmony_cicr_getframe(PyCoroObject *coro, void *Py_UNUSED(ignored))
11327db96d56Sopenharmony_ci{
11337db96d56Sopenharmony_ci    return _gen_getframe((PyGenObject *)coro, "cr_frame");
11347db96d56Sopenharmony_ci}
11357db96d56Sopenharmony_ci
11367db96d56Sopenharmony_ci
11377db96d56Sopenharmony_cistatic PyGetSetDef coro_getsetlist[] = {
11387db96d56Sopenharmony_ci    {"__name__", (getter)gen_get_name, (setter)gen_set_name,
11397db96d56Sopenharmony_ci     PyDoc_STR("name of the coroutine")},
11407db96d56Sopenharmony_ci    {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
11417db96d56Sopenharmony_ci     PyDoc_STR("qualified name of the coroutine")},
11427db96d56Sopenharmony_ci    {"cr_await", (getter)coro_get_cr_await, NULL,
11437db96d56Sopenharmony_ci     PyDoc_STR("object being awaited on, or None")},
11447db96d56Sopenharmony_ci    {"cr_running", (getter)cr_getrunning, NULL, NULL},
11457db96d56Sopenharmony_ci    {"cr_frame", (getter)cr_getframe, NULL, NULL},
11467db96d56Sopenharmony_ci    {"cr_suspended", (getter)cr_getsuspended, NULL, NULL},
11477db96d56Sopenharmony_ci    {NULL} /* Sentinel */
11487db96d56Sopenharmony_ci};
11497db96d56Sopenharmony_ci
11507db96d56Sopenharmony_cistatic PyMemberDef coro_memberlist[] = {
11517db96d56Sopenharmony_ci    {"cr_code",      T_OBJECT, offsetof(PyCoroObject, cr_code),     READONLY|PY_AUDIT_READ},
11527db96d56Sopenharmony_ci    {"cr_origin",    T_OBJECT, offsetof(PyCoroObject, cr_origin_or_finalizer),   READONLY},
11537db96d56Sopenharmony_ci    {NULL}      /* Sentinel */
11547db96d56Sopenharmony_ci};
11557db96d56Sopenharmony_ci
11567db96d56Sopenharmony_ciPyDoc_STRVAR(coro_send_doc,
11577db96d56Sopenharmony_ci"send(arg) -> send 'arg' into coroutine,\n\
11587db96d56Sopenharmony_cireturn next iterated value or raise StopIteration.");
11597db96d56Sopenharmony_ci
11607db96d56Sopenharmony_ciPyDoc_STRVAR(coro_throw_doc,
11617db96d56Sopenharmony_ci"throw(value)\n\
11627db96d56Sopenharmony_cithrow(type[,value[,traceback]])\n\
11637db96d56Sopenharmony_ci\n\
11647db96d56Sopenharmony_ciRaise exception in coroutine, return next iterated value or raise\n\
11657db96d56Sopenharmony_ciStopIteration.");
11667db96d56Sopenharmony_ci
11677db96d56Sopenharmony_ciPyDoc_STRVAR(coro_close_doc,
11687db96d56Sopenharmony_ci"close() -> raise GeneratorExit inside coroutine.");
11697db96d56Sopenharmony_ci
11707db96d56Sopenharmony_cistatic PyMethodDef coro_methods[] = {
11717db96d56Sopenharmony_ci    {"send",(PyCFunction)gen_send, METH_O, coro_send_doc},
11727db96d56Sopenharmony_ci    {"throw",_PyCFunction_CAST(gen_throw), METH_FASTCALL, coro_throw_doc},
11737db96d56Sopenharmony_ci    {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
11747db96d56Sopenharmony_ci    {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
11757db96d56Sopenharmony_ci    {NULL, NULL}        /* Sentinel */
11767db96d56Sopenharmony_ci};
11777db96d56Sopenharmony_ci
11787db96d56Sopenharmony_cistatic PyAsyncMethods coro_as_async = {
11797db96d56Sopenharmony_ci    (unaryfunc)coro_await,                      /* am_await */
11807db96d56Sopenharmony_ci    0,                                          /* am_aiter */
11817db96d56Sopenharmony_ci    0,                                          /* am_anext */
11827db96d56Sopenharmony_ci    (sendfunc)PyGen_am_send,                    /* am_send  */
11837db96d56Sopenharmony_ci};
11847db96d56Sopenharmony_ci
11857db96d56Sopenharmony_ciPyTypeObject PyCoro_Type = {
11867db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
11877db96d56Sopenharmony_ci    "coroutine",                                /* tp_name */
11887db96d56Sopenharmony_ci    offsetof(PyCoroObject, cr_iframe) +
11897db96d56Sopenharmony_ci    offsetof(_PyInterpreterFrame, localsplus),       /* tp_basicsize */
11907db96d56Sopenharmony_ci    sizeof(PyObject *),                         /* tp_itemsize */
11917db96d56Sopenharmony_ci    /* methods */
11927db96d56Sopenharmony_ci    (destructor)gen_dealloc,                    /* tp_dealloc */
11937db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
11947db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
11957db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
11967db96d56Sopenharmony_ci    &coro_as_async,                             /* tp_as_async */
11977db96d56Sopenharmony_ci    (reprfunc)coro_repr,                        /* tp_repr */
11987db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
11997db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
12007db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
12017db96d56Sopenharmony_ci    0,                                          /* tp_hash */
12027db96d56Sopenharmony_ci    0,                                          /* tp_call */
12037db96d56Sopenharmony_ci    0,                                          /* tp_str */
12047db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
12057db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
12067db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
12077db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
12087db96d56Sopenharmony_ci    0,                                          /* tp_doc */
12097db96d56Sopenharmony_ci    (traverseproc)gen_traverse,                 /* tp_traverse */
12107db96d56Sopenharmony_ci    0,                                          /* tp_clear */
12117db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
12127db96d56Sopenharmony_ci    offsetof(PyCoroObject, cr_weakreflist),     /* tp_weaklistoffset */
12137db96d56Sopenharmony_ci    0,                                          /* tp_iter */
12147db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
12157db96d56Sopenharmony_ci    coro_methods,                               /* tp_methods */
12167db96d56Sopenharmony_ci    coro_memberlist,                            /* tp_members */
12177db96d56Sopenharmony_ci    coro_getsetlist,                            /* tp_getset */
12187db96d56Sopenharmony_ci    0,                                          /* tp_base */
12197db96d56Sopenharmony_ci    0,                                          /* tp_dict */
12207db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
12217db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
12227db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
12237db96d56Sopenharmony_ci    0,                                          /* tp_init */
12247db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
12257db96d56Sopenharmony_ci    0,                                          /* tp_new */
12267db96d56Sopenharmony_ci    0,                                          /* tp_free */
12277db96d56Sopenharmony_ci    0,                                          /* tp_is_gc */
12287db96d56Sopenharmony_ci    0,                                          /* tp_bases */
12297db96d56Sopenharmony_ci    0,                                          /* tp_mro */
12307db96d56Sopenharmony_ci    0,                                          /* tp_cache */
12317db96d56Sopenharmony_ci    0,                                          /* tp_subclasses */
12327db96d56Sopenharmony_ci    0,                                          /* tp_weaklist */
12337db96d56Sopenharmony_ci    0,                                          /* tp_del */
12347db96d56Sopenharmony_ci    0,                                          /* tp_version_tag */
12357db96d56Sopenharmony_ci    _PyGen_Finalize,                            /* tp_finalize */
12367db96d56Sopenharmony_ci};
12377db96d56Sopenharmony_ci
12387db96d56Sopenharmony_cistatic void
12397db96d56Sopenharmony_cicoro_wrapper_dealloc(PyCoroWrapper *cw)
12407db96d56Sopenharmony_ci{
12417db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK((PyObject *)cw);
12427db96d56Sopenharmony_ci    Py_CLEAR(cw->cw_coroutine);
12437db96d56Sopenharmony_ci    PyObject_GC_Del(cw);
12447db96d56Sopenharmony_ci}
12457db96d56Sopenharmony_ci
12467db96d56Sopenharmony_cistatic PyObject *
12477db96d56Sopenharmony_cicoro_wrapper_iternext(PyCoroWrapper *cw)
12487db96d56Sopenharmony_ci{
12497db96d56Sopenharmony_ci    return gen_iternext((PyGenObject *)cw->cw_coroutine);
12507db96d56Sopenharmony_ci}
12517db96d56Sopenharmony_ci
12527db96d56Sopenharmony_cistatic PyObject *
12537db96d56Sopenharmony_cicoro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
12547db96d56Sopenharmony_ci{
12557db96d56Sopenharmony_ci    return gen_send((PyGenObject *)cw->cw_coroutine, arg);
12567db96d56Sopenharmony_ci}
12577db96d56Sopenharmony_ci
12587db96d56Sopenharmony_cistatic PyObject *
12597db96d56Sopenharmony_cicoro_wrapper_throw(PyCoroWrapper *cw, PyObject *const *args, Py_ssize_t nargs)
12607db96d56Sopenharmony_ci{
12617db96d56Sopenharmony_ci    return gen_throw((PyGenObject *)cw->cw_coroutine, args, nargs);
12627db96d56Sopenharmony_ci}
12637db96d56Sopenharmony_ci
12647db96d56Sopenharmony_cistatic PyObject *
12657db96d56Sopenharmony_cicoro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
12667db96d56Sopenharmony_ci{
12677db96d56Sopenharmony_ci    return gen_close((PyGenObject *)cw->cw_coroutine, args);
12687db96d56Sopenharmony_ci}
12697db96d56Sopenharmony_ci
12707db96d56Sopenharmony_cistatic int
12717db96d56Sopenharmony_cicoro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
12727db96d56Sopenharmony_ci{
12737db96d56Sopenharmony_ci    Py_VISIT((PyObject *)cw->cw_coroutine);
12747db96d56Sopenharmony_ci    return 0;
12757db96d56Sopenharmony_ci}
12767db96d56Sopenharmony_ci
12777db96d56Sopenharmony_cistatic PyMethodDef coro_wrapper_methods[] = {
12787db96d56Sopenharmony_ci    {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc},
12797db96d56Sopenharmony_ci    {"throw",_PyCFunction_CAST(coro_wrapper_throw),
12807db96d56Sopenharmony_ci    METH_FASTCALL, coro_throw_doc},
12817db96d56Sopenharmony_ci    {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc},
12827db96d56Sopenharmony_ci    {NULL, NULL}        /* Sentinel */
12837db96d56Sopenharmony_ci};
12847db96d56Sopenharmony_ci
12857db96d56Sopenharmony_ciPyTypeObject _PyCoroWrapper_Type = {
12867db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
12877db96d56Sopenharmony_ci    "coroutine_wrapper",
12887db96d56Sopenharmony_ci    sizeof(PyCoroWrapper),                      /* tp_basicsize */
12897db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
12907db96d56Sopenharmony_ci    (destructor)coro_wrapper_dealloc,           /* destructor tp_dealloc */
12917db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
12927db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
12937db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
12947db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
12957db96d56Sopenharmony_ci    0,                                          /* tp_repr */
12967db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
12977db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
12987db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
12997db96d56Sopenharmony_ci    0,                                          /* tp_hash */
13007db96d56Sopenharmony_ci    0,                                          /* tp_call */
13017db96d56Sopenharmony_ci    0,                                          /* tp_str */
13027db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
13037db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
13047db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
13057db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
13067db96d56Sopenharmony_ci    "A wrapper object implementing __await__ for coroutines.",
13077db96d56Sopenharmony_ci    (traverseproc)coro_wrapper_traverse,        /* tp_traverse */
13087db96d56Sopenharmony_ci    0,                                          /* tp_clear */
13097db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
13107db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
13117db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* tp_iter */
13127db96d56Sopenharmony_ci    (iternextfunc)coro_wrapper_iternext,        /* tp_iternext */
13137db96d56Sopenharmony_ci    coro_wrapper_methods,                       /* tp_methods */
13147db96d56Sopenharmony_ci    0,                                          /* tp_members */
13157db96d56Sopenharmony_ci    0,                                          /* tp_getset */
13167db96d56Sopenharmony_ci    0,                                          /* tp_base */
13177db96d56Sopenharmony_ci    0,                                          /* tp_dict */
13187db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
13197db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
13207db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
13217db96d56Sopenharmony_ci    0,                                          /* tp_init */
13227db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
13237db96d56Sopenharmony_ci    0,                                          /* tp_new */
13247db96d56Sopenharmony_ci    0,                                          /* tp_free */
13257db96d56Sopenharmony_ci};
13267db96d56Sopenharmony_ci
13277db96d56Sopenharmony_cistatic PyObject *
13287db96d56Sopenharmony_cicompute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame)
13297db96d56Sopenharmony_ci{
13307db96d56Sopenharmony_ci    _PyInterpreterFrame *frame = current_frame;
13317db96d56Sopenharmony_ci    /* First count how many frames we have */
13327db96d56Sopenharmony_ci    int frame_count = 0;
13337db96d56Sopenharmony_ci    for (; frame && frame_count < origin_depth; ++frame_count) {
13347db96d56Sopenharmony_ci        frame = frame->previous;
13357db96d56Sopenharmony_ci    }
13367db96d56Sopenharmony_ci
13377db96d56Sopenharmony_ci    /* Now collect them */
13387db96d56Sopenharmony_ci    PyObject *cr_origin = PyTuple_New(frame_count);
13397db96d56Sopenharmony_ci    if (cr_origin == NULL) {
13407db96d56Sopenharmony_ci        return NULL;
13417db96d56Sopenharmony_ci    }
13427db96d56Sopenharmony_ci    frame = current_frame;
13437db96d56Sopenharmony_ci    for (int i = 0; i < frame_count; ++i) {
13447db96d56Sopenharmony_ci        PyCodeObject *code = frame->f_code;
13457db96d56Sopenharmony_ci        int line = _PyInterpreterFrame_GetLine(frame);
13467db96d56Sopenharmony_ci        PyObject *frameinfo = Py_BuildValue("OiO", code->co_filename, line,
13477db96d56Sopenharmony_ci                                            code->co_name);
13487db96d56Sopenharmony_ci        if (!frameinfo) {
13497db96d56Sopenharmony_ci            Py_DECREF(cr_origin);
13507db96d56Sopenharmony_ci            return NULL;
13517db96d56Sopenharmony_ci        }
13527db96d56Sopenharmony_ci        PyTuple_SET_ITEM(cr_origin, i, frameinfo);
13537db96d56Sopenharmony_ci        frame = frame->previous;
13547db96d56Sopenharmony_ci    }
13557db96d56Sopenharmony_ci
13567db96d56Sopenharmony_ci    return cr_origin;
13577db96d56Sopenharmony_ci}
13587db96d56Sopenharmony_ci
13597db96d56Sopenharmony_ciPyObject *
13607db96d56Sopenharmony_ciPyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
13617db96d56Sopenharmony_ci{
13627db96d56Sopenharmony_ci    PyObject *coro = gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
13637db96d56Sopenharmony_ci    if (!coro) {
13647db96d56Sopenharmony_ci        return NULL;
13657db96d56Sopenharmony_ci    }
13667db96d56Sopenharmony_ci
13677db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
13687db96d56Sopenharmony_ci    int origin_depth = tstate->coroutine_origin_tracking_depth;
13697db96d56Sopenharmony_ci
13707db96d56Sopenharmony_ci    if (origin_depth == 0) {
13717db96d56Sopenharmony_ci        ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL;
13727db96d56Sopenharmony_ci    } else {
13737db96d56Sopenharmony_ci        PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame());
13747db96d56Sopenharmony_ci        ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin;
13757db96d56Sopenharmony_ci        if (!cr_origin) {
13767db96d56Sopenharmony_ci            Py_DECREF(coro);
13777db96d56Sopenharmony_ci            return NULL;
13787db96d56Sopenharmony_ci        }
13797db96d56Sopenharmony_ci    }
13807db96d56Sopenharmony_ci
13817db96d56Sopenharmony_ci    return coro;
13827db96d56Sopenharmony_ci}
13837db96d56Sopenharmony_ci
13847db96d56Sopenharmony_ci
13857db96d56Sopenharmony_ci/* ========= Asynchronous Generators ========= */
13867db96d56Sopenharmony_ci
13877db96d56Sopenharmony_ci
13887db96d56Sopenharmony_citypedef enum {
13897db96d56Sopenharmony_ci    AWAITABLE_STATE_INIT,   /* new awaitable, has not yet been iterated */
13907db96d56Sopenharmony_ci    AWAITABLE_STATE_ITER,   /* being iterated */
13917db96d56Sopenharmony_ci    AWAITABLE_STATE_CLOSED, /* closed */
13927db96d56Sopenharmony_ci} AwaitableState;
13937db96d56Sopenharmony_ci
13947db96d56Sopenharmony_ci
13957db96d56Sopenharmony_citypedef struct PyAsyncGenASend {
13967db96d56Sopenharmony_ci    PyObject_HEAD
13977db96d56Sopenharmony_ci    PyAsyncGenObject *ags_gen;
13987db96d56Sopenharmony_ci
13997db96d56Sopenharmony_ci    /* Can be NULL, when in the __anext__() mode
14007db96d56Sopenharmony_ci       (equivalent of "asend(None)") */
14017db96d56Sopenharmony_ci    PyObject *ags_sendval;
14027db96d56Sopenharmony_ci
14037db96d56Sopenharmony_ci    AwaitableState ags_state;
14047db96d56Sopenharmony_ci} PyAsyncGenASend;
14057db96d56Sopenharmony_ci
14067db96d56Sopenharmony_ci
14077db96d56Sopenharmony_citypedef struct PyAsyncGenAThrow {
14087db96d56Sopenharmony_ci    PyObject_HEAD
14097db96d56Sopenharmony_ci    PyAsyncGenObject *agt_gen;
14107db96d56Sopenharmony_ci
14117db96d56Sopenharmony_ci    /* Can be NULL, when in the "aclose()" mode
14127db96d56Sopenharmony_ci       (equivalent of "athrow(GeneratorExit)") */
14137db96d56Sopenharmony_ci    PyObject *agt_args;
14147db96d56Sopenharmony_ci
14157db96d56Sopenharmony_ci    AwaitableState agt_state;
14167db96d56Sopenharmony_ci} PyAsyncGenAThrow;
14177db96d56Sopenharmony_ci
14187db96d56Sopenharmony_ci
14197db96d56Sopenharmony_citypedef struct _PyAsyncGenWrappedValue {
14207db96d56Sopenharmony_ci    PyObject_HEAD
14217db96d56Sopenharmony_ci    PyObject *agw_val;
14227db96d56Sopenharmony_ci} _PyAsyncGenWrappedValue;
14237db96d56Sopenharmony_ci
14247db96d56Sopenharmony_ci
14257db96d56Sopenharmony_ci#define _PyAsyncGenWrappedValue_CheckExact(o) \
14267db96d56Sopenharmony_ci                    Py_IS_TYPE(o, &_PyAsyncGenWrappedValue_Type)
14277db96d56Sopenharmony_ci
14287db96d56Sopenharmony_ci#define PyAsyncGenASend_CheckExact(o) \
14297db96d56Sopenharmony_ci                    Py_IS_TYPE(o, &_PyAsyncGenASend_Type)
14307db96d56Sopenharmony_ci
14317db96d56Sopenharmony_ci
14327db96d56Sopenharmony_cistatic int
14337db96d56Sopenharmony_ciasync_gen_traverse(PyAsyncGenObject *gen, visitproc visit, void *arg)
14347db96d56Sopenharmony_ci{
14357db96d56Sopenharmony_ci    Py_VISIT(gen->ag_origin_or_finalizer);
14367db96d56Sopenharmony_ci    return gen_traverse((PyGenObject*)gen, visit, arg);
14377db96d56Sopenharmony_ci}
14387db96d56Sopenharmony_ci
14397db96d56Sopenharmony_ci
14407db96d56Sopenharmony_cistatic PyObject *
14417db96d56Sopenharmony_ciasync_gen_repr(PyAsyncGenObject *o)
14427db96d56Sopenharmony_ci{
14437db96d56Sopenharmony_ci    return PyUnicode_FromFormat("<async_generator object %S at %p>",
14447db96d56Sopenharmony_ci                                o->ag_qualname, o);
14457db96d56Sopenharmony_ci}
14467db96d56Sopenharmony_ci
14477db96d56Sopenharmony_ci
14487db96d56Sopenharmony_cistatic int
14497db96d56Sopenharmony_ciasync_gen_init_hooks(PyAsyncGenObject *o)
14507db96d56Sopenharmony_ci{
14517db96d56Sopenharmony_ci    PyThreadState *tstate;
14527db96d56Sopenharmony_ci    PyObject *finalizer;
14537db96d56Sopenharmony_ci    PyObject *firstiter;
14547db96d56Sopenharmony_ci
14557db96d56Sopenharmony_ci    if (o->ag_hooks_inited) {
14567db96d56Sopenharmony_ci        return 0;
14577db96d56Sopenharmony_ci    }
14587db96d56Sopenharmony_ci
14597db96d56Sopenharmony_ci    o->ag_hooks_inited = 1;
14607db96d56Sopenharmony_ci
14617db96d56Sopenharmony_ci    tstate = _PyThreadState_GET();
14627db96d56Sopenharmony_ci
14637db96d56Sopenharmony_ci    finalizer = tstate->async_gen_finalizer;
14647db96d56Sopenharmony_ci    if (finalizer) {
14657db96d56Sopenharmony_ci        Py_INCREF(finalizer);
14667db96d56Sopenharmony_ci        o->ag_origin_or_finalizer = finalizer;
14677db96d56Sopenharmony_ci    }
14687db96d56Sopenharmony_ci
14697db96d56Sopenharmony_ci    firstiter = tstate->async_gen_firstiter;
14707db96d56Sopenharmony_ci    if (firstiter) {
14717db96d56Sopenharmony_ci        PyObject *res;
14727db96d56Sopenharmony_ci
14737db96d56Sopenharmony_ci        Py_INCREF(firstiter);
14747db96d56Sopenharmony_ci        res = PyObject_CallOneArg(firstiter, (PyObject *)o);
14757db96d56Sopenharmony_ci        Py_DECREF(firstiter);
14767db96d56Sopenharmony_ci        if (res == NULL) {
14777db96d56Sopenharmony_ci            return 1;
14787db96d56Sopenharmony_ci        }
14797db96d56Sopenharmony_ci        Py_DECREF(res);
14807db96d56Sopenharmony_ci    }
14817db96d56Sopenharmony_ci
14827db96d56Sopenharmony_ci    return 0;
14837db96d56Sopenharmony_ci}
14847db96d56Sopenharmony_ci
14857db96d56Sopenharmony_ci
14867db96d56Sopenharmony_cistatic PyObject *
14877db96d56Sopenharmony_ciasync_gen_anext(PyAsyncGenObject *o)
14887db96d56Sopenharmony_ci{
14897db96d56Sopenharmony_ci    if (async_gen_init_hooks(o)) {
14907db96d56Sopenharmony_ci        return NULL;
14917db96d56Sopenharmony_ci    }
14927db96d56Sopenharmony_ci    return async_gen_asend_new(o, NULL);
14937db96d56Sopenharmony_ci}
14947db96d56Sopenharmony_ci
14957db96d56Sopenharmony_ci
14967db96d56Sopenharmony_cistatic PyObject *
14977db96d56Sopenharmony_ciasync_gen_asend(PyAsyncGenObject *o, PyObject *arg)
14987db96d56Sopenharmony_ci{
14997db96d56Sopenharmony_ci    if (async_gen_init_hooks(o)) {
15007db96d56Sopenharmony_ci        return NULL;
15017db96d56Sopenharmony_ci    }
15027db96d56Sopenharmony_ci    return async_gen_asend_new(o, arg);
15037db96d56Sopenharmony_ci}
15047db96d56Sopenharmony_ci
15057db96d56Sopenharmony_ci
15067db96d56Sopenharmony_cistatic PyObject *
15077db96d56Sopenharmony_ciasync_gen_aclose(PyAsyncGenObject *o, PyObject *arg)
15087db96d56Sopenharmony_ci{
15097db96d56Sopenharmony_ci    if (async_gen_init_hooks(o)) {
15107db96d56Sopenharmony_ci        return NULL;
15117db96d56Sopenharmony_ci    }
15127db96d56Sopenharmony_ci    return async_gen_athrow_new(o, NULL);
15137db96d56Sopenharmony_ci}
15147db96d56Sopenharmony_ci
15157db96d56Sopenharmony_cistatic PyObject *
15167db96d56Sopenharmony_ciasync_gen_athrow(PyAsyncGenObject *o, PyObject *args)
15177db96d56Sopenharmony_ci{
15187db96d56Sopenharmony_ci    if (async_gen_init_hooks(o)) {
15197db96d56Sopenharmony_ci        return NULL;
15207db96d56Sopenharmony_ci    }
15217db96d56Sopenharmony_ci    return async_gen_athrow_new(o, args);
15227db96d56Sopenharmony_ci}
15237db96d56Sopenharmony_ci
15247db96d56Sopenharmony_cistatic PyObject *
15257db96d56Sopenharmony_ciag_getframe(PyAsyncGenObject *ag, void *Py_UNUSED(ignored))
15267db96d56Sopenharmony_ci{
15277db96d56Sopenharmony_ci    return _gen_getframe((PyGenObject *)ag, "ag_frame");
15287db96d56Sopenharmony_ci}
15297db96d56Sopenharmony_ci
15307db96d56Sopenharmony_cistatic PyGetSetDef async_gen_getsetlist[] = {
15317db96d56Sopenharmony_ci    {"__name__", (getter)gen_get_name, (setter)gen_set_name,
15327db96d56Sopenharmony_ci     PyDoc_STR("name of the async generator")},
15337db96d56Sopenharmony_ci    {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
15347db96d56Sopenharmony_ci     PyDoc_STR("qualified name of the async generator")},
15357db96d56Sopenharmony_ci    {"ag_await", (getter)coro_get_cr_await, NULL,
15367db96d56Sopenharmony_ci     PyDoc_STR("object being awaited on, or None")},
15377db96d56Sopenharmony_ci     {"ag_frame",  (getter)ag_getframe, NULL, NULL},
15387db96d56Sopenharmony_ci    {NULL} /* Sentinel */
15397db96d56Sopenharmony_ci};
15407db96d56Sopenharmony_ci
15417db96d56Sopenharmony_cistatic PyMemberDef async_gen_memberlist[] = {
15427db96d56Sopenharmony_ci    {"ag_running", T_BOOL,   offsetof(PyAsyncGenObject, ag_running_async),
15437db96d56Sopenharmony_ci        READONLY},
15447db96d56Sopenharmony_ci    {"ag_code",    T_OBJECT, offsetof(PyAsyncGenObject, ag_code),    READONLY|PY_AUDIT_READ},
15457db96d56Sopenharmony_ci    {NULL}      /* Sentinel */
15467db96d56Sopenharmony_ci};
15477db96d56Sopenharmony_ci
15487db96d56Sopenharmony_ciPyDoc_STRVAR(async_aclose_doc,
15497db96d56Sopenharmony_ci"aclose() -> raise GeneratorExit inside generator.");
15507db96d56Sopenharmony_ci
15517db96d56Sopenharmony_ciPyDoc_STRVAR(async_asend_doc,
15527db96d56Sopenharmony_ci"asend(v) -> send 'v' in generator.");
15537db96d56Sopenharmony_ci
15547db96d56Sopenharmony_ciPyDoc_STRVAR(async_athrow_doc,
15557db96d56Sopenharmony_ci"athrow(typ[,val[,tb]]) -> raise exception in generator.");
15567db96d56Sopenharmony_ci
15577db96d56Sopenharmony_cistatic PyMethodDef async_gen_methods[] = {
15587db96d56Sopenharmony_ci    {"asend", (PyCFunction)async_gen_asend, METH_O, async_asend_doc},
15597db96d56Sopenharmony_ci    {"athrow",(PyCFunction)async_gen_athrow, METH_VARARGS, async_athrow_doc},
15607db96d56Sopenharmony_ci    {"aclose", (PyCFunction)async_gen_aclose, METH_NOARGS, async_aclose_doc},
15617db96d56Sopenharmony_ci    {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
15627db96d56Sopenharmony_ci    {"__class_getitem__",    Py_GenericAlias,
15637db96d56Sopenharmony_ci    METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
15647db96d56Sopenharmony_ci    {NULL, NULL}        /* Sentinel */
15657db96d56Sopenharmony_ci};
15667db96d56Sopenharmony_ci
15677db96d56Sopenharmony_ci
15687db96d56Sopenharmony_cistatic PyAsyncMethods async_gen_as_async = {
15697db96d56Sopenharmony_ci    0,                                          /* am_await */
15707db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* am_aiter */
15717db96d56Sopenharmony_ci    (unaryfunc)async_gen_anext,                 /* am_anext */
15727db96d56Sopenharmony_ci    (sendfunc)PyGen_am_send,                    /* am_send  */
15737db96d56Sopenharmony_ci};
15747db96d56Sopenharmony_ci
15757db96d56Sopenharmony_ci
15767db96d56Sopenharmony_ciPyTypeObject PyAsyncGen_Type = {
15777db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
15787db96d56Sopenharmony_ci    "async_generator",                          /* tp_name */
15797db96d56Sopenharmony_ci    offsetof(PyAsyncGenObject, ag_iframe) +
15807db96d56Sopenharmony_ci    offsetof(_PyInterpreterFrame, localsplus),       /* tp_basicsize */
15817db96d56Sopenharmony_ci    sizeof(PyObject *),                         /* tp_itemsize */
15827db96d56Sopenharmony_ci    /* methods */
15837db96d56Sopenharmony_ci    (destructor)gen_dealloc,                    /* tp_dealloc */
15847db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
15857db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
15867db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
15877db96d56Sopenharmony_ci    &async_gen_as_async,                        /* tp_as_async */
15887db96d56Sopenharmony_ci    (reprfunc)async_gen_repr,                   /* tp_repr */
15897db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
15907db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
15917db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
15927db96d56Sopenharmony_ci    0,                                          /* tp_hash */
15937db96d56Sopenharmony_ci    0,                                          /* tp_call */
15947db96d56Sopenharmony_ci    0,                                          /* tp_str */
15957db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
15967db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
15977db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
15987db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
15997db96d56Sopenharmony_ci    0,                                          /* tp_doc */
16007db96d56Sopenharmony_ci    (traverseproc)async_gen_traverse,           /* tp_traverse */
16017db96d56Sopenharmony_ci    0,                                          /* tp_clear */
16027db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
16037db96d56Sopenharmony_ci    offsetof(PyAsyncGenObject, ag_weakreflist), /* tp_weaklistoffset */
16047db96d56Sopenharmony_ci    0,                                          /* tp_iter */
16057db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
16067db96d56Sopenharmony_ci    async_gen_methods,                          /* tp_methods */
16077db96d56Sopenharmony_ci    async_gen_memberlist,                       /* tp_members */
16087db96d56Sopenharmony_ci    async_gen_getsetlist,                       /* tp_getset */
16097db96d56Sopenharmony_ci    0,                                          /* tp_base */
16107db96d56Sopenharmony_ci    0,                                          /* tp_dict */
16117db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
16127db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
16137db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
16147db96d56Sopenharmony_ci    0,                                          /* tp_init */
16157db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
16167db96d56Sopenharmony_ci    0,                                          /* tp_new */
16177db96d56Sopenharmony_ci    0,                                          /* tp_free */
16187db96d56Sopenharmony_ci    0,                                          /* tp_is_gc */
16197db96d56Sopenharmony_ci    0,                                          /* tp_bases */
16207db96d56Sopenharmony_ci    0,                                          /* tp_mro */
16217db96d56Sopenharmony_ci    0,                                          /* tp_cache */
16227db96d56Sopenharmony_ci    0,                                          /* tp_subclasses */
16237db96d56Sopenharmony_ci    0,                                          /* tp_weaklist */
16247db96d56Sopenharmony_ci    0,                                          /* tp_del */
16257db96d56Sopenharmony_ci    0,                                          /* tp_version_tag */
16267db96d56Sopenharmony_ci    _PyGen_Finalize,                            /* tp_finalize */
16277db96d56Sopenharmony_ci};
16287db96d56Sopenharmony_ci
16297db96d56Sopenharmony_ci
16307db96d56Sopenharmony_ci#if _PyAsyncGen_MAXFREELIST > 0
16317db96d56Sopenharmony_cistatic struct _Py_async_gen_state *
16327db96d56Sopenharmony_ciget_async_gen_state(void)
16337db96d56Sopenharmony_ci{
16347db96d56Sopenharmony_ci    PyInterpreterState *interp = _PyInterpreterState_GET();
16357db96d56Sopenharmony_ci    return &interp->async_gen;
16367db96d56Sopenharmony_ci}
16377db96d56Sopenharmony_ci#endif
16387db96d56Sopenharmony_ci
16397db96d56Sopenharmony_ci
16407db96d56Sopenharmony_ciPyObject *
16417db96d56Sopenharmony_ciPyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
16427db96d56Sopenharmony_ci{
16437db96d56Sopenharmony_ci    PyAsyncGenObject *o;
16447db96d56Sopenharmony_ci    o = (PyAsyncGenObject *)gen_new_with_qualname(
16457db96d56Sopenharmony_ci        &PyAsyncGen_Type, f, name, qualname);
16467db96d56Sopenharmony_ci    if (o == NULL) {
16477db96d56Sopenharmony_ci        return NULL;
16487db96d56Sopenharmony_ci    }
16497db96d56Sopenharmony_ci    o->ag_origin_or_finalizer = NULL;
16507db96d56Sopenharmony_ci    o->ag_closed = 0;
16517db96d56Sopenharmony_ci    o->ag_hooks_inited = 0;
16527db96d56Sopenharmony_ci    o->ag_running_async = 0;
16537db96d56Sopenharmony_ci    return (PyObject*)o;
16547db96d56Sopenharmony_ci}
16557db96d56Sopenharmony_ci
16567db96d56Sopenharmony_ci
16577db96d56Sopenharmony_civoid
16587db96d56Sopenharmony_ci_PyAsyncGen_ClearFreeLists(PyInterpreterState *interp)
16597db96d56Sopenharmony_ci{
16607db96d56Sopenharmony_ci#if _PyAsyncGen_MAXFREELIST > 0
16617db96d56Sopenharmony_ci    struct _Py_async_gen_state *state = &interp->async_gen;
16627db96d56Sopenharmony_ci
16637db96d56Sopenharmony_ci    while (state->value_numfree) {
16647db96d56Sopenharmony_ci        _PyAsyncGenWrappedValue *o;
16657db96d56Sopenharmony_ci        o = state->value_freelist[--state->value_numfree];
16667db96d56Sopenharmony_ci        assert(_PyAsyncGenWrappedValue_CheckExact(o));
16677db96d56Sopenharmony_ci        PyObject_GC_Del(o);
16687db96d56Sopenharmony_ci    }
16697db96d56Sopenharmony_ci
16707db96d56Sopenharmony_ci    while (state->asend_numfree) {
16717db96d56Sopenharmony_ci        PyAsyncGenASend *o;
16727db96d56Sopenharmony_ci        o = state->asend_freelist[--state->asend_numfree];
16737db96d56Sopenharmony_ci        assert(Py_IS_TYPE(o, &_PyAsyncGenASend_Type));
16747db96d56Sopenharmony_ci        PyObject_GC_Del(o);
16757db96d56Sopenharmony_ci    }
16767db96d56Sopenharmony_ci#endif
16777db96d56Sopenharmony_ci}
16787db96d56Sopenharmony_ci
16797db96d56Sopenharmony_civoid
16807db96d56Sopenharmony_ci_PyAsyncGen_Fini(PyInterpreterState *interp)
16817db96d56Sopenharmony_ci{
16827db96d56Sopenharmony_ci    _PyAsyncGen_ClearFreeLists(interp);
16837db96d56Sopenharmony_ci#if defined(Py_DEBUG) && _PyAsyncGen_MAXFREELIST > 0
16847db96d56Sopenharmony_ci    struct _Py_async_gen_state *state = &interp->async_gen;
16857db96d56Sopenharmony_ci    state->value_numfree = -1;
16867db96d56Sopenharmony_ci    state->asend_numfree = -1;
16877db96d56Sopenharmony_ci#endif
16887db96d56Sopenharmony_ci}
16897db96d56Sopenharmony_ci
16907db96d56Sopenharmony_ci
16917db96d56Sopenharmony_cistatic PyObject *
16927db96d56Sopenharmony_ciasync_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result)
16937db96d56Sopenharmony_ci{
16947db96d56Sopenharmony_ci    if (result == NULL) {
16957db96d56Sopenharmony_ci        if (!PyErr_Occurred()) {
16967db96d56Sopenharmony_ci            PyErr_SetNone(PyExc_StopAsyncIteration);
16977db96d56Sopenharmony_ci        }
16987db96d56Sopenharmony_ci
16997db96d56Sopenharmony_ci        if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)
17007db96d56Sopenharmony_ci            || PyErr_ExceptionMatches(PyExc_GeneratorExit)
17017db96d56Sopenharmony_ci        ) {
17027db96d56Sopenharmony_ci            gen->ag_closed = 1;
17037db96d56Sopenharmony_ci        }
17047db96d56Sopenharmony_ci
17057db96d56Sopenharmony_ci        gen->ag_running_async = 0;
17067db96d56Sopenharmony_ci        return NULL;
17077db96d56Sopenharmony_ci    }
17087db96d56Sopenharmony_ci
17097db96d56Sopenharmony_ci    if (_PyAsyncGenWrappedValue_CheckExact(result)) {
17107db96d56Sopenharmony_ci        /* async yield */
17117db96d56Sopenharmony_ci        _PyGen_SetStopIterationValue(((_PyAsyncGenWrappedValue*)result)->agw_val);
17127db96d56Sopenharmony_ci        Py_DECREF(result);
17137db96d56Sopenharmony_ci        gen->ag_running_async = 0;
17147db96d56Sopenharmony_ci        return NULL;
17157db96d56Sopenharmony_ci    }
17167db96d56Sopenharmony_ci
17177db96d56Sopenharmony_ci    return result;
17187db96d56Sopenharmony_ci}
17197db96d56Sopenharmony_ci
17207db96d56Sopenharmony_ci
17217db96d56Sopenharmony_ci/* ---------- Async Generator ASend Awaitable ------------ */
17227db96d56Sopenharmony_ci
17237db96d56Sopenharmony_ci
17247db96d56Sopenharmony_cistatic void
17257db96d56Sopenharmony_ciasync_gen_asend_dealloc(PyAsyncGenASend *o)
17267db96d56Sopenharmony_ci{
17277db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK((PyObject *)o);
17287db96d56Sopenharmony_ci    Py_CLEAR(o->ags_gen);
17297db96d56Sopenharmony_ci    Py_CLEAR(o->ags_sendval);
17307db96d56Sopenharmony_ci#if _PyAsyncGen_MAXFREELIST > 0
17317db96d56Sopenharmony_ci    struct _Py_async_gen_state *state = get_async_gen_state();
17327db96d56Sopenharmony_ci#ifdef Py_DEBUG
17337db96d56Sopenharmony_ci    // async_gen_asend_dealloc() must not be called after _PyAsyncGen_Fini()
17347db96d56Sopenharmony_ci    assert(state->asend_numfree != -1);
17357db96d56Sopenharmony_ci#endif
17367db96d56Sopenharmony_ci    if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) {
17377db96d56Sopenharmony_ci        assert(PyAsyncGenASend_CheckExact(o));
17387db96d56Sopenharmony_ci        state->asend_freelist[state->asend_numfree++] = o;
17397db96d56Sopenharmony_ci    }
17407db96d56Sopenharmony_ci    else
17417db96d56Sopenharmony_ci#endif
17427db96d56Sopenharmony_ci    {
17437db96d56Sopenharmony_ci        PyObject_GC_Del(o);
17447db96d56Sopenharmony_ci    }
17457db96d56Sopenharmony_ci}
17467db96d56Sopenharmony_ci
17477db96d56Sopenharmony_cistatic int
17487db96d56Sopenharmony_ciasync_gen_asend_traverse(PyAsyncGenASend *o, visitproc visit, void *arg)
17497db96d56Sopenharmony_ci{
17507db96d56Sopenharmony_ci    Py_VISIT(o->ags_gen);
17517db96d56Sopenharmony_ci    Py_VISIT(o->ags_sendval);
17527db96d56Sopenharmony_ci    return 0;
17537db96d56Sopenharmony_ci}
17547db96d56Sopenharmony_ci
17557db96d56Sopenharmony_ci
17567db96d56Sopenharmony_cistatic PyObject *
17577db96d56Sopenharmony_ciasync_gen_asend_send(PyAsyncGenASend *o, PyObject *arg)
17587db96d56Sopenharmony_ci{
17597db96d56Sopenharmony_ci    PyObject *result;
17607db96d56Sopenharmony_ci
17617db96d56Sopenharmony_ci    if (o->ags_state == AWAITABLE_STATE_CLOSED) {
17627db96d56Sopenharmony_ci        PyErr_SetString(
17637db96d56Sopenharmony_ci            PyExc_RuntimeError,
17647db96d56Sopenharmony_ci            "cannot reuse already awaited __anext__()/asend()");
17657db96d56Sopenharmony_ci        return NULL;
17667db96d56Sopenharmony_ci    }
17677db96d56Sopenharmony_ci
17687db96d56Sopenharmony_ci    if (o->ags_state == AWAITABLE_STATE_INIT) {
17697db96d56Sopenharmony_ci        if (o->ags_gen->ag_running_async) {
17707db96d56Sopenharmony_ci            PyErr_SetString(
17717db96d56Sopenharmony_ci                PyExc_RuntimeError,
17727db96d56Sopenharmony_ci                "anext(): asynchronous generator is already running");
17737db96d56Sopenharmony_ci            return NULL;
17747db96d56Sopenharmony_ci        }
17757db96d56Sopenharmony_ci
17767db96d56Sopenharmony_ci        if (arg == NULL || arg == Py_None) {
17777db96d56Sopenharmony_ci            arg = o->ags_sendval;
17787db96d56Sopenharmony_ci        }
17797db96d56Sopenharmony_ci        o->ags_state = AWAITABLE_STATE_ITER;
17807db96d56Sopenharmony_ci    }
17817db96d56Sopenharmony_ci
17827db96d56Sopenharmony_ci    o->ags_gen->ag_running_async = 1;
17837db96d56Sopenharmony_ci    result = gen_send((PyGenObject*)o->ags_gen, arg);
17847db96d56Sopenharmony_ci    result = async_gen_unwrap_value(o->ags_gen, result);
17857db96d56Sopenharmony_ci
17867db96d56Sopenharmony_ci    if (result == NULL) {
17877db96d56Sopenharmony_ci        o->ags_state = AWAITABLE_STATE_CLOSED;
17887db96d56Sopenharmony_ci    }
17897db96d56Sopenharmony_ci
17907db96d56Sopenharmony_ci    return result;
17917db96d56Sopenharmony_ci}
17927db96d56Sopenharmony_ci
17937db96d56Sopenharmony_ci
17947db96d56Sopenharmony_cistatic PyObject *
17957db96d56Sopenharmony_ciasync_gen_asend_iternext(PyAsyncGenASend *o)
17967db96d56Sopenharmony_ci{
17977db96d56Sopenharmony_ci    return async_gen_asend_send(o, NULL);
17987db96d56Sopenharmony_ci}
17997db96d56Sopenharmony_ci
18007db96d56Sopenharmony_ci
18017db96d56Sopenharmony_cistatic PyObject *
18027db96d56Sopenharmony_ciasync_gen_asend_throw(PyAsyncGenASend *o, PyObject *const *args, Py_ssize_t nargs)
18037db96d56Sopenharmony_ci{
18047db96d56Sopenharmony_ci    PyObject *result;
18057db96d56Sopenharmony_ci
18067db96d56Sopenharmony_ci    if (o->ags_state == AWAITABLE_STATE_CLOSED) {
18077db96d56Sopenharmony_ci        PyErr_SetString(
18087db96d56Sopenharmony_ci            PyExc_RuntimeError,
18097db96d56Sopenharmony_ci            "cannot reuse already awaited __anext__()/asend()");
18107db96d56Sopenharmony_ci        return NULL;
18117db96d56Sopenharmony_ci    }
18127db96d56Sopenharmony_ci
18137db96d56Sopenharmony_ci    result = gen_throw((PyGenObject*)o->ags_gen, args, nargs);
18147db96d56Sopenharmony_ci    result = async_gen_unwrap_value(o->ags_gen, result);
18157db96d56Sopenharmony_ci
18167db96d56Sopenharmony_ci    if (result == NULL) {
18177db96d56Sopenharmony_ci        o->ags_state = AWAITABLE_STATE_CLOSED;
18187db96d56Sopenharmony_ci    }
18197db96d56Sopenharmony_ci
18207db96d56Sopenharmony_ci    return result;
18217db96d56Sopenharmony_ci}
18227db96d56Sopenharmony_ci
18237db96d56Sopenharmony_ci
18247db96d56Sopenharmony_cistatic PyObject *
18257db96d56Sopenharmony_ciasync_gen_asend_close(PyAsyncGenASend *o, PyObject *args)
18267db96d56Sopenharmony_ci{
18277db96d56Sopenharmony_ci    o->ags_state = AWAITABLE_STATE_CLOSED;
18287db96d56Sopenharmony_ci    Py_RETURN_NONE;
18297db96d56Sopenharmony_ci}
18307db96d56Sopenharmony_ci
18317db96d56Sopenharmony_ci
18327db96d56Sopenharmony_cistatic PyMethodDef async_gen_asend_methods[] = {
18337db96d56Sopenharmony_ci    {"send", (PyCFunction)async_gen_asend_send, METH_O, send_doc},
18347db96d56Sopenharmony_ci    {"throw", _PyCFunction_CAST(async_gen_asend_throw), METH_FASTCALL, throw_doc},
18357db96d56Sopenharmony_ci    {"close", (PyCFunction)async_gen_asend_close, METH_NOARGS, close_doc},
18367db96d56Sopenharmony_ci    {NULL, NULL}        /* Sentinel */
18377db96d56Sopenharmony_ci};
18387db96d56Sopenharmony_ci
18397db96d56Sopenharmony_ci
18407db96d56Sopenharmony_cistatic PyAsyncMethods async_gen_asend_as_async = {
18417db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* am_await */
18427db96d56Sopenharmony_ci    0,                                          /* am_aiter */
18437db96d56Sopenharmony_ci    0,                                          /* am_anext */
18447db96d56Sopenharmony_ci    0,                                          /* am_send  */
18457db96d56Sopenharmony_ci};
18467db96d56Sopenharmony_ci
18477db96d56Sopenharmony_ci
18487db96d56Sopenharmony_ciPyTypeObject _PyAsyncGenASend_Type = {
18497db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
18507db96d56Sopenharmony_ci    "async_generator_asend",                    /* tp_name */
18517db96d56Sopenharmony_ci    sizeof(PyAsyncGenASend),                    /* tp_basicsize */
18527db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
18537db96d56Sopenharmony_ci    /* methods */
18547db96d56Sopenharmony_ci    (destructor)async_gen_asend_dealloc,        /* tp_dealloc */
18557db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
18567db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
18577db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
18587db96d56Sopenharmony_ci    &async_gen_asend_as_async,                  /* tp_as_async */
18597db96d56Sopenharmony_ci    0,                                          /* tp_repr */
18607db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
18617db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
18627db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
18637db96d56Sopenharmony_ci    0,                                          /* tp_hash */
18647db96d56Sopenharmony_ci    0,                                          /* tp_call */
18657db96d56Sopenharmony_ci    0,                                          /* tp_str */
18667db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
18677db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
18687db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
18697db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
18707db96d56Sopenharmony_ci    0,                                          /* tp_doc */
18717db96d56Sopenharmony_ci    (traverseproc)async_gen_asend_traverse,     /* tp_traverse */
18727db96d56Sopenharmony_ci    0,                                          /* tp_clear */
18737db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
18747db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
18757db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* tp_iter */
18767db96d56Sopenharmony_ci    (iternextfunc)async_gen_asend_iternext,     /* tp_iternext */
18777db96d56Sopenharmony_ci    async_gen_asend_methods,                    /* tp_methods */
18787db96d56Sopenharmony_ci    0,                                          /* tp_members */
18797db96d56Sopenharmony_ci    0,                                          /* tp_getset */
18807db96d56Sopenharmony_ci    0,                                          /* tp_base */
18817db96d56Sopenharmony_ci    0,                                          /* tp_dict */
18827db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
18837db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
18847db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
18857db96d56Sopenharmony_ci    0,                                          /* tp_init */
18867db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
18877db96d56Sopenharmony_ci    0,                                          /* tp_new */
18887db96d56Sopenharmony_ci};
18897db96d56Sopenharmony_ci
18907db96d56Sopenharmony_ci
18917db96d56Sopenharmony_cistatic PyObject *
18927db96d56Sopenharmony_ciasync_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval)
18937db96d56Sopenharmony_ci{
18947db96d56Sopenharmony_ci    PyAsyncGenASend *o;
18957db96d56Sopenharmony_ci#if _PyAsyncGen_MAXFREELIST > 0
18967db96d56Sopenharmony_ci    struct _Py_async_gen_state *state = get_async_gen_state();
18977db96d56Sopenharmony_ci#ifdef Py_DEBUG
18987db96d56Sopenharmony_ci    // async_gen_asend_new() must not be called after _PyAsyncGen_Fini()
18997db96d56Sopenharmony_ci    assert(state->asend_numfree != -1);
19007db96d56Sopenharmony_ci#endif
19017db96d56Sopenharmony_ci    if (state->asend_numfree) {
19027db96d56Sopenharmony_ci        state->asend_numfree--;
19037db96d56Sopenharmony_ci        o = state->asend_freelist[state->asend_numfree];
19047db96d56Sopenharmony_ci        _Py_NewReference((PyObject *)o);
19057db96d56Sopenharmony_ci    }
19067db96d56Sopenharmony_ci    else
19077db96d56Sopenharmony_ci#endif
19087db96d56Sopenharmony_ci    {
19097db96d56Sopenharmony_ci        o = PyObject_GC_New(PyAsyncGenASend, &_PyAsyncGenASend_Type);
19107db96d56Sopenharmony_ci        if (o == NULL) {
19117db96d56Sopenharmony_ci            return NULL;
19127db96d56Sopenharmony_ci        }
19137db96d56Sopenharmony_ci    }
19147db96d56Sopenharmony_ci
19157db96d56Sopenharmony_ci    Py_INCREF(gen);
19167db96d56Sopenharmony_ci    o->ags_gen = gen;
19177db96d56Sopenharmony_ci
19187db96d56Sopenharmony_ci    Py_XINCREF(sendval);
19197db96d56Sopenharmony_ci    o->ags_sendval = sendval;
19207db96d56Sopenharmony_ci
19217db96d56Sopenharmony_ci    o->ags_state = AWAITABLE_STATE_INIT;
19227db96d56Sopenharmony_ci
19237db96d56Sopenharmony_ci    _PyObject_GC_TRACK((PyObject*)o);
19247db96d56Sopenharmony_ci    return (PyObject*)o;
19257db96d56Sopenharmony_ci}
19267db96d56Sopenharmony_ci
19277db96d56Sopenharmony_ci
19287db96d56Sopenharmony_ci/* ---------- Async Generator Value Wrapper ------------ */
19297db96d56Sopenharmony_ci
19307db96d56Sopenharmony_ci
19317db96d56Sopenharmony_cistatic void
19327db96d56Sopenharmony_ciasync_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o)
19337db96d56Sopenharmony_ci{
19347db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK((PyObject *)o);
19357db96d56Sopenharmony_ci    Py_CLEAR(o->agw_val);
19367db96d56Sopenharmony_ci#if _PyAsyncGen_MAXFREELIST > 0
19377db96d56Sopenharmony_ci    struct _Py_async_gen_state *state = get_async_gen_state();
19387db96d56Sopenharmony_ci#ifdef Py_DEBUG
19397db96d56Sopenharmony_ci    // async_gen_wrapped_val_dealloc() must not be called after _PyAsyncGen_Fini()
19407db96d56Sopenharmony_ci    assert(state->value_numfree != -1);
19417db96d56Sopenharmony_ci#endif
19427db96d56Sopenharmony_ci    if (state->value_numfree < _PyAsyncGen_MAXFREELIST) {
19437db96d56Sopenharmony_ci        assert(_PyAsyncGenWrappedValue_CheckExact(o));
19447db96d56Sopenharmony_ci        state->value_freelist[state->value_numfree++] = o;
19457db96d56Sopenharmony_ci        OBJECT_STAT_INC(to_freelist);
19467db96d56Sopenharmony_ci    }
19477db96d56Sopenharmony_ci    else
19487db96d56Sopenharmony_ci#endif
19497db96d56Sopenharmony_ci    {
19507db96d56Sopenharmony_ci        PyObject_GC_Del(o);
19517db96d56Sopenharmony_ci    }
19527db96d56Sopenharmony_ci}
19537db96d56Sopenharmony_ci
19547db96d56Sopenharmony_ci
19557db96d56Sopenharmony_cistatic int
19567db96d56Sopenharmony_ciasync_gen_wrapped_val_traverse(_PyAsyncGenWrappedValue *o,
19577db96d56Sopenharmony_ci                               visitproc visit, void *arg)
19587db96d56Sopenharmony_ci{
19597db96d56Sopenharmony_ci    Py_VISIT(o->agw_val);
19607db96d56Sopenharmony_ci    return 0;
19617db96d56Sopenharmony_ci}
19627db96d56Sopenharmony_ci
19637db96d56Sopenharmony_ci
19647db96d56Sopenharmony_ciPyTypeObject _PyAsyncGenWrappedValue_Type = {
19657db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
19667db96d56Sopenharmony_ci    "async_generator_wrapped_value",            /* tp_name */
19677db96d56Sopenharmony_ci    sizeof(_PyAsyncGenWrappedValue),            /* tp_basicsize */
19687db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
19697db96d56Sopenharmony_ci    /* methods */
19707db96d56Sopenharmony_ci    (destructor)async_gen_wrapped_val_dealloc,  /* tp_dealloc */
19717db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
19727db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
19737db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
19747db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
19757db96d56Sopenharmony_ci    0,                                          /* tp_repr */
19767db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
19777db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
19787db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
19797db96d56Sopenharmony_ci    0,                                          /* tp_hash */
19807db96d56Sopenharmony_ci    0,                                          /* tp_call */
19817db96d56Sopenharmony_ci    0,                                          /* tp_str */
19827db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
19837db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
19847db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
19857db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
19867db96d56Sopenharmony_ci    0,                                          /* tp_doc */
19877db96d56Sopenharmony_ci    (traverseproc)async_gen_wrapped_val_traverse, /* tp_traverse */
19887db96d56Sopenharmony_ci    0,                                          /* tp_clear */
19897db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
19907db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
19917db96d56Sopenharmony_ci    0,                                          /* tp_iter */
19927db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
19937db96d56Sopenharmony_ci    0,                                          /* tp_methods */
19947db96d56Sopenharmony_ci    0,                                          /* tp_members */
19957db96d56Sopenharmony_ci    0,                                          /* tp_getset */
19967db96d56Sopenharmony_ci    0,                                          /* tp_base */
19977db96d56Sopenharmony_ci    0,                                          /* tp_dict */
19987db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
19997db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
20007db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
20017db96d56Sopenharmony_ci    0,                                          /* tp_init */
20027db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
20037db96d56Sopenharmony_ci    0,                                          /* tp_new */
20047db96d56Sopenharmony_ci};
20057db96d56Sopenharmony_ci
20067db96d56Sopenharmony_ci
20077db96d56Sopenharmony_ciPyObject *
20087db96d56Sopenharmony_ci_PyAsyncGenValueWrapperNew(PyObject *val)
20097db96d56Sopenharmony_ci{
20107db96d56Sopenharmony_ci    _PyAsyncGenWrappedValue *o;
20117db96d56Sopenharmony_ci    assert(val);
20127db96d56Sopenharmony_ci
20137db96d56Sopenharmony_ci#if _PyAsyncGen_MAXFREELIST > 0
20147db96d56Sopenharmony_ci    struct _Py_async_gen_state *state = get_async_gen_state();
20157db96d56Sopenharmony_ci#ifdef Py_DEBUG
20167db96d56Sopenharmony_ci    // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini()
20177db96d56Sopenharmony_ci    assert(state->value_numfree != -1);
20187db96d56Sopenharmony_ci#endif
20197db96d56Sopenharmony_ci    if (state->value_numfree) {
20207db96d56Sopenharmony_ci        state->value_numfree--;
20217db96d56Sopenharmony_ci        o = state->value_freelist[state->value_numfree];
20227db96d56Sopenharmony_ci        OBJECT_STAT_INC(from_freelist);
20237db96d56Sopenharmony_ci        assert(_PyAsyncGenWrappedValue_CheckExact(o));
20247db96d56Sopenharmony_ci        _Py_NewReference((PyObject*)o);
20257db96d56Sopenharmony_ci    }
20267db96d56Sopenharmony_ci    else
20277db96d56Sopenharmony_ci#endif
20287db96d56Sopenharmony_ci    {
20297db96d56Sopenharmony_ci        o = PyObject_GC_New(_PyAsyncGenWrappedValue,
20307db96d56Sopenharmony_ci                            &_PyAsyncGenWrappedValue_Type);
20317db96d56Sopenharmony_ci        if (o == NULL) {
20327db96d56Sopenharmony_ci            return NULL;
20337db96d56Sopenharmony_ci        }
20347db96d56Sopenharmony_ci    }
20357db96d56Sopenharmony_ci    o->agw_val = val;
20367db96d56Sopenharmony_ci    Py_INCREF(val);
20377db96d56Sopenharmony_ci    _PyObject_GC_TRACK((PyObject*)o);
20387db96d56Sopenharmony_ci    return (PyObject*)o;
20397db96d56Sopenharmony_ci}
20407db96d56Sopenharmony_ci
20417db96d56Sopenharmony_ci
20427db96d56Sopenharmony_ci/* ---------- Async Generator AThrow awaitable ------------ */
20437db96d56Sopenharmony_ci
20447db96d56Sopenharmony_ci
20457db96d56Sopenharmony_cistatic void
20467db96d56Sopenharmony_ciasync_gen_athrow_dealloc(PyAsyncGenAThrow *o)
20477db96d56Sopenharmony_ci{
20487db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK((PyObject *)o);
20497db96d56Sopenharmony_ci    Py_CLEAR(o->agt_gen);
20507db96d56Sopenharmony_ci    Py_CLEAR(o->agt_args);
20517db96d56Sopenharmony_ci    PyObject_GC_Del(o);
20527db96d56Sopenharmony_ci}
20537db96d56Sopenharmony_ci
20547db96d56Sopenharmony_ci
20557db96d56Sopenharmony_cistatic int
20567db96d56Sopenharmony_ciasync_gen_athrow_traverse(PyAsyncGenAThrow *o, visitproc visit, void *arg)
20577db96d56Sopenharmony_ci{
20587db96d56Sopenharmony_ci    Py_VISIT(o->agt_gen);
20597db96d56Sopenharmony_ci    Py_VISIT(o->agt_args);
20607db96d56Sopenharmony_ci    return 0;
20617db96d56Sopenharmony_ci}
20627db96d56Sopenharmony_ci
20637db96d56Sopenharmony_ci
20647db96d56Sopenharmony_cistatic PyObject *
20657db96d56Sopenharmony_ciasync_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
20667db96d56Sopenharmony_ci{
20677db96d56Sopenharmony_ci    PyGenObject *gen = (PyGenObject*)o->agt_gen;
20687db96d56Sopenharmony_ci    PyObject *retval;
20697db96d56Sopenharmony_ci
20707db96d56Sopenharmony_ci    if (o->agt_state == AWAITABLE_STATE_CLOSED) {
20717db96d56Sopenharmony_ci        PyErr_SetString(
20727db96d56Sopenharmony_ci            PyExc_RuntimeError,
20737db96d56Sopenharmony_ci            "cannot reuse already awaited aclose()/athrow()");
20747db96d56Sopenharmony_ci        return NULL;
20757db96d56Sopenharmony_ci    }
20767db96d56Sopenharmony_ci
20777db96d56Sopenharmony_ci    if (gen->gi_frame_state >= FRAME_COMPLETED) {
20787db96d56Sopenharmony_ci        o->agt_state = AWAITABLE_STATE_CLOSED;
20797db96d56Sopenharmony_ci        PyErr_SetNone(PyExc_StopIteration);
20807db96d56Sopenharmony_ci        return NULL;
20817db96d56Sopenharmony_ci    }
20827db96d56Sopenharmony_ci
20837db96d56Sopenharmony_ci    if (o->agt_state == AWAITABLE_STATE_INIT) {
20847db96d56Sopenharmony_ci        if (o->agt_gen->ag_running_async) {
20857db96d56Sopenharmony_ci            o->agt_state = AWAITABLE_STATE_CLOSED;
20867db96d56Sopenharmony_ci            if (o->agt_args == NULL) {
20877db96d56Sopenharmony_ci                PyErr_SetString(
20887db96d56Sopenharmony_ci                    PyExc_RuntimeError,
20897db96d56Sopenharmony_ci                    "aclose(): asynchronous generator is already running");
20907db96d56Sopenharmony_ci            }
20917db96d56Sopenharmony_ci            else {
20927db96d56Sopenharmony_ci                PyErr_SetString(
20937db96d56Sopenharmony_ci                    PyExc_RuntimeError,
20947db96d56Sopenharmony_ci                    "athrow(): asynchronous generator is already running");
20957db96d56Sopenharmony_ci            }
20967db96d56Sopenharmony_ci            return NULL;
20977db96d56Sopenharmony_ci        }
20987db96d56Sopenharmony_ci
20997db96d56Sopenharmony_ci        if (o->agt_gen->ag_closed) {
21007db96d56Sopenharmony_ci            o->agt_state = AWAITABLE_STATE_CLOSED;
21017db96d56Sopenharmony_ci            PyErr_SetNone(PyExc_StopAsyncIteration);
21027db96d56Sopenharmony_ci            return NULL;
21037db96d56Sopenharmony_ci        }
21047db96d56Sopenharmony_ci
21057db96d56Sopenharmony_ci        if (arg != Py_None) {
21067db96d56Sopenharmony_ci            PyErr_SetString(PyExc_RuntimeError, NON_INIT_CORO_MSG);
21077db96d56Sopenharmony_ci            return NULL;
21087db96d56Sopenharmony_ci        }
21097db96d56Sopenharmony_ci
21107db96d56Sopenharmony_ci        o->agt_state = AWAITABLE_STATE_ITER;
21117db96d56Sopenharmony_ci        o->agt_gen->ag_running_async = 1;
21127db96d56Sopenharmony_ci
21137db96d56Sopenharmony_ci        if (o->agt_args == NULL) {
21147db96d56Sopenharmony_ci            /* aclose() mode */
21157db96d56Sopenharmony_ci            o->agt_gen->ag_closed = 1;
21167db96d56Sopenharmony_ci
21177db96d56Sopenharmony_ci            retval = _gen_throw((PyGenObject *)gen,
21187db96d56Sopenharmony_ci                                0,  /* Do not close generator when
21197db96d56Sopenharmony_ci                                       PyExc_GeneratorExit is passed */
21207db96d56Sopenharmony_ci                                PyExc_GeneratorExit, NULL, NULL);
21217db96d56Sopenharmony_ci
21227db96d56Sopenharmony_ci            if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) {
21237db96d56Sopenharmony_ci                Py_DECREF(retval);
21247db96d56Sopenharmony_ci                goto yield_close;
21257db96d56Sopenharmony_ci            }
21267db96d56Sopenharmony_ci        } else {
21277db96d56Sopenharmony_ci            PyObject *typ;
21287db96d56Sopenharmony_ci            PyObject *tb = NULL;
21297db96d56Sopenharmony_ci            PyObject *val = NULL;
21307db96d56Sopenharmony_ci
21317db96d56Sopenharmony_ci            if (!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3,
21327db96d56Sopenharmony_ci                                   &typ, &val, &tb)) {
21337db96d56Sopenharmony_ci                return NULL;
21347db96d56Sopenharmony_ci            }
21357db96d56Sopenharmony_ci
21367db96d56Sopenharmony_ci            retval = _gen_throw((PyGenObject *)gen,
21377db96d56Sopenharmony_ci                                0,  /* Do not close generator when
21387db96d56Sopenharmony_ci                                       PyExc_GeneratorExit is passed */
21397db96d56Sopenharmony_ci                                typ, val, tb);
21407db96d56Sopenharmony_ci            retval = async_gen_unwrap_value(o->agt_gen, retval);
21417db96d56Sopenharmony_ci        }
21427db96d56Sopenharmony_ci        if (retval == NULL) {
21437db96d56Sopenharmony_ci            goto check_error;
21447db96d56Sopenharmony_ci        }
21457db96d56Sopenharmony_ci        return retval;
21467db96d56Sopenharmony_ci    }
21477db96d56Sopenharmony_ci
21487db96d56Sopenharmony_ci    assert(o->agt_state == AWAITABLE_STATE_ITER);
21497db96d56Sopenharmony_ci
21507db96d56Sopenharmony_ci    retval = gen_send((PyGenObject *)gen, arg);
21517db96d56Sopenharmony_ci    if (o->agt_args) {
21527db96d56Sopenharmony_ci        return async_gen_unwrap_value(o->agt_gen, retval);
21537db96d56Sopenharmony_ci    } else {
21547db96d56Sopenharmony_ci        /* aclose() mode */
21557db96d56Sopenharmony_ci        if (retval) {
21567db96d56Sopenharmony_ci            if (_PyAsyncGenWrappedValue_CheckExact(retval)) {
21577db96d56Sopenharmony_ci                Py_DECREF(retval);
21587db96d56Sopenharmony_ci                goto yield_close;
21597db96d56Sopenharmony_ci            }
21607db96d56Sopenharmony_ci            else {
21617db96d56Sopenharmony_ci                return retval;
21627db96d56Sopenharmony_ci            }
21637db96d56Sopenharmony_ci        }
21647db96d56Sopenharmony_ci        else {
21657db96d56Sopenharmony_ci            goto check_error;
21667db96d56Sopenharmony_ci        }
21677db96d56Sopenharmony_ci    }
21687db96d56Sopenharmony_ci
21697db96d56Sopenharmony_ciyield_close:
21707db96d56Sopenharmony_ci    o->agt_gen->ag_running_async = 0;
21717db96d56Sopenharmony_ci    o->agt_state = AWAITABLE_STATE_CLOSED;
21727db96d56Sopenharmony_ci    PyErr_SetString(
21737db96d56Sopenharmony_ci        PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);
21747db96d56Sopenharmony_ci    return NULL;
21757db96d56Sopenharmony_ci
21767db96d56Sopenharmony_cicheck_error:
21777db96d56Sopenharmony_ci    o->agt_gen->ag_running_async = 0;
21787db96d56Sopenharmony_ci    o->agt_state = AWAITABLE_STATE_CLOSED;
21797db96d56Sopenharmony_ci    if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||
21807db96d56Sopenharmony_ci            PyErr_ExceptionMatches(PyExc_GeneratorExit))
21817db96d56Sopenharmony_ci    {
21827db96d56Sopenharmony_ci        if (o->agt_args == NULL) {
21837db96d56Sopenharmony_ci            /* when aclose() is called we don't want to propagate
21847db96d56Sopenharmony_ci               StopAsyncIteration or GeneratorExit; just raise
21857db96d56Sopenharmony_ci               StopIteration, signalling that this 'aclose()' await
21867db96d56Sopenharmony_ci               is done.
21877db96d56Sopenharmony_ci            */
21887db96d56Sopenharmony_ci            PyErr_Clear();
21897db96d56Sopenharmony_ci            PyErr_SetNone(PyExc_StopIteration);
21907db96d56Sopenharmony_ci        }
21917db96d56Sopenharmony_ci    }
21927db96d56Sopenharmony_ci    return NULL;
21937db96d56Sopenharmony_ci}
21947db96d56Sopenharmony_ci
21957db96d56Sopenharmony_ci
21967db96d56Sopenharmony_cistatic PyObject *
21977db96d56Sopenharmony_ciasync_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *const *args, Py_ssize_t nargs)
21987db96d56Sopenharmony_ci{
21997db96d56Sopenharmony_ci    PyObject *retval;
22007db96d56Sopenharmony_ci
22017db96d56Sopenharmony_ci    if (o->agt_state == AWAITABLE_STATE_CLOSED) {
22027db96d56Sopenharmony_ci        PyErr_SetString(
22037db96d56Sopenharmony_ci            PyExc_RuntimeError,
22047db96d56Sopenharmony_ci            "cannot reuse already awaited aclose()/athrow()");
22057db96d56Sopenharmony_ci        return NULL;
22067db96d56Sopenharmony_ci    }
22077db96d56Sopenharmony_ci
22087db96d56Sopenharmony_ci    retval = gen_throw((PyGenObject*)o->agt_gen, args, nargs);
22097db96d56Sopenharmony_ci    if (o->agt_args) {
22107db96d56Sopenharmony_ci        return async_gen_unwrap_value(o->agt_gen, retval);
22117db96d56Sopenharmony_ci    } else {
22127db96d56Sopenharmony_ci        /* aclose() mode */
22137db96d56Sopenharmony_ci        if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) {
22147db96d56Sopenharmony_ci            o->agt_gen->ag_running_async = 0;
22157db96d56Sopenharmony_ci            o->agt_state = AWAITABLE_STATE_CLOSED;
22167db96d56Sopenharmony_ci            Py_DECREF(retval);
22177db96d56Sopenharmony_ci            PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);
22187db96d56Sopenharmony_ci            return NULL;
22197db96d56Sopenharmony_ci        }
22207db96d56Sopenharmony_ci        if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||
22217db96d56Sopenharmony_ci            PyErr_ExceptionMatches(PyExc_GeneratorExit))
22227db96d56Sopenharmony_ci        {
22237db96d56Sopenharmony_ci            /* when aclose() is called we don't want to propagate
22247db96d56Sopenharmony_ci               StopAsyncIteration or GeneratorExit; just raise
22257db96d56Sopenharmony_ci               StopIteration, signalling that this 'aclose()' await
22267db96d56Sopenharmony_ci               is done.
22277db96d56Sopenharmony_ci            */
22287db96d56Sopenharmony_ci            PyErr_Clear();
22297db96d56Sopenharmony_ci            PyErr_SetNone(PyExc_StopIteration);
22307db96d56Sopenharmony_ci        }
22317db96d56Sopenharmony_ci        return retval;
22327db96d56Sopenharmony_ci    }
22337db96d56Sopenharmony_ci}
22347db96d56Sopenharmony_ci
22357db96d56Sopenharmony_ci
22367db96d56Sopenharmony_cistatic PyObject *
22377db96d56Sopenharmony_ciasync_gen_athrow_iternext(PyAsyncGenAThrow *o)
22387db96d56Sopenharmony_ci{
22397db96d56Sopenharmony_ci    return async_gen_athrow_send(o, Py_None);
22407db96d56Sopenharmony_ci}
22417db96d56Sopenharmony_ci
22427db96d56Sopenharmony_ci
22437db96d56Sopenharmony_cistatic PyObject *
22447db96d56Sopenharmony_ciasync_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args)
22457db96d56Sopenharmony_ci{
22467db96d56Sopenharmony_ci    o->agt_state = AWAITABLE_STATE_CLOSED;
22477db96d56Sopenharmony_ci    Py_RETURN_NONE;
22487db96d56Sopenharmony_ci}
22497db96d56Sopenharmony_ci
22507db96d56Sopenharmony_ci
22517db96d56Sopenharmony_cistatic PyMethodDef async_gen_athrow_methods[] = {
22527db96d56Sopenharmony_ci    {"send", (PyCFunction)async_gen_athrow_send, METH_O, send_doc},
22537db96d56Sopenharmony_ci    {"throw", _PyCFunction_CAST(async_gen_athrow_throw),
22547db96d56Sopenharmony_ci    METH_FASTCALL, throw_doc},
22557db96d56Sopenharmony_ci    {"close", (PyCFunction)async_gen_athrow_close, METH_NOARGS, close_doc},
22567db96d56Sopenharmony_ci    {NULL, NULL}        /* Sentinel */
22577db96d56Sopenharmony_ci};
22587db96d56Sopenharmony_ci
22597db96d56Sopenharmony_ci
22607db96d56Sopenharmony_cistatic PyAsyncMethods async_gen_athrow_as_async = {
22617db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* am_await */
22627db96d56Sopenharmony_ci    0,                                          /* am_aiter */
22637db96d56Sopenharmony_ci    0,                                          /* am_anext */
22647db96d56Sopenharmony_ci    0,                                          /* am_send  */
22657db96d56Sopenharmony_ci};
22667db96d56Sopenharmony_ci
22677db96d56Sopenharmony_ci
22687db96d56Sopenharmony_ciPyTypeObject _PyAsyncGenAThrow_Type = {
22697db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
22707db96d56Sopenharmony_ci    "async_generator_athrow",                   /* tp_name */
22717db96d56Sopenharmony_ci    sizeof(PyAsyncGenAThrow),                   /* tp_basicsize */
22727db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
22737db96d56Sopenharmony_ci    /* methods */
22747db96d56Sopenharmony_ci    (destructor)async_gen_athrow_dealloc,       /* tp_dealloc */
22757db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
22767db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
22777db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
22787db96d56Sopenharmony_ci    &async_gen_athrow_as_async,                 /* tp_as_async */
22797db96d56Sopenharmony_ci    0,                                          /* tp_repr */
22807db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
22817db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
22827db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
22837db96d56Sopenharmony_ci    0,                                          /* tp_hash */
22847db96d56Sopenharmony_ci    0,                                          /* tp_call */
22857db96d56Sopenharmony_ci    0,                                          /* tp_str */
22867db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
22877db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
22887db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
22897db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
22907db96d56Sopenharmony_ci    0,                                          /* tp_doc */
22917db96d56Sopenharmony_ci    (traverseproc)async_gen_athrow_traverse,    /* tp_traverse */
22927db96d56Sopenharmony_ci    0,                                          /* tp_clear */
22937db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
22947db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
22957db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* tp_iter */
22967db96d56Sopenharmony_ci    (iternextfunc)async_gen_athrow_iternext,    /* tp_iternext */
22977db96d56Sopenharmony_ci    async_gen_athrow_methods,                   /* tp_methods */
22987db96d56Sopenharmony_ci    0,                                          /* tp_members */
22997db96d56Sopenharmony_ci    0,                                          /* tp_getset */
23007db96d56Sopenharmony_ci    0,                                          /* tp_base */
23017db96d56Sopenharmony_ci    0,                                          /* tp_dict */
23027db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
23037db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
23047db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
23057db96d56Sopenharmony_ci    0,                                          /* tp_init */
23067db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
23077db96d56Sopenharmony_ci    0,                                          /* tp_new */
23087db96d56Sopenharmony_ci};
23097db96d56Sopenharmony_ci
23107db96d56Sopenharmony_ci
23117db96d56Sopenharmony_cistatic PyObject *
23127db96d56Sopenharmony_ciasync_gen_athrow_new(PyAsyncGenObject *gen, PyObject *args)
23137db96d56Sopenharmony_ci{
23147db96d56Sopenharmony_ci    PyAsyncGenAThrow *o;
23157db96d56Sopenharmony_ci    o = PyObject_GC_New(PyAsyncGenAThrow, &_PyAsyncGenAThrow_Type);
23167db96d56Sopenharmony_ci    if (o == NULL) {
23177db96d56Sopenharmony_ci        return NULL;
23187db96d56Sopenharmony_ci    }
23197db96d56Sopenharmony_ci    o->agt_gen = gen;
23207db96d56Sopenharmony_ci    o->agt_args = args;
23217db96d56Sopenharmony_ci    o->agt_state = AWAITABLE_STATE_INIT;
23227db96d56Sopenharmony_ci    Py_INCREF(gen);
23237db96d56Sopenharmony_ci    Py_XINCREF(args);
23247db96d56Sopenharmony_ci    _PyObject_GC_TRACK((PyObject*)o);
23257db96d56Sopenharmony_ci    return (PyObject*)o;
23267db96d56Sopenharmony_ci}
2327