Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/python3.14/internal/pycore_call.h
1 #ifndef Py_INTERNAL_CALL_H 2 #define Py_INTERNAL_CALL_H 3 #ifdef __cplusplus 4 extern "C" { 5 #endif 6 7 #ifndef Py_BUILD_CORE 8 # error "this header requires Py_BUILD_CORE define" 9 #endif 10 11 #include "pycore_code.h" // EVAL_CALL_STAT_INC_IF_FUNCTION() 12 #include "pycore_pystate.h" // _PyThreadState_GET() 13 #include "pycore_stats.h" 14 15 /* Suggested size (number of positional arguments) for arrays of PyObject* 16 allocated on a C stack to avoid allocating memory on the heap memory. Such 17 array is used to pass positional arguments to call functions of the 18 PyObject_Vectorcall() family. 19 20 The size is chosen to not abuse the C stack and so limit the risk of stack 21 overflow. The size is also chosen to allow using the small stack for most 22 function calls of the Python standard library. On 64-bit CPU, it allocates 23 40 bytes on the stack. */ 24 #define _PY_FASTCALL_SMALL_STACK 5 25 26 27 // Export for 'math' shared extension, used via _PyObject_VectorcallTstate() 28 // static inline function. 29 PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult( 30 PyThreadState *tstate, 31 PyObject *callable, 32 PyObject *result, 33 const char *where); 34 35 extern PyObject* _PyObject_Call_Prepend( 36 PyThreadState *tstate, 37 PyObject *callable, 38 PyObject *obj, 39 PyObject *args, 40 PyObject *kwargs); 41 42 extern PyObject* _PyObject_VectorcallDictTstate( 43 PyThreadState *tstate, 44 PyObject *callable, 45 PyObject *const *args, 46 size_t nargsf, 47 PyObject *kwargs); 48 49 extern PyObject* _PyObject_Call( 50 PyThreadState *tstate, 51 PyObject *callable, 52 PyObject *args, 53 PyObject *kwargs); 54 55 extern PyObject * _PyObject_CallMethodFormat( 56 PyThreadState *tstate, 57 PyObject *callable, 58 const char *format, 59 ...); 60 61 // Export for 'array' shared extension 62 PyAPI_FUNC(PyObject*) _PyObject_CallMethod( 63 PyObject *obj, 64 PyObject *name, 65 const char *format, ...); 66 67 extern PyObject* _PyObject_CallMethodIdObjArgs( 68 PyObject *obj, 69 _Py_Identifier *name, 70 ...); 71 72 static inline PyObject * 73 _PyObject_VectorcallMethodId( 74 _Py_Identifier *name, PyObject *const *args, 75 size_t nargsf, PyObject *kwnames) 76 { 77 PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ 78 if (!oname) { 79 return _Py_NULL; 80 } 81 return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); 82 } 83 84 static inline PyObject * 85 _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) 86 { 87 size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; 88 return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL); 89 } 90 91 static inline PyObject * 92 _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) 93 { 94 PyObject *args[2] = {self, arg}; 95 size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; 96 assert(arg != NULL); 97 return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL); 98 } 99 100 101 extern PyObject *_PyObject_VectorcallPrepend( 102 PyThreadState *tstate, 103 PyObject *callable, 104 PyObject *arg, 105 PyObject *const *args, 106 size_t nargsf, 107 PyObject *kwnames); 108 109 /* === Vectorcall protocol (PEP 590) ============================= */ 110 111 // Call callable using tp_call. Arguments are like PyObject_Vectorcall(), 112 // except that nargs is plainly the number of arguments without flags. 113 // 114 // Export for 'math' shared extension, used via _PyObject_VectorcallTstate() 115 // static inline function. 116 PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall( 117 PyThreadState *tstate, 118 PyObject *callable, 119 PyObject *const *args, Py_ssize_t nargs, 120 PyObject *keywords); 121 122 // Static inline variant of public PyVectorcall_Function(). 123 static inline vectorcallfunc 124 _PyVectorcall_FunctionInline(PyObject *callable) 125 { 126 assert(callable != NULL); 127 128 PyTypeObject *tp = Py_TYPE(callable); 129 if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { 130 return NULL; 131 } 132 assert(PyCallable_Check(callable)); 133 134 Py_ssize_t offset = tp->tp_vectorcall_offset; 135 assert(offset > 0); 136 137 vectorcallfunc ptr; 138 memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); 139 return ptr; 140 } 141 142 143 /* Call the callable object 'callable' with the "vectorcall" calling 144 convention. 145 146 args is a C array for positional arguments. 147 148 nargsf is the number of positional arguments plus optionally the flag 149 PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to 150 modify args[-1]. 151 152 kwnames is a tuple of keyword names. The values of the keyword arguments 153 are stored in "args" after the positional arguments (note that the number 154 of keyword arguments does not change nargsf). kwnames can also be NULL if 155 there are no keyword arguments. 156 157 keywords must only contain strings and all keys must be unique. 158 159 Return the result on success. Raise an exception and return NULL on 160 error. */ 161 static inline PyObject * 162 _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, 163 PyObject *const *args, size_t nargsf, 164 PyObject *kwnames) 165 { 166 vectorcallfunc func; 167 PyObject *res; 168 169 assert(kwnames == NULL || PyTuple_Check(kwnames)); 170 assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); 171 172 func = _PyVectorcall_FunctionInline(callable); 173 if (func == NULL) { 174 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); 175 return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); 176 } 177 res = func(callable, args, nargsf, kwnames); 178 return _Py_CheckFunctionResult(tstate, callable, res, NULL); 179 } 180 181 182 static inline PyObject * 183 _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) { 184 return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); 185 } 186 187 188 // Private static inline function variant of public PyObject_CallNoArgs() 189 static inline PyObject * 190 _PyObject_CallNoArgs(PyObject *func) { 191 EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); 192 PyThreadState *tstate = _PyThreadState_GET(); 193 return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); 194 } 195 196 197 extern PyObject *const * 198 _PyStack_UnpackDict(PyThreadState *tstate, 199 PyObject *const *args, Py_ssize_t nargs, 200 PyObject *kwargs, PyObject **p_kwnames); 201 202 extern void _PyStack_UnpackDict_Free( 203 PyObject *const *stack, 204 Py_ssize_t nargs, 205 PyObject *kwnames); 206 207 extern void _PyStack_UnpackDict_FreeNoDecRef( 208 PyObject *const *stack, 209 PyObject *kwnames); 210 211 #ifdef __cplusplus 212 } 213 #endif 214 #endif /* !Py_INTERNAL_CALL_H */