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