You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

427 lines
12 KiB

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