1#ifndef Py_INTERNAL_CALL_H 2#define Py_INTERNAL_CALL_H 3#ifdef __cplusplus 4extern "C" { 5#endif 6 7#ifndef Py_BUILD_CORE 8# error "this header requires Py_BUILD_CORE define" 9#endif 10 11#include "pycore_pystate.h" // _PyThreadState_GET() 12 13PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( 14 PyThreadState *tstate, 15 PyObject *callable, 16 PyObject *obj, 17 PyObject *args, 18 PyObject *kwargs); 19 20PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate( 21 PyThreadState *tstate, 22 PyObject *callable, 23 PyObject *const *args, 24 size_t nargsf, 25 PyObject *kwargs); 26 27PyAPI_FUNC(PyObject *) _PyObject_Call( 28 PyThreadState *tstate, 29 PyObject *callable, 30 PyObject *args, 31 PyObject *kwargs); 32 33extern PyObject * _PyObject_CallMethodFormat( 34 PyThreadState *tstate, PyObject *callable, const char *format, ...); 35 36 37// Static inline variant of public PyVectorcall_Function(). 38static inline vectorcallfunc 39_PyVectorcall_FunctionInline(PyObject *callable) 40{ 41 assert(callable != NULL); 42 43 PyTypeObject *tp = Py_TYPE(callable); 44 if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { 45 return NULL; 46 } 47 assert(PyCallable_Check(callable)); 48 49 Py_ssize_t offset = tp->tp_vectorcall_offset; 50 assert(offset > 0); 51 52 vectorcallfunc ptr; 53 memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); 54 return ptr; 55} 56 57 58/* Call the callable object 'callable' with the "vectorcall" calling 59 convention. 60 61 args is a C array for positional arguments. 62 63 nargsf is the number of positional arguments plus optionally the flag 64 PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to 65 modify args[-1]. 66 67 kwnames is a tuple of keyword names. The values of the keyword arguments 68 are stored in "args" after the positional arguments (note that the number 69 of keyword arguments does not change nargsf). kwnames can also be NULL if 70 there are no keyword arguments. 71 72 keywords must only contain strings and all keys must be unique. 73 74 Return the result on success. Raise an exception and return NULL on 75 error. */ 76static inline PyObject * 77_PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, 78 PyObject *const *args, size_t nargsf, 79 PyObject *kwnames) 80{ 81 vectorcallfunc func; 82 PyObject *res; 83 84 assert(kwnames == NULL || PyTuple_Check(kwnames)); 85 assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); 86 87 func = _PyVectorcall_FunctionInline(callable); 88 if (func == NULL) { 89 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); 90 return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); 91 } 92 res = func(callable, args, nargsf, kwnames); 93 return _Py_CheckFunctionResult(tstate, callable, res, NULL); 94} 95 96 97static inline PyObject * 98_PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) { 99 return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); 100} 101 102 103// Private static inline function variant of public PyObject_CallNoArgs() 104static inline PyObject * 105_PyObject_CallNoArgs(PyObject *func) { 106 PyThreadState *tstate = _PyThreadState_GET(); 107 return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); 108} 109 110 111static inline PyObject * 112_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs) 113{ 114 return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL); 115} 116 117 118#ifdef __cplusplus 119} 120#endif 121#endif /* !Py_INTERNAL_CALL_H */ 122