LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Objects - methodobject.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 62 154 40.3 %
Date: 2012-12-17 Functions: 8 18 44.4 %
Legend: Lines: hit not hit

          Line data    Source code
       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       29978 : PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
      18             : {
      19             :     PyCFunctionObject *op;
      20       29978 :     op = free_list;
      21       29978 :     if (op != NULL) {
      22       29357 :         free_list = (PyCFunctionObject *)(op->m_self);
      23       29357 :         PyObject_INIT(op, &PyCFunction_Type);
      24       29357 :         numfree--;
      25             :     }
      26             :     else {
      27         621 :         op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
      28         621 :         if (op == NULL)
      29           0 :             return NULL;
      30             :     }
      31       29978 :     op->m_ml = ml;
      32       29978 :     Py_XINCREF(self);
      33       29978 :     op->m_self = self;
      34       29978 :     Py_XINCREF(module);
      35       29978 :     op->m_module = module;
      36       29978 :     _PyObject_GC_TRACK(op);
      37       29978 :     return (PyObject *)op;
      38             : }
      39             : 
      40             : PyCFunction
      41           0 : PyCFunction_GetFunction(PyObject *op)
      42             : {
      43           0 :     if (!PyCFunction_Check(op)) {
      44           0 :         PyErr_BadInternalCall();
      45           0 :         return NULL;
      46             :     }
      47           0 :     return PyCFunction_GET_FUNCTION(op);
      48             : }
      49             : 
      50             : PyObject *
      51           0 : PyCFunction_GetSelf(PyObject *op)
      52             : {
      53           0 :     if (!PyCFunction_Check(op)) {
      54           0 :         PyErr_BadInternalCall();
      55           0 :         return NULL;
      56             :     }
      57           0 :     return PyCFunction_GET_SELF(op);
      58             : }
      59             : 
      60             : int
      61           0 : PyCFunction_GetFlags(PyObject *op)
      62             : {
      63           0 :     if (!PyCFunction_Check(op)) {
      64           0 :         PyErr_BadInternalCall();
      65           0 :         return -1;
      66             :     }
      67           0 :     return PyCFunction_GET_FLAGS(op);
      68             : }
      69             : 
      70             : PyObject *
      71       30044 : PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
      72             : {
      73       30044 :     PyCFunctionObject* f = (PyCFunctionObject*)func;
      74       30044 :     PyCFunction meth = PyCFunction_GET_FUNCTION(func);
      75       30044 :     PyObject *self = PyCFunction_GET_SELF(func);
      76             :     Py_ssize_t size;
      77             : 
      78       30044 :     switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
      79             :     case METH_VARARGS:
      80       19137 :         if (kw == NULL || PyDict_Size(kw) == 0)
      81       19137 :             return (*meth)(self, arg);
      82           0 :         break;
      83             :     case METH_VARARGS | METH_KEYWORDS:
      84        5363 :         return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
      85             :     case METH_NOARGS:
      86        2159 :         if (kw == NULL || PyDict_Size(kw) == 0) {
      87        2159 :             size = PyTuple_GET_SIZE(arg);
      88        2159 :             if (size == 0)
      89        2159 :                 return (*meth)(self, NULL);
      90           0 :             PyErr_Format(PyExc_TypeError,
      91             :                 "%.200s() takes no arguments (%zd given)",
      92           0 :                 f->m_ml->ml_name, size);
      93           0 :             return NULL;
      94             :         }
      95           0 :         break;
      96             :     case METH_O:
      97        3385 :         if (kw == NULL || PyDict_Size(kw) == 0) {
      98        3385 :             size = PyTuple_GET_SIZE(arg);
      99        3385 :             if (size == 1)
     100        3385 :                 return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
     101           0 :             PyErr_Format(PyExc_TypeError,
     102             :                 "%.200s() takes exactly one argument (%zd given)",
     103           0 :                 f->m_ml->ml_name, size);
     104           0 :             return NULL;
     105             :         }
     106           0 :         break;
     107             :     default:
     108           0 :         PyErr_SetString(PyExc_SystemError, "Bad call flags in "
     109             :                         "PyCFunction_Call. METH_OLDARGS is no "
     110             :                         "longer supported!");
     111             : 
     112           0 :         return NULL;
     113             :     }
     114           0 :     PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
     115           0 :                  f->m_ml->ml_name);
     116           0 :     return NULL;
     117             : }
     118             : 
     119             : /* Methods (the standard built-in methods, that is) */
     120             : 
     121             : static void
     122       29366 : meth_dealloc(PyCFunctionObject *m)
     123             : {
     124       29366 :     _PyObject_GC_UNTRACK(m);
     125       29366 :     Py_XDECREF(m->m_self);
     126       29366 :     Py_XDECREF(m->m_module);
     127       29366 :     if (numfree < PyCFunction_MAXFREELIST) {
     128       29366 :         m->m_self = (PyObject *)free_list;
     129       29366 :         free_list = m;
     130       29366 :         numfree++;
     131             :     }
     132             :     else {
     133           0 :         PyObject_GC_Del(m);
     134             :     }
     135       29366 : }
     136             : 
     137             : static PyObject *
     138           1 : meth_get__doc__(PyCFunctionObject *m, void *closure)
     139             : {
     140           1 :     const char *doc = m->m_ml->ml_doc;
     141             : 
     142           1 :     if (doc != NULL)
     143           1 :         return PyUnicode_FromString(doc);
     144           0 :     Py_INCREF(Py_None);
     145           0 :     return Py_None;
     146             : }
     147             : 
     148             : static PyObject *
     149           1 : meth_get__name__(PyCFunctionObject *m, void *closure)
     150             : {
     151           1 :     return PyUnicode_FromString(m->m_ml->ml_name);
     152             : }
     153             : 
     154             : static PyObject *
     155           1 : meth_get__qualname__(PyCFunctionObject *m, void *closure)
     156             : {
     157             :     /* If __self__ is a module or NULL, return m.__name__
     158             :        (e.g. len.__qualname__ == 'len')
     159             : 
     160             :        If __self__ is a type, return m.__self__.__qualname__ + '.' + m.__name__
     161             :        (e.g. dict.fromkeys.__qualname__ == 'dict.fromkeys')
     162             : 
     163             :        Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__
     164             :        (e.g. [].append.__qualname__ == 'list.append') */
     165             :     PyObject *type, *type_qualname, *res;
     166             :     _Py_IDENTIFIER(__qualname__);
     167             : 
     168           1 :     if (m->m_self == NULL || PyModule_Check(m->m_self))
     169           1 :         return PyUnicode_FromString(m->m_ml->ml_name);
     170             : 
     171           0 :     type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self);
     172             : 
     173           0 :     type_qualname = _PyObject_GetAttrId(type, &PyId___qualname__);
     174           0 :     if (type_qualname == NULL)
     175           0 :         return NULL;
     176             : 
     177           0 :     if (!PyUnicode_Check(type_qualname)) {
     178           0 :         PyErr_SetString(PyExc_TypeError, "<method>.__class__."
     179             :                         "__qualname__ is not a unicode object");
     180           0 :         Py_XDECREF(type_qualname);
     181           0 :         return NULL;
     182             :     }
     183             : 
     184           0 :     res = PyUnicode_FromFormat("%S.%s", type_qualname, m->m_ml->ml_name);
     185           0 :     Py_DECREF(type_qualname);
     186           0 :     return res;
     187             : }
     188             : 
     189             : static int
     190        2334 : meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
     191             : {
     192        2334 :     Py_VISIT(m->m_self);
     193        2334 :     Py_VISIT(m->m_module);
     194        2334 :     return 0;
     195             : }
     196             : 
     197             : static PyObject *
     198           0 : meth_get__self__(PyCFunctionObject *m, void *closure)
     199             : {
     200             :     PyObject *self;
     201             : 
     202           0 :     self = PyCFunction_GET_SELF(m);
     203           0 :     if (self == NULL)
     204           0 :         self = Py_None;
     205           0 :     Py_INCREF(self);
     206           0 :     return self;
     207             : }
     208             : 
     209             : static PyGetSetDef meth_getsets [] = {
     210             :     {"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
     211             :     {"__name__", (getter)meth_get__name__, NULL, NULL},
     212             :     {"__qualname__", (getter)meth_get__qualname__, NULL, NULL},
     213             :     {"__self__", (getter)meth_get__self__, NULL, NULL},
     214             :     {0}
     215             : };
     216             : 
     217             : #define OFF(x) offsetof(PyCFunctionObject, x)
     218             : 
     219             : static PyMemberDef meth_members[] = {
     220             :     {"__module__",    T_OBJECT,     OFF(m_module), PY_WRITE_RESTRICTED},
     221             :     {NULL}
     222             : };
     223             : 
     224             : static PyObject *
     225           0 : meth_repr(PyCFunctionObject *m)
     226             : {
     227           0 :     if (m->m_self == NULL || PyModule_Check(m->m_self))
     228           0 :         return PyUnicode_FromFormat("<built-in function %s>",
     229           0 :                                    m->m_ml->ml_name);
     230           0 :     return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
     231           0 :                                m->m_ml->ml_name,
     232           0 :                                m->m_self->ob_type->tp_name,
     233             :                                m->m_self);
     234             : }
     235             : 
     236             : static PyObject *
     237           0 : meth_richcompare(PyObject *self, PyObject *other, int op)
     238             : {
     239             :     PyCFunctionObject *a, *b;
     240             :     PyObject *res;
     241             :     int eq;
     242             : 
     243           0 :     if ((op != Py_EQ && op != Py_NE) ||
     244           0 :         !PyCFunction_Check(self) ||
     245           0 :         !PyCFunction_Check(other))
     246             :     {
     247           0 :         Py_RETURN_NOTIMPLEMENTED;
     248             :     }
     249           0 :     a = (PyCFunctionObject *)self;
     250           0 :     b = (PyCFunctionObject *)other;
     251           0 :     eq = a->m_self == b->m_self;
     252           0 :     if (eq)
     253           0 :         eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
     254           0 :     if (op == Py_EQ)
     255           0 :         res = eq ? Py_True : Py_False;
     256             :     else
     257           0 :         res = eq ? Py_False : Py_True;
     258           0 :     Py_INCREF(res);
     259           0 :     return res;
     260             : }
     261             : 
     262             : static Py_hash_t
     263          39 : meth_hash(PyCFunctionObject *a)
     264             : {
     265             :     Py_hash_t x, y;
     266          39 :     if (a->m_self == NULL)
     267           0 :         x = 0;
     268             :     else {
     269          39 :         x = PyObject_Hash(a->m_self);
     270          39 :         if (x == -1)
     271           0 :             return -1;
     272             :     }
     273          39 :     y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
     274          39 :     if (y == -1)
     275           0 :         return -1;
     276          39 :     x ^= y;
     277          39 :     if (x == -1)
     278           0 :         x = -2;
     279          39 :     return x;
     280             : }
     281             : 
     282             : 
     283             : PyTypeObject PyCFunction_Type = {
     284             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     285             :     "builtin_function_or_method",
     286             :     sizeof(PyCFunctionObject),
     287             :     0,
     288             :     (destructor)meth_dealloc,                   /* tp_dealloc */
     289             :     0,                                          /* tp_print */
     290             :     0,                                          /* tp_getattr */
     291             :     0,                                          /* tp_setattr */
     292             :     0,                                          /* tp_reserved */
     293             :     (reprfunc)meth_repr,                        /* tp_repr */
     294             :     0,                                          /* tp_as_number */
     295             :     0,                                          /* tp_as_sequence */
     296             :     0,                                          /* tp_as_mapping */
     297             :     (hashfunc)meth_hash,                        /* tp_hash */
     298             :     PyCFunction_Call,                           /* tp_call */
     299             :     0,                                          /* tp_str */
     300             :     PyObject_GenericGetAttr,                    /* tp_getattro */
     301             :     0,                                          /* tp_setattro */
     302             :     0,                                          /* tp_as_buffer */
     303             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
     304             :     0,                                          /* tp_doc */
     305             :     (traverseproc)meth_traverse,                /* tp_traverse */
     306             :     0,                                          /* tp_clear */
     307             :     meth_richcompare,                           /* tp_richcompare */
     308             :     0,                                          /* tp_weaklistoffset */
     309             :     0,                                          /* tp_iter */
     310             :     0,                                          /* tp_iternext */
     311             :     0,                                          /* tp_methods */
     312             :     meth_members,                               /* tp_members */
     313             :     meth_getsets,                               /* tp_getset */
     314             :     0,                                          /* tp_base */
     315             :     0,                                          /* tp_dict */
     316             : };
     317             : 
     318             : /* Clear out the free list */
     319             : 
     320             : int
     321           0 : PyCFunction_ClearFreeList(void)
     322             : {
     323           0 :     int freelist_size = numfree;
     324             : 
     325           0 :     while (free_list) {
     326           0 :         PyCFunctionObject *v = free_list;
     327           0 :         free_list = (PyCFunctionObject *)(v->m_self);
     328           0 :         PyObject_GC_Del(v);
     329           0 :         numfree--;
     330             :     }
     331             :     assert(numfree == 0);
     332           0 :     return freelist_size;
     333             : }
     334             : 
     335             : void
     336           0 : PyCFunction_Fini(void)
     337             : {
     338           0 :     (void)PyCFunction_ClearFreeList();
     339           0 : }
     340             : 
     341             : /* Print summary info about the state of the optimized allocator */
     342             : void
     343           0 : _PyCFunction_DebugMallocStats(FILE *out)
     344             : {
     345           0 :     _PyDebugAllocatorStats(out,
     346             :                            "free PyCFunction",
     347             :                            numfree, sizeof(PyCFunction));
     348           0 : }
     349             : 
     350             : /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
     351             :    but it's part of the API so we need to keep a function around that
     352             :    existing C extensions can call.
     353             : */
     354             : 
     355             : #undef PyCFunction_New
     356             : PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
     357             : 
     358             : PyObject *
     359           0 : PyCFunction_New(PyMethodDef *ml, PyObject *self)
     360             : {
     361           0 :     return PyCFunction_NewEx(ml, self, NULL);
     362             : }

Generated by: LCOV version 1.10