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