Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-19 09:50:45

0001 #ifndef Py_INTERNAL_CALL_H
0002 #define Py_INTERNAL_CALL_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006 
0007 #ifndef Py_BUILD_CORE
0008 #  error "this header requires Py_BUILD_CORE define"
0009 #endif
0010 
0011 #include "pycore_identifier.h"    // _Py_Identifier
0012 #include "pycore_pystate.h"       // _PyThreadState_GET()
0013 
0014 /* Suggested size (number of positional arguments) for arrays of PyObject*
0015    allocated on a C stack to avoid allocating memory on the heap memory. Such
0016    array is used to pass positional arguments to call functions of the
0017    PyObject_Vectorcall() family.
0018 
0019    The size is chosen to not abuse the C stack and so limit the risk of stack
0020    overflow. The size is also chosen to allow using the small stack for most
0021    function calls of the Python standard library. On 64-bit CPU, it allocates
0022    40 bytes on the stack. */
0023 #define _PY_FASTCALL_SMALL_STACK 5
0024 
0025 
0026 // Export for 'math' shared extension, used via _PyObject_VectorcallTstate()
0027 // static inline function.
0028 PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult(
0029     PyThreadState *tstate,
0030     PyObject *callable,
0031     PyObject *result,
0032     const char *where);
0033 
0034 extern PyObject* _PyObject_Call_Prepend(
0035     PyThreadState *tstate,
0036     PyObject *callable,
0037     PyObject *obj,
0038     PyObject *args,
0039     PyObject *kwargs);
0040 
0041 extern PyObject* _PyObject_VectorcallDictTstate(
0042     PyThreadState *tstate,
0043     PyObject *callable,
0044     PyObject *const *args,
0045     size_t nargsf,
0046     PyObject *kwargs);
0047 
0048 extern PyObject* _PyObject_Call(
0049     PyThreadState *tstate,
0050     PyObject *callable,
0051     PyObject *args,
0052     PyObject *kwargs);
0053 
0054 extern PyObject * _PyObject_CallMethodFormat(
0055     PyThreadState *tstate,
0056     PyObject *callable,
0057     const char *format,
0058     ...);
0059 
0060 // Export for 'array' shared extension
0061 PyAPI_FUNC(PyObject*) _PyObject_CallMethod(
0062     PyObject *obj,
0063     PyObject *name,
0064     const char *format, ...);
0065 
0066 extern PyObject* _PyObject_CallMethodIdObjArgs(
0067     PyObject *obj,
0068     _Py_Identifier *name,
0069     ...);
0070 
0071 static inline PyObject *
0072 _PyObject_VectorcallMethodId(
0073     _Py_Identifier *name, PyObject *const *args,
0074     size_t nargsf, PyObject *kwnames)
0075 {
0076     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
0077     if (!oname) {
0078         return _Py_NULL;
0079     }
0080     return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
0081 }
0082 
0083 static inline PyObject *
0084 _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
0085 {
0086     size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
0087     return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
0088 }
0089 
0090 static inline PyObject *
0091 _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
0092 {
0093     PyObject *args[2] = {self, arg};
0094     size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
0095     assert(arg != NULL);
0096     return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
0097 }
0098 
0099 
0100 /* === Vectorcall protocol (PEP 590) ============================= */
0101 
0102 // Call callable using tp_call. Arguments are like PyObject_Vectorcall(),
0103 // except that nargs is plainly the number of arguments without flags.
0104 //
0105 // Export for 'math' shared extension, used via _PyObject_VectorcallTstate()
0106 // static inline function.
0107 PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall(
0108     PyThreadState *tstate,
0109     PyObject *callable,
0110     PyObject *const *args, Py_ssize_t nargs,
0111     PyObject *keywords);
0112 
0113 // Static inline variant of public PyVectorcall_Function().
0114 static inline vectorcallfunc
0115 _PyVectorcall_FunctionInline(PyObject *callable)
0116 {
0117     assert(callable != NULL);
0118 
0119     PyTypeObject *tp = Py_TYPE(callable);
0120     if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) {
0121         return NULL;
0122     }
0123     assert(PyCallable_Check(callable));
0124 
0125     Py_ssize_t offset = tp->tp_vectorcall_offset;
0126     assert(offset > 0);
0127 
0128     vectorcallfunc ptr;
0129     memcpy(&ptr, (char *) callable + offset, sizeof(ptr));
0130     return ptr;
0131 }
0132 
0133 
0134 /* Call the callable object 'callable' with the "vectorcall" calling
0135    convention.
0136 
0137    args is a C array for positional arguments.
0138 
0139    nargsf is the number of positional arguments plus optionally the flag
0140    PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to
0141    modify args[-1].
0142 
0143    kwnames is a tuple of keyword names. The values of the keyword arguments
0144    are stored in "args" after the positional arguments (note that the number
0145    of keyword arguments does not change nargsf). kwnames can also be NULL if
0146    there are no keyword arguments.
0147 
0148    keywords must only contain strings and all keys must be unique.
0149 
0150    Return the result on success. Raise an exception and return NULL on
0151    error. */
0152 static inline PyObject *
0153 _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable,
0154                            PyObject *const *args, size_t nargsf,
0155                            PyObject *kwnames)
0156 {
0157     vectorcallfunc func;
0158     PyObject *res;
0159 
0160     assert(kwnames == NULL || PyTuple_Check(kwnames));
0161     assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0);
0162 
0163     func = _PyVectorcall_FunctionInline(callable);
0164     if (func == NULL) {
0165         Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
0166         return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
0167     }
0168     res = func(callable, args, nargsf, kwnames);
0169     return _Py_CheckFunctionResult(tstate, callable, res, NULL);
0170 }
0171 
0172 
0173 static inline PyObject *
0174 _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) {
0175     return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
0176 }
0177 
0178 
0179 // Private static inline function variant of public PyObject_CallNoArgs()
0180 static inline PyObject *
0181 _PyObject_CallNoArgs(PyObject *func) {
0182     EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
0183     PyThreadState *tstate = _PyThreadState_GET();
0184     return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
0185 }
0186 
0187 
0188 extern PyObject *const *
0189 _PyStack_UnpackDict(PyThreadState *tstate,
0190     PyObject *const *args, Py_ssize_t nargs,
0191     PyObject *kwargs, PyObject **p_kwnames);
0192 
0193 extern void _PyStack_UnpackDict_Free(
0194     PyObject *const *stack,
0195     Py_ssize_t nargs,
0196     PyObject *kwnames);
0197 
0198 extern void _PyStack_UnpackDict_FreeNoDecRef(
0199     PyObject *const *stack,
0200     PyObject *kwnames);
0201 
0202 #ifdef __cplusplus
0203 }
0204 #endif
0205 #endif /* !Py_INTERNAL_CALL_H */