1 /* Class object implementation (dead now except for methods) */
2 
3 #include "Python.h"
4 #include "pycore_call.h"          // _PyObject_VectorcallTstate()
5 #include "pycore_object.h"
6 #include "pycore_pyerrors.h"
7 #include "pycore_pystate.h"       // _PyThreadState_GET()
8 #include "structmember.h"         // PyMemberDef
9 
10 #define TP_DESCR_GET(t) ((t)->tp_descr_get)
11 
12 _Py_IDENTIFIER(__name__);
13 _Py_IDENTIFIER(__qualname__);
14 
15 PyObject *
PyMethod_Function(PyObject * im)16 PyMethod_Function(PyObject *im)
17 {
18     if (!PyMethod_Check(im)) {
19         PyErr_BadInternalCall();
20         return NULL;
21     }
22     return ((PyMethodObject *)im)->im_func;
23 }
24 
25 PyObject *
PyMethod_Self(PyObject * im)26 PyMethod_Self(PyObject *im)
27 {
28     if (!PyMethod_Check(im)) {
29         PyErr_BadInternalCall();
30         return NULL;
31     }
32     return ((PyMethodObject *)im)->im_self;
33 }
34 
35 
36 static PyObject *
method_vectorcall(PyObject * method,PyObject * const * args,size_t nargsf,PyObject * kwnames)37 method_vectorcall(PyObject *method, PyObject *const *args,
38                   size_t nargsf, PyObject *kwnames)
39 {
40     assert(Py_IS_TYPE(method, &PyMethod_Type));
41 
42     PyThreadState *tstate = _PyThreadState_GET();
43     PyObject *self = PyMethod_GET_SELF(method);
44     PyObject *func = PyMethod_GET_FUNCTION(method);
45     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
46 
47     PyObject *result;
48     if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) {
49         /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */
50         PyObject **newargs = (PyObject**)args - 1;
51         nargs += 1;
52         PyObject *tmp = newargs[0];
53         newargs[0] = self;
54         result = _PyObject_VectorcallTstate(tstate, func, newargs,
55                                             nargs, kwnames);
56         newargs[0] = tmp;
57     }
58     else {
59         Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
60         Py_ssize_t totalargs = nargs + nkwargs;
61         if (totalargs == 0) {
62             return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL);
63         }
64 
65         PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK];
66         PyObject **newargs;
67         if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) {
68             newargs = newargs_stack;
69         }
70         else {
71             newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *));
72             if (newargs == NULL) {
73                 _PyErr_NoMemory(tstate);
74                 return NULL;
75             }
76         }
77         /* use borrowed references */
78         newargs[0] = self;
79         /* bpo-37138: since totalargs > 0, it's impossible that args is NULL.
80          * We need this, since calling memcpy() with a NULL pointer is
81          * undefined behaviour. */
82         assert(args != NULL);
83         memcpy(newargs + 1, args, totalargs * sizeof(PyObject *));
84         result = _PyObject_VectorcallTstate(tstate, func,
85                                             newargs, nargs+1, kwnames);
86         if (newargs != newargs_stack) {
87             PyMem_Free(newargs);
88         }
89     }
90     return result;
91 }
92 
93 
94 /* Method objects are used for bound instance methods returned by
95    instancename.methodname. ClassName.methodname returns an ordinary
96    function.
97 */
98 
99 PyObject *
PyMethod_New(PyObject * func,PyObject * self)100 PyMethod_New(PyObject *func, PyObject *self)
101 {
102     if (self == NULL) {
103         PyErr_BadInternalCall();
104         return NULL;
105     }
106     PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
107     if (im == NULL) {
108         return NULL;
109     }
110     im->im_weakreflist = NULL;
111     Py_INCREF(func);
112     im->im_func = func;
113     Py_INCREF(self);
114     im->im_self = self;
115     im->vectorcall = method_vectorcall;
116     _PyObject_GC_TRACK(im);
117     return (PyObject *)im;
118 }
119 
120 static PyObject *
method_reduce(PyMethodObject * im,PyObject * Py_UNUSED (ignored))121 method_reduce(PyMethodObject *im, PyObject *Py_UNUSED(ignored))
122 {
123     PyObject *self = PyMethod_GET_SELF(im);
124     PyObject *func = PyMethod_GET_FUNCTION(im);
125     PyObject *funcname;
126     _Py_IDENTIFIER(getattr);
127 
128     funcname = _PyObject_GetAttrId(func, &PyId___name__);
129     if (funcname == NULL) {
130         return NULL;
131     }
132     return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr),
133                          self, funcname);
134 }
135 
136 static PyMethodDef method_methods[] = {
137     {"__reduce__", (PyCFunction)method_reduce, METH_NOARGS, NULL},
138     {NULL, NULL}
139 };
140 
141 /* Descriptors for PyMethod attributes */
142 
143 /* im_func and im_self are stored in the PyMethod object */
144 
145 #define MO_OFF(x) offsetof(PyMethodObject, x)
146 
147 static PyMemberDef method_memberlist[] = {
148     {"__func__", T_OBJECT, MO_OFF(im_func), READONLY,
149      "the function (or other callable) implementing a method"},
150     {"__self__", T_OBJECT, MO_OFF(im_self), READONLY,
151      "the instance to which a method is bound"},
152     {NULL}      /* Sentinel */
153 };
154 
155 /* Christian Tismer argued convincingly that method attributes should
156    (nearly) always override function attributes.
157    The one exception is __doc__; there's a default __doc__ which
158    should only be used for the class, not for instances */
159 
160 static PyObject *
method_get_doc(PyMethodObject * im,void * context)161 method_get_doc(PyMethodObject *im, void *context)
162 {
163     static PyObject *docstr;
164     if (docstr == NULL) {
165         docstr= PyUnicode_InternFromString("__doc__");
166         if (docstr == NULL)
167             return NULL;
168     }
169     return PyObject_GetAttr(im->im_func, docstr);
170 }
171 
172 static PyGetSetDef method_getset[] = {
173     {"__doc__", (getter)method_get_doc, NULL, NULL},
174     {0}
175 };
176 
177 static PyObject *
method_getattro(PyObject * obj,PyObject * name)178 method_getattro(PyObject *obj, PyObject *name)
179 {
180     PyMethodObject *im = (PyMethodObject *)obj;
181     PyTypeObject *tp = Py_TYPE(obj);
182     PyObject *descr = NULL;
183 
184     {
185         if (tp->tp_dict == NULL) {
186             if (PyType_Ready(tp) < 0)
187                 return NULL;
188         }
189         descr = _PyType_Lookup(tp, name);
190     }
191 
192     if (descr != NULL) {
193         descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
194         if (f != NULL)
195             return f(descr, obj, (PyObject *)Py_TYPE(obj));
196         else {
197             Py_INCREF(descr);
198             return descr;
199         }
200     }
201 
202     return PyObject_GetAttr(im->im_func, name);
203 }
204 
205 PyDoc_STRVAR(method_doc,
206 "method(function, instance)\n\
207 \n\
208 Create a bound instance method object.");
209 
210 static PyObject *
method_new(PyTypeObject * type,PyObject * args,PyObject * kw)211 method_new(PyTypeObject* type, PyObject* args, PyObject *kw)
212 {
213     PyObject *func;
214     PyObject *self;
215 
216     if (!_PyArg_NoKeywords("method", kw))
217         return NULL;
218     if (!PyArg_UnpackTuple(args, "method", 2, 2,
219                           &func, &self))
220         return NULL;
221     if (!PyCallable_Check(func)) {
222         PyErr_SetString(PyExc_TypeError,
223                         "first argument must be callable");
224         return NULL;
225     }
226     if (self == NULL || self == Py_None) {
227         PyErr_SetString(PyExc_TypeError,
228             "self must not be None");
229         return NULL;
230     }
231 
232     return PyMethod_New(func, self);
233 }
234 
235 static void
method_dealloc(PyMethodObject * im)236 method_dealloc(PyMethodObject *im)
237 {
238     _PyObject_GC_UNTRACK(im);
239     if (im->im_weakreflist != NULL)
240         PyObject_ClearWeakRefs((PyObject *)im);
241     Py_DECREF(im->im_func);
242     Py_XDECREF(im->im_self);
243     PyObject_GC_Del(im);
244 }
245 
246 static PyObject *
method_richcompare(PyObject * self,PyObject * other,int op)247 method_richcompare(PyObject *self, PyObject *other, int op)
248 {
249     PyMethodObject *a, *b;
250     PyObject *res;
251     int eq;
252 
253     if ((op != Py_EQ && op != Py_NE) ||
254         !PyMethod_Check(self) ||
255         !PyMethod_Check(other))
256     {
257         Py_RETURN_NOTIMPLEMENTED;
258     }
259     a = (PyMethodObject *)self;
260     b = (PyMethodObject *)other;
261     eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ);
262     if (eq == 1) {
263         eq = (a->im_self == b->im_self);
264     }
265     else if (eq < 0)
266         return NULL;
267     if (op == Py_EQ)
268         res = eq ? Py_True : Py_False;
269     else
270         res = eq ? Py_False : Py_True;
271     Py_INCREF(res);
272     return res;
273 }
274 
275 static PyObject *
method_repr(PyMethodObject * a)276 method_repr(PyMethodObject *a)
277 {
278     PyObject *self = a->im_self;
279     PyObject *func = a->im_func;
280     PyObject *funcname, *result;
281     const char *defname = "?";
282 
283     if (_PyObject_LookupAttrId(func, &PyId___qualname__, &funcname) < 0 ||
284         (funcname == NULL &&
285          _PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0))
286     {
287         return NULL;
288     }
289 
290     if (funcname != NULL && !PyUnicode_Check(funcname)) {
291         Py_DECREF(funcname);
292         funcname = NULL;
293     }
294 
295     /* XXX Shouldn't use repr()/%R here! */
296     result = PyUnicode_FromFormat("<bound method %V of %R>",
297                                   funcname, defname, self);
298 
299     Py_XDECREF(funcname);
300     return result;
301 }
302 
303 static Py_hash_t
method_hash(PyMethodObject * a)304 method_hash(PyMethodObject *a)
305 {
306     Py_hash_t x, y;
307     x = _Py_HashPointer(a->im_self);
308     y = PyObject_Hash(a->im_func);
309     if (y == -1)
310         return -1;
311     x = x ^ y;
312     if (x == -1)
313         x = -2;
314     return x;
315 }
316 
317 static int
method_traverse(PyMethodObject * im,visitproc visit,void * arg)318 method_traverse(PyMethodObject *im, visitproc visit, void *arg)
319 {
320     Py_VISIT(im->im_func);
321     Py_VISIT(im->im_self);
322     return 0;
323 }
324 
325 static PyObject *
method_descr_get(PyObject * meth,PyObject * obj,PyObject * cls)326 method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
327 {
328     Py_INCREF(meth);
329     return meth;
330 }
331 
332 PyTypeObject PyMethod_Type = {
333     PyVarObject_HEAD_INIT(&PyType_Type, 0)
334     "method",
335     sizeof(PyMethodObject),
336     0,
337     (destructor)method_dealloc,                 /* tp_dealloc */
338     offsetof(PyMethodObject, vectorcall),       /* tp_vectorcall_offset */
339     0,                                          /* tp_getattr */
340     0,                                          /* tp_setattr */
341     0,                                          /* tp_as_async */
342     (reprfunc)method_repr,                      /* tp_repr */
343     0,                                          /* tp_as_number */
344     0,                                          /* tp_as_sequence */
345     0,                                          /* tp_as_mapping */
346     (hashfunc)method_hash,                      /* tp_hash */
347     PyVectorcall_Call,                          /* tp_call */
348     0,                                          /* tp_str */
349     method_getattro,                            /* tp_getattro */
350     PyObject_GenericSetAttr,                    /* tp_setattro */
351     0,                                          /* tp_as_buffer */
352     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
353     Py_TPFLAGS_HAVE_VECTORCALL,                 /* tp_flags */
354     method_doc,                                 /* tp_doc */
355     (traverseproc)method_traverse,              /* tp_traverse */
356     0,                                          /* tp_clear */
357     method_richcompare,                         /* tp_richcompare */
358     offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */
359     0,                                          /* tp_iter */
360     0,                                          /* tp_iternext */
361     method_methods,                             /* tp_methods */
362     method_memberlist,                          /* tp_members */
363     method_getset,                              /* tp_getset */
364     0,                                          /* tp_base */
365     0,                                          /* tp_dict */
366     method_descr_get,                           /* tp_descr_get */
367     0,                                          /* tp_descr_set */
368     0,                                          /* tp_dictoffset */
369     0,                                          /* tp_init */
370     0,                                          /* tp_alloc */
371     method_new,                                 /* tp_new */
372 };
373 
374 /* ------------------------------------------------------------------------
375  * instance method
376  */
377 
378 PyObject *
PyInstanceMethod_New(PyObject * func)379 PyInstanceMethod_New(PyObject *func) {
380     PyInstanceMethodObject *method;
381     method = PyObject_GC_New(PyInstanceMethodObject,
382                              &PyInstanceMethod_Type);
383     if (method == NULL) return NULL;
384     Py_INCREF(func);
385     method->func = func;
386     _PyObject_GC_TRACK(method);
387     return (PyObject *)method;
388 }
389 
390 PyObject *
PyInstanceMethod_Function(PyObject * im)391 PyInstanceMethod_Function(PyObject *im)
392 {
393     if (!PyInstanceMethod_Check(im)) {
394         PyErr_BadInternalCall();
395         return NULL;
396     }
397     return PyInstanceMethod_GET_FUNCTION(im);
398 }
399 
400 #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x)
401 
402 static PyMemberDef instancemethod_memberlist[] = {
403     {"__func__", T_OBJECT, IMO_OFF(func), READONLY,
404      "the function (or other callable) implementing a method"},
405     {NULL}      /* Sentinel */
406 };
407 
408 static PyObject *
instancemethod_get_doc(PyObject * self,void * context)409 instancemethod_get_doc(PyObject *self, void *context)
410 {
411     static PyObject *docstr;
412     if (docstr == NULL) {
413         docstr = PyUnicode_InternFromString("__doc__");
414         if (docstr == NULL)
415             return NULL;
416     }
417     return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr);
418 }
419 
420 static PyGetSetDef instancemethod_getset[] = {
421     {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
422     {0}
423 };
424 
425 static PyObject *
instancemethod_getattro(PyObject * self,PyObject * name)426 instancemethod_getattro(PyObject *self, PyObject *name)
427 {
428     PyTypeObject *tp = Py_TYPE(self);
429     PyObject *descr = NULL;
430 
431     if (tp->tp_dict == NULL) {
432         if (PyType_Ready(tp) < 0)
433             return NULL;
434     }
435     descr = _PyType_Lookup(tp, name);
436 
437     if (descr != NULL) {
438         descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
439         if (f != NULL)
440             return f(descr, self, (PyObject *)Py_TYPE(self));
441         else {
442             Py_INCREF(descr);
443             return descr;
444         }
445     }
446 
447     return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name);
448 }
449 
450 static void
instancemethod_dealloc(PyObject * self)451 instancemethod_dealloc(PyObject *self) {
452     _PyObject_GC_UNTRACK(self);
453     Py_DECREF(PyInstanceMethod_GET_FUNCTION(self));
454     PyObject_GC_Del(self);
455 }
456 
457 static int
instancemethod_traverse(PyObject * self,visitproc visit,void * arg)458 instancemethod_traverse(PyObject *self, visitproc visit, void *arg) {
459     Py_VISIT(PyInstanceMethod_GET_FUNCTION(self));
460     return 0;
461 }
462 
463 static PyObject *
instancemethod_call(PyObject * self,PyObject * arg,PyObject * kw)464 instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw)
465 {
466     return PyObject_Call(PyInstanceMethod_GET_FUNCTION(self), arg, kw);
467 }
468 
469 static PyObject *
instancemethod_descr_get(PyObject * descr,PyObject * obj,PyObject * type)470 instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) {
471     PyObject *func = PyInstanceMethod_GET_FUNCTION(descr);
472     if (obj == NULL) {
473         Py_INCREF(func);
474         return func;
475     }
476     else
477         return PyMethod_New(func, obj);
478 }
479 
480 static PyObject *
instancemethod_richcompare(PyObject * self,PyObject * other,int op)481 instancemethod_richcompare(PyObject *self, PyObject *other, int op)
482 {
483     PyInstanceMethodObject *a, *b;
484     PyObject *res;
485     int eq;
486 
487     if ((op != Py_EQ && op != Py_NE) ||
488         !PyInstanceMethod_Check(self) ||
489         !PyInstanceMethod_Check(other))
490     {
491         Py_RETURN_NOTIMPLEMENTED;
492     }
493     a = (PyInstanceMethodObject *)self;
494     b = (PyInstanceMethodObject *)other;
495     eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ);
496     if (eq < 0)
497         return NULL;
498     if (op == Py_EQ)
499         res = eq ? Py_True : Py_False;
500     else
501         res = eq ? Py_False : Py_True;
502     Py_INCREF(res);
503     return res;
504 }
505 
506 static PyObject *
instancemethod_repr(PyObject * self)507 instancemethod_repr(PyObject *self)
508 {
509     PyObject *func = PyInstanceMethod_Function(self);
510     PyObject *funcname, *result;
511     const char *defname = "?";
512 
513     if (func == NULL) {
514         PyErr_BadInternalCall();
515         return NULL;
516     }
517 
518     if (_PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0) {
519         return NULL;
520     }
521     if (funcname != NULL && !PyUnicode_Check(funcname)) {
522         Py_DECREF(funcname);
523         funcname = NULL;
524     }
525 
526     result = PyUnicode_FromFormat("<instancemethod %V at %p>",
527                                   funcname, defname, self);
528 
529     Py_XDECREF(funcname);
530     return result;
531 }
532 
533 /*
534 static long
535 instancemethod_hash(PyObject *self)
536 {
537     long x, y;
538     x = (long)self;
539     y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self));
540     if (y == -1)
541         return -1;
542     x = x ^ y;
543     if (x == -1)
544         x = -2;
545     return x;
546 }
547 */
548 
549 PyDoc_STRVAR(instancemethod_doc,
550 "instancemethod(function)\n\
551 \n\
552 Bind a function to a class.");
553 
554 static PyObject *
instancemethod_new(PyTypeObject * type,PyObject * args,PyObject * kw)555 instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw)
556 {
557     PyObject *func;
558 
559     if (!_PyArg_NoKeywords("instancemethod", kw))
560         return NULL;
561     if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func))
562         return NULL;
563     if (!PyCallable_Check(func)) {
564         PyErr_SetString(PyExc_TypeError,
565                         "first argument must be callable");
566         return NULL;
567     }
568 
569     return PyInstanceMethod_New(func);
570 }
571 
572 PyTypeObject PyInstanceMethod_Type = {
573     PyVarObject_HEAD_INIT(&PyType_Type, 0)
574     "instancemethod",                           /* tp_name */
575     sizeof(PyInstanceMethodObject),             /* tp_basicsize */
576     0,                                          /* tp_itemsize */
577     instancemethod_dealloc,                     /* tp_dealloc */
578     0,                                          /* tp_vectorcall_offset */
579     0,                                          /* tp_getattr */
580     0,                                          /* tp_setattr */
581     0,                                          /* tp_as_async */
582     (reprfunc)instancemethod_repr,              /* tp_repr */
583     0,                                          /* tp_as_number */
584     0,                                          /* tp_as_sequence */
585     0,                                          /* tp_as_mapping */
586     0, /*(hashfunc)instancemethod_hash,         tp_hash  */
587     instancemethod_call,                        /* tp_call */
588     0,                                          /* tp_str */
589     instancemethod_getattro,                    /* tp_getattro */
590     PyObject_GenericSetAttr,                    /* tp_setattro */
591     0,                                          /* tp_as_buffer */
592     Py_TPFLAGS_DEFAULT
593         | Py_TPFLAGS_HAVE_GC,                   /* tp_flags */
594     instancemethod_doc,                         /* tp_doc */
595     instancemethod_traverse,                    /* tp_traverse */
596     0,                                          /* tp_clear */
597     instancemethod_richcompare,                 /* tp_richcompare */
598     0,                                          /* tp_weaklistoffset */
599     0,                                          /* tp_iter */
600     0,                                          /* tp_iternext */
601     0,                                          /* tp_methods */
602     instancemethod_memberlist,                  /* tp_members */
603     instancemethod_getset,                      /* tp_getset */
604     0,                                          /* tp_base */
605     0,                                          /* tp_dict */
606     instancemethod_descr_get,                   /* tp_descr_get */
607     0,                                          /* tp_descr_set */
608     0,                                          /* tp_dictoffset */
609     0,                                          /* tp_init */
610     0,                                          /* tp_alloc */
611     instancemethod_new,                         /* tp_new */
612 };
613