Branch data Line data Source code
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_pystate.h" // _PyThreadState_GET()
12 : :
13 : : PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
14 : : PyThreadState *tstate,
15 : : PyObject *callable,
16 : : PyObject *obj,
17 : : PyObject *args,
18 : : PyObject *kwargs);
19 : :
20 : : PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate(
21 : : PyThreadState *tstate,
22 : : PyObject *callable,
23 : : PyObject *const *args,
24 : : size_t nargsf,
25 : : PyObject *kwargs);
26 : :
27 : : PyAPI_FUNC(PyObject *) _PyObject_Call(
28 : : PyThreadState *tstate,
29 : : PyObject *callable,
30 : : PyObject *args,
31 : : PyObject *kwargs);
32 : :
33 : : extern PyObject * _PyObject_CallMethodFormat(
34 : : PyThreadState *tstate, PyObject *callable, const char *format, ...);
35 : :
36 : :
37 : : // Static inline variant of public PyVectorcall_Function().
38 : : static inline vectorcallfunc
39 : 277258771 : _PyVectorcall_FunctionInline(PyObject *callable)
40 : : {
41 : : assert(callable != NULL);
42 : :
43 : 277258771 : PyTypeObject *tp = Py_TYPE(callable);
44 [ + + ]: 277258771 : if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) {
45 : 24346782 : return NULL;
46 : : }
47 : : assert(PyCallable_Check(callable));
48 : :
49 : 252911989 : Py_ssize_t offset = tp->tp_vectorcall_offset;
50 : : assert(offset > 0);
51 : :
52 : : vectorcallfunc ptr;
53 : 252911989 : memcpy(&ptr, (char *) callable + offset, sizeof(ptr));
54 : 252911989 : 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. */
76 : : static inline PyObject *
77 : 235782532 : _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 : 235782532 : func = _PyVectorcall_FunctionInline(callable);
88 [ + + ]: 235782532 : if (func == NULL) {
89 : 77356241 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
90 : 77356241 : return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
91 : : }
92 : 158426291 : res = func(callable, args, nargsf, kwnames);
93 : 158425979 : return _Py_CheckFunctionResult(tstate, callable, res, NULL);
94 : : }
95 : :
96 : :
97 : : static inline PyObject *
98 : 147282 : _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) {
99 : 147282 : return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
100 : : }
101 : :
102 : :
103 : : // Private static inline function variant of public PyObject_CallNoArgs()
104 : : static inline PyObject *
105 : 10789843 : _PyObject_CallNoArgs(PyObject *func) {
106 : : EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
107 : 10789843 : PyThreadState *tstate = _PyThreadState_GET();
108 : 10789843 : return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
109 : : }
110 : :
111 : :
112 : : static inline PyObject *
113 : 6610311 : _PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs)
114 : : {
115 : : EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
116 : 6610311 : return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL);
117 : : }
118 : :
119 : :
120 : : #ifdef __cplusplus
121 : : }
122 : : #endif
123 : : #endif /* !Py_INTERNAL_CALL_H */
|