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