• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdbool.h>
2 
3 #include "Python.h"
4 #include "code.h"
5 #include "structmember.h"
6 
7 #define NAME_CHARS \
8     "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
9 
10 /* Holder for co_extra information */
11 typedef struct {
12     Py_ssize_t ce_size;
13     void **ce_extras;
14 } _PyCodeObjectExtra;
15 
16 /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
17 
18 static int
all_name_chars(PyObject * o)19 all_name_chars(PyObject *o)
20 {
21     static char ok_name_char[256];
22     static const unsigned char *name_chars = (unsigned char *)NAME_CHARS;
23     const unsigned char *s, *e;
24 
25     if (!PyUnicode_Check(o) || PyUnicode_READY(o) == -1 ||
26         !PyUnicode_IS_ASCII(o))
27         return 0;
28 
29     if (ok_name_char[*name_chars] == 0) {
30         const unsigned char *p;
31         for (p = name_chars; *p; p++)
32             ok_name_char[*p] = 1;
33     }
34     s = PyUnicode_1BYTE_DATA(o);
35     e = s + PyUnicode_GET_LENGTH(o);
36     while (s != e) {
37         if (ok_name_char[*s++] == 0)
38             return 0;
39     }
40     return 1;
41 }
42 
43 static void
intern_strings(PyObject * tuple)44 intern_strings(PyObject *tuple)
45 {
46     Py_ssize_t i;
47 
48     for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
49         PyObject *v = PyTuple_GET_ITEM(tuple, i);
50         if (v == NULL || !PyUnicode_CheckExact(v)) {
51             Py_FatalError("non-string found in code slot");
52         }
53         PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
54     }
55 }
56 
57 /* Intern selected string constants */
58 static int
intern_string_constants(PyObject * tuple)59 intern_string_constants(PyObject *tuple)
60 {
61     int modified = 0;
62     Py_ssize_t i;
63 
64     for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
65         PyObject *v = PyTuple_GET_ITEM(tuple, i);
66         if (PyUnicode_CheckExact(v)) {
67             if (all_name_chars(v)) {
68                 PyObject *w = v;
69                 PyUnicode_InternInPlace(&v);
70                 if (w != v) {
71                     PyTuple_SET_ITEM(tuple, i, v);
72                     modified = 1;
73                 }
74             }
75         }
76         else if (PyTuple_CheckExact(v)) {
77             intern_string_constants(v);
78         }
79         else if (PyFrozenSet_CheckExact(v)) {
80             PyObject *w = v;
81             PyObject *tmp = PySequence_Tuple(v);
82             if (tmp == NULL) {
83                 PyErr_Clear();
84                 continue;
85             }
86             if (intern_string_constants(tmp)) {
87                 v = PyFrozenSet_New(tmp);
88                 if (v == NULL) {
89                     PyErr_Clear();
90                 }
91                 else {
92                     PyTuple_SET_ITEM(tuple, i, v);
93                     Py_DECREF(w);
94                     modified = 1;
95                 }
96             }
97             Py_DECREF(tmp);
98         }
99     }
100     return modified;
101 }
102 
103 
104 PyCodeObject *
PyCode_New(int argcount,int kwonlyargcount,int nlocals,int stacksize,int flags,PyObject * code,PyObject * consts,PyObject * names,PyObject * varnames,PyObject * freevars,PyObject * cellvars,PyObject * filename,PyObject * name,int firstlineno,PyObject * lnotab)105 PyCode_New(int argcount, int kwonlyargcount,
106            int nlocals, int stacksize, int flags,
107            PyObject *code, PyObject *consts, PyObject *names,
108            PyObject *varnames, PyObject *freevars, PyObject *cellvars,
109            PyObject *filename, PyObject *name, int firstlineno,
110            PyObject *lnotab)
111 {
112     PyCodeObject *co;
113     unsigned char *cell2arg = NULL;
114     Py_ssize_t i, n_cellvars;
115 
116     /* Check argument types */
117     if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
118         code == NULL ||
119         consts == NULL || !PyTuple_Check(consts) ||
120         names == NULL || !PyTuple_Check(names) ||
121         varnames == NULL || !PyTuple_Check(varnames) ||
122         freevars == NULL || !PyTuple_Check(freevars) ||
123         cellvars == NULL || !PyTuple_Check(cellvars) ||
124         name == NULL || !PyUnicode_Check(name) ||
125         filename == NULL || !PyUnicode_Check(filename) ||
126         lnotab == NULL || !PyBytes_Check(lnotab) ||
127         !PyObject_CheckReadBuffer(code)) {
128         PyErr_BadInternalCall();
129         return NULL;
130     }
131 
132     /* Ensure that the filename is a ready Unicode string */
133     if (PyUnicode_READY(filename) < 0)
134         return NULL;
135 
136     n_cellvars = PyTuple_GET_SIZE(cellvars);
137     intern_strings(names);
138     intern_strings(varnames);
139     intern_strings(freevars);
140     intern_strings(cellvars);
141     intern_string_constants(consts);
142     /* Create mapping between cells and arguments if needed. */
143     if (n_cellvars) {
144         Py_ssize_t total_args = argcount + kwonlyargcount +
145             ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
146         Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars;
147         bool used_cell2arg = false;
148         cell2arg = PyMem_MALLOC(alloc_size);
149         if (cell2arg == NULL)
150             return NULL;
151         memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size);
152         /* Find cells which are also arguments. */
153         for (i = 0; i < n_cellvars; i++) {
154             Py_ssize_t j;
155             PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
156             for (j = 0; j < total_args; j++) {
157                 PyObject *arg = PyTuple_GET_ITEM(varnames, j);
158                 if (!PyUnicode_Compare(cell, arg)) {
159                     cell2arg[i] = j;
160                     used_cell2arg = true;
161                     break;
162                 }
163             }
164         }
165         if (!used_cell2arg) {
166             PyMem_FREE(cell2arg);
167             cell2arg = NULL;
168         }
169     }
170     co = PyObject_NEW(PyCodeObject, &PyCode_Type);
171     if (co == NULL) {
172         if (cell2arg)
173             PyMem_FREE(cell2arg);
174         return NULL;
175     }
176     co->co_argcount = argcount;
177     co->co_kwonlyargcount = kwonlyargcount;
178     co->co_nlocals = nlocals;
179     co->co_stacksize = stacksize;
180     co->co_flags = flags;
181     Py_INCREF(code);
182     co->co_code = code;
183     Py_INCREF(consts);
184     co->co_consts = consts;
185     Py_INCREF(names);
186     co->co_names = names;
187     Py_INCREF(varnames);
188     co->co_varnames = varnames;
189     Py_INCREF(freevars);
190     co->co_freevars = freevars;
191     Py_INCREF(cellvars);
192     co->co_cellvars = cellvars;
193     co->co_cell2arg = cell2arg;
194     Py_INCREF(filename);
195     co->co_filename = filename;
196     Py_INCREF(name);
197     co->co_name = name;
198     co->co_firstlineno = firstlineno;
199     Py_INCREF(lnotab);
200     co->co_lnotab = lnotab;
201     co->co_zombieframe = NULL;
202     co->co_weakreflist = NULL;
203     co->co_extra = NULL;
204     return co;
205 }
206 
207 PyCodeObject *
PyCode_NewEmpty(const char * filename,const char * funcname,int firstlineno)208 PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
209 {
210     static PyObject *emptystring = NULL;
211     static PyObject *nulltuple = NULL;
212     PyObject *filename_ob = NULL;
213     PyObject *funcname_ob = NULL;
214     PyCodeObject *result = NULL;
215     if (emptystring == NULL) {
216         emptystring = PyBytes_FromString("");
217         if (emptystring == NULL)
218             goto failed;
219     }
220     if (nulltuple == NULL) {
221         nulltuple = PyTuple_New(0);
222         if (nulltuple == NULL)
223             goto failed;
224     }
225     funcname_ob = PyUnicode_FromString(funcname);
226     if (funcname_ob == NULL)
227         goto failed;
228     filename_ob = PyUnicode_DecodeFSDefault(filename);
229     if (filename_ob == NULL)
230         goto failed;
231 
232     result = PyCode_New(0,                      /* argcount */
233                 0,                              /* kwonlyargcount */
234                 0,                              /* nlocals */
235                 0,                              /* stacksize */
236                 0,                              /* flags */
237                 emptystring,                    /* code */
238                 nulltuple,                      /* consts */
239                 nulltuple,                      /* names */
240                 nulltuple,                      /* varnames */
241                 nulltuple,                      /* freevars */
242                 nulltuple,                      /* cellvars */
243                 filename_ob,                    /* filename */
244                 funcname_ob,                    /* name */
245                 firstlineno,                    /* firstlineno */
246                 emptystring                     /* lnotab */
247                 );
248 
249 failed:
250     Py_XDECREF(funcname_ob);
251     Py_XDECREF(filename_ob);
252     return result;
253 }
254 
255 #define OFF(x) offsetof(PyCodeObject, x)
256 
257 static PyMemberDef code_memberlist[] = {
258     {"co_argcount",     T_INT,          OFF(co_argcount),       READONLY},
259     {"co_kwonlyargcount",       T_INT,  OFF(co_kwonlyargcount), READONLY},
260     {"co_nlocals",      T_INT,          OFF(co_nlocals),        READONLY},
261     {"co_stacksize",T_INT,              OFF(co_stacksize),      READONLY},
262     {"co_flags",        T_INT,          OFF(co_flags),          READONLY},
263     {"co_code",         T_OBJECT,       OFF(co_code),           READONLY},
264     {"co_consts",       T_OBJECT,       OFF(co_consts),         READONLY},
265     {"co_names",        T_OBJECT,       OFF(co_names),          READONLY},
266     {"co_varnames",     T_OBJECT,       OFF(co_varnames),       READONLY},
267     {"co_freevars",     T_OBJECT,       OFF(co_freevars),       READONLY},
268     {"co_cellvars",     T_OBJECT,       OFF(co_cellvars),       READONLY},
269     {"co_filename",     T_OBJECT,       OFF(co_filename),       READONLY},
270     {"co_name",         T_OBJECT,       OFF(co_name),           READONLY},
271     {"co_firstlineno", T_INT,           OFF(co_firstlineno),    READONLY},
272     {"co_lnotab",       T_OBJECT,       OFF(co_lnotab),         READONLY},
273     {NULL}      /* Sentinel */
274 };
275 
276 /* Helper for code_new: return a shallow copy of a tuple that is
277    guaranteed to contain exact strings, by converting string subclasses
278    to exact strings and complaining if a non-string is found. */
279 static PyObject*
validate_and_copy_tuple(PyObject * tup)280 validate_and_copy_tuple(PyObject *tup)
281 {
282     PyObject *newtuple;
283     PyObject *item;
284     Py_ssize_t i, len;
285 
286     len = PyTuple_GET_SIZE(tup);
287     newtuple = PyTuple_New(len);
288     if (newtuple == NULL)
289         return NULL;
290 
291     for (i = 0; i < len; i++) {
292         item = PyTuple_GET_ITEM(tup, i);
293         if (PyUnicode_CheckExact(item)) {
294             Py_INCREF(item);
295         }
296         else if (!PyUnicode_Check(item)) {
297             PyErr_Format(
298                 PyExc_TypeError,
299                 "name tuples must contain only "
300                 "strings, not '%.500s'",
301                 item->ob_type->tp_name);
302             Py_DECREF(newtuple);
303             return NULL;
304         }
305         else {
306             item = _PyUnicode_Copy(item);
307             if (item == NULL) {
308                 Py_DECREF(newtuple);
309                 return NULL;
310             }
311         }
312         PyTuple_SET_ITEM(newtuple, i, item);
313     }
314 
315     return newtuple;
316 }
317 
318 PyDoc_STRVAR(code_doc,
319 "code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\
320       constants, names, varnames, filename, name, firstlineno,\n\
321       lnotab[, freevars[, cellvars]])\n\
322 \n\
323 Create a code object.  Not for the faint of heart.");
324 
325 static PyObject *
code_new(PyTypeObject * type,PyObject * args,PyObject * kw)326 code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
327 {
328     int argcount;
329     int kwonlyargcount;
330     int nlocals;
331     int stacksize;
332     int flags;
333     PyObject *co = NULL;
334     PyObject *code;
335     PyObject *consts;
336     PyObject *names, *ournames = NULL;
337     PyObject *varnames, *ourvarnames = NULL;
338     PyObject *freevars = NULL, *ourfreevars = NULL;
339     PyObject *cellvars = NULL, *ourcellvars = NULL;
340     PyObject *filename;
341     PyObject *name;
342     int firstlineno;
343     PyObject *lnotab;
344 
345     if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code",
346                           &argcount, &kwonlyargcount,
347                               &nlocals, &stacksize, &flags,
348                           &code,
349                           &PyTuple_Type, &consts,
350                           &PyTuple_Type, &names,
351                           &PyTuple_Type, &varnames,
352                           &filename, &name,
353                           &firstlineno, &lnotab,
354                           &PyTuple_Type, &freevars,
355                           &PyTuple_Type, &cellvars))
356         return NULL;
357 
358     if (argcount < 0) {
359         PyErr_SetString(
360             PyExc_ValueError,
361             "code: argcount must not be negative");
362         goto cleanup;
363     }
364 
365     if (kwonlyargcount < 0) {
366         PyErr_SetString(
367             PyExc_ValueError,
368             "code: kwonlyargcount must not be negative");
369         goto cleanup;
370     }
371     if (nlocals < 0) {
372         PyErr_SetString(
373             PyExc_ValueError,
374             "code: nlocals must not be negative");
375         goto cleanup;
376     }
377 
378     ournames = validate_and_copy_tuple(names);
379     if (ournames == NULL)
380         goto cleanup;
381     ourvarnames = validate_and_copy_tuple(varnames);
382     if (ourvarnames == NULL)
383         goto cleanup;
384     if (freevars)
385         ourfreevars = validate_and_copy_tuple(freevars);
386     else
387         ourfreevars = PyTuple_New(0);
388     if (ourfreevars == NULL)
389         goto cleanup;
390     if (cellvars)
391         ourcellvars = validate_and_copy_tuple(cellvars);
392     else
393         ourcellvars = PyTuple_New(0);
394     if (ourcellvars == NULL)
395         goto cleanup;
396 
397     co = (PyObject *)PyCode_New(argcount, kwonlyargcount,
398                                 nlocals, stacksize, flags,
399                                 code, consts, ournames, ourvarnames,
400                                 ourfreevars, ourcellvars, filename,
401                                 name, firstlineno, lnotab);
402   cleanup:
403     Py_XDECREF(ournames);
404     Py_XDECREF(ourvarnames);
405     Py_XDECREF(ourfreevars);
406     Py_XDECREF(ourcellvars);
407     return co;
408 }
409 
410 static void
code_dealloc(PyCodeObject * co)411 code_dealloc(PyCodeObject *co)
412 {
413     if (co->co_extra != NULL) {
414         PyThreadState *tstate = PyThreadState_Get();
415         _PyCodeObjectExtra *co_extra = co->co_extra;
416 
417         for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
418             freefunc free_extra = tstate->co_extra_freefuncs[i];
419 
420             if (free_extra != NULL) {
421                 free_extra(co_extra->ce_extras[i]);
422             }
423         }
424 
425         PyMem_FREE(co->co_extra);
426     }
427 
428     Py_XDECREF(co->co_code);
429     Py_XDECREF(co->co_consts);
430     Py_XDECREF(co->co_names);
431     Py_XDECREF(co->co_varnames);
432     Py_XDECREF(co->co_freevars);
433     Py_XDECREF(co->co_cellvars);
434     Py_XDECREF(co->co_filename);
435     Py_XDECREF(co->co_name);
436     Py_XDECREF(co->co_lnotab);
437     if (co->co_cell2arg != NULL)
438         PyMem_FREE(co->co_cell2arg);
439     if (co->co_zombieframe != NULL)
440         PyObject_GC_Del(co->co_zombieframe);
441     if (co->co_weakreflist != NULL)
442         PyObject_ClearWeakRefs((PyObject*)co);
443     PyObject_DEL(co);
444 }
445 
446 static PyObject *
code_sizeof(PyCodeObject * co,void * unused)447 code_sizeof(PyCodeObject *co, void *unused)
448 {
449     Py_ssize_t res;
450 
451     res = _PyObject_SIZE(Py_TYPE(co));
452     if (co->co_cell2arg != NULL && co->co_cellvars != NULL)
453         res += PyTuple_GET_SIZE(co->co_cellvars) * sizeof(unsigned char);
454     return PyLong_FromSsize_t(res);
455 }
456 
457 static PyObject *
code_repr(PyCodeObject * co)458 code_repr(PyCodeObject *co)
459 {
460     int lineno;
461     if (co->co_firstlineno != 0)
462         lineno = co->co_firstlineno;
463     else
464         lineno = -1;
465     if (co->co_filename && PyUnicode_Check(co->co_filename)) {
466         return PyUnicode_FromFormat(
467             "<code object %U at %p, file \"%U\", line %d>",
468             co->co_name, co, co->co_filename, lineno);
469     } else {
470         return PyUnicode_FromFormat(
471             "<code object %U at %p, file ???, line %d>",
472             co->co_name, co, lineno);
473     }
474 }
475 
476 PyObject*
_PyCode_ConstantKey(PyObject * op)477 _PyCode_ConstantKey(PyObject *op)
478 {
479     PyObject *key;
480 
481     /* Py_None and Py_Ellipsis are singleton */
482     if (op == Py_None || op == Py_Ellipsis
483        || PyLong_CheckExact(op)
484        || PyBool_Check(op)
485        || PyBytes_CheckExact(op)
486        || PyUnicode_CheckExact(op)
487           /* code_richcompare() uses _PyCode_ConstantKey() internally */
488        || PyCode_Check(op)) {
489         key = PyTuple_Pack(2, Py_TYPE(op), op);
490     }
491     else if (PyFloat_CheckExact(op)) {
492         double d = PyFloat_AS_DOUBLE(op);
493         /* all we need is to make the tuple different in either the 0.0
494          * or -0.0 case from all others, just to avoid the "coercion".
495          */
496         if (d == 0.0 && copysign(1.0, d) < 0.0)
497             key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
498         else
499             key = PyTuple_Pack(2, Py_TYPE(op), op);
500     }
501     else if (PyComplex_CheckExact(op)) {
502         Py_complex z;
503         int real_negzero, imag_negzero;
504         /* For the complex case we must make complex(x, 0.)
505            different from complex(x, -0.) and complex(0., y)
506            different from complex(-0., y), for any x and y.
507            All four complex zeros must be distinguished.*/
508         z = PyComplex_AsCComplex(op);
509         real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
510         imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
511         /* use True, False and None singleton as tags for the real and imag
512          * sign, to make tuples different */
513         if (real_negzero && imag_negzero) {
514             key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
515         }
516         else if (imag_negzero) {
517             key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
518         }
519         else if (real_negzero) {
520             key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
521         }
522         else {
523             key = PyTuple_Pack(2, Py_TYPE(op), op);
524         }
525     }
526     else if (PyTuple_CheckExact(op)) {
527         Py_ssize_t i, len;
528         PyObject *tuple;
529 
530         len = PyTuple_GET_SIZE(op);
531         tuple = PyTuple_New(len);
532         if (tuple == NULL)
533             return NULL;
534 
535         for (i=0; i < len; i++) {
536             PyObject *item, *item_key;
537 
538             item = PyTuple_GET_ITEM(op, i);
539             item_key = _PyCode_ConstantKey(item);
540             if (item_key == NULL) {
541                 Py_DECREF(tuple);
542                 return NULL;
543             }
544 
545             PyTuple_SET_ITEM(tuple, i, item_key);
546         }
547 
548         key = PyTuple_Pack(2, tuple, op);
549         Py_DECREF(tuple);
550     }
551     else if (PyFrozenSet_CheckExact(op)) {
552         Py_ssize_t pos = 0;
553         PyObject *item;
554         Py_hash_t hash;
555         Py_ssize_t i, len;
556         PyObject *tuple, *set;
557 
558         len = PySet_GET_SIZE(op);
559         tuple = PyTuple_New(len);
560         if (tuple == NULL)
561             return NULL;
562 
563         i = 0;
564         while (_PySet_NextEntry(op, &pos, &item, &hash)) {
565             PyObject *item_key;
566 
567             item_key = _PyCode_ConstantKey(item);
568             if (item_key == NULL) {
569                 Py_DECREF(tuple);
570                 return NULL;
571             }
572 
573             assert(i < len);
574             PyTuple_SET_ITEM(tuple, i, item_key);
575             i++;
576         }
577         set = PyFrozenSet_New(tuple);
578         Py_DECREF(tuple);
579         if (set == NULL)
580             return NULL;
581 
582         key = PyTuple_Pack(2, set, op);
583         Py_DECREF(set);
584         return key;
585     }
586     else {
587         /* for other types, use the object identifier as a unique identifier
588          * to ensure that they are seen as unequal. */
589         PyObject *obj_id = PyLong_FromVoidPtr(op);
590         if (obj_id == NULL)
591             return NULL;
592 
593         key = PyTuple_Pack(2, obj_id, op);
594         Py_DECREF(obj_id);
595     }
596     return key;
597 }
598 
599 static PyObject *
code_richcompare(PyObject * self,PyObject * other,int op)600 code_richcompare(PyObject *self, PyObject *other, int op)
601 {
602     PyCodeObject *co, *cp;
603     int eq;
604     PyObject *consts1, *consts2;
605     PyObject *res;
606 
607     if ((op != Py_EQ && op != Py_NE) ||
608         !PyCode_Check(self) ||
609         !PyCode_Check(other)) {
610         Py_RETURN_NOTIMPLEMENTED;
611     }
612 
613     co = (PyCodeObject *)self;
614     cp = (PyCodeObject *)other;
615 
616     eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
617     if (eq <= 0) goto unequal;
618     eq = co->co_argcount == cp->co_argcount;
619     if (!eq) goto unequal;
620     eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
621     if (!eq) goto unequal;
622     eq = co->co_nlocals == cp->co_nlocals;
623     if (!eq) goto unequal;
624     eq = co->co_flags == cp->co_flags;
625     if (!eq) goto unequal;
626     eq = co->co_firstlineno == cp->co_firstlineno;
627     if (!eq) goto unequal;
628     eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
629     if (eq <= 0) goto unequal;
630 
631     /* compare constants */
632     consts1 = _PyCode_ConstantKey(co->co_consts);
633     if (!consts1)
634         return NULL;
635     consts2 = _PyCode_ConstantKey(cp->co_consts);
636     if (!consts2) {
637         Py_DECREF(consts1);
638         return NULL;
639     }
640     eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
641     Py_DECREF(consts1);
642     Py_DECREF(consts2);
643     if (eq <= 0) goto unequal;
644 
645     eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
646     if (eq <= 0) goto unequal;
647     eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
648     if (eq <= 0) goto unequal;
649     eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
650     if (eq <= 0) goto unequal;
651     eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
652     if (eq <= 0) goto unequal;
653 
654     if (op == Py_EQ)
655         res = Py_True;
656     else
657         res = Py_False;
658     goto done;
659 
660   unequal:
661     if (eq < 0)
662         return NULL;
663     if (op == Py_NE)
664         res = Py_True;
665     else
666         res = Py_False;
667 
668   done:
669     Py_INCREF(res);
670     return res;
671 }
672 
673 static Py_hash_t
code_hash(PyCodeObject * co)674 code_hash(PyCodeObject *co)
675 {
676     Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
677     h0 = PyObject_Hash(co->co_name);
678     if (h0 == -1) return -1;
679     h1 = PyObject_Hash(co->co_code);
680     if (h1 == -1) return -1;
681     h2 = PyObject_Hash(co->co_consts);
682     if (h2 == -1) return -1;
683     h3 = PyObject_Hash(co->co_names);
684     if (h3 == -1) return -1;
685     h4 = PyObject_Hash(co->co_varnames);
686     if (h4 == -1) return -1;
687     h5 = PyObject_Hash(co->co_freevars);
688     if (h5 == -1) return -1;
689     h6 = PyObject_Hash(co->co_cellvars);
690     if (h6 == -1) return -1;
691     h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
692         co->co_argcount ^ co->co_kwonlyargcount ^
693         co->co_nlocals ^ co->co_flags;
694     if (h == -1) h = -2;
695     return h;
696 }
697 
698 /* XXX code objects need to participate in GC? */
699 
700 static struct PyMethodDef code_methods[] = {
701     {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
702     {NULL, NULL}                /* sentinel */
703 };
704 
705 PyTypeObject PyCode_Type = {
706     PyVarObject_HEAD_INIT(&PyType_Type, 0)
707     "code",
708     sizeof(PyCodeObject),
709     0,
710     (destructor)code_dealloc,           /* tp_dealloc */
711     0,                                  /* tp_print */
712     0,                                  /* tp_getattr */
713     0,                                  /* tp_setattr */
714     0,                                  /* tp_reserved */
715     (reprfunc)code_repr,                /* tp_repr */
716     0,                                  /* tp_as_number */
717     0,                                  /* tp_as_sequence */
718     0,                                  /* tp_as_mapping */
719     (hashfunc)code_hash,                /* tp_hash */
720     0,                                  /* tp_call */
721     0,                                  /* tp_str */
722     PyObject_GenericGetAttr,            /* tp_getattro */
723     0,                                  /* tp_setattro */
724     0,                                  /* tp_as_buffer */
725     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
726     code_doc,                           /* tp_doc */
727     0,                                  /* tp_traverse */
728     0,                                  /* tp_clear */
729     code_richcompare,                   /* tp_richcompare */
730     offsetof(PyCodeObject, co_weakreflist),     /* tp_weaklistoffset */
731     0,                                  /* tp_iter */
732     0,                                  /* tp_iternext */
733     code_methods,                       /* tp_methods */
734     code_memberlist,                    /* tp_members */
735     0,                                  /* tp_getset */
736     0,                                  /* tp_base */
737     0,                                  /* tp_dict */
738     0,                                  /* tp_descr_get */
739     0,                                  /* tp_descr_set */
740     0,                                  /* tp_dictoffset */
741     0,                                  /* tp_init */
742     0,                                  /* tp_alloc */
743     code_new,                           /* tp_new */
744 };
745 
746 /* Use co_lnotab to compute the line number from a bytecode index, addrq.  See
747    lnotab_notes.txt for the details of the lnotab representation.
748 */
749 
750 int
PyCode_Addr2Line(PyCodeObject * co,int addrq)751 PyCode_Addr2Line(PyCodeObject *co, int addrq)
752 {
753     Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2;
754     unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab);
755     int line = co->co_firstlineno;
756     int addr = 0;
757     while (--size >= 0) {
758         addr += *p++;
759         if (addr > addrq)
760             break;
761         line += (signed char)*p;
762         p++;
763     }
764     return line;
765 }
766 
767 /* Update *bounds to describe the first and one-past-the-last instructions in
768    the same line as lasti.  Return the number of that line. */
769 int
_PyCode_CheckLineNumber(PyCodeObject * co,int lasti,PyAddrPair * bounds)770 _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
771 {
772     Py_ssize_t size;
773     int addr, line;
774     unsigned char* p;
775 
776     p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab);
777     size = PyBytes_GET_SIZE(co->co_lnotab) / 2;
778 
779     addr = 0;
780     line = co->co_firstlineno;
781     assert(line > 0);
782 
783     /* possible optimization: if f->f_lasti == instr_ub
784        (likely to be a common case) then we already know
785        instr_lb -- if we stored the matching value of p
786        somewhere we could skip the first while loop. */
787 
788     /* See lnotab_notes.txt for the description of
789        co_lnotab.  A point to remember: increments to p
790        come in (addr, line) pairs. */
791 
792     bounds->ap_lower = 0;
793     while (size > 0) {
794         if (addr + *p > lasti)
795             break;
796         addr += *p++;
797         if ((signed char)*p)
798             bounds->ap_lower = addr;
799         line += (signed char)*p;
800         p++;
801         --size;
802     }
803 
804     if (size > 0) {
805         while (--size >= 0) {
806             addr += *p++;
807             if ((signed char)*p)
808                 break;
809             p++;
810         }
811         bounds->ap_upper = addr;
812     }
813     else {
814         bounds->ap_upper = INT_MAX;
815     }
816 
817     return line;
818 }
819 
820 
821 int
_PyCode_GetExtra(PyObject * code,Py_ssize_t index,void ** extra)822 _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
823 {
824     assert(*extra == NULL);
825 
826     if (!PyCode_Check(code)) {
827         PyErr_BadInternalCall();
828         return -1;
829     }
830 
831     PyCodeObject *o = (PyCodeObject*) code;
832     _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra;
833 
834 
835     if (co_extra == NULL || co_extra->ce_size <= index) {
836         return 0;
837     }
838 
839     *extra = co_extra->ce_extras[index];
840     return 0;
841 }
842 
843 
844 int
_PyCode_SetExtra(PyObject * code,Py_ssize_t index,void * extra)845 _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
846 {
847     PyThreadState *tstate = PyThreadState_Get();
848 
849     if (!PyCode_Check(code) || index < 0 ||
850             index >= tstate->co_extra_user_count) {
851         PyErr_BadInternalCall();
852         return -1;
853     }
854 
855     PyCodeObject *o = (PyCodeObject*) code;
856     _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra;
857 
858     if (co_extra == NULL) {
859         co_extra = PyMem_Malloc(sizeof(_PyCodeObjectExtra));
860         if (co_extra == NULL) {
861             return -1;
862         }
863 
864         co_extra->ce_extras = PyMem_Malloc(
865             tstate->co_extra_user_count * sizeof(void*));
866         if (co_extra->ce_extras == NULL) {
867             PyMem_Free(co_extra);
868             return -1;
869         }
870 
871         co_extra->ce_size = tstate->co_extra_user_count;
872 
873         for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
874             co_extra->ce_extras[i] = NULL;
875         }
876 
877         o->co_extra = co_extra;
878     }
879     else if (co_extra->ce_size <= index) {
880         void** ce_extras = PyMem_Realloc(
881             co_extra->ce_extras, tstate->co_extra_user_count * sizeof(void*));
882 
883         if (ce_extras == NULL) {
884             return -1;
885         }
886 
887         for (Py_ssize_t i = co_extra->ce_size;
888              i < tstate->co_extra_user_count;
889              i++) {
890             ce_extras[i] = NULL;
891         }
892 
893         co_extra->ce_extras = ce_extras;
894         co_extra->ce_size = tstate->co_extra_user_count;
895     }
896 
897     co_extra->ce_extras[index] = extra;
898     return 0;
899 }
900