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