17db96d56Sopenharmony_ci#include "Python.h"
27db96d56Sopenharmony_ci#include "pycore_call.h"          // _PyObject_CallNoArgsTstate()
37db96d56Sopenharmony_ci#include "pycore_ceval.h"         // _PyEval_EvalFrame()
47db96d56Sopenharmony_ci#include "pycore_object.h"        // _PyObject_GC_TRACK()
57db96d56Sopenharmony_ci#include "pycore_pyerrors.h"      // _PyErr_Occurred()
67db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyThreadState_GET()
77db96d56Sopenharmony_ci#include "pycore_tuple.h"         // _PyTuple_ITEMS()
87db96d56Sopenharmony_ci#include "frameobject.h"          // _PyFrame_New_NoTrack()
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_cistatic PyObject *const *
127db96d56Sopenharmony_ci_PyStack_UnpackDict(PyThreadState *tstate,
137db96d56Sopenharmony_ci                    PyObject *const *args, Py_ssize_t nargs,
147db96d56Sopenharmony_ci                    PyObject *kwargs, PyObject **p_kwnames);
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_cistatic void
177db96d56Sopenharmony_ci_PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs,
187db96d56Sopenharmony_ci                         PyObject *kwnames);
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_cistatic PyObject *
227db96d56Sopenharmony_cinull_error(PyThreadState *tstate)
237db96d56Sopenharmony_ci{
247db96d56Sopenharmony_ci    if (!_PyErr_Occurred(tstate)) {
257db96d56Sopenharmony_ci        _PyErr_SetString(tstate, PyExc_SystemError,
267db96d56Sopenharmony_ci                         "null argument to internal routine");
277db96d56Sopenharmony_ci    }
287db96d56Sopenharmony_ci    return NULL;
297db96d56Sopenharmony_ci}
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ciPyObject*
337db96d56Sopenharmony_ci_Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
347db96d56Sopenharmony_ci                        PyObject *result, const char *where)
357db96d56Sopenharmony_ci{
367db96d56Sopenharmony_ci    assert((callable != NULL) ^ (where != NULL));
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_ci    if (result == NULL) {
397db96d56Sopenharmony_ci        if (!_PyErr_Occurred(tstate)) {
407db96d56Sopenharmony_ci            if (callable)
417db96d56Sopenharmony_ci                _PyErr_Format(tstate, PyExc_SystemError,
427db96d56Sopenharmony_ci                              "%R returned NULL without setting an exception",
437db96d56Sopenharmony_ci                              callable);
447db96d56Sopenharmony_ci            else
457db96d56Sopenharmony_ci                _PyErr_Format(tstate, PyExc_SystemError,
467db96d56Sopenharmony_ci                              "%s returned NULL without setting an exception",
477db96d56Sopenharmony_ci                              where);
487db96d56Sopenharmony_ci#ifdef Py_DEBUG
497db96d56Sopenharmony_ci            /* Ensure that the bug is caught in debug mode.
507db96d56Sopenharmony_ci               Py_FatalError() logs the SystemError exception raised above. */
517db96d56Sopenharmony_ci            Py_FatalError("a function returned NULL without setting an exception");
527db96d56Sopenharmony_ci#endif
537db96d56Sopenharmony_ci            return NULL;
547db96d56Sopenharmony_ci        }
557db96d56Sopenharmony_ci    }
567db96d56Sopenharmony_ci    else {
577db96d56Sopenharmony_ci        if (_PyErr_Occurred(tstate)) {
587db96d56Sopenharmony_ci            Py_DECREF(result);
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci            if (callable) {
617db96d56Sopenharmony_ci                _PyErr_FormatFromCauseTstate(
627db96d56Sopenharmony_ci                    tstate, PyExc_SystemError,
637db96d56Sopenharmony_ci                    "%R returned a result with an exception set", callable);
647db96d56Sopenharmony_ci            }
657db96d56Sopenharmony_ci            else {
667db96d56Sopenharmony_ci                _PyErr_FormatFromCauseTstate(
677db96d56Sopenharmony_ci                    tstate, PyExc_SystemError,
687db96d56Sopenharmony_ci                    "%s returned a result with an exception set", where);
697db96d56Sopenharmony_ci            }
707db96d56Sopenharmony_ci#ifdef Py_DEBUG
717db96d56Sopenharmony_ci            /* Ensure that the bug is caught in debug mode.
727db96d56Sopenharmony_ci               Py_FatalError() logs the SystemError exception raised above. */
737db96d56Sopenharmony_ci            Py_FatalError("a function returned a result with an exception set");
747db96d56Sopenharmony_ci#endif
757db96d56Sopenharmony_ci            return NULL;
767db96d56Sopenharmony_ci        }
777db96d56Sopenharmony_ci    }
787db96d56Sopenharmony_ci    return result;
797db96d56Sopenharmony_ci}
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ciint
837db96d56Sopenharmony_ci_Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success)
847db96d56Sopenharmony_ci{
857db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
867db96d56Sopenharmony_ci    if (!success) {
877db96d56Sopenharmony_ci        if (!_PyErr_Occurred(tstate)) {
887db96d56Sopenharmony_ci            _Py_FatalErrorFormat(__func__,
897db96d56Sopenharmony_ci                                 "Slot %s of type %s failed "
907db96d56Sopenharmony_ci                                 "without setting an exception",
917db96d56Sopenharmony_ci                                 slot_name, Py_TYPE(obj)->tp_name);
927db96d56Sopenharmony_ci        }
937db96d56Sopenharmony_ci    }
947db96d56Sopenharmony_ci    else {
957db96d56Sopenharmony_ci        if (_PyErr_Occurred(tstate)) {
967db96d56Sopenharmony_ci            _Py_FatalErrorFormat(__func__,
977db96d56Sopenharmony_ci                                 "Slot %s of type %s succeeded "
987db96d56Sopenharmony_ci                                 "with an exception set",
997db96d56Sopenharmony_ci                                 slot_name, Py_TYPE(obj)->tp_name);
1007db96d56Sopenharmony_ci        }
1017db96d56Sopenharmony_ci    }
1027db96d56Sopenharmony_ci    return 1;
1037db96d56Sopenharmony_ci}
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ci/* --- Core PyObject call functions ------------------------------- */
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ci/* Call a callable Python object without any arguments */
1097db96d56Sopenharmony_ciPyObject *
1107db96d56Sopenharmony_ciPyObject_CallNoArgs(PyObject *func)
1117db96d56Sopenharmony_ci{
1127db96d56Sopenharmony_ci    return _PyObject_CallNoArgs(func);
1137db96d56Sopenharmony_ci}
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ciPyObject *
1177db96d56Sopenharmony_ci_PyObject_FastCallDictTstate(PyThreadState *tstate, PyObject *callable,
1187db96d56Sopenharmony_ci                             PyObject *const *args, size_t nargsf,
1197db96d56Sopenharmony_ci                             PyObject *kwargs)
1207db96d56Sopenharmony_ci{
1217db96d56Sopenharmony_ci    assert(callable != NULL);
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_ci    /* PyObject_VectorcallDict() must not be called with an exception set,
1247db96d56Sopenharmony_ci       because it can clear it (directly or indirectly) and so the
1257db96d56Sopenharmony_ci       caller loses its exception */
1267db96d56Sopenharmony_ci    assert(!_PyErr_Occurred(tstate));
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1297db96d56Sopenharmony_ci    assert(nargs >= 0);
1307db96d56Sopenharmony_ci    assert(nargs == 0 || args != NULL);
1317db96d56Sopenharmony_ci    assert(kwargs == NULL || PyDict_Check(kwargs));
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ci    vectorcallfunc func = _PyVectorcall_Function(callable);
1347db96d56Sopenharmony_ci    if (func == NULL) {
1357db96d56Sopenharmony_ci        /* Use tp_call instead */
1367db96d56Sopenharmony_ci        return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwargs);
1377db96d56Sopenharmony_ci    }
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci    PyObject *res;
1407db96d56Sopenharmony_ci    if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) {
1417db96d56Sopenharmony_ci        res = func(callable, args, nargsf, NULL);
1427db96d56Sopenharmony_ci    }
1437db96d56Sopenharmony_ci    else {
1447db96d56Sopenharmony_ci        PyObject *kwnames;
1457db96d56Sopenharmony_ci        PyObject *const *newargs;
1467db96d56Sopenharmony_ci        newargs = _PyStack_UnpackDict(tstate,
1477db96d56Sopenharmony_ci                                      args, nargs,
1487db96d56Sopenharmony_ci                                      kwargs, &kwnames);
1497db96d56Sopenharmony_ci        if (newargs == NULL) {
1507db96d56Sopenharmony_ci            return NULL;
1517db96d56Sopenharmony_ci        }
1527db96d56Sopenharmony_ci        res = func(callable, newargs,
1537db96d56Sopenharmony_ci                   nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames);
1547db96d56Sopenharmony_ci        _PyStack_UnpackDict_Free(newargs, nargs, kwnames);
1557db96d56Sopenharmony_ci    }
1567db96d56Sopenharmony_ci    return _Py_CheckFunctionResult(tstate, callable, res, NULL);
1577db96d56Sopenharmony_ci}
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_ci
1607db96d56Sopenharmony_ciPyObject *
1617db96d56Sopenharmony_ciPyObject_VectorcallDict(PyObject *callable, PyObject *const *args,
1627db96d56Sopenharmony_ci                       size_t nargsf, PyObject *kwargs)
1637db96d56Sopenharmony_ci{
1647db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
1657db96d56Sopenharmony_ci    return _PyObject_FastCallDictTstate(tstate, callable, args, nargsf, kwargs);
1667db96d56Sopenharmony_ci}
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ciPyObject *
1707db96d56Sopenharmony_ci_PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable,
1717db96d56Sopenharmony_ci                     PyObject *const *args, Py_ssize_t nargs,
1727db96d56Sopenharmony_ci                     PyObject *keywords)
1737db96d56Sopenharmony_ci{
1747db96d56Sopenharmony_ci    assert(nargs >= 0);
1757db96d56Sopenharmony_ci    assert(nargs == 0 || args != NULL);
1767db96d56Sopenharmony_ci    assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords));
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_ci    /* Slow path: build a temporary tuple for positional arguments and a
1797db96d56Sopenharmony_ci     * temporary dictionary for keyword arguments (if any) */
1807db96d56Sopenharmony_ci    ternaryfunc call = Py_TYPE(callable)->tp_call;
1817db96d56Sopenharmony_ci    if (call == NULL) {
1827db96d56Sopenharmony_ci        _PyErr_Format(tstate, PyExc_TypeError,
1837db96d56Sopenharmony_ci                      "'%.200s' object is not callable",
1847db96d56Sopenharmony_ci                      Py_TYPE(callable)->tp_name);
1857db96d56Sopenharmony_ci        return NULL;
1867db96d56Sopenharmony_ci    }
1877db96d56Sopenharmony_ci
1887db96d56Sopenharmony_ci    PyObject *argstuple = _PyTuple_FromArray(args, nargs);
1897db96d56Sopenharmony_ci    if (argstuple == NULL) {
1907db96d56Sopenharmony_ci        return NULL;
1917db96d56Sopenharmony_ci    }
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ci    PyObject *kwdict;
1947db96d56Sopenharmony_ci    if (keywords == NULL || PyDict_Check(keywords)) {
1957db96d56Sopenharmony_ci        kwdict = keywords;
1967db96d56Sopenharmony_ci    }
1977db96d56Sopenharmony_ci    else {
1987db96d56Sopenharmony_ci        if (PyTuple_GET_SIZE(keywords)) {
1997db96d56Sopenharmony_ci            assert(args != NULL);
2007db96d56Sopenharmony_ci            kwdict = _PyStack_AsDict(args + nargs, keywords);
2017db96d56Sopenharmony_ci            if (kwdict == NULL) {
2027db96d56Sopenharmony_ci                Py_DECREF(argstuple);
2037db96d56Sopenharmony_ci                return NULL;
2047db96d56Sopenharmony_ci            }
2057db96d56Sopenharmony_ci        }
2067db96d56Sopenharmony_ci        else {
2077db96d56Sopenharmony_ci            keywords = kwdict = NULL;
2087db96d56Sopenharmony_ci        }
2097db96d56Sopenharmony_ci    }
2107db96d56Sopenharmony_ci
2117db96d56Sopenharmony_ci    PyObject *result = NULL;
2127db96d56Sopenharmony_ci    if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object") == 0)
2137db96d56Sopenharmony_ci    {
2147db96d56Sopenharmony_ci        result = _PyCFunctionWithKeywords_TrampolineCall(
2157db96d56Sopenharmony_ci            (PyCFunctionWithKeywords)call, callable, argstuple, kwdict);
2167db96d56Sopenharmony_ci        _Py_LeaveRecursiveCallTstate(tstate);
2177db96d56Sopenharmony_ci    }
2187db96d56Sopenharmony_ci
2197db96d56Sopenharmony_ci    Py_DECREF(argstuple);
2207db96d56Sopenharmony_ci    if (kwdict != keywords) {
2217db96d56Sopenharmony_ci        Py_DECREF(kwdict);
2227db96d56Sopenharmony_ci    }
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci    return _Py_CheckFunctionResult(tstate, callable, result, NULL);
2257db96d56Sopenharmony_ci}
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_civectorcallfunc
2297db96d56Sopenharmony_ciPyVectorcall_Function(PyObject *callable)
2307db96d56Sopenharmony_ci{
2317db96d56Sopenharmony_ci    return _PyVectorcall_FunctionInline(callable);
2327db96d56Sopenharmony_ci}
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_cistatic PyObject *
2367db96d56Sopenharmony_ci_PyVectorcall_Call(PyThreadState *tstate, vectorcallfunc func,
2377db96d56Sopenharmony_ci                   PyObject *callable, PyObject *tuple, PyObject *kwargs)
2387db96d56Sopenharmony_ci{
2397db96d56Sopenharmony_ci    assert(func != NULL);
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci    Py_ssize_t nargs = PyTuple_GET_SIZE(tuple);
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_ci    /* Fast path for no keywords */
2447db96d56Sopenharmony_ci    if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) {
2457db96d56Sopenharmony_ci        return func(callable, _PyTuple_ITEMS(tuple), nargs, NULL);
2467db96d56Sopenharmony_ci    }
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ci    /* Convert arguments & call */
2497db96d56Sopenharmony_ci    PyObject *const *args;
2507db96d56Sopenharmony_ci    PyObject *kwnames;
2517db96d56Sopenharmony_ci    args = _PyStack_UnpackDict(tstate,
2527db96d56Sopenharmony_ci                               _PyTuple_ITEMS(tuple), nargs,
2537db96d56Sopenharmony_ci                               kwargs, &kwnames);
2547db96d56Sopenharmony_ci    if (args == NULL) {
2557db96d56Sopenharmony_ci        return NULL;
2567db96d56Sopenharmony_ci    }
2577db96d56Sopenharmony_ci    PyObject *result = func(callable, args,
2587db96d56Sopenharmony_ci                            nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames);
2597db96d56Sopenharmony_ci    _PyStack_UnpackDict_Free(args, nargs, kwnames);
2607db96d56Sopenharmony_ci
2617db96d56Sopenharmony_ci    return _Py_CheckFunctionResult(tstate, callable, result, NULL);
2627db96d56Sopenharmony_ci}
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci
2657db96d56Sopenharmony_ciPyObject *
2667db96d56Sopenharmony_ciPyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
2677db96d56Sopenharmony_ci{
2687db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci    /* get vectorcallfunc as in _PyVectorcall_Function, but without
2717db96d56Sopenharmony_ci     * the Py_TPFLAGS_HAVE_VECTORCALL check */
2727db96d56Sopenharmony_ci    Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
2737db96d56Sopenharmony_ci    if (offset <= 0) {
2747db96d56Sopenharmony_ci        _PyErr_Format(tstate, PyExc_TypeError,
2757db96d56Sopenharmony_ci                      "'%.200s' object does not support vectorcall",
2767db96d56Sopenharmony_ci                      Py_TYPE(callable)->tp_name);
2777db96d56Sopenharmony_ci        return NULL;
2787db96d56Sopenharmony_ci    }
2797db96d56Sopenharmony_ci    assert(PyCallable_Check(callable));
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci    vectorcallfunc func;
2827db96d56Sopenharmony_ci    memcpy(&func, (char *) callable + offset, sizeof(func));
2837db96d56Sopenharmony_ci    if (func == NULL) {
2847db96d56Sopenharmony_ci        _PyErr_Format(tstate, PyExc_TypeError,
2857db96d56Sopenharmony_ci                      "'%.200s' object does not support vectorcall",
2867db96d56Sopenharmony_ci                      Py_TYPE(callable)->tp_name);
2877db96d56Sopenharmony_ci        return NULL;
2887db96d56Sopenharmony_ci    }
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci    return _PyVectorcall_Call(tstate, func, callable, tuple, kwargs);
2917db96d56Sopenharmony_ci}
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ciPyObject *
2957db96d56Sopenharmony_ciPyObject_Vectorcall(PyObject *callable, PyObject *const *args,
2967db96d56Sopenharmony_ci                     size_t nargsf, PyObject *kwnames)
2977db96d56Sopenharmony_ci{
2987db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
2997db96d56Sopenharmony_ci    return _PyObject_VectorcallTstate(tstate, callable,
3007db96d56Sopenharmony_ci                                      args, nargsf, kwnames);
3017db96d56Sopenharmony_ci}
3027db96d56Sopenharmony_ci
3037db96d56Sopenharmony_ci
3047db96d56Sopenharmony_ciPyObject *
3057db96d56Sopenharmony_ci_PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs)
3067db96d56Sopenharmony_ci{
3077db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
3087db96d56Sopenharmony_ci    return _PyObject_FastCallTstate(tstate, func, args, nargs);
3097db96d56Sopenharmony_ci}
3107db96d56Sopenharmony_ci
3117db96d56Sopenharmony_ci
3127db96d56Sopenharmony_ciPyObject *
3137db96d56Sopenharmony_ci_PyObject_Call(PyThreadState *tstate, PyObject *callable,
3147db96d56Sopenharmony_ci               PyObject *args, PyObject *kwargs)
3157db96d56Sopenharmony_ci{
3167db96d56Sopenharmony_ci    ternaryfunc call;
3177db96d56Sopenharmony_ci    PyObject *result;
3187db96d56Sopenharmony_ci
3197db96d56Sopenharmony_ci    /* PyObject_Call() must not be called with an exception set,
3207db96d56Sopenharmony_ci       because it can clear it (directly or indirectly) and so the
3217db96d56Sopenharmony_ci       caller loses its exception */
3227db96d56Sopenharmony_ci    assert(!_PyErr_Occurred(tstate));
3237db96d56Sopenharmony_ci    assert(PyTuple_Check(args));
3247db96d56Sopenharmony_ci    assert(kwargs == NULL || PyDict_Check(kwargs));
3257db96d56Sopenharmony_ci
3267db96d56Sopenharmony_ci    vectorcallfunc vector_func = _PyVectorcall_Function(callable);
3277db96d56Sopenharmony_ci    if (vector_func != NULL) {
3287db96d56Sopenharmony_ci        return _PyVectorcall_Call(tstate, vector_func, callable, args, kwargs);
3297db96d56Sopenharmony_ci    }
3307db96d56Sopenharmony_ci    else {
3317db96d56Sopenharmony_ci        call = Py_TYPE(callable)->tp_call;
3327db96d56Sopenharmony_ci        if (call == NULL) {
3337db96d56Sopenharmony_ci            _PyErr_Format(tstate, PyExc_TypeError,
3347db96d56Sopenharmony_ci                          "'%.200s' object is not callable",
3357db96d56Sopenharmony_ci                          Py_TYPE(callable)->tp_name);
3367db96d56Sopenharmony_ci            return NULL;
3377db96d56Sopenharmony_ci        }
3387db96d56Sopenharmony_ci
3397db96d56Sopenharmony_ci        if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
3407db96d56Sopenharmony_ci            return NULL;
3417db96d56Sopenharmony_ci        }
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_ci        result = (*call)(callable, args, kwargs);
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_ci        _Py_LeaveRecursiveCallTstate(tstate);
3467db96d56Sopenharmony_ci
3477db96d56Sopenharmony_ci        return _Py_CheckFunctionResult(tstate, callable, result, NULL);
3487db96d56Sopenharmony_ci    }
3497db96d56Sopenharmony_ci}
3507db96d56Sopenharmony_ci
3517db96d56Sopenharmony_ciPyObject *
3527db96d56Sopenharmony_ciPyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
3537db96d56Sopenharmony_ci{
3547db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
3557db96d56Sopenharmony_ci    return _PyObject_Call(tstate, callable, args, kwargs);
3567db96d56Sopenharmony_ci}
3577db96d56Sopenharmony_ci
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ciPyObject *
3607db96d56Sopenharmony_ciPyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
3617db96d56Sopenharmony_ci{
3627db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
3637db96d56Sopenharmony_ci    return _PyObject_Call(tstate, callable, args, kwargs);
3647db96d56Sopenharmony_ci}
3657db96d56Sopenharmony_ci
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ciPyObject *
3687db96d56Sopenharmony_ciPyObject_CallOneArg(PyObject *func, PyObject *arg)
3697db96d56Sopenharmony_ci{
3707db96d56Sopenharmony_ci    assert(arg != NULL);
3717db96d56Sopenharmony_ci    PyObject *_args[2];
3727db96d56Sopenharmony_ci    PyObject **args = _args + 1;  // For PY_VECTORCALL_ARGUMENTS_OFFSET
3737db96d56Sopenharmony_ci    args[0] = arg;
3747db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
3757db96d56Sopenharmony_ci    size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
3767db96d56Sopenharmony_ci    return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL);
3777db96d56Sopenharmony_ci}
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci
3807db96d56Sopenharmony_ci/* --- PyFunction call functions ---------------------------------- */
3817db96d56Sopenharmony_ci
3827db96d56Sopenharmony_ciPyObject *
3837db96d56Sopenharmony_ci_PyFunction_Vectorcall(PyObject *func, PyObject* const* stack,
3847db96d56Sopenharmony_ci                       size_t nargsf, PyObject *kwnames)
3857db96d56Sopenharmony_ci{
3867db96d56Sopenharmony_ci    assert(PyFunction_Check(func));
3877db96d56Sopenharmony_ci    PyFunctionObject *f = (PyFunctionObject *)func;
3887db96d56Sopenharmony_ci    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
3897db96d56Sopenharmony_ci    assert(nargs >= 0);
3907db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
3917db96d56Sopenharmony_ci    assert(nargs == 0 || stack != NULL);
3927db96d56Sopenharmony_ci    if (((PyCodeObject *)f->func_code)->co_flags & CO_OPTIMIZED) {
3937db96d56Sopenharmony_ci        return _PyEval_Vector(tstate, f, NULL, stack, nargs, kwnames);
3947db96d56Sopenharmony_ci    }
3957db96d56Sopenharmony_ci    else {
3967db96d56Sopenharmony_ci        return _PyEval_Vector(tstate, f, f->func_globals, stack, nargs, kwnames);
3977db96d56Sopenharmony_ci    }
3987db96d56Sopenharmony_ci}
3997db96d56Sopenharmony_ci
4007db96d56Sopenharmony_ci/* --- More complex call functions -------------------------------- */
4017db96d56Sopenharmony_ci
4027db96d56Sopenharmony_ci/* External interface to call any callable object.
4037db96d56Sopenharmony_ci   The args must be a tuple or NULL.  The kwargs must be a dict or NULL. */
4047db96d56Sopenharmony_ciPyObject *
4057db96d56Sopenharmony_ciPyEval_CallObjectWithKeywords(PyObject *callable,
4067db96d56Sopenharmony_ci                              PyObject *args, PyObject *kwargs)
4077db96d56Sopenharmony_ci{
4087db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
4097db96d56Sopenharmony_ci#ifdef Py_DEBUG
4107db96d56Sopenharmony_ci    /* PyEval_CallObjectWithKeywords() must not be called with an exception
4117db96d56Sopenharmony_ci       set. It raises a new exception if parameters are invalid or if
4127db96d56Sopenharmony_ci       PyTuple_New() fails, and so the original exception is lost. */
4137db96d56Sopenharmony_ci    assert(!_PyErr_Occurred(tstate));
4147db96d56Sopenharmony_ci#endif
4157db96d56Sopenharmony_ci
4167db96d56Sopenharmony_ci    if (args != NULL && !PyTuple_Check(args)) {
4177db96d56Sopenharmony_ci        _PyErr_SetString(tstate, PyExc_TypeError,
4187db96d56Sopenharmony_ci                         "argument list must be a tuple");
4197db96d56Sopenharmony_ci        return NULL;
4207db96d56Sopenharmony_ci    }
4217db96d56Sopenharmony_ci
4227db96d56Sopenharmony_ci    if (kwargs != NULL && !PyDict_Check(kwargs)) {
4237db96d56Sopenharmony_ci        _PyErr_SetString(tstate, PyExc_TypeError,
4247db96d56Sopenharmony_ci                         "keyword list must be a dictionary");
4257db96d56Sopenharmony_ci        return NULL;
4267db96d56Sopenharmony_ci    }
4277db96d56Sopenharmony_ci
4287db96d56Sopenharmony_ci    if (args == NULL) {
4297db96d56Sopenharmony_ci        return _PyObject_FastCallDictTstate(tstate, callable, NULL, 0, kwargs);
4307db96d56Sopenharmony_ci    }
4317db96d56Sopenharmony_ci    else {
4327db96d56Sopenharmony_ci        return _PyObject_Call(tstate, callable, args, kwargs);
4337db96d56Sopenharmony_ci    }
4347db96d56Sopenharmony_ci}
4357db96d56Sopenharmony_ci
4367db96d56Sopenharmony_ci
4377db96d56Sopenharmony_ciPyObject *
4387db96d56Sopenharmony_ciPyObject_CallObject(PyObject *callable, PyObject *args)
4397db96d56Sopenharmony_ci{
4407db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
4417db96d56Sopenharmony_ci    assert(!_PyErr_Occurred(tstate));
4427db96d56Sopenharmony_ci    if (args == NULL) {
4437db96d56Sopenharmony_ci        return _PyObject_CallNoArgsTstate(tstate, callable);
4447db96d56Sopenharmony_ci    }
4457db96d56Sopenharmony_ci    if (!PyTuple_Check(args)) {
4467db96d56Sopenharmony_ci        _PyErr_SetString(tstate, PyExc_TypeError,
4477db96d56Sopenharmony_ci                         "argument list must be a tuple");
4487db96d56Sopenharmony_ci        return NULL;
4497db96d56Sopenharmony_ci    }
4507db96d56Sopenharmony_ci    return _PyObject_Call(tstate, callable, args, NULL);
4517db96d56Sopenharmony_ci}
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ci
4547db96d56Sopenharmony_ci/* Call callable(obj, *args, **kwargs). */
4557db96d56Sopenharmony_ciPyObject *
4567db96d56Sopenharmony_ci_PyObject_Call_Prepend(PyThreadState *tstate, PyObject *callable,
4577db96d56Sopenharmony_ci                       PyObject *obj, PyObject *args, PyObject *kwargs)
4587db96d56Sopenharmony_ci{
4597db96d56Sopenharmony_ci    assert(PyTuple_Check(args));
4607db96d56Sopenharmony_ci
4617db96d56Sopenharmony_ci    PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
4627db96d56Sopenharmony_ci    PyObject **stack;
4637db96d56Sopenharmony_ci
4647db96d56Sopenharmony_ci    Py_ssize_t argcount = PyTuple_GET_SIZE(args);
4657db96d56Sopenharmony_ci    if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
4667db96d56Sopenharmony_ci        stack = small_stack;
4677db96d56Sopenharmony_ci    }
4687db96d56Sopenharmony_ci    else {
4697db96d56Sopenharmony_ci        stack = PyMem_Malloc((argcount + 1) * sizeof(PyObject *));
4707db96d56Sopenharmony_ci        if (stack == NULL) {
4717db96d56Sopenharmony_ci            PyErr_NoMemory();
4727db96d56Sopenharmony_ci            return NULL;
4737db96d56Sopenharmony_ci        }
4747db96d56Sopenharmony_ci    }
4757db96d56Sopenharmony_ci
4767db96d56Sopenharmony_ci    /* use borrowed references */
4777db96d56Sopenharmony_ci    stack[0] = obj;
4787db96d56Sopenharmony_ci    memcpy(&stack[1],
4797db96d56Sopenharmony_ci           _PyTuple_ITEMS(args),
4807db96d56Sopenharmony_ci           argcount * sizeof(PyObject *));
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_ci    PyObject *result = _PyObject_FastCallDictTstate(tstate, callable,
4837db96d56Sopenharmony_ci                                                    stack, argcount + 1,
4847db96d56Sopenharmony_ci                                                    kwargs);
4857db96d56Sopenharmony_ci    if (stack != small_stack) {
4867db96d56Sopenharmony_ci        PyMem_Free(stack);
4877db96d56Sopenharmony_ci    }
4887db96d56Sopenharmony_ci    return result;
4897db96d56Sopenharmony_ci}
4907db96d56Sopenharmony_ci
4917db96d56Sopenharmony_ci
4927db96d56Sopenharmony_ci/* --- Call with a format string ---------------------------------- */
4937db96d56Sopenharmony_ci
4947db96d56Sopenharmony_cistatic PyObject *
4957db96d56Sopenharmony_ci_PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable,
4967db96d56Sopenharmony_ci                         const char *format, va_list va, int is_size_t)
4977db96d56Sopenharmony_ci{
4987db96d56Sopenharmony_ci    PyObject* small_stack[_PY_FASTCALL_SMALL_STACK];
4997db96d56Sopenharmony_ci    const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack);
5007db96d56Sopenharmony_ci    PyObject **stack;
5017db96d56Sopenharmony_ci    Py_ssize_t nargs, i;
5027db96d56Sopenharmony_ci    PyObject *result;
5037db96d56Sopenharmony_ci
5047db96d56Sopenharmony_ci    if (callable == NULL) {
5057db96d56Sopenharmony_ci        return null_error(tstate);
5067db96d56Sopenharmony_ci    }
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ci    if (!format || !*format) {
5097db96d56Sopenharmony_ci        return _PyObject_CallNoArgsTstate(tstate, callable);
5107db96d56Sopenharmony_ci    }
5117db96d56Sopenharmony_ci
5127db96d56Sopenharmony_ci    if (is_size_t) {
5137db96d56Sopenharmony_ci        stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len,
5147db96d56Sopenharmony_ci                                       format, va, &nargs);
5157db96d56Sopenharmony_ci    }
5167db96d56Sopenharmony_ci    else {
5177db96d56Sopenharmony_ci        stack = _Py_VaBuildStack(small_stack, small_stack_len,
5187db96d56Sopenharmony_ci                                 format, va, &nargs);
5197db96d56Sopenharmony_ci    }
5207db96d56Sopenharmony_ci    if (stack == NULL) {
5217db96d56Sopenharmony_ci        return NULL;
5227db96d56Sopenharmony_ci    }
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ci    if (nargs == 1 && PyTuple_Check(stack[0])) {
5257db96d56Sopenharmony_ci        /* Special cases for backward compatibility:
5267db96d56Sopenharmony_ci           - PyObject_CallFunction(func, "O", tuple) calls func(*tuple)
5277db96d56Sopenharmony_ci           - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls
5287db96d56Sopenharmony_ci             func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */
5297db96d56Sopenharmony_ci        PyObject *args = stack[0];
5307db96d56Sopenharmony_ci        result = _PyObject_VectorcallTstate(tstate, callable,
5317db96d56Sopenharmony_ci                                            _PyTuple_ITEMS(args),
5327db96d56Sopenharmony_ci                                            PyTuple_GET_SIZE(args),
5337db96d56Sopenharmony_ci                                            NULL);
5347db96d56Sopenharmony_ci    }
5357db96d56Sopenharmony_ci    else {
5367db96d56Sopenharmony_ci        result = _PyObject_VectorcallTstate(tstate, callable,
5377db96d56Sopenharmony_ci                                            stack, nargs, NULL);
5387db96d56Sopenharmony_ci    }
5397db96d56Sopenharmony_ci
5407db96d56Sopenharmony_ci    for (i = 0; i < nargs; ++i) {
5417db96d56Sopenharmony_ci        Py_DECREF(stack[i]);
5427db96d56Sopenharmony_ci    }
5437db96d56Sopenharmony_ci    if (stack != small_stack) {
5447db96d56Sopenharmony_ci        PyMem_Free(stack);
5457db96d56Sopenharmony_ci    }
5467db96d56Sopenharmony_ci    return result;
5477db96d56Sopenharmony_ci}
5487db96d56Sopenharmony_ci
5497db96d56Sopenharmony_ci
5507db96d56Sopenharmony_ciPyObject *
5517db96d56Sopenharmony_ciPyObject_CallFunction(PyObject *callable, const char *format, ...)
5527db96d56Sopenharmony_ci{
5537db96d56Sopenharmony_ci    va_list va;
5547db96d56Sopenharmony_ci    PyObject *result;
5557db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
5567db96d56Sopenharmony_ci
5577db96d56Sopenharmony_ci    va_start(va, format);
5587db96d56Sopenharmony_ci    result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0);
5597db96d56Sopenharmony_ci    va_end(va);
5607db96d56Sopenharmony_ci
5617db96d56Sopenharmony_ci    return result;
5627db96d56Sopenharmony_ci}
5637db96d56Sopenharmony_ci
5647db96d56Sopenharmony_ci
5657db96d56Sopenharmony_ci/* PyEval_CallFunction is exact copy of PyObject_CallFunction.
5667db96d56Sopenharmony_ci * This function is kept for backward compatibility.
5677db96d56Sopenharmony_ci */
5687db96d56Sopenharmony_ciPyObject *
5697db96d56Sopenharmony_ciPyEval_CallFunction(PyObject *callable, const char *format, ...)
5707db96d56Sopenharmony_ci{
5717db96d56Sopenharmony_ci    va_list va;
5727db96d56Sopenharmony_ci    PyObject *result;
5737db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
5747db96d56Sopenharmony_ci
5757db96d56Sopenharmony_ci    va_start(va, format);
5767db96d56Sopenharmony_ci    result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0);
5777db96d56Sopenharmony_ci    va_end(va);
5787db96d56Sopenharmony_ci
5797db96d56Sopenharmony_ci    return result;
5807db96d56Sopenharmony_ci}
5817db96d56Sopenharmony_ci
5827db96d56Sopenharmony_ci
5837db96d56Sopenharmony_ciPyObject *
5847db96d56Sopenharmony_ci_PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...)
5857db96d56Sopenharmony_ci{
5867db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
5877db96d56Sopenharmony_ci
5887db96d56Sopenharmony_ci    va_list va;
5897db96d56Sopenharmony_ci    va_start(va, format);
5907db96d56Sopenharmony_ci    PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va, 1);
5917db96d56Sopenharmony_ci    va_end(va);
5927db96d56Sopenharmony_ci
5937db96d56Sopenharmony_ci    return result;
5947db96d56Sopenharmony_ci}
5957db96d56Sopenharmony_ci
5967db96d56Sopenharmony_ci
5977db96d56Sopenharmony_cistatic PyObject*
5987db96d56Sopenharmony_cicallmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_list va, int is_size_t)
5997db96d56Sopenharmony_ci{
6007db96d56Sopenharmony_ci    assert(callable != NULL);
6017db96d56Sopenharmony_ci    if (!PyCallable_Check(callable)) {
6027db96d56Sopenharmony_ci        _PyErr_Format(tstate, PyExc_TypeError,
6037db96d56Sopenharmony_ci                      "attribute of type '%.200s' is not callable",
6047db96d56Sopenharmony_ci                      Py_TYPE(callable)->tp_name);
6057db96d56Sopenharmony_ci        return NULL;
6067db96d56Sopenharmony_ci    }
6077db96d56Sopenharmony_ci
6087db96d56Sopenharmony_ci    return _PyObject_CallFunctionVa(tstate, callable, format, va, is_size_t);
6097db96d56Sopenharmony_ci}
6107db96d56Sopenharmony_ci
6117db96d56Sopenharmony_ciPyObject *
6127db96d56Sopenharmony_ciPyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)
6137db96d56Sopenharmony_ci{
6147db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
6157db96d56Sopenharmony_ci
6167db96d56Sopenharmony_ci    if (obj == NULL || name == NULL) {
6177db96d56Sopenharmony_ci        return null_error(tstate);
6187db96d56Sopenharmony_ci    }
6197db96d56Sopenharmony_ci
6207db96d56Sopenharmony_ci    PyObject *callable = PyObject_GetAttrString(obj, name);
6217db96d56Sopenharmony_ci    if (callable == NULL) {
6227db96d56Sopenharmony_ci        return NULL;
6237db96d56Sopenharmony_ci    }
6247db96d56Sopenharmony_ci
6257db96d56Sopenharmony_ci    va_list va;
6267db96d56Sopenharmony_ci    va_start(va, format);
6277db96d56Sopenharmony_ci    PyObject *retval = callmethod(tstate, callable, format, va, 0);
6287db96d56Sopenharmony_ci    va_end(va);
6297db96d56Sopenharmony_ci
6307db96d56Sopenharmony_ci    Py_DECREF(callable);
6317db96d56Sopenharmony_ci    return retval;
6327db96d56Sopenharmony_ci}
6337db96d56Sopenharmony_ci
6347db96d56Sopenharmony_ci
6357db96d56Sopenharmony_ci/* PyEval_CallMethod is exact copy of PyObject_CallMethod.
6367db96d56Sopenharmony_ci * This function is kept for backward compatibility.
6377db96d56Sopenharmony_ci */
6387db96d56Sopenharmony_ciPyObject *
6397db96d56Sopenharmony_ciPyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...)
6407db96d56Sopenharmony_ci{
6417db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
6427db96d56Sopenharmony_ci    if (obj == NULL || name == NULL) {
6437db96d56Sopenharmony_ci        return null_error(tstate);
6447db96d56Sopenharmony_ci    }
6457db96d56Sopenharmony_ci
6467db96d56Sopenharmony_ci    PyObject *callable = PyObject_GetAttrString(obj, name);
6477db96d56Sopenharmony_ci    if (callable == NULL) {
6487db96d56Sopenharmony_ci        return NULL;
6497db96d56Sopenharmony_ci    }
6507db96d56Sopenharmony_ci
6517db96d56Sopenharmony_ci    va_list va;
6527db96d56Sopenharmony_ci    va_start(va, format);
6537db96d56Sopenharmony_ci    PyObject *retval = callmethod(tstate, callable, format, va, 0);
6547db96d56Sopenharmony_ci    va_end(va);
6557db96d56Sopenharmony_ci
6567db96d56Sopenharmony_ci    Py_DECREF(callable);
6577db96d56Sopenharmony_ci    return retval;
6587db96d56Sopenharmony_ci}
6597db96d56Sopenharmony_ci
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_ciPyObject *
6627db96d56Sopenharmony_ci_PyObject_CallMethod(PyObject *obj, PyObject *name,
6637db96d56Sopenharmony_ci                     const char *format, ...)
6647db96d56Sopenharmony_ci{
6657db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
6667db96d56Sopenharmony_ci    if (obj == NULL || name == NULL) {
6677db96d56Sopenharmony_ci        return null_error(tstate);
6687db96d56Sopenharmony_ci    }
6697db96d56Sopenharmony_ci
6707db96d56Sopenharmony_ci    PyObject *callable = PyObject_GetAttr(obj, name);
6717db96d56Sopenharmony_ci    if (callable == NULL) {
6727db96d56Sopenharmony_ci        return NULL;
6737db96d56Sopenharmony_ci    }
6747db96d56Sopenharmony_ci
6757db96d56Sopenharmony_ci    va_list va;
6767db96d56Sopenharmony_ci    va_start(va, format);
6777db96d56Sopenharmony_ci    PyObject *retval = callmethod(tstate, callable, format, va, 1);
6787db96d56Sopenharmony_ci    va_end(va);
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ci    Py_DECREF(callable);
6817db96d56Sopenharmony_ci    return retval;
6827db96d56Sopenharmony_ci}
6837db96d56Sopenharmony_ci
6847db96d56Sopenharmony_ci
6857db96d56Sopenharmony_ciPyObject *
6867db96d56Sopenharmony_ci_PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name,
6877db96d56Sopenharmony_ci                       const char *format, ...)
6887db96d56Sopenharmony_ci{
6897db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
6907db96d56Sopenharmony_ci    if (obj == NULL || name == NULL) {
6917db96d56Sopenharmony_ci        return null_error(tstate);
6927db96d56Sopenharmony_ci    }
6937db96d56Sopenharmony_ci
6947db96d56Sopenharmony_ci    PyObject *callable = _PyObject_GetAttrId(obj, name);
6957db96d56Sopenharmony_ci    if (callable == NULL) {
6967db96d56Sopenharmony_ci        return NULL;
6977db96d56Sopenharmony_ci    }
6987db96d56Sopenharmony_ci
6997db96d56Sopenharmony_ci    va_list va;
7007db96d56Sopenharmony_ci    va_start(va, format);
7017db96d56Sopenharmony_ci    PyObject *retval = callmethod(tstate, callable, format, va, 0);
7027db96d56Sopenharmony_ci    va_end(va);
7037db96d56Sopenharmony_ci
7047db96d56Sopenharmony_ci    Py_DECREF(callable);
7057db96d56Sopenharmony_ci    return retval;
7067db96d56Sopenharmony_ci}
7077db96d56Sopenharmony_ci
7087db96d56Sopenharmony_ci
7097db96d56Sopenharmony_ciPyObject * _PyObject_CallMethodFormat(PyThreadState *tstate, PyObject *callable,
7107db96d56Sopenharmony_ci                                      const char *format, ...)
7117db96d56Sopenharmony_ci{
7127db96d56Sopenharmony_ci    va_list va;
7137db96d56Sopenharmony_ci    va_start(va, format);
7147db96d56Sopenharmony_ci    PyObject *retval = callmethod(tstate, callable, format, va, 0);
7157db96d56Sopenharmony_ci    va_end(va);
7167db96d56Sopenharmony_ci    return retval;
7177db96d56Sopenharmony_ci}
7187db96d56Sopenharmony_ci
7197db96d56Sopenharmony_ci
7207db96d56Sopenharmony_ciPyObject *
7217db96d56Sopenharmony_ci_PyObject_CallMethod_SizeT(PyObject *obj, const char *name,
7227db96d56Sopenharmony_ci                           const char *format, ...)
7237db96d56Sopenharmony_ci{
7247db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
7257db96d56Sopenharmony_ci    if (obj == NULL || name == NULL) {
7267db96d56Sopenharmony_ci        return null_error(tstate);
7277db96d56Sopenharmony_ci    }
7287db96d56Sopenharmony_ci
7297db96d56Sopenharmony_ci    PyObject *callable = PyObject_GetAttrString(obj, name);
7307db96d56Sopenharmony_ci    if (callable == NULL) {
7317db96d56Sopenharmony_ci        return NULL;
7327db96d56Sopenharmony_ci    }
7337db96d56Sopenharmony_ci
7347db96d56Sopenharmony_ci    va_list va;
7357db96d56Sopenharmony_ci    va_start(va, format);
7367db96d56Sopenharmony_ci    PyObject *retval = callmethod(tstate, callable, format, va, 1);
7377db96d56Sopenharmony_ci    va_end(va);
7387db96d56Sopenharmony_ci
7397db96d56Sopenharmony_ci    Py_DECREF(callable);
7407db96d56Sopenharmony_ci    return retval;
7417db96d56Sopenharmony_ci}
7427db96d56Sopenharmony_ci
7437db96d56Sopenharmony_ci
7447db96d56Sopenharmony_ciPyObject *
7457db96d56Sopenharmony_ci_PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name,
7467db96d56Sopenharmony_ci                             const char *format, ...)
7477db96d56Sopenharmony_ci{
7487db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
7497db96d56Sopenharmony_ci    if (obj == NULL || name == NULL) {
7507db96d56Sopenharmony_ci        return null_error(tstate);
7517db96d56Sopenharmony_ci    }
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ci    PyObject *callable = _PyObject_GetAttrId(obj, name);
7547db96d56Sopenharmony_ci    if (callable == NULL) {
7557db96d56Sopenharmony_ci        return NULL;
7567db96d56Sopenharmony_ci    }
7577db96d56Sopenharmony_ci
7587db96d56Sopenharmony_ci    va_list va;
7597db96d56Sopenharmony_ci    va_start(va, format);
7607db96d56Sopenharmony_ci    PyObject *retval = callmethod(tstate, callable, format, va, 1);
7617db96d56Sopenharmony_ci    va_end(va);
7627db96d56Sopenharmony_ci
7637db96d56Sopenharmony_ci    Py_DECREF(callable);
7647db96d56Sopenharmony_ci    return retval;
7657db96d56Sopenharmony_ci}
7667db96d56Sopenharmony_ci
7677db96d56Sopenharmony_ci
7687db96d56Sopenharmony_ci/* --- Call with "..." arguments ---------------------------------- */
7697db96d56Sopenharmony_ci
7707db96d56Sopenharmony_cistatic PyObject *
7717db96d56Sopenharmony_ciobject_vacall(PyThreadState *tstate, PyObject *base,
7727db96d56Sopenharmony_ci              PyObject *callable, va_list vargs)
7737db96d56Sopenharmony_ci{
7747db96d56Sopenharmony_ci    PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
7757db96d56Sopenharmony_ci    PyObject **stack;
7767db96d56Sopenharmony_ci    Py_ssize_t nargs;
7777db96d56Sopenharmony_ci    PyObject *result;
7787db96d56Sopenharmony_ci    Py_ssize_t i;
7797db96d56Sopenharmony_ci    va_list countva;
7807db96d56Sopenharmony_ci
7817db96d56Sopenharmony_ci    if (callable == NULL) {
7827db96d56Sopenharmony_ci        return null_error(tstate);
7837db96d56Sopenharmony_ci    }
7847db96d56Sopenharmony_ci
7857db96d56Sopenharmony_ci    /* Count the number of arguments */
7867db96d56Sopenharmony_ci    va_copy(countva, vargs);
7877db96d56Sopenharmony_ci    nargs = base ? 1 : 0;
7887db96d56Sopenharmony_ci    while (1) {
7897db96d56Sopenharmony_ci        PyObject *arg = va_arg(countva, PyObject *);
7907db96d56Sopenharmony_ci        if (arg == NULL) {
7917db96d56Sopenharmony_ci            break;
7927db96d56Sopenharmony_ci        }
7937db96d56Sopenharmony_ci        nargs++;
7947db96d56Sopenharmony_ci    }
7957db96d56Sopenharmony_ci    va_end(countva);
7967db96d56Sopenharmony_ci
7977db96d56Sopenharmony_ci    /* Copy arguments */
7987db96d56Sopenharmony_ci    if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
7997db96d56Sopenharmony_ci        stack = small_stack;
8007db96d56Sopenharmony_ci    }
8017db96d56Sopenharmony_ci    else {
8027db96d56Sopenharmony_ci        stack = PyMem_Malloc(nargs * sizeof(stack[0]));
8037db96d56Sopenharmony_ci        if (stack == NULL) {
8047db96d56Sopenharmony_ci            PyErr_NoMemory();
8057db96d56Sopenharmony_ci            return NULL;
8067db96d56Sopenharmony_ci        }
8077db96d56Sopenharmony_ci    }
8087db96d56Sopenharmony_ci
8097db96d56Sopenharmony_ci    i = 0;
8107db96d56Sopenharmony_ci    if (base) {
8117db96d56Sopenharmony_ci        stack[i++] = base;
8127db96d56Sopenharmony_ci    }
8137db96d56Sopenharmony_ci
8147db96d56Sopenharmony_ci    for (; i < nargs; ++i) {
8157db96d56Sopenharmony_ci        stack[i] = va_arg(vargs, PyObject *);
8167db96d56Sopenharmony_ci    }
8177db96d56Sopenharmony_ci
8187db96d56Sopenharmony_ci    /* Call the function */
8197db96d56Sopenharmony_ci    result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL);
8207db96d56Sopenharmony_ci
8217db96d56Sopenharmony_ci    if (stack != small_stack) {
8227db96d56Sopenharmony_ci        PyMem_Free(stack);
8237db96d56Sopenharmony_ci    }
8247db96d56Sopenharmony_ci    return result;
8257db96d56Sopenharmony_ci}
8267db96d56Sopenharmony_ci
8277db96d56Sopenharmony_ci
8287db96d56Sopenharmony_ciPyObject *
8297db96d56Sopenharmony_ciPyObject_VectorcallMethod(PyObject *name, PyObject *const *args,
8307db96d56Sopenharmony_ci                           size_t nargsf, PyObject *kwnames)
8317db96d56Sopenharmony_ci{
8327db96d56Sopenharmony_ci    assert(name != NULL);
8337db96d56Sopenharmony_ci    assert(args != NULL);
8347db96d56Sopenharmony_ci    assert(PyVectorcall_NARGS(nargsf) >= 1);
8357db96d56Sopenharmony_ci
8367db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
8377db96d56Sopenharmony_ci    PyObject *callable = NULL;
8387db96d56Sopenharmony_ci    /* Use args[0] as "self" argument */
8397db96d56Sopenharmony_ci    int unbound = _PyObject_GetMethod(args[0], name, &callable);
8407db96d56Sopenharmony_ci    if (callable == NULL) {
8417db96d56Sopenharmony_ci        return NULL;
8427db96d56Sopenharmony_ci    }
8437db96d56Sopenharmony_ci
8447db96d56Sopenharmony_ci    if (unbound) {
8457db96d56Sopenharmony_ci        /* We must remove PY_VECTORCALL_ARGUMENTS_OFFSET since
8467db96d56Sopenharmony_ci         * that would be interpreted as allowing to change args[-1] */
8477db96d56Sopenharmony_ci        nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET;
8487db96d56Sopenharmony_ci    }
8497db96d56Sopenharmony_ci    else {
8507db96d56Sopenharmony_ci        /* Skip "self". We can keep PY_VECTORCALL_ARGUMENTS_OFFSET since
8517db96d56Sopenharmony_ci         * args[-1] in the onward call is args[0] here. */
8527db96d56Sopenharmony_ci        args++;
8537db96d56Sopenharmony_ci        nargsf--;
8547db96d56Sopenharmony_ci    }
8557db96d56Sopenharmony_ci    PyObject *result = _PyObject_VectorcallTstate(tstate, callable,
8567db96d56Sopenharmony_ci                                                  args, nargsf, kwnames);
8577db96d56Sopenharmony_ci    Py_DECREF(callable);
8587db96d56Sopenharmony_ci    return result;
8597db96d56Sopenharmony_ci}
8607db96d56Sopenharmony_ci
8617db96d56Sopenharmony_ci
8627db96d56Sopenharmony_ciPyObject *
8637db96d56Sopenharmony_ciPyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...)
8647db96d56Sopenharmony_ci{
8657db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
8667db96d56Sopenharmony_ci    if (obj == NULL || name == NULL) {
8677db96d56Sopenharmony_ci        return null_error(tstate);
8687db96d56Sopenharmony_ci    }
8697db96d56Sopenharmony_ci
8707db96d56Sopenharmony_ci    PyObject *callable = NULL;
8717db96d56Sopenharmony_ci    int is_method = _PyObject_GetMethod(obj, name, &callable);
8727db96d56Sopenharmony_ci    if (callable == NULL) {
8737db96d56Sopenharmony_ci        return NULL;
8747db96d56Sopenharmony_ci    }
8757db96d56Sopenharmony_ci    obj = is_method ? obj : NULL;
8767db96d56Sopenharmony_ci
8777db96d56Sopenharmony_ci    va_list vargs;
8787db96d56Sopenharmony_ci    va_start(vargs, name);
8797db96d56Sopenharmony_ci    PyObject *result = object_vacall(tstate, obj, callable, vargs);
8807db96d56Sopenharmony_ci    va_end(vargs);
8817db96d56Sopenharmony_ci
8827db96d56Sopenharmony_ci    Py_DECREF(callable);
8837db96d56Sopenharmony_ci    return result;
8847db96d56Sopenharmony_ci}
8857db96d56Sopenharmony_ci
8867db96d56Sopenharmony_ci
8877db96d56Sopenharmony_ciPyObject *
8887db96d56Sopenharmony_ci_PyObject_CallMethodIdObjArgs(PyObject *obj, _Py_Identifier *name, ...)
8897db96d56Sopenharmony_ci{
8907db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
8917db96d56Sopenharmony_ci    if (obj == NULL || name == NULL) {
8927db96d56Sopenharmony_ci        return null_error(tstate);
8937db96d56Sopenharmony_ci    }
8947db96d56Sopenharmony_ci
8957db96d56Sopenharmony_ci    PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
8967db96d56Sopenharmony_ci    if (!oname) {
8977db96d56Sopenharmony_ci        return NULL;
8987db96d56Sopenharmony_ci    }
8997db96d56Sopenharmony_ci
9007db96d56Sopenharmony_ci    PyObject *callable = NULL;
9017db96d56Sopenharmony_ci    int is_method = _PyObject_GetMethod(obj, oname, &callable);
9027db96d56Sopenharmony_ci    if (callable == NULL) {
9037db96d56Sopenharmony_ci        return NULL;
9047db96d56Sopenharmony_ci    }
9057db96d56Sopenharmony_ci    obj = is_method ? obj : NULL;
9067db96d56Sopenharmony_ci
9077db96d56Sopenharmony_ci    va_list vargs;
9087db96d56Sopenharmony_ci    va_start(vargs, name);
9097db96d56Sopenharmony_ci    PyObject *result = object_vacall(tstate, obj, callable, vargs);
9107db96d56Sopenharmony_ci    va_end(vargs);
9117db96d56Sopenharmony_ci
9127db96d56Sopenharmony_ci    Py_DECREF(callable);
9137db96d56Sopenharmony_ci    return result;
9147db96d56Sopenharmony_ci}
9157db96d56Sopenharmony_ci
9167db96d56Sopenharmony_ci
9177db96d56Sopenharmony_ciPyObject *
9187db96d56Sopenharmony_ciPyObject_CallFunctionObjArgs(PyObject *callable, ...)
9197db96d56Sopenharmony_ci{
9207db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
9217db96d56Sopenharmony_ci    va_list vargs;
9227db96d56Sopenharmony_ci    PyObject *result;
9237db96d56Sopenharmony_ci
9247db96d56Sopenharmony_ci    va_start(vargs, callable);
9257db96d56Sopenharmony_ci    result = object_vacall(tstate, NULL, callable, vargs);
9267db96d56Sopenharmony_ci    va_end(vargs);
9277db96d56Sopenharmony_ci
9287db96d56Sopenharmony_ci    return result;
9297db96d56Sopenharmony_ci}
9307db96d56Sopenharmony_ci
9317db96d56Sopenharmony_ci
9327db96d56Sopenharmony_ci/* --- PyStack functions ------------------------------------------ */
9337db96d56Sopenharmony_ci
9347db96d56Sopenharmony_ciPyObject *
9357db96d56Sopenharmony_ci_PyStack_AsDict(PyObject *const *values, PyObject *kwnames)
9367db96d56Sopenharmony_ci{
9377db96d56Sopenharmony_ci    Py_ssize_t nkwargs;
9387db96d56Sopenharmony_ci
9397db96d56Sopenharmony_ci    assert(kwnames != NULL);
9407db96d56Sopenharmony_ci    nkwargs = PyTuple_GET_SIZE(kwnames);
9417db96d56Sopenharmony_ci    return _PyDict_FromItems(&PyTuple_GET_ITEM(kwnames, 0), 1,
9427db96d56Sopenharmony_ci                             values, 1, nkwargs);
9437db96d56Sopenharmony_ci}
9447db96d56Sopenharmony_ci
9457db96d56Sopenharmony_ci
9467db96d56Sopenharmony_ci/* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple).
9477db96d56Sopenharmony_ci
9487db96d56Sopenharmony_ci   Allocate a new argument vector and keyword names tuple. Return the argument
9497db96d56Sopenharmony_ci   vector; return NULL with exception set on error. Return the keyword names
9507db96d56Sopenharmony_ci   tuple in *p_kwnames.
9517db96d56Sopenharmony_ci
9527db96d56Sopenharmony_ci   This also checks that all keyword names are strings. If not, a TypeError is
9537db96d56Sopenharmony_ci   raised.
9547db96d56Sopenharmony_ci
9557db96d56Sopenharmony_ci   The newly allocated argument vector supports PY_VECTORCALL_ARGUMENTS_OFFSET.
9567db96d56Sopenharmony_ci
9577db96d56Sopenharmony_ci   When done, you must call _PyStack_UnpackDict_Free(stack, nargs, kwnames) */
9587db96d56Sopenharmony_cistatic PyObject *const *
9597db96d56Sopenharmony_ci_PyStack_UnpackDict(PyThreadState *tstate,
9607db96d56Sopenharmony_ci                    PyObject *const *args, Py_ssize_t nargs,
9617db96d56Sopenharmony_ci                    PyObject *kwargs, PyObject **p_kwnames)
9627db96d56Sopenharmony_ci{
9637db96d56Sopenharmony_ci    assert(nargs >= 0);
9647db96d56Sopenharmony_ci    assert(kwargs != NULL);
9657db96d56Sopenharmony_ci    assert(PyDict_Check(kwargs));
9667db96d56Sopenharmony_ci
9677db96d56Sopenharmony_ci    Py_ssize_t nkwargs = PyDict_GET_SIZE(kwargs);
9687db96d56Sopenharmony_ci    /* Check for overflow in the PyMem_Malloc() call below. The subtraction
9697db96d56Sopenharmony_ci     * in this check cannot overflow: both maxnargs and nkwargs are
9707db96d56Sopenharmony_ci     * non-negative signed integers, so their difference fits in the type. */
9717db96d56Sopenharmony_ci    Py_ssize_t maxnargs = PY_SSIZE_T_MAX / sizeof(args[0]) - 1;
9727db96d56Sopenharmony_ci    if (nargs > maxnargs - nkwargs) {
9737db96d56Sopenharmony_ci        _PyErr_NoMemory(tstate);
9747db96d56Sopenharmony_ci        return NULL;
9757db96d56Sopenharmony_ci    }
9767db96d56Sopenharmony_ci
9777db96d56Sopenharmony_ci    /* Add 1 to support PY_VECTORCALL_ARGUMENTS_OFFSET */
9787db96d56Sopenharmony_ci    PyObject **stack = PyMem_Malloc((1 + nargs + nkwargs) * sizeof(args[0]));
9797db96d56Sopenharmony_ci    if (stack == NULL) {
9807db96d56Sopenharmony_ci        _PyErr_NoMemory(tstate);
9817db96d56Sopenharmony_ci        return NULL;
9827db96d56Sopenharmony_ci    }
9837db96d56Sopenharmony_ci
9847db96d56Sopenharmony_ci    PyObject *kwnames = PyTuple_New(nkwargs);
9857db96d56Sopenharmony_ci    if (kwnames == NULL) {
9867db96d56Sopenharmony_ci        PyMem_Free(stack);
9877db96d56Sopenharmony_ci        return NULL;
9887db96d56Sopenharmony_ci    }
9897db96d56Sopenharmony_ci
9907db96d56Sopenharmony_ci    stack++;  /* For PY_VECTORCALL_ARGUMENTS_OFFSET */
9917db96d56Sopenharmony_ci
9927db96d56Sopenharmony_ci    /* Copy positional arguments */
9937db96d56Sopenharmony_ci    for (Py_ssize_t i = 0; i < nargs; i++) {
9947db96d56Sopenharmony_ci        Py_INCREF(args[i]);
9957db96d56Sopenharmony_ci        stack[i] = args[i];
9967db96d56Sopenharmony_ci    }
9977db96d56Sopenharmony_ci
9987db96d56Sopenharmony_ci    PyObject **kwstack = stack + nargs;
9997db96d56Sopenharmony_ci    /* This loop doesn't support lookup function mutating the dictionary
10007db96d56Sopenharmony_ci       to change its size. It's a deliberate choice for speed, this function is
10017db96d56Sopenharmony_ci       called in the performance critical hot code. */
10027db96d56Sopenharmony_ci    Py_ssize_t pos = 0, i = 0;
10037db96d56Sopenharmony_ci    PyObject *key, *value;
10047db96d56Sopenharmony_ci    unsigned long keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS;
10057db96d56Sopenharmony_ci    while (PyDict_Next(kwargs, &pos, &key, &value)) {
10067db96d56Sopenharmony_ci        keys_are_strings &= Py_TYPE(key)->tp_flags;
10077db96d56Sopenharmony_ci        Py_INCREF(key);
10087db96d56Sopenharmony_ci        Py_INCREF(value);
10097db96d56Sopenharmony_ci        PyTuple_SET_ITEM(kwnames, i, key);
10107db96d56Sopenharmony_ci        kwstack[i] = value;
10117db96d56Sopenharmony_ci        i++;
10127db96d56Sopenharmony_ci    }
10137db96d56Sopenharmony_ci
10147db96d56Sopenharmony_ci    /* keys_are_strings has the value Py_TPFLAGS_UNICODE_SUBCLASS if that
10157db96d56Sopenharmony_ci     * flag is set for all keys. Otherwise, keys_are_strings equals 0.
10167db96d56Sopenharmony_ci     * We do this check once at the end instead of inside the loop above
10177db96d56Sopenharmony_ci     * because it simplifies the deallocation in the failing case.
10187db96d56Sopenharmony_ci     * It happens to also make the loop above slightly more efficient. */
10197db96d56Sopenharmony_ci    if (!keys_are_strings) {
10207db96d56Sopenharmony_ci        _PyErr_SetString(tstate, PyExc_TypeError,
10217db96d56Sopenharmony_ci                         "keywords must be strings");
10227db96d56Sopenharmony_ci        _PyStack_UnpackDict_Free(stack, nargs, kwnames);
10237db96d56Sopenharmony_ci        return NULL;
10247db96d56Sopenharmony_ci    }
10257db96d56Sopenharmony_ci
10267db96d56Sopenharmony_ci    *p_kwnames = kwnames;
10277db96d56Sopenharmony_ci    return stack;
10287db96d56Sopenharmony_ci}
10297db96d56Sopenharmony_ci
10307db96d56Sopenharmony_cistatic void
10317db96d56Sopenharmony_ci_PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs,
10327db96d56Sopenharmony_ci                         PyObject *kwnames)
10337db96d56Sopenharmony_ci{
10347db96d56Sopenharmony_ci    Py_ssize_t n = PyTuple_GET_SIZE(kwnames) + nargs;
10357db96d56Sopenharmony_ci    for (Py_ssize_t i = 0; i < n; i++) {
10367db96d56Sopenharmony_ci        Py_DECREF(stack[i]);
10377db96d56Sopenharmony_ci    }
10387db96d56Sopenharmony_ci    PyMem_Free((PyObject **)stack - 1);
10397db96d56Sopenharmony_ci    Py_DECREF(kwnames);
10407db96d56Sopenharmony_ci}
1041