/src/cpython/Objects/methodobject.c
Line | Count | Source |
1 | | |
2 | | /* Method object implementation */ |
3 | | |
4 | | #include "Python.h" |
5 | | #include "pycore_call.h" // _Py_CheckFunctionResult() |
6 | | #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() |
7 | | #include "pycore_freelist.h" |
8 | | #include "pycore_object.h" |
9 | | #include "pycore_pyerrors.h" |
10 | | #include "pycore_pystate.h" // _PyThreadState_GET() |
11 | | #include "pycore_weakref.h" // FT_CLEAR_WEAKREFS() |
12 | | |
13 | | |
14 | | /* undefine macro trampoline to PyCFunction_NewEx */ |
15 | | #undef PyCFunction_New |
16 | | /* undefine macro trampoline to PyCMethod_New */ |
17 | | #undef PyCFunction_NewEx |
18 | | |
19 | | /* Forward declarations */ |
20 | | static PyObject * cfunction_vectorcall_FASTCALL( |
21 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); |
22 | | static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS( |
23 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); |
24 | | static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD( |
25 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); |
26 | | static PyObject * cfunction_vectorcall_NOARGS( |
27 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); |
28 | | static PyObject * cfunction_vectorcall_O( |
29 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); |
30 | | static PyObject * cfunction_call( |
31 | | PyObject *func, PyObject *args, PyObject *kwargs); |
32 | | |
33 | | |
34 | | PyObject * |
35 | | PyCFunction_New(PyMethodDef *ml, PyObject *self) |
36 | 0 | { |
37 | 0 | return PyCFunction_NewEx(ml, self, NULL); |
38 | 0 | } |
39 | | |
40 | | PyObject * |
41 | | PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) |
42 | 0 | { |
43 | 0 | return PyCMethod_New(ml, self, module, NULL); |
44 | 0 | } |
45 | | |
46 | | PyObject * |
47 | | PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *cls) |
48 | 166M | { |
49 | | /* Figure out correct vectorcall function to use */ |
50 | 166M | vectorcallfunc vectorcall; |
51 | 166M | switch (ml->ml_flags & _Py_METH_CALL_FLAGS) |
52 | 166M | { |
53 | 123 | case METH_VARARGS: |
54 | 1.09k | case METH_VARARGS | METH_KEYWORDS: |
55 | | /* For METH_VARARGS functions, it's more efficient to use tp_call |
56 | | * instead of vectorcall. */ |
57 | 1.09k | vectorcall = NULL; |
58 | 1.09k | break; |
59 | 51.5M | case METH_FASTCALL: |
60 | 51.5M | vectorcall = cfunction_vectorcall_FASTCALL; |
61 | 51.5M | break; |
62 | 24.6M | case METH_FASTCALL | METH_KEYWORDS: |
63 | 24.6M | vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS; |
64 | 24.6M | break; |
65 | 44.8M | case METH_NOARGS: |
66 | 44.8M | vectorcall = cfunction_vectorcall_NOARGS; |
67 | 44.8M | break; |
68 | 34.8M | case METH_O: |
69 | 34.8M | vectorcall = cfunction_vectorcall_O; |
70 | 34.8M | break; |
71 | 10.4M | case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: |
72 | 10.4M | vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD; |
73 | 10.4M | break; |
74 | 0 | default: |
75 | 0 | PyErr_Format(PyExc_SystemError, |
76 | 0 | "%s() method: bad call flags", ml->ml_name); |
77 | 0 | return NULL; |
78 | 166M | } |
79 | | |
80 | 166M | PyCFunctionObject *op = NULL; |
81 | | |
82 | 166M | if (ml->ml_flags & METH_METHOD) { |
83 | 10.4M | if (!cls) { |
84 | 0 | PyErr_SetString(PyExc_SystemError, |
85 | 0 | "attempting to create PyCMethod with a METH_METHOD " |
86 | 0 | "flag but no class"); |
87 | 0 | return NULL; |
88 | 0 | } |
89 | 10.4M | PyCMethodObject *om = _Py_FREELIST_POP(PyCMethodObject, pycmethodobject); |
90 | 10.4M | if (om == NULL) { |
91 | 367 | om = PyObject_GC_New(PyCMethodObject, &PyCMethod_Type); |
92 | 367 | if (om == NULL) { |
93 | 0 | return NULL; |
94 | 0 | } |
95 | 367 | } |
96 | 10.4M | om->mm_class = (PyTypeObject*)Py_NewRef(cls); |
97 | 10.4M | op = (PyCFunctionObject *)om; |
98 | 155M | } else { |
99 | 155M | if (cls) { |
100 | 0 | PyErr_SetString(PyExc_SystemError, |
101 | 0 | "attempting to create PyCFunction with class " |
102 | 0 | "but no METH_METHOD flag"); |
103 | 0 | return NULL; |
104 | 0 | } |
105 | 155M | op = _Py_FREELIST_POP(PyCFunctionObject, pycfunctionobject); |
106 | 155M | if (op == NULL) { |
107 | 105k | op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type); |
108 | 105k | if (op == NULL) { |
109 | 0 | return NULL; |
110 | 0 | } |
111 | 105k | } |
112 | 155M | } |
113 | | |
114 | 166M | op->m_weakreflist = NULL; |
115 | 166M | op->m_ml = ml; |
116 | 166M | op->m_self = Py_XNewRef(self); |
117 | 166M | op->m_module = Py_XNewRef(module); |
118 | 166M | op->vectorcall = vectorcall; |
119 | 166M | _PyObject_GC_TRACK(op); |
120 | 166M | return (PyObject *)op; |
121 | 166M | } |
122 | | |
123 | | PyCFunction |
124 | | PyCFunction_GetFunction(PyObject *op) |
125 | 3.81k | { |
126 | 3.81k | if (!PyCFunction_Check(op)) { |
127 | 0 | PyErr_BadInternalCall(); |
128 | 0 | return NULL; |
129 | 0 | } |
130 | 3.81k | return PyCFunction_GET_FUNCTION(op); |
131 | 3.81k | } |
132 | | |
133 | | PyObject * |
134 | | PyCFunction_GetSelf(PyObject *op) |
135 | 0 | { |
136 | 0 | if (!PyCFunction_Check(op)) { |
137 | 0 | PyErr_BadInternalCall(); |
138 | 0 | return NULL; |
139 | 0 | } |
140 | 0 | return PyCFunction_GET_SELF(op); |
141 | 0 | } |
142 | | |
143 | | int |
144 | | PyCFunction_GetFlags(PyObject *op) |
145 | 0 | { |
146 | 0 | if (!PyCFunction_Check(op)) { |
147 | 0 | PyErr_BadInternalCall(); |
148 | 0 | return -1; |
149 | 0 | } |
150 | 0 | return PyCFunction_GET_FLAGS(op); |
151 | 0 | } |
152 | | |
153 | | PyTypeObject * |
154 | | PyCMethod_GetClass(PyObject *op) |
155 | 0 | { |
156 | 0 | if (!PyCFunction_Check(op)) { |
157 | 0 | PyErr_BadInternalCall(); |
158 | 0 | return NULL; |
159 | 0 | } |
160 | 0 | return PyCFunction_GET_CLASS(op); |
161 | 0 | } |
162 | | |
163 | | /* Methods (the standard built-in methods, that is) */ |
164 | | |
165 | | static void |
166 | | meth_dealloc(PyObject *self) |
167 | 166M | { |
168 | 166M | PyCFunctionObject *m = _PyCFunctionObject_CAST(self); |
169 | 166M | PyObject_GC_UnTrack(m); |
170 | 166M | FT_CLEAR_WEAKREFS(self, m->m_weakreflist); |
171 | | // We need to access ml_flags here rather than later. |
172 | | // `m->m_ml` might have the same lifetime |
173 | | // as `m_self` when it's dynamically allocated. |
174 | 166M | int ml_flags = m->m_ml->ml_flags; |
175 | | // Dereference class before m_self: PyCFunction_GET_CLASS accesses |
176 | | // PyMethodDef m_ml, which could be kept alive by m_self |
177 | 166M | Py_XDECREF(PyCFunction_GET_CLASS(m)); |
178 | 166M | Py_XDECREF(m->m_self); |
179 | 166M | Py_XDECREF(m->m_module); |
180 | 166M | if (ml_flags & METH_METHOD) { |
181 | 10.4M | assert(Py_IS_TYPE(self, &PyCMethod_Type)); |
182 | 10.4M | _Py_FREELIST_FREE(pycmethodobject, m, PyObject_GC_Del); |
183 | 10.4M | } |
184 | 155M | else { |
185 | 155M | assert(Py_IS_TYPE(self, &PyCFunction_Type)); |
186 | 155M | _Py_FREELIST_FREE(pycfunctionobject, m, PyObject_GC_Del); |
187 | 155M | } |
188 | 166M | } |
189 | | |
190 | | static PyObject * |
191 | | meth_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) |
192 | 0 | { |
193 | 0 | PyCFunctionObject *m = _PyCFunctionObject_CAST(self); |
194 | 0 | if (m->m_self == NULL || PyModule_Check(m->m_self)) |
195 | 0 | return PyUnicode_FromString(m->m_ml->ml_name); |
196 | | |
197 | 0 | return Py_BuildValue("N(Os)", _PyEval_GetBuiltin(&_Py_ID(getattr)), |
198 | 0 | m->m_self, m->m_ml->ml_name); |
199 | 0 | } |
200 | | |
201 | | static PyMethodDef meth_methods[] = { |
202 | | {"__reduce__", meth_reduce, METH_NOARGS, NULL}, |
203 | | {NULL, NULL} |
204 | | }; |
205 | | |
206 | | static PyObject * |
207 | | meth_get__text_signature__(PyObject *self, void *closure) |
208 | 0 | { |
209 | 0 | PyCFunctionObject *m = _PyCFunctionObject_CAST(self); |
210 | 0 | return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, |
211 | 0 | m->m_ml->ml_doc, |
212 | 0 | m->m_ml->ml_flags); |
213 | 0 | } |
214 | | |
215 | | static PyObject * |
216 | | meth_get__doc__(PyObject *self, void *closure) |
217 | 139 | { |
218 | 139 | PyCFunctionObject *m = _PyCFunctionObject_CAST(self); |
219 | 139 | return _PyType_GetDocFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc); |
220 | 139 | } |
221 | | |
222 | | static PyObject * |
223 | | meth_get__name__(PyObject *self, void *closure) |
224 | 263 | { |
225 | 263 | PyCFunctionObject *m = _PyCFunctionObject_CAST(self); |
226 | 263 | return PyUnicode_FromString(m->m_ml->ml_name); |
227 | 263 | } |
228 | | |
229 | | static PyObject * |
230 | | meth_get__qualname__(PyObject *self, void *closure) |
231 | 115 | { |
232 | | /* If __self__ is a module or NULL, return m.__name__ |
233 | | (e.g. len.__qualname__ == 'len') |
234 | | |
235 | | If __self__ is a type, return m.__self__.__qualname__ + '.' + m.__name__ |
236 | | (e.g. dict.fromkeys.__qualname__ == 'dict.fromkeys') |
237 | | |
238 | | Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__ |
239 | | (e.g. [].append.__qualname__ == 'list.append') */ |
240 | | |
241 | 115 | PyCFunctionObject *m = _PyCFunctionObject_CAST(self); |
242 | 115 | if (m->m_self == NULL || PyModule_Check(m->m_self)) { |
243 | 4 | return PyUnicode_FromString(m->m_ml->ml_name); |
244 | 4 | } |
245 | | |
246 | 111 | PyObject *type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self); |
247 | | |
248 | 111 | PyObject *type_qualname = PyObject_GetAttr(type, &_Py_ID(__qualname__)); |
249 | 111 | if (type_qualname == NULL) |
250 | 0 | return NULL; |
251 | | |
252 | 111 | if (!PyUnicode_Check(type_qualname)) { |
253 | 0 | PyErr_SetString(PyExc_TypeError, "<method>.__class__." |
254 | 0 | "__qualname__ is not a unicode object"); |
255 | 0 | Py_XDECREF(type_qualname); |
256 | 0 | return NULL; |
257 | 0 | } |
258 | | |
259 | 111 | PyObject *res = PyUnicode_FromFormat("%S.%s", type_qualname, m->m_ml->ml_name); |
260 | 111 | Py_DECREF(type_qualname); |
261 | 111 | return res; |
262 | 111 | } |
263 | | |
264 | | static int |
265 | | meth_traverse(PyObject *self, visitproc visit, void *arg) |
266 | 1.50M | { |
267 | 1.50M | PyCFunctionObject *m = _PyCFunctionObject_CAST(self); |
268 | 1.50M | Py_VISIT(PyCFunction_GET_CLASS(m)); |
269 | 1.50M | Py_VISIT(m->m_self); |
270 | 1.50M | Py_VISIT(m->m_module); |
271 | 1.50M | return 0; |
272 | 1.50M | } |
273 | | |
274 | | static PyObject * |
275 | | meth_get__self__(PyObject *meth, void *closure) |
276 | 10 | { |
277 | 10 | PyCFunctionObject *m = _PyCFunctionObject_CAST(meth); |
278 | 10 | PyObject *self = PyCFunction_GET_SELF(m); |
279 | 10 | if (self == NULL) { |
280 | 0 | self = Py_None; |
281 | 0 | } |
282 | 10 | return Py_NewRef(self); |
283 | 10 | } |
284 | | |
285 | | static PyGetSetDef meth_getsets[] = { |
286 | | {"__doc__", meth_get__doc__, NULL, NULL}, |
287 | | {"__name__", meth_get__name__, NULL, NULL}, |
288 | | {"__qualname__", meth_get__qualname__, NULL, NULL}, |
289 | | {"__self__", meth_get__self__, NULL, NULL}, |
290 | | {"__text_signature__", meth_get__text_signature__, NULL, NULL}, |
291 | | {0} |
292 | | }; |
293 | | |
294 | | #define OFF(x) offsetof(PyCFunctionObject, x) |
295 | | |
296 | | static PyMemberDef meth_members[] = { |
297 | | {"__module__", _Py_T_OBJECT, OFF(m_module), 0}, |
298 | | {NULL} |
299 | | }; |
300 | | |
301 | | static PyObject * |
302 | | meth_repr(PyObject *self) |
303 | 0 | { |
304 | 0 | PyCFunctionObject *m = _PyCFunctionObject_CAST(self); |
305 | 0 | if (m->m_self == NULL || PyModule_Check(m->m_self)) { |
306 | 0 | return PyUnicode_FromFormat("<built-in function %s>", |
307 | 0 | m->m_ml->ml_name); |
308 | 0 | } |
309 | | |
310 | 0 | return PyUnicode_FromFormat("<built-in method %s of %s object at %p>", |
311 | 0 | m->m_ml->ml_name, |
312 | 0 | Py_TYPE(m->m_self)->tp_name, |
313 | 0 | m->m_self); |
314 | 0 | } |
315 | | |
316 | | static PyObject * |
317 | | meth_richcompare(PyObject *self, PyObject *other, int op) |
318 | 42.6k | { |
319 | 42.6k | PyCFunctionObject *a, *b; |
320 | 42.6k | PyObject *res; |
321 | 42.6k | int eq; |
322 | | |
323 | 42.6k | if ((op != Py_EQ && op != Py_NE) || |
324 | 42.6k | !PyCFunction_Check(self) || |
325 | 42.6k | !PyCFunction_Check(other)) |
326 | 42.5k | { |
327 | 42.5k | Py_RETURN_NOTIMPLEMENTED; |
328 | 42.5k | } |
329 | 81 | a = (PyCFunctionObject *)self; |
330 | 81 | b = (PyCFunctionObject *)other; |
331 | 81 | eq = a->m_self == b->m_self; |
332 | 81 | if (eq) |
333 | 0 | eq = a->m_ml->ml_meth == b->m_ml->ml_meth; |
334 | 81 | if (op == Py_EQ) |
335 | 81 | res = eq ? Py_True : Py_False; |
336 | 0 | else |
337 | 0 | res = eq ? Py_False : Py_True; |
338 | 81 | return Py_NewRef(res); |
339 | 42.6k | } |
340 | | |
341 | | static Py_hash_t |
342 | | meth_hash(PyObject *self) |
343 | 3.28k | { |
344 | 3.28k | PyCFunctionObject *a = _PyCFunctionObject_CAST(self); |
345 | 3.28k | Py_hash_t x = PyObject_GenericHash(a->m_self); |
346 | 3.28k | Py_hash_t y = Py_HashPointer((void*)(a->m_ml->ml_meth)); |
347 | 3.28k | x ^= y; |
348 | 3.28k | if (x == -1) { |
349 | 0 | x = -2; |
350 | 0 | } |
351 | 3.28k | return x; |
352 | 3.28k | } |
353 | | |
354 | | |
355 | | PyTypeObject PyCFunction_Type = { |
356 | | PyVarObject_HEAD_INIT(&PyType_Type, 0) |
357 | | "builtin_function_or_method", |
358 | | sizeof(PyCFunctionObject), |
359 | | 0, |
360 | | meth_dealloc, /* tp_dealloc */ |
361 | | offsetof(PyCFunctionObject, vectorcall), /* tp_vectorcall_offset */ |
362 | | 0, /* tp_getattr */ |
363 | | 0, /* tp_setattr */ |
364 | | 0, /* tp_as_async */ |
365 | | meth_repr, /* tp_repr */ |
366 | | 0, /* tp_as_number */ |
367 | | 0, /* tp_as_sequence */ |
368 | | 0, /* tp_as_mapping */ |
369 | | meth_hash, /* tp_hash */ |
370 | | cfunction_call, /* tp_call */ |
371 | | 0, /* tp_str */ |
372 | | PyObject_GenericGetAttr, /* tp_getattro */ |
373 | | 0, /* tp_setattro */ |
374 | | 0, /* tp_as_buffer */ |
375 | | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | |
376 | | Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ |
377 | | 0, /* tp_doc */ |
378 | | meth_traverse, /* tp_traverse */ |
379 | | 0, /* tp_clear */ |
380 | | meth_richcompare, /* tp_richcompare */ |
381 | | offsetof(PyCFunctionObject, m_weakreflist), /* tp_weaklistoffset */ |
382 | | 0, /* tp_iter */ |
383 | | 0, /* tp_iternext */ |
384 | | meth_methods, /* tp_methods */ |
385 | | meth_members, /* tp_members */ |
386 | | meth_getsets, /* tp_getset */ |
387 | | 0, /* tp_base */ |
388 | | 0, /* tp_dict */ |
389 | | }; |
390 | | |
391 | | PyTypeObject PyCMethod_Type = { |
392 | | PyVarObject_HEAD_INIT(&PyType_Type, 0) |
393 | | .tp_name = "builtin_method", |
394 | | .tp_basicsize = sizeof(PyCMethodObject), |
395 | | .tp_base = &PyCFunction_Type, |
396 | | }; |
397 | | |
398 | | /* Vectorcall functions for each of the PyCFunction calling conventions, |
399 | | * except for METH_VARARGS (possibly combined with METH_KEYWORDS) which |
400 | | * doesn't use vectorcall. |
401 | | * |
402 | | * First, common helpers |
403 | | */ |
404 | | |
405 | | static inline int |
406 | | cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames) |
407 | 122M | { |
408 | 122M | assert(!_PyErr_Occurred(tstate)); |
409 | 122M | assert(PyCFunction_Check(func)); |
410 | 122M | if (kwnames && PyTuple_GET_SIZE(kwnames)) { |
411 | 0 | PyObject *funcstr = _PyObject_FunctionStr(func); |
412 | 0 | if (funcstr != NULL) { |
413 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
414 | 0 | "%U takes no keyword arguments", funcstr); |
415 | 0 | Py_DECREF(funcstr); |
416 | 0 | } |
417 | 0 | return -1; |
418 | 0 | } |
419 | 122M | return 0; |
420 | 122M | } |
421 | | |
422 | | typedef void (*funcptr)(void); |
423 | | |
424 | | static inline funcptr |
425 | | cfunction_enter_call(PyThreadState *tstate, PyObject *func) |
426 | 154M | { |
427 | 154M | if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { |
428 | 0 | return NULL; |
429 | 0 | } |
430 | 154M | return (funcptr)PyCFunction_GET_FUNCTION(func); |
431 | 154M | } |
432 | | |
433 | | /* Now the actual vectorcall functions */ |
434 | | static PyObject * |
435 | | cfunction_vectorcall_FASTCALL( |
436 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) |
437 | 821k | { |
438 | 821k | PyThreadState *tstate = _PyThreadState_GET(); |
439 | 821k | if (cfunction_check_kwargs(tstate, func, kwnames)) { |
440 | 0 | return NULL; |
441 | 0 | } |
442 | 821k | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
443 | 821k | PyCFunctionFast meth = (PyCFunctionFast) |
444 | 821k | cfunction_enter_call(tstate, func); |
445 | 821k | if (meth == NULL) { |
446 | 0 | return NULL; |
447 | 0 | } |
448 | 821k | PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs); |
449 | 821k | _Py_LeaveRecursiveCallTstate(tstate); |
450 | 821k | return result; |
451 | 821k | } |
452 | | |
453 | | static PyObject * |
454 | | cfunction_vectorcall_FASTCALL_KEYWORDS( |
455 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) |
456 | 6.22M | { |
457 | 6.22M | PyThreadState *tstate = _PyThreadState_GET(); |
458 | 6.22M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
459 | 6.22M | PyCFunctionFastWithKeywords meth = (PyCFunctionFastWithKeywords) |
460 | 6.22M | cfunction_enter_call(tstate, func); |
461 | 6.22M | if (meth == NULL) { |
462 | 0 | return NULL; |
463 | 0 | } |
464 | 6.22M | PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames); |
465 | 6.22M | _Py_LeaveRecursiveCallTstate(tstate); |
466 | 6.22M | return result; |
467 | 6.22M | } |
468 | | |
469 | | static PyObject * |
470 | | cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD( |
471 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) |
472 | 25.7M | { |
473 | 25.7M | PyThreadState *tstate = _PyThreadState_GET(); |
474 | 25.7M | PyTypeObject *cls = PyCFunction_GET_CLASS(func); |
475 | 25.7M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
476 | 25.7M | PyCMethod meth = (PyCMethod)cfunction_enter_call(tstate, func); |
477 | 25.7M | if (meth == NULL) { |
478 | 0 | return NULL; |
479 | 0 | } |
480 | 25.7M | PyObject *result = meth(PyCFunction_GET_SELF(func), cls, args, nargs, kwnames); |
481 | 25.7M | _Py_LeaveRecursiveCallTstate(tstate); |
482 | 25.7M | return result; |
483 | 25.7M | } |
484 | | |
485 | | static PyObject * |
486 | | cfunction_vectorcall_NOARGS( |
487 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) |
488 | 45.3M | { |
489 | 45.3M | PyThreadState *tstate = _PyThreadState_GET(); |
490 | 45.3M | if (cfunction_check_kwargs(tstate, func, kwnames)) { |
491 | 0 | return NULL; |
492 | 0 | } |
493 | 45.3M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
494 | 45.3M | if (nargs != 0) { |
495 | 0 | PyObject *funcstr = _PyObject_FunctionStr(func); |
496 | 0 | if (funcstr != NULL) { |
497 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
498 | 0 | "%U takes no arguments (%zd given)", funcstr, nargs); |
499 | 0 | Py_DECREF(funcstr); |
500 | 0 | } |
501 | 0 | return NULL; |
502 | 0 | } |
503 | 45.3M | PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func); |
504 | 45.3M | if (meth == NULL) { |
505 | 0 | return NULL; |
506 | 0 | } |
507 | 45.3M | PyObject *result = _PyCFunction_TrampolineCall( |
508 | 45.3M | meth, PyCFunction_GET_SELF(func), NULL); |
509 | 45.3M | _Py_LeaveRecursiveCallTstate(tstate); |
510 | 45.3M | return result; |
511 | 45.3M | } |
512 | | |
513 | | static PyObject * |
514 | | cfunction_vectorcall_O( |
515 | | PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) |
516 | 76.2M | { |
517 | 76.2M | PyThreadState *tstate = _PyThreadState_GET(); |
518 | 76.2M | if (cfunction_check_kwargs(tstate, func, kwnames)) { |
519 | 0 | return NULL; |
520 | 0 | } |
521 | 76.2M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
522 | 76.2M | if (nargs != 1) { |
523 | 0 | PyObject *funcstr = _PyObject_FunctionStr(func); |
524 | 0 | if (funcstr != NULL) { |
525 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
526 | 0 | "%U takes exactly one argument (%zd given)", funcstr, nargs); |
527 | 0 | Py_DECREF(funcstr); |
528 | 0 | } |
529 | 0 | return NULL; |
530 | 0 | } |
531 | 76.2M | PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func); |
532 | 76.2M | if (meth == NULL) { |
533 | 0 | return NULL; |
534 | 0 | } |
535 | 76.2M | PyObject *result = _PyCFunction_TrampolineCall( |
536 | 76.2M | meth, PyCFunction_GET_SELF(func), args[0]); |
537 | 76.2M | _Py_LeaveRecursiveCallTstate(tstate); |
538 | 76.2M | return result; |
539 | 76.2M | } |
540 | | |
541 | | |
542 | | static PyObject * |
543 | | cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) |
544 | 3.93k | { |
545 | 3.93k | assert(kwargs == NULL || PyDict_Check(kwargs)); |
546 | | |
547 | 3.93k | PyThreadState *tstate = _PyThreadState_GET(); |
548 | 3.93k | assert(!_PyErr_Occurred(tstate)); |
549 | | |
550 | 3.93k | int flags = PyCFunction_GET_FLAGS(func); |
551 | 3.93k | if (!(flags & METH_VARARGS)) { |
552 | | /* If this is not a METH_VARARGS function, delegate to vectorcall */ |
553 | 0 | return PyVectorcall_Call(func, args, kwargs); |
554 | 0 | } |
555 | | |
556 | | /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer |
557 | | * is NULL. This is intentional, since vectorcall would be slower. */ |
558 | 3.93k | PyCFunction meth = PyCFunction_GET_FUNCTION(func); |
559 | 3.93k | PyObject *self = PyCFunction_GET_SELF(func); |
560 | | |
561 | 3.93k | PyObject *result; |
562 | 3.93k | if (flags & METH_KEYWORDS) { |
563 | 3.90k | result = _PyCFunctionWithKeywords_TrampolineCall( |
564 | 3.90k | *_PyCFunctionWithKeywords_CAST(meth), |
565 | 3.90k | self, args, kwargs); |
566 | 3.90k | } |
567 | 24 | else { |
568 | 24 | if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { |
569 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
570 | 0 | "%.200s() takes no keyword arguments", |
571 | 0 | ((PyCFunctionObject*)func)->m_ml->ml_name); |
572 | 0 | return NULL; |
573 | 0 | } |
574 | 24 | result = _PyCFunction_TrampolineCall(meth, self, args); |
575 | 24 | } |
576 | 3.93k | return _Py_CheckFunctionResult(tstate, func, result, NULL); |
577 | 3.93k | } |