LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Objects - codeobject.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 139 304 45.7 %
Date: 2012-12-17 Functions: 6 13 46.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include "Python.h"
       2             : #include "code.h"
       3             : #include "structmember.h"
       4             : 
       5             : #define NAME_CHARS \
       6             :     "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
       7             : 
       8             : /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
       9             : 
      10             : static int
      11       11001 : all_name_chars(PyObject *o)
      12             : {
      13             :     static char ok_name_char[256];
      14             :     static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
      15       11001 :     PyUnicodeObject *u = (PyUnicodeObject *)o;
      16             :     const unsigned char *s;
      17             : 
      18       18178 :     if (!PyUnicode_Check(o) || PyUnicode_READY(u) == -1 ||
      19        7177 :         PyUnicode_MAX_CHAR_VALUE(u) >= 128)
      20        3909 :         return 0;
      21             : 
      22        7092 :     if (ok_name_char[*name_chars] == 0) {
      23             :         unsigned char *p;
      24          64 :         for (p = name_chars; *p; p++)
      25          63 :             ok_name_char[*p] = 1;
      26             :     }
      27        7092 :     s = PyUnicode_1BYTE_DATA(u);
      28       64085 :     while (*s) {
      29       53239 :         if (ok_name_char[*s++] == 0)
      30        3338 :             return 0;
      31             :     }
      32        3754 :     return 1;
      33             : }
      34             : 
      35             : static void
      36        5364 : intern_strings(PyObject *tuple)
      37             : {
      38             :     Py_ssize_t i;
      39             : 
      40       23180 :     for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
      41       12452 :         PyObject *v = PyTuple_GET_ITEM(tuple, i);
      42       12452 :         if (v == NULL || !PyUnicode_CheckExact(v)) {
      43           0 :             Py_FatalError("non-string found in code slot");
      44             :         }
      45       12452 :         PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
      46             :     }
      47        5364 : }
      48             : 
      49             : 
      50             : PyCodeObject *
      51        1341 : PyCode_New(int argcount, int kwonlyargcount,
      52             :            int nlocals, int stacksize, int flags,
      53             :            PyObject *code, PyObject *consts, PyObject *names,
      54             :            PyObject *varnames, PyObject *freevars, PyObject *cellvars,
      55             :            PyObject *filename, PyObject *name, int firstlineno,
      56             :            PyObject *lnotab)
      57             : {
      58             :     PyCodeObject *co;
      59        1341 :     unsigned char *cell2arg = NULL;
      60             :     Py_ssize_t i, n_cellvars;
      61             : 
      62             :     /* Check argument types */
      63        1341 :     if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
      64        1341 :         code == NULL ||
      65        1341 :         consts == NULL || !PyTuple_Check(consts) ||
      66        1341 :         names == NULL || !PyTuple_Check(names) ||
      67        1341 :         varnames == NULL || !PyTuple_Check(varnames) ||
      68        1341 :         freevars == NULL || !PyTuple_Check(freevars) ||
      69        1341 :         cellvars == NULL || !PyTuple_Check(cellvars) ||
      70        1341 :         name == NULL || !PyUnicode_Check(name) ||
      71        1341 :         filename == NULL || !PyUnicode_Check(filename) ||
      72        2682 :         lnotab == NULL || !PyBytes_Check(lnotab) ||
      73        1341 :         !PyObject_CheckReadBuffer(code)) {
      74           0 :         PyErr_BadInternalCall();
      75           0 :         return NULL;
      76             :     }
      77        1341 :     n_cellvars = PyTuple_GET_SIZE(cellvars);
      78        1341 :     intern_strings(names);
      79        1341 :     intern_strings(varnames);
      80        1341 :     intern_strings(freevars);
      81        1341 :     intern_strings(cellvars);
      82             :     /* Intern selected string constants */
      83       13683 :     for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) {
      84       11001 :         PyObject *v = PyTuple_GetItem(consts, i);
      85       11001 :         if (!all_name_chars(v))
      86        7247 :             continue;
      87        3754 :         PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
      88             :     }
      89             :     /* Create mapping between cells and arguments if needed. */
      90        1341 :     if (n_cellvars) {
      91         123 :         Py_ssize_t total_args = argcount + kwonlyargcount +
      92          82 :             ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
      93          41 :         Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars;
      94          41 :         int used_cell2arg = 0;
      95          41 :         cell2arg = PyMem_MALLOC(alloc_size);
      96          41 :         if (cell2arg == NULL)
      97           0 :             return NULL;
      98          41 :         memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size);
      99             :         /* Find cells which are also arguments. */
     100         104 :         for (i = 0; i < n_cellvars; i++) {
     101             :             Py_ssize_t j;
     102          63 :             PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
     103         126 :             for (j = 0; j < total_args; j++) {
     104          90 :                 PyObject *arg = PyTuple_GET_ITEM(varnames, j);
     105          90 :                 if (!PyUnicode_Compare(cell, arg)) {
     106          27 :                     cell2arg[i] = j;
     107          27 :                     used_cell2arg = 1;
     108          27 :                     break;
     109             :                 }
     110             :             }
     111             :         }
     112          41 :         if (!used_cell2arg) {
     113          16 :             PyMem_FREE(cell2arg);
     114          16 :             cell2arg = NULL;
     115             :         }
     116             :     }
     117        1341 :     co = PyObject_NEW(PyCodeObject, &PyCode_Type);
     118        1341 :     if (co == NULL) {
     119           0 :         if (cell2arg)
     120           0 :             PyMem_FREE(cell2arg);
     121           0 :         return NULL;
     122             :     }
     123        1341 :     co->co_argcount = argcount;
     124        1341 :     co->co_kwonlyargcount = kwonlyargcount;
     125        1341 :     co->co_nlocals = nlocals;
     126        1341 :     co->co_stacksize = stacksize;
     127        1341 :     co->co_flags = flags;
     128        1341 :     Py_INCREF(code);
     129        1341 :     co->co_code = code;
     130        1341 :     Py_INCREF(consts);
     131        1341 :     co->co_consts = consts;
     132        1341 :     Py_INCREF(names);
     133        1341 :     co->co_names = names;
     134        1341 :     Py_INCREF(varnames);
     135        1341 :     co->co_varnames = varnames;
     136        1341 :     Py_INCREF(freevars);
     137        1341 :     co->co_freevars = freevars;
     138        1341 :     Py_INCREF(cellvars);
     139        1341 :     co->co_cellvars = cellvars;
     140        1341 :     co->co_cell2arg = cell2arg;
     141        1341 :     Py_INCREF(filename);
     142        1341 :     co->co_filename = filename;
     143        1341 :     Py_INCREF(name);
     144        1341 :     co->co_name = name;
     145        1341 :     co->co_firstlineno = firstlineno;
     146        1341 :     Py_INCREF(lnotab);
     147        1341 :     co->co_lnotab = lnotab;
     148        1341 :     co->co_zombieframe = NULL;
     149        1341 :     co->co_weakreflist = NULL;
     150        1341 :     return co;
     151             : }
     152             : 
     153             : PyCodeObject *
     154           0 : PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
     155             : {
     156             :     static PyObject *emptystring = NULL;
     157             :     static PyObject *nulltuple = NULL;
     158           0 :     PyObject *filename_ob = NULL;
     159           0 :     PyObject *funcname_ob = NULL;
     160           0 :     PyCodeObject *result = NULL;
     161           0 :     if (emptystring == NULL) {
     162           0 :         emptystring = PyBytes_FromString("");
     163           0 :         if (emptystring == NULL)
     164           0 :             goto failed;
     165             :     }
     166           0 :     if (nulltuple == NULL) {
     167           0 :         nulltuple = PyTuple_New(0);
     168           0 :         if (nulltuple == NULL)
     169           0 :             goto failed;
     170             :     }
     171           0 :     funcname_ob = PyUnicode_FromString(funcname);
     172           0 :     if (funcname_ob == NULL)
     173           0 :         goto failed;
     174           0 :     filename_ob = PyUnicode_DecodeFSDefault(filename);
     175           0 :     if (filename_ob == NULL)
     176           0 :         goto failed;
     177             : 
     178           0 :     result = PyCode_New(0,                      /* argcount */
     179             :                 0,                              /* kwonlyargcount */
     180             :                 0,                              /* nlocals */
     181             :                 0,                              /* stacksize */
     182             :                 0,                              /* flags */
     183             :                 emptystring,                    /* code */
     184             :                 nulltuple,                      /* consts */
     185             :                 nulltuple,                      /* names */
     186             :                 nulltuple,                      /* varnames */
     187             :                 nulltuple,                      /* freevars */
     188             :                 nulltuple,                      /* cellvars */
     189             :                 filename_ob,                    /* filename */
     190             :                 funcname_ob,                    /* name */
     191             :                 firstlineno,                    /* firstlineno */
     192             :                 emptystring                     /* lnotab */
     193             :                 );
     194             : 
     195             : failed:
     196           0 :     Py_XDECREF(funcname_ob);
     197           0 :     Py_XDECREF(filename_ob);
     198           0 :     return result;
     199             : }
     200             : 
     201             : #define OFF(x) offsetof(PyCodeObject, x)
     202             : 
     203             : static PyMemberDef code_memberlist[] = {
     204             :     {"co_argcount",     T_INT,          OFF(co_argcount),       READONLY},
     205             :     {"co_kwonlyargcount",       T_INT,  OFF(co_kwonlyargcount), READONLY},
     206             :     {"co_nlocals",      T_INT,          OFF(co_nlocals),        READONLY},
     207             :     {"co_stacksize",T_INT,              OFF(co_stacksize),      READONLY},
     208             :     {"co_flags",        T_INT,          OFF(co_flags),          READONLY},
     209             :     {"co_code",         T_OBJECT,       OFF(co_code),           READONLY},
     210             :     {"co_consts",       T_OBJECT,       OFF(co_consts),         READONLY},
     211             :     {"co_names",        T_OBJECT,       OFF(co_names),          READONLY},
     212             :     {"co_varnames",     T_OBJECT,       OFF(co_varnames),       READONLY},
     213             :     {"co_freevars",     T_OBJECT,       OFF(co_freevars),       READONLY},
     214             :     {"co_cellvars",     T_OBJECT,       OFF(co_cellvars),       READONLY},
     215             :     {"co_filename",     T_OBJECT,       OFF(co_filename),       READONLY},
     216             :     {"co_name",         T_OBJECT,       OFF(co_name),           READONLY},
     217             :     {"co_firstlineno", T_INT,           OFF(co_firstlineno),    READONLY},
     218             :     {"co_lnotab",       T_OBJECT,       OFF(co_lnotab),         READONLY},
     219             :     {NULL}      /* Sentinel */
     220             : };
     221             : 
     222             : /* Helper for code_new: return a shallow copy of a tuple that is
     223             :    guaranteed to contain exact strings, by converting string subclasses
     224             :    to exact strings and complaining if a non-string is found. */
     225             : static PyObject*
     226           0 : validate_and_copy_tuple(PyObject *tup)
     227             : {
     228             :     PyObject *newtuple;
     229             :     PyObject *item;
     230             :     Py_ssize_t i, len;
     231             : 
     232           0 :     len = PyTuple_GET_SIZE(tup);
     233           0 :     newtuple = PyTuple_New(len);
     234           0 :     if (newtuple == NULL)
     235           0 :         return NULL;
     236             : 
     237           0 :     for (i = 0; i < len; i++) {
     238           0 :         item = PyTuple_GET_ITEM(tup, i);
     239           0 :         if (PyUnicode_CheckExact(item)) {
     240           0 :             Py_INCREF(item);
     241             :         }
     242           0 :         else if (!PyUnicode_Check(item)) {
     243           0 :             PyErr_Format(
     244             :                 PyExc_TypeError,
     245             :                 "name tuples must contain only "
     246             :                 "strings, not '%.500s'",
     247           0 :                 item->ob_type->tp_name);
     248           0 :             Py_DECREF(newtuple);
     249           0 :             return NULL;
     250             :         }
     251             :         else {
     252           0 :             item = _PyUnicode_Copy(item);
     253           0 :             if (item == NULL) {
     254           0 :                 Py_DECREF(newtuple);
     255           0 :                 return NULL;
     256             :             }
     257             :         }
     258           0 :         PyTuple_SET_ITEM(newtuple, i, item);
     259             :     }
     260             : 
     261           0 :     return newtuple;
     262             : }
     263             : 
     264             : PyDoc_STRVAR(code_doc,
     265             : "code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\
     266             :       constants, names, varnames, filename, name, firstlineno,\n\
     267             :       lnotab[, freevars[, cellvars]])\n\
     268             : \n\
     269             : Create a code object.  Not for the faint of heart.");
     270             : 
     271             : static PyObject *
     272           0 : code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
     273             : {
     274             :     int argcount;
     275             :     int kwonlyargcount;
     276             :     int nlocals;
     277             :     int stacksize;
     278             :     int flags;
     279           0 :     PyObject *co = NULL;
     280             :     PyObject *code;
     281             :     PyObject *consts;
     282           0 :     PyObject *names, *ournames = NULL;
     283           0 :     PyObject *varnames, *ourvarnames = NULL;
     284           0 :     PyObject *freevars = NULL, *ourfreevars = NULL;
     285           0 :     PyObject *cellvars = NULL, *ourcellvars = NULL;
     286             :     PyObject *filename;
     287             :     PyObject *name;
     288             :     int firstlineno;
     289             :     PyObject *lnotab;
     290             : 
     291           0 :     if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code",
     292             :                           &argcount, &kwonlyargcount,
     293             :                               &nlocals, &stacksize, &flags,
     294             :                           &code,
     295             :                           &PyTuple_Type, &consts,
     296             :                           &PyTuple_Type, &names,
     297             :                           &PyTuple_Type, &varnames,
     298             :                           &filename, &name,
     299             :                           &firstlineno, &lnotab,
     300             :                           &PyTuple_Type, &freevars,
     301             :                           &PyTuple_Type, &cellvars))
     302           0 :         return NULL;
     303             : 
     304           0 :     if (argcount < 0) {
     305           0 :         PyErr_SetString(
     306             :             PyExc_ValueError,
     307             :             "code: argcount must not be negative");
     308           0 :         goto cleanup;
     309             :     }
     310             : 
     311           0 :     if (kwonlyargcount < 0) {
     312           0 :         PyErr_SetString(
     313             :             PyExc_ValueError,
     314             :             "code: kwonlyargcount must not be negative");
     315           0 :         goto cleanup;
     316             :     }
     317           0 :     if (nlocals < 0) {
     318           0 :         PyErr_SetString(
     319             :             PyExc_ValueError,
     320             :             "code: nlocals must not be negative");
     321           0 :         goto cleanup;
     322             :     }
     323             : 
     324           0 :     ournames = validate_and_copy_tuple(names);
     325           0 :     if (ournames == NULL)
     326           0 :         goto cleanup;
     327           0 :     ourvarnames = validate_and_copy_tuple(varnames);
     328           0 :     if (ourvarnames == NULL)
     329           0 :         goto cleanup;
     330           0 :     if (freevars)
     331           0 :         ourfreevars = validate_and_copy_tuple(freevars);
     332             :     else
     333           0 :         ourfreevars = PyTuple_New(0);
     334           0 :     if (ourfreevars == NULL)
     335           0 :         goto cleanup;
     336           0 :     if (cellvars)
     337           0 :         ourcellvars = validate_and_copy_tuple(cellvars);
     338             :     else
     339           0 :         ourcellvars = PyTuple_New(0);
     340           0 :     if (ourcellvars == NULL)
     341           0 :         goto cleanup;
     342             : 
     343           0 :     co = (PyObject *)PyCode_New(argcount, kwonlyargcount,
     344             :                                 nlocals, stacksize, flags,
     345             :                                 code, consts, ournames, ourvarnames,
     346             :                                 ourfreevars, ourcellvars, filename,
     347             :                                 name, firstlineno, lnotab);
     348             :   cleanup:
     349           0 :     Py_XDECREF(ournames);
     350           0 :     Py_XDECREF(ourvarnames);
     351           0 :     Py_XDECREF(ourfreevars);
     352           0 :     Py_XDECREF(ourcellvars);
     353           0 :     return co;
     354             : }
     355             : 
     356             : static void
     357         204 : code_dealloc(PyCodeObject *co)
     358             : {
     359         204 :     Py_XDECREF(co->co_code);
     360         204 :     Py_XDECREF(co->co_consts);
     361         204 :     Py_XDECREF(co->co_names);
     362         204 :     Py_XDECREF(co->co_varnames);
     363         204 :     Py_XDECREF(co->co_freevars);
     364         204 :     Py_XDECREF(co->co_cellvars);
     365         204 :     Py_XDECREF(co->co_filename);
     366         204 :     Py_XDECREF(co->co_name);
     367         204 :     Py_XDECREF(co->co_lnotab);
     368         204 :     if (co->co_cell2arg != NULL)
     369           1 :         PyMem_FREE(co->co_cell2arg);
     370         204 :     if (co->co_zombieframe != NULL)
     371         170 :         PyObject_GC_Del(co->co_zombieframe);
     372         204 :     if (co->co_weakreflist != NULL)
     373           0 :         PyObject_ClearWeakRefs((PyObject*)co);
     374         204 :     PyObject_DEL(co);
     375         204 : }
     376             : 
     377             : static PyObject *
     378           0 : code_sizeof(PyCodeObject *co, void *unused)
     379             : {
     380             :     Py_ssize_t res;
     381             : 
     382           0 :     res = sizeof(PyCodeObject);
     383           0 :     if (co->co_cell2arg != NULL && co->co_cellvars != NULL)
     384           0 :         res += PyTuple_GET_SIZE(co->co_cellvars) * sizeof(unsigned char);
     385           0 :     return PyLong_FromSsize_t(res);
     386             : }
     387             : 
     388             : static PyObject *
     389           0 : code_repr(PyCodeObject *co)
     390             : {
     391             :     int lineno;
     392           0 :     if (co->co_firstlineno != 0)
     393           0 :         lineno = co->co_firstlineno;
     394             :     else
     395           0 :         lineno = -1;
     396           0 :     if (co->co_filename && PyUnicode_Check(co->co_filename)) {
     397           0 :         return PyUnicode_FromFormat(
     398             :             "<code object %U at %p, file \"%U\", line %d>",
     399             :             co->co_name, co, co->co_filename, lineno);
     400             :     } else {
     401           0 :         return PyUnicode_FromFormat(
     402             :             "<code object %U at %p, file ???, line %d>",
     403             :             co->co_name, co, lineno);
     404             :     }
     405             : }
     406             : 
     407             : static PyObject *
     408           0 : code_richcompare(PyObject *self, PyObject *other, int op)
     409             : {
     410             :     PyCodeObject *co, *cp;
     411             :     int eq;
     412             :     PyObject *res;
     413             : 
     414           0 :     if ((op != Py_EQ && op != Py_NE) ||
     415           0 :         !PyCode_Check(self) ||
     416           0 :         !PyCode_Check(other)) {
     417           0 :         Py_RETURN_NOTIMPLEMENTED;
     418             :     }
     419             : 
     420           0 :     co = (PyCodeObject *)self;
     421           0 :     cp = (PyCodeObject *)other;
     422             : 
     423           0 :     eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
     424           0 :     if (eq <= 0) goto unequal;
     425           0 :     eq = co->co_argcount == cp->co_argcount;
     426           0 :     if (!eq) goto unequal;
     427           0 :     eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
     428           0 :     if (!eq) goto unequal;
     429           0 :     eq = co->co_nlocals == cp->co_nlocals;
     430           0 :     if (!eq) goto unequal;
     431           0 :     eq = co->co_flags == cp->co_flags;
     432           0 :     if (!eq) goto unequal;
     433           0 :     eq = co->co_firstlineno == cp->co_firstlineno;
     434           0 :     if (!eq) goto unequal;
     435           0 :     eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
     436           0 :     if (eq <= 0) goto unequal;
     437           0 :     eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
     438           0 :     if (eq <= 0) goto unequal;
     439           0 :     eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
     440           0 :     if (eq <= 0) goto unequal;
     441           0 :     eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
     442           0 :     if (eq <= 0) goto unequal;
     443           0 :     eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
     444           0 :     if (eq <= 0) goto unequal;
     445           0 :     eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
     446           0 :     if (eq <= 0) goto unequal;
     447             : 
     448           0 :     if (op == Py_EQ)
     449           0 :         res = Py_True;
     450             :     else
     451           0 :         res = Py_False;
     452           0 :     goto done;
     453             : 
     454             :   unequal:
     455           0 :     if (eq < 0)
     456           0 :         return NULL;
     457           0 :     if (op == Py_NE)
     458           0 :         res = Py_True;
     459             :     else
     460           0 :         res = Py_False;
     461             : 
     462             :   done:
     463           0 :     Py_INCREF(res);
     464           0 :     return res;
     465             : }
     466             : 
     467             : static Py_hash_t
     468         102 : code_hash(PyCodeObject *co)
     469             : {
     470             :     Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
     471         102 :     h0 = PyObject_Hash(co->co_name);
     472         102 :     if (h0 == -1) return -1;
     473         102 :     h1 = PyObject_Hash(co->co_code);
     474         102 :     if (h1 == -1) return -1;
     475         102 :     h2 = PyObject_Hash(co->co_consts);
     476         102 :     if (h2 == -1) return -1;
     477         102 :     h3 = PyObject_Hash(co->co_names);
     478         102 :     if (h3 == -1) return -1;
     479         102 :     h4 = PyObject_Hash(co->co_varnames);
     480         102 :     if (h4 == -1) return -1;
     481         102 :     h5 = PyObject_Hash(co->co_freevars);
     482         102 :     if (h5 == -1) return -1;
     483         102 :     h6 = PyObject_Hash(co->co_cellvars);
     484         102 :     if (h6 == -1) return -1;
     485         306 :     h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
     486         306 :         co->co_argcount ^ co->co_kwonlyargcount ^
     487         204 :         co->co_nlocals ^ co->co_flags;
     488         102 :     if (h == -1) h = -2;
     489         102 :     return h;
     490             : }
     491             : 
     492             : /* XXX code objects need to participate in GC? */
     493             : 
     494             : static struct PyMethodDef code_methods[] = {
     495             :     {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
     496             :     {NULL, NULL}                /* sentinel */
     497             : };
     498             : 
     499             : PyTypeObject PyCode_Type = {
     500             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     501             :     "code",
     502             :     sizeof(PyCodeObject),
     503             :     0,
     504             :     (destructor)code_dealloc,           /* tp_dealloc */
     505             :     0,                                  /* tp_print */
     506             :     0,                                  /* tp_getattr */
     507             :     0,                                  /* tp_setattr */
     508             :     0,                                  /* tp_reserved */
     509             :     (reprfunc)code_repr,                /* tp_repr */
     510             :     0,                                  /* tp_as_number */
     511             :     0,                                  /* tp_as_sequence */
     512             :     0,                                  /* tp_as_mapping */
     513             :     (hashfunc)code_hash,                /* tp_hash */
     514             :     0,                                  /* tp_call */
     515             :     0,                                  /* tp_str */
     516             :     PyObject_GenericGetAttr,            /* tp_getattro */
     517             :     0,                                  /* tp_setattro */
     518             :     0,                                  /* tp_as_buffer */
     519             :     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
     520             :     code_doc,                           /* tp_doc */
     521             :     0,                                  /* tp_traverse */
     522             :     0,                                  /* tp_clear */
     523             :     code_richcompare,                   /* tp_richcompare */
     524             :     offsetof(PyCodeObject, co_weakreflist),     /* tp_weaklistoffset */
     525             :     0,                                  /* tp_iter */
     526             :     0,                                  /* tp_iternext */
     527             :     code_methods,                       /* tp_methods */
     528             :     code_memberlist,                    /* tp_members */
     529             :     0,                                  /* tp_getset */
     530             :     0,                                  /* tp_base */
     531             :     0,                                  /* tp_dict */
     532             :     0,                                  /* tp_descr_get */
     533             :     0,                                  /* tp_descr_set */
     534             :     0,                                  /* tp_dictoffset */
     535             :     0,                                  /* tp_init */
     536             :     0,                                  /* tp_alloc */
     537             :     code_new,                           /* tp_new */
     538             : };
     539             : 
     540             : /* Use co_lnotab to compute the line number from a bytecode index, addrq.  See
     541             :    lnotab_notes.txt for the details of the lnotab representation.
     542             : */
     543             : 
     544             : int
     545        1273 : PyCode_Addr2Line(PyCodeObject *co, int addrq)
     546             : {
     547        1273 :     Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2;
     548        1273 :     unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab);
     549        1273 :     int line = co->co_firstlineno;
     550        1273 :     int addr = 0;
     551        7991 :     while (--size >= 0) {
     552        6011 :         addr += *p++;
     553        6011 :         if (addr > addrq)
     554         566 :             break;
     555        5445 :         line += *p++;
     556             :     }
     557        1273 :     return line;
     558             : }
     559             : 
     560             : /* Update *bounds to describe the first and one-past-the-last instructions in
     561             :    the same line as lasti.  Return the number of that line. */
     562             : int
     563           0 : _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
     564             : {
     565             :     Py_ssize_t size;
     566             :     int addr, line;
     567             :     unsigned char* p;
     568             : 
     569           0 :     p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab);
     570           0 :     size = PyBytes_GET_SIZE(co->co_lnotab) / 2;
     571             : 
     572           0 :     addr = 0;
     573           0 :     line = co->co_firstlineno;
     574             :     assert(line > 0);
     575             : 
     576             :     /* possible optimization: if f->f_lasti == instr_ub
     577             :        (likely to be a common case) then we already know
     578             :        instr_lb -- if we stored the matching value of p
     579             :        somwhere we could skip the first while loop. */
     580             : 
     581             :     /* See lnotab_notes.txt for the description of
     582             :        co_lnotab.  A point to remember: increments to p
     583             :        come in (addr, line) pairs. */
     584             : 
     585           0 :     bounds->ap_lower = 0;
     586           0 :     while (size > 0) {
     587           0 :         if (addr + *p > lasti)
     588           0 :             break;
     589           0 :         addr += *p++;
     590           0 :         if (*p)
     591           0 :             bounds->ap_lower = addr;
     592           0 :         line += *p++;
     593           0 :         --size;
     594             :     }
     595             : 
     596           0 :     if (size > 0) {
     597           0 :         while (--size >= 0) {
     598           0 :             addr += *p++;
     599           0 :             if (*p++)
     600           0 :                 break;
     601             :         }
     602           0 :         bounds->ap_upper = addr;
     603             :     }
     604             :     else {
     605           0 :         bounds->ap_upper = INT_MAX;
     606             :     }
     607             : 
     608           0 :     return line;
     609             : }

Generated by: LCOV version 1.10