// @generated by UpstreamBorrow.py.
// See the Buck target fbcode//cinderx/UpstreamBorrow:gen_borrowed.c.


#include "internal/pycore_ceval.h"
#include "internal/pycore_stackref.h"
#include "internal/pycore_unicodeobject.h"
#include "internal/pycore_list.h"
#include "internal/pycore_long.h"
#include "internal/pycore_sliceobject.h"
#include "internal/pycore_stackref.h"
#include "internal/pycore_interpolation.h"
#include "internal/pycore_emscripten_signal.h"
#include "internal/pycore_template.h"
#include "internal/pycore_setobject.h"
#include "internal/pycore_intrinsics.h"
#include "internal/pycore_cell.h"
#include "internal/pycore_import.h"
#include "internal/pycore_range.h"
#include "internal/pycore_genobject.h"
#include "internal/pycore_function.h"
#include "internal/pycore_call.h"
#include "internal/pycore_floatobject.h"
#include "internal/pycore_tuple.h"
#include "Python/ceval_macros.h"

#define _PyCoro_GetAwaitableIter JitCoro_GetAwaitableIter
#define _PyEval_GetAwaitable Ci_PyEval_GetAwaitable
#define _PyEval_GetANext Ci_PyEval_GetANext

PyObject *
_PyEval_GetANext(PyObject *aiter)
{
    unaryfunc getter = NULL;
    PyObject *next_iter = NULL;
    PyTypeObject *type = Py_TYPE(aiter);
    if (PyAsyncGen_CheckExact(aiter)) {
        return type->tp_as_async->am_anext(aiter);
    }
    if (type->tp_as_async != NULL){
        getter = type->tp_as_async->am_anext;
    }

    if (getter != NULL) {
        next_iter = (*getter)(aiter);
        if (next_iter == NULL) {
            return NULL;
        }
    }
    else {
        PyErr_Format(PyExc_TypeError,
                        "'async for' requires an iterator with "
                        "__anext__ method, got %.100s",
                        type->tp_name);
        return NULL;
    }

    PyObject *awaitable = _PyCoro_GetAwaitableIter(next_iter);
    if (awaitable == NULL) {
        _PyErr_FormatFromCause(
            PyExc_TypeError,
            "'async for' received an invalid object "
            "from __anext__: %.100s",
            Py_TYPE(next_iter)->tp_name);
    }
    Py_DECREF(next_iter);
    return awaitable;
}
PyObject *
_PyEval_GetAwaitable(PyObject *iterable, int oparg)
{
    PyObject *iter = _PyCoro_GetAwaitableIter(iterable);

    if (iter == NULL) {
        _PyEval_FormatAwaitableError(PyThreadState_GET(),
            Py_TYPE(iterable), oparg);
    }
    else if (PyCoro_CheckExact(iter)) {
        PyCoroObject *coro = (PyCoroObject *)iter;
        int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(coro->cr_frame_state);
        if (frame_state == FRAME_SUSPENDED_YIELD_FROM ||
            frame_state == FRAME_SUSPENDED_YIELD_FROM_LOCKED)
        {
            /* `iter` is a coroutine object that is being awaited. */
            Py_CLEAR(iter);
            _PyErr_SetString(PyThreadState_GET(), PyExc_RuntimeError,
                             "coroutine is being awaited already");
        }
    }
    return iter;
}

#undef _PyCoro_GetAwaitableIter
#undef _PyEval_GetAwaitable
#undef _PyEval_GetANext

#if Py_TAIL_CALL_INTERP
#include "cinderx/Interpreter/cinderx_opcode_targets.h"
#include "cinderx/Interpreter/3.15/Includes/generated_cases.c.h"
#endif
