1 2 /* Method object implementation */ 3 4 #include "Python.h" 5 #include "structmember.h" 6 7 /* Free list for method objects to safe malloc/free overhead 8 * The m_self element is used to chain the objects. 9 */ 10 static PyCFunctionObject *free_list = NULL; 11 static int numfree = 0; 12 #ifndef PyCFunction_MAXFREELIST 13 #define PyCFunction_MAXFREELIST 256 14 #endif 15 16 PyObject * 17 PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) 18 { 19 PyCFunctionObject *op; 20 op = free_list; 21 if (op != NULL) { 22 free_list = (PyCFunctionObject *)(op->m_self); 23 (void)PyObject_INIT(op, &PyCFunction_Type); 24 numfree--; 25 } 26 else { 27 op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type); 28 if (op == NULL) 29 return NULL; 30 } 31 op->m_ml = ml; 32 Py_XINCREF(self); 33 op->m_self = self; 34 Py_XINCREF(module); 35 op->m_module = module; 36 _PyObject_GC_TRACK(op); 37 return (PyObject *)op; 38 } 39 40 PyCFunction 41 PyCFunction_GetFunction(PyObject *op) 42 { 43 if (!PyCFunction_Check(op)) { 44 PyErr_BadInternalCall(); 45 return NULL; 46 } 47 return ((PyCFunctionObject *)op) -> m_ml -> ml_meth; 48 } 49 50 PyObject * 51 PyCFunction_GetSelf(PyObject *op) 52 { 53 if (!PyCFunction_Check(op)) { 54 PyErr_BadInternalCall(); 55 return NULL; 56 } 57 return ((PyCFunctionObject *)op) -> m_self; 58 } 59 60 int 61 PyCFunction_GetFlags(PyObject *op) 62 { 63 if (!PyCFunction_Check(op)) { 64 PyErr_BadInternalCall(); 65 return -1; 66 } 67 return ((PyCFunctionObject *)op) -> m_ml -> ml_flags; 68 } 69 70 PyObject * 71 PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) 72 { 73 PyCFunctionObject* f = (PyCFunctionObject*)func; 74 PyCFunction meth = PyCFunction_GET_FUNCTION(func); 75 PyObject *self = PyCFunction_GET_SELF(func); 76 Py_ssize_t size; 77 78 switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { 79 case METH_VARARGS: 80 if (kw == NULL || PyDict_Size(kw) == 0) 81 return (*meth)(self, arg); 82 break; 83 case METH_VARARGS | METH_KEYWORDS: 84 case METH_OLDARGS | METH_KEYWORDS: 85 return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); 86 case METH_NOARGS: 87 if (kw == NULL || PyDict_Size(kw) == 0) { 88 size = PyTuple_GET_SIZE(arg); 89 if (size == 0) 90 return (*meth)(self, NULL); 91 PyErr_Format(PyExc_TypeError, 92 "%.200s() takes no arguments (%zd given)", 93 f->m_ml->ml_name, size); 94 return NULL; 95 } 96 break; 97 case METH_O: 98 if (kw == NULL || PyDict_Size(kw) == 0) { 99 size = PyTuple_GET_SIZE(arg); 100 if (size == 1) 101 return (*meth)(self, PyTuple_GET_ITEM(arg, 0)); 102 PyErr_Format(PyExc_TypeError, 103 "%.200s() takes exactly one argument (%zd given)", 104 f->m_ml->ml_name, size); 105 return NULL; 106 } 107 break; 108 case METH_OLDARGS: 109 /* the really old style */ 110 if (kw == NULL || PyDict_Size(kw) == 0) { 111 size = PyTuple_GET_SIZE(arg); 112 if (size == 1) 113 arg = PyTuple_GET_ITEM(arg, 0); 114 else if (size == 0) 115 arg = NULL; 116 return (*meth)(self, arg); 117 } 118 break; 119 default: 120 PyErr_BadInternalCall(); 121 return NULL; 122 } 123 PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", 124 f->m_ml->ml_name); 125 return NULL; 126 } 127 128 /* Methods (the standard built-in methods, that is) */ 129 130 static void 131 meth_dealloc(PyCFunctionObject *m) 132 { 133 _PyObject_GC_UNTRACK(m); 134 Py_XDECREF(m->m_self); 135 Py_XDECREF(m->m_module); 136 if (numfree < PyCFunction_MAXFREELIST) { 137 m->m_self = (PyObject *)free_list; 138 free_list = m; 139 numfree++; 140 } 141 else { 142 PyObject_GC_Del(m); 143 } 144 } 145 146 static PyObject * 147 meth_get__doc__(PyCFunctionObject *m, void *closure) 148 { 149 const char *doc = m->m_ml->ml_doc; 150 151 if (doc != NULL) 152 return PyString_FromString(doc); 153 Py_INCREF(Py_None); 154 return Py_None; 155 } 156 157 static PyObject * 158 meth_get__name__(PyCFunctionObject *m, void *closure) 159 { 160 return PyString_FromString(m->m_ml->ml_name); 161 } 162 163 static int 164 meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) 165 { 166 Py_VISIT(m->m_self); 167 Py_VISIT(m->m_module); 168 return 0; 169 } 170 171 static PyObject * 172 meth_get__self__(PyCFunctionObject *m, void *closure) 173 { 174 PyObject *self; 175 if (PyEval_GetRestricted()) { 176 PyErr_SetString(PyExc_RuntimeError, 177 "method.__self__ not accessible in restricted mode"); 178 return NULL; 179 } 180 self = m->m_self; 181 if (self == NULL) 182 self = Py_None; 183 Py_INCREF(self); 184 return self; 185 } 186 187 static PyGetSetDef meth_getsets [] = { 188 {"__doc__", (getter)meth_get__doc__, NULL, NULL}, 189 {"__name__", (getter)meth_get__name__, NULL, NULL}, 190 {"__self__", (getter)meth_get__self__, NULL, NULL}, 191 {0} 192 }; 193 194 #define OFF(x) offsetof(PyCFunctionObject, x) 195 196 static PyMemberDef meth_members[] = { 197 {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED}, 198 {NULL} 199 }; 200 201 static PyObject * 202 meth_repr(PyCFunctionObject *m) 203 { 204 if (m->m_self == NULL) 205 return PyString_FromFormat("<built-in function %s>", 206 m->m_ml->ml_name); 207 return PyString_FromFormat("<built-in method %s of %s object at %p>", 208 m->m_ml->ml_name, 209 m->m_self->ob_type->tp_name, 210 m->m_self); 211 } 212 213 static int 214 meth_compare(PyCFunctionObject *a, PyCFunctionObject *b) 215 { 216 if (a->m_self != b->m_self) 217 return (a->m_self < b->m_self) ? -1 : 1; 218 if (a->m_ml->ml_meth == b->m_ml->ml_meth) 219 return 0; 220 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0) 221 return -1; 222 else 223 return 1; 224 } 225 226 static PyObject * 227 meth_richcompare(PyObject *self, PyObject *other, int op) 228 { 229 PyCFunctionObject *a, *b; 230 PyObject *res; 231 int eq; 232 233 if (op != Py_EQ && op != Py_NE) { 234 /* Py3K warning if comparison isn't == or !=. */ 235 if (PyErr_WarnPy3k("builtin_function_or_method order " 236 "comparisons not supported in 3.x", 1) < 0) { 237 return NULL; 238 } 239 240 Py_INCREF(Py_NotImplemented); 241 return Py_NotImplemented; 242 } 243 else if (!PyCFunction_Check(self) || !PyCFunction_Check(other)) { 244 Py_INCREF(Py_NotImplemented); 245 return Py_NotImplemented; 246 } 247 a = (PyCFunctionObject *)self; 248 b = (PyCFunctionObject *)other; 249 eq = a->m_self == b->m_self; 250 if (eq) 251 eq = a->m_ml->ml_meth == b->m_ml->ml_meth; 252 if (op == Py_EQ) 253 res = eq ? Py_True : Py_False; 254 else 255 res = eq ? Py_False : Py_True; 256 Py_INCREF(res); 257 return res; 258 } 259 260 static long 261 meth_hash(PyCFunctionObject *a) 262 { 263 long x,y; 264 if (a->m_self == NULL) 265 x = 0; 266 else { 267 x = PyObject_Hash(a->m_self); 268 if (x == -1) 269 return -1; 270 } 271 y = _Py_HashPointer((void*)(a->m_ml->ml_meth)); 272 if (y == -1) 273 return -1; 274 x ^= y; 275 if (x == -1) 276 x = -2; 277 return x; 278 } 279 280 281 PyTypeObject PyCFunction_Type = { 282 PyVarObject_HEAD_INIT(&PyType_Type, 0) 283 "builtin_function_or_method", 284 sizeof(PyCFunctionObject), 285 0, 286 (destructor)meth_dealloc, /* tp_dealloc */ 287 0, /* tp_print */ 288 0, /* tp_getattr */ 289 0, /* tp_setattr */ 290 (cmpfunc)meth_compare, /* tp_compare */ 291 (reprfunc)meth_repr, /* tp_repr */ 292 0, /* tp_as_number */ 293 0, /* tp_as_sequence */ 294 0, /* tp_as_mapping */ 295 (hashfunc)meth_hash, /* tp_hash */ 296 PyCFunction_Call, /* tp_call */ 297 0, /* tp_str */ 298 PyObject_GenericGetAttr, /* tp_getattro */ 299 0, /* tp_setattro */ 300 0, /* tp_as_buffer */ 301 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 302 0, /* tp_doc */ 303 (traverseproc)meth_traverse, /* tp_traverse */ 304 0, /* tp_clear */ 305 meth_richcompare, /* tp_richcompare */ 306 0, /* tp_weaklistoffset */ 307 0, /* tp_iter */ 308 0, /* tp_iternext */ 309 0, /* tp_methods */ 310 meth_members, /* tp_members */ 311 meth_getsets, /* tp_getset */ 312 0, /* tp_base */ 313 0, /* tp_dict */ 314 }; 315 316 /* List all methods in a chain -- helper for findmethodinchain */ 317 318 static PyObject * 319 listmethodchain(PyMethodChain *chain) 320 { 321 PyMethodChain *c; 322 PyMethodDef *ml; 323 int i, n; 324 PyObject *v; 325 326 n = 0; 327 for (c = chain; c != NULL; c = c->link) { 328 for (ml = c->methods; ml->ml_name != NULL; ml++) 329 n++; 330 } 331 v = PyList_New(n); 332 if (v == NULL) 333 return NULL; 334 i = 0; 335 for (c = chain; c != NULL; c = c->link) { 336 for (ml = c->methods; ml->ml_name != NULL; ml++) { 337 PyList_SetItem(v, i, PyString_FromString(ml->ml_name)); 338 i++; 339 } 340 } 341 if (PyErr_Occurred()) { 342 Py_DECREF(v); 343 return NULL; 344 } 345 PyList_Sort(v); 346 return v; 347 } 348 349 /* Find a method in a method chain */ 350 351 PyObject * 352 Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, const char *name) 353 { 354 if (name[0] == '_' && name[1] == '_') { 355 if (strcmp(name, "__methods__") == 0) { 356 if (PyErr_WarnPy3k("__methods__ not supported in 3.x", 357 1) < 0) 358 return NULL; 359 return listmethodchain(chain); 360 } 361 if (strcmp(name, "__doc__") == 0) { 362 const char *doc = self->ob_type->tp_doc; 363 if (doc != NULL) 364 return PyString_FromString(doc); 365 } 366 } 367 while (chain != NULL) { 368 PyMethodDef *ml = chain->methods; 369 for (; ml->ml_name != NULL; ml++) { 370 if (name[0] == ml->ml_name[0] && 371 strcmp(name+1, ml->ml_name+1) == 0) 372 /* XXX */ 373 return PyCFunction_New(ml, self); 374 } 375 chain = chain->link; 376 } 377 PyErr_SetString(PyExc_AttributeError, name); 378 return NULL; 379 } 380 381 /* Find a method in a single method list */ 382 383 PyObject * 384 Py_FindMethod(PyMethodDef *methods, PyObject *self, const char *name) 385 { 386 PyMethodChain chain; 387 chain.methods = methods; 388 chain.link = NULL; 389 return Py_FindMethodInChain(&chain, self, name); 390 } 391 392 /* Clear out the free list */ 393 394 int 395 PyCFunction_ClearFreeList(void) 396 { 397 int freelist_size = numfree; 398 399 while (free_list) { 400 PyCFunctionObject *v = free_list; 401 free_list = (PyCFunctionObject *)(v->m_self); 402 PyObject_GC_Del(v); 403 numfree--; 404 } 405 assert(numfree == 0); 406 return freelist_size; 407 } 408 409 void 410 PyCFunction_Fini(void) 411 { 412 (void)PyCFunction_ClearFreeList(); 413 } 414 415 /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(), 416 but it's part of the API so we need to keep a function around that 417 existing C extensions can call. 418 */ 419 420 #undef PyCFunction_New 421 PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *); 422 423 PyObject * 424 PyCFunction_New(PyMethodDef *ml, PyObject *self) 425 { 426 return PyCFunction_NewEx(ml, self, NULL); 427 } 428