1 #include <stdbool.h>
2 
3 #include "Python.h"
4 #include "opcode.h"
5 #include "structmember.h"         // PyMemberDef
6 #include "pycore_code.h"          // _PyCodeConstructor
7 #include "pycore_interp.h"        // PyInterpreterState.co_extra_freefuncs
8 #include "pycore_opcode.h"        // _PyOpcode_Deopt
9 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
10 #include "pycore_tuple.h"         // _PyTuple_ITEMS()
11 #include "clinic/codeobject.c.h"
12 
13 
14 /******************
15  * generic helpers
16  ******************/
17 
18 /* all_name_chars(s): true iff s matches [a-zA-Z0-9_]* */
19 static int
all_name_chars(PyObject * o)20 all_name_chars(PyObject *o)
21 {
22     const unsigned char *s, *e;
23 
24     if (!PyUnicode_IS_ASCII(o))
25         return 0;
26 
27     s = PyUnicode_1BYTE_DATA(o);
28     e = s + PyUnicode_GET_LENGTH(o);
29     for (; s != e; s++) {
30         if (!Py_ISALNUM(*s) && *s != '_')
31             return 0;
32     }
33     return 1;
34 }
35 
36 static int
intern_strings(PyObject * tuple)37 intern_strings(PyObject *tuple)
38 {
39     Py_ssize_t i;
40 
41     for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
42         PyObject *v = PyTuple_GET_ITEM(tuple, i);
43         if (v == NULL || !PyUnicode_CheckExact(v)) {
44             PyErr_SetString(PyExc_SystemError,
45                             "non-string found in code slot");
46             return -1;
47         }
48         PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]);
49     }
50     return 0;
51 }
52 
53 /* Intern selected string constants */
54 static int
intern_string_constants(PyObject * tuple,int * modified)55 intern_string_constants(PyObject *tuple, int *modified)
56 {
57     for (Py_ssize_t i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
58         PyObject *v = PyTuple_GET_ITEM(tuple, i);
59         if (PyUnicode_CheckExact(v)) {
60             if (PyUnicode_READY(v) == -1) {
61                 return -1;
62             }
63 
64             if (all_name_chars(v)) {
65                 PyObject *w = v;
66                 PyUnicode_InternInPlace(&v);
67                 if (w != v) {
68                     PyTuple_SET_ITEM(tuple, i, v);
69                     if (modified) {
70                         *modified = 1;
71                     }
72                 }
73             }
74         }
75         else if (PyTuple_CheckExact(v)) {
76             if (intern_string_constants(v, NULL) < 0) {
77                 return -1;
78             }
79         }
80         else if (PyFrozenSet_CheckExact(v)) {
81             PyObject *w = v;
82             PyObject *tmp = PySequence_Tuple(v);
83             if (tmp == NULL) {
84                 return -1;
85             }
86             int tmp_modified = 0;
87             if (intern_string_constants(tmp, &tmp_modified) < 0) {
88                 Py_DECREF(tmp);
89                 return -1;
90             }
91             if (tmp_modified) {
92                 v = PyFrozenSet_New(tmp);
93                 if (v == NULL) {
94                     Py_DECREF(tmp);
95                     return -1;
96                 }
97 
98                 PyTuple_SET_ITEM(tuple, i, v);
99                 Py_DECREF(w);
100                 if (modified) {
101                     *modified = 1;
102                 }
103             }
104             Py_DECREF(tmp);
105         }
106     }
107     return 0;
108 }
109 
110 /* Return a shallow copy of a tuple that is
111    guaranteed to contain exact strings, by converting string subclasses
112    to exact strings and complaining if a non-string is found. */
113 static PyObject*
validate_and_copy_tuple(PyObject * tup)114 validate_and_copy_tuple(PyObject *tup)
115 {
116     PyObject *newtuple;
117     PyObject *item;
118     Py_ssize_t i, len;
119 
120     len = PyTuple_GET_SIZE(tup);
121     newtuple = PyTuple_New(len);
122     if (newtuple == NULL)
123         return NULL;
124 
125     for (i = 0; i < len; i++) {
126         item = PyTuple_GET_ITEM(tup, i);
127         if (PyUnicode_CheckExact(item)) {
128             Py_INCREF(item);
129         }
130         else if (!PyUnicode_Check(item)) {
131             PyErr_Format(
132                 PyExc_TypeError,
133                 "name tuples must contain only "
134                 "strings, not '%.500s'",
135                 Py_TYPE(item)->tp_name);
136             Py_DECREF(newtuple);
137             return NULL;
138         }
139         else {
140             item = _PyUnicode_Copy(item);
141             if (item == NULL) {
142                 Py_DECREF(newtuple);
143                 return NULL;
144             }
145         }
146         PyTuple_SET_ITEM(newtuple, i, item);
147     }
148 
149     return newtuple;
150 }
151 
152 
153 /******************
154  * _PyCode_New()
155  ******************/
156 
157 // This is also used in compile.c.
158 void
_Py_set_localsplus_info(int offset,PyObject * name,_PyLocals_Kind kind,PyObject * names,PyObject * kinds)159 _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
160                         PyObject *names, PyObject *kinds)
161 {
162     Py_INCREF(name);
163     PyTuple_SET_ITEM(names, offset, name);
164     _PyLocals_SetKind(kinds, offset, kind);
165 }
166 
167 static void
get_localsplus_counts(PyObject * names,PyObject * kinds,int * pnlocals,int * pnplaincellvars,int * pncellvars,int * pnfreevars)168 get_localsplus_counts(PyObject *names, PyObject *kinds,
169                       int *pnlocals, int *pnplaincellvars, int *pncellvars,
170                       int *pnfreevars)
171 {
172     int nlocals = 0;
173     int nplaincellvars = 0;
174     int ncellvars = 0;
175     int nfreevars = 0;
176     Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
177     for (int i = 0; i < nlocalsplus; i++) {
178         _PyLocals_Kind kind = _PyLocals_GetKind(kinds, i);
179         if (kind & CO_FAST_LOCAL) {
180             nlocals += 1;
181             if (kind & CO_FAST_CELL) {
182                 ncellvars += 1;
183             }
184         }
185         else if (kind & CO_FAST_CELL) {
186             ncellvars += 1;
187             nplaincellvars += 1;
188         }
189         else if (kind & CO_FAST_FREE) {
190             nfreevars += 1;
191         }
192     }
193     if (pnlocals != NULL) {
194         *pnlocals = nlocals;
195     }
196     if (pnplaincellvars != NULL) {
197         *pnplaincellvars = nplaincellvars;
198     }
199     if (pncellvars != NULL) {
200         *pncellvars = ncellvars;
201     }
202     if (pnfreevars != NULL) {
203         *pnfreevars = nfreevars;
204     }
205 }
206 
207 static PyObject *
get_localsplus_names(PyCodeObject * co,_PyLocals_Kind kind,int num)208 get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num)
209 {
210     PyObject *names = PyTuple_New(num);
211     if (names == NULL) {
212         return NULL;
213     }
214     int index = 0;
215     for (int offset = 0; offset < co->co_nlocalsplus; offset++) {
216         _PyLocals_Kind k = _PyLocals_GetKind(co->co_localspluskinds, offset);
217         if ((k & kind) == 0) {
218             continue;
219         }
220         assert(index < num);
221         PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, offset);
222         Py_INCREF(name);
223         PyTuple_SET_ITEM(names, index, name);
224         index += 1;
225     }
226     assert(index == num);
227     return names;
228 }
229 
230 int
_PyCode_Validate(struct _PyCodeConstructor * con)231 _PyCode_Validate(struct _PyCodeConstructor *con)
232 {
233     /* Check argument types */
234     if (con->argcount < con->posonlyargcount || con->posonlyargcount < 0 ||
235         con->kwonlyargcount < 0 ||
236         con->stacksize < 0 || con->flags < 0 ||
237         con->code == NULL || !PyBytes_Check(con->code) ||
238         con->consts == NULL || !PyTuple_Check(con->consts) ||
239         con->names == NULL || !PyTuple_Check(con->names) ||
240         con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) ||
241         con->localspluskinds == NULL || !PyBytes_Check(con->localspluskinds) ||
242         PyTuple_GET_SIZE(con->localsplusnames)
243             != PyBytes_GET_SIZE(con->localspluskinds) ||
244         con->name == NULL || !PyUnicode_Check(con->name) ||
245         con->qualname == NULL || !PyUnicode_Check(con->qualname) ||
246         con->filename == NULL || !PyUnicode_Check(con->filename) ||
247         con->linetable == NULL || !PyBytes_Check(con->linetable) ||
248         con->exceptiontable == NULL || !PyBytes_Check(con->exceptiontable)
249         ) {
250         PyErr_BadInternalCall();
251         return -1;
252     }
253 
254     /* Make sure that code is indexable with an int, this is
255        a long running assumption in ceval.c and many parts of
256        the interpreter. */
257     if (PyBytes_GET_SIZE(con->code) > INT_MAX) {
258         PyErr_SetString(PyExc_OverflowError,
259                         "code: co_code larger than INT_MAX");
260         return -1;
261     }
262     if (PyBytes_GET_SIZE(con->code) % sizeof(_Py_CODEUNIT) != 0 ||
263         !_Py_IS_ALIGNED(PyBytes_AS_STRING(con->code), sizeof(_Py_CODEUNIT))
264         ) {
265         PyErr_SetString(PyExc_ValueError, "code: co_code is malformed");
266         return -1;
267     }
268 
269     /* Ensure that the co_varnames has enough names to cover the arg counts.
270      * Note that totalargs = nlocals - nplainlocals.  We check nplainlocals
271      * here to avoid the possibility of overflow (however remote). */
272     int nlocals;
273     get_localsplus_counts(con->localsplusnames, con->localspluskinds,
274                           &nlocals, NULL, NULL, NULL);
275     int nplainlocals = nlocals -
276                        con->argcount -
277                        con->kwonlyargcount -
278                        ((con->flags & CO_VARARGS) != 0) -
279                        ((con->flags & CO_VARKEYWORDS) != 0);
280     if (nplainlocals < 0) {
281         PyErr_SetString(PyExc_ValueError, "code: co_varnames is too small");
282         return -1;
283     }
284 
285     return 0;
286 }
287 
288 static void
init_code(PyCodeObject * co,struct _PyCodeConstructor * con)289 init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
290 {
291     int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames);
292     int nlocals, nplaincellvars, ncellvars, nfreevars;
293     get_localsplus_counts(con->localsplusnames, con->localspluskinds,
294                           &nlocals, &nplaincellvars, &ncellvars, &nfreevars);
295 
296     Py_INCREF(con->filename);
297     co->co_filename = con->filename;
298     Py_INCREF(con->name);
299     co->co_name = con->name;
300     Py_INCREF(con->qualname);
301     co->co_qualname = con->qualname;
302     co->co_flags = con->flags;
303 
304     co->co_firstlineno = con->firstlineno;
305     Py_INCREF(con->linetable);
306     co->co_linetable = con->linetable;
307 
308     Py_INCREF(con->consts);
309     co->co_consts = con->consts;
310     Py_INCREF(con->names);
311     co->co_names = con->names;
312 
313     Py_INCREF(con->localsplusnames);
314     co->co_localsplusnames = con->localsplusnames;
315     Py_INCREF(con->localspluskinds);
316     co->co_localspluskinds = con->localspluskinds;
317 
318     co->co_argcount = con->argcount;
319     co->co_posonlyargcount = con->posonlyargcount;
320     co->co_kwonlyargcount = con->kwonlyargcount;
321 
322     co->co_stacksize = con->stacksize;
323 
324     Py_INCREF(con->exceptiontable);
325     co->co_exceptiontable = con->exceptiontable;
326 
327     /* derived values */
328     co->co_nlocalsplus = nlocalsplus;
329     co->co_nlocals = nlocals;
330     co->co_nplaincellvars = nplaincellvars;
331     co->co_ncellvars = ncellvars;
332     co->co_nfreevars = nfreevars;
333 
334     /* not set */
335     co->co_weakreflist = NULL;
336     co->co_extra = NULL;
337     co->_co_code = NULL;
338 
339     co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
340     co->_co_linearray_entry_size = 0;
341     co->_co_linearray = NULL;
342     memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code),
343            PyBytes_GET_SIZE(con->code));
344     int entry_point = 0;
345     while (entry_point < Py_SIZE(co) &&
346         _Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) {
347         entry_point++;
348     }
349     co->_co_firsttraceable = entry_point;
350 }
351 
352 static int
scan_varint(const uint8_t * ptr)353 scan_varint(const uint8_t *ptr)
354 {
355     unsigned int read = *ptr++;
356     unsigned int val = read & 63;
357     unsigned int shift = 0;
358     while (read & 64) {
359         read = *ptr++;
360         shift += 6;
361         val |= (read & 63) << shift;
362     }
363     return val;
364 }
365 
366 static int
scan_signed_varint(const uint8_t * ptr)367 scan_signed_varint(const uint8_t *ptr)
368 {
369     unsigned int uval = scan_varint(ptr);
370     if (uval & 1) {
371         return -(int)(uval >> 1);
372     }
373     else {
374         return uval >> 1;
375     }
376 }
377 
378 static int
get_line_delta(const uint8_t * ptr)379 get_line_delta(const uint8_t *ptr)
380 {
381     int code = ((*ptr) >> 3) & 15;
382     switch (code) {
383         case PY_CODE_LOCATION_INFO_NONE:
384             return 0;
385         case PY_CODE_LOCATION_INFO_NO_COLUMNS:
386         case PY_CODE_LOCATION_INFO_LONG:
387             return scan_signed_varint(ptr+1);
388         case PY_CODE_LOCATION_INFO_ONE_LINE0:
389             return 0;
390         case PY_CODE_LOCATION_INFO_ONE_LINE1:
391             return 1;
392         case PY_CODE_LOCATION_INFO_ONE_LINE2:
393             return 2;
394         default:
395             /* Same line */
396             return 0;
397     }
398 }
399 
400 static PyObject *
remove_column_info(PyObject * locations)401 remove_column_info(PyObject *locations)
402 {
403     int offset = 0;
404     const uint8_t *data = (const uint8_t *)PyBytes_AS_STRING(locations);
405     PyObject *res = PyBytes_FromStringAndSize(NULL, 32);
406     if (res == NULL) {
407         PyErr_NoMemory();
408         return NULL;
409     }
410     uint8_t *output = (uint8_t *)PyBytes_AS_STRING(res);
411     while (offset < PyBytes_GET_SIZE(locations)) {
412         Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
413         if (write_offset + 16 >= PyBytes_GET_SIZE(res)) {
414             if (_PyBytes_Resize(&res, PyBytes_GET_SIZE(res) * 2) < 0) {
415                 return NULL;
416             }
417             output = (uint8_t *)PyBytes_AS_STRING(res) + write_offset;
418         }
419         int code = (data[offset] >> 3) & 15;
420         if (code == PY_CODE_LOCATION_INFO_NONE) {
421             *output++ = data[offset];
422         }
423         else {
424             int blength = (data[offset] & 7)+1;
425             output += write_location_entry_start(
426                 output, PY_CODE_LOCATION_INFO_NO_COLUMNS, blength);
427             int ldelta = get_line_delta(&data[offset]);
428             output += write_signed_varint(output, ldelta);
429         }
430         offset++;
431         while (offset < PyBytes_GET_SIZE(locations) &&
432             (data[offset] & 128) == 0) {
433             offset++;
434         }
435     }
436     Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
437     if (_PyBytes_Resize(&res, write_offset)) {
438         return NULL;
439     }
440     return res;
441 }
442 
443 /* The caller is responsible for ensuring that the given data is valid. */
444 
445 PyCodeObject *
_PyCode_New(struct _PyCodeConstructor * con)446 _PyCode_New(struct _PyCodeConstructor *con)
447 {
448     /* Ensure that strings are ready Unicode string */
449     if (PyUnicode_READY(con->name) < 0) {
450         return NULL;
451     }
452     if (PyUnicode_READY(con->qualname) < 0) {
453         return NULL;
454     }
455     if (PyUnicode_READY(con->filename) < 0) {
456         return NULL;
457     }
458 
459     if (intern_strings(con->names) < 0) {
460         return NULL;
461     }
462     if (intern_string_constants(con->consts, NULL) < 0) {
463         return NULL;
464     }
465     if (intern_strings(con->localsplusnames) < 0) {
466         return NULL;
467     }
468 
469     PyObject *replacement_locations = NULL;
470     // Compact the linetable if we are opted out of debug
471     // ranges.
472     if (!_Py_GetConfig()->code_debug_ranges) {
473         replacement_locations = remove_column_info(con->linetable);
474         if (replacement_locations == NULL) {
475             return NULL;
476         }
477         con->linetable = replacement_locations;
478     }
479 
480     Py_ssize_t size = PyBytes_GET_SIZE(con->code) / sizeof(_Py_CODEUNIT);
481     PyCodeObject *co = PyObject_NewVar(PyCodeObject, &PyCode_Type, size);
482     if (co == NULL) {
483         Py_XDECREF(replacement_locations);
484         PyErr_NoMemory();
485         return NULL;
486     }
487     init_code(co, con);
488     Py_XDECREF(replacement_locations);
489     return co;
490 }
491 
492 
493 /******************
494  * the legacy "constructors"
495  ******************/
496 
497 PyCodeObject *
PyCode_NewWithPosOnlyArgs(int argcount,int posonlyargcount,int kwonlyargcount,int nlocals,int stacksize,int flags,PyObject * code,PyObject * consts,PyObject * names,PyObject * varnames,PyObject * freevars,PyObject * cellvars,PyObject * filename,PyObject * name,PyObject * qualname,int firstlineno,PyObject * linetable,PyObject * exceptiontable)498 PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
499                           int nlocals, int stacksize, int flags,
500                           PyObject *code, PyObject *consts, PyObject *names,
501                           PyObject *varnames, PyObject *freevars, PyObject *cellvars,
502                           PyObject *filename, PyObject *name,
503                           PyObject *qualname, int firstlineno,
504                           PyObject *linetable,
505                           PyObject *exceptiontable)
506 {
507     PyCodeObject *co = NULL;
508     PyObject *localsplusnames = NULL;
509     PyObject *localspluskinds = NULL;
510 
511     if (varnames == NULL || !PyTuple_Check(varnames) ||
512         cellvars == NULL || !PyTuple_Check(cellvars) ||
513         freevars == NULL || !PyTuple_Check(freevars)
514         ) {
515         PyErr_BadInternalCall();
516         return NULL;
517     }
518 
519     // Set the "fast locals plus" info.
520     int nvarnames = (int)PyTuple_GET_SIZE(varnames);
521     int ncellvars = (int)PyTuple_GET_SIZE(cellvars);
522     int nfreevars = (int)PyTuple_GET_SIZE(freevars);
523     int nlocalsplus = nvarnames + ncellvars + nfreevars;
524     localsplusnames = PyTuple_New(nlocalsplus);
525     if (localsplusnames == NULL) {
526         goto error;
527     }
528     localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
529     if (localspluskinds == NULL) {
530         goto error;
531     }
532     int  offset = 0;
533     for (int i = 0; i < nvarnames; i++, offset++) {
534         PyObject *name = PyTuple_GET_ITEM(varnames, i);
535         _Py_set_localsplus_info(offset, name, CO_FAST_LOCAL,
536                                localsplusnames, localspluskinds);
537     }
538     for (int i = 0; i < ncellvars; i++, offset++) {
539         PyObject *name = PyTuple_GET_ITEM(cellvars, i);
540         int argoffset = -1;
541         for (int j = 0; j < nvarnames; j++) {
542             int cmp = PyUnicode_Compare(PyTuple_GET_ITEM(varnames, j),
543                                         name);
544             assert(!PyErr_Occurred());
545             if (cmp == 0) {
546                 argoffset = j;
547                 break;
548             }
549         }
550         if (argoffset >= 0) {
551             // Merge the localsplus indices.
552             nlocalsplus -= 1;
553             offset -= 1;
554             _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, argoffset);
555             _PyLocals_SetKind(localspluskinds, argoffset, kind | CO_FAST_CELL);
556             continue;
557         }
558         _Py_set_localsplus_info(offset, name, CO_FAST_CELL,
559                                localsplusnames, localspluskinds);
560     }
561     for (int i = 0; i < nfreevars; i++, offset++) {
562         PyObject *name = PyTuple_GET_ITEM(freevars, i);
563         _Py_set_localsplus_info(offset, name, CO_FAST_FREE,
564                                localsplusnames, localspluskinds);
565     }
566     // If any cells were args then nlocalsplus will have shrunk.
567     if (nlocalsplus != PyTuple_GET_SIZE(localsplusnames)) {
568         if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0
569                 || _PyBytes_Resize(&localspluskinds, nlocalsplus) < 0) {
570             goto error;
571         }
572     }
573 
574     struct _PyCodeConstructor con = {
575         .filename = filename,
576         .name = name,
577         .qualname = qualname,
578         .flags = flags,
579 
580         .code = code,
581         .firstlineno = firstlineno,
582         .linetable = linetable,
583 
584         .consts = consts,
585         .names = names,
586 
587         .localsplusnames = localsplusnames,
588         .localspluskinds = localspluskinds,
589 
590         .argcount = argcount,
591         .posonlyargcount = posonlyargcount,
592         .kwonlyargcount = kwonlyargcount,
593 
594         .stacksize = stacksize,
595 
596         .exceptiontable = exceptiontable,
597     };
598 
599     if (_PyCode_Validate(&con) < 0) {
600         goto error;
601     }
602     assert(PyBytes_GET_SIZE(code) % sizeof(_Py_CODEUNIT) == 0);
603     assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(code), sizeof(_Py_CODEUNIT)));
604     if (nlocals != PyTuple_GET_SIZE(varnames)) {
605         PyErr_SetString(PyExc_ValueError,
606                         "code: co_nlocals != len(co_varnames)");
607         goto error;
608     }
609 
610     co = _PyCode_New(&con);
611     if (co == NULL) {
612         goto error;
613     }
614 
615 error:
616     Py_XDECREF(localsplusnames);
617     Py_XDECREF(localspluskinds);
618     return co;
619 }
620 
621 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,PyObject * qualname,int firstlineno,PyObject * linetable,PyObject * exceptiontable)622 PyCode_New(int argcount, int kwonlyargcount,
623            int nlocals, int stacksize, int flags,
624            PyObject *code, PyObject *consts, PyObject *names,
625            PyObject *varnames, PyObject *freevars, PyObject *cellvars,
626            PyObject *filename, PyObject *name, PyObject *qualname,
627            int firstlineno,
628            PyObject *linetable,
629            PyObject *exceptiontable)
630 {
631     return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals,
632                                      stacksize, flags, code, consts, names,
633                                      varnames, freevars, cellvars, filename,
634                                      name, qualname, firstlineno,
635                                      linetable,
636                                      exceptiontable);
637 }
638 
639 // NOTE: When modifying the construction of PyCode_NewEmpty, please also change
640 // test.test_code.CodeLocationTest.test_code_new_empty to keep it in sync!
641 
642 static const uint8_t assert0[6] = {
643     RESUME, 0,
644     LOAD_ASSERTION_ERROR, 0,
645     RAISE_VARARGS, 1
646 };
647 
648 static const uint8_t linetable[2] = {
649     (1 << 7)  // New entry.
650     | (PY_CODE_LOCATION_INFO_NO_COLUMNS << 3)
651     | (3 - 1),  // Three code units.
652     0,  // Offset from co_firstlineno.
653 };
654 
655 PyCodeObject *
PyCode_NewEmpty(const char * filename,const char * funcname,int firstlineno)656 PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
657 {
658     PyObject *nulltuple = NULL;
659     PyObject *filename_ob = NULL;
660     PyObject *funcname_ob = NULL;
661     PyObject *code_ob = NULL;
662     PyObject *linetable_ob = NULL;
663     PyCodeObject *result = NULL;
664 
665     nulltuple = PyTuple_New(0);
666     if (nulltuple == NULL) {
667         goto failed;
668     }
669     funcname_ob = PyUnicode_FromString(funcname);
670     if (funcname_ob == NULL) {
671         goto failed;
672     }
673     filename_ob = PyUnicode_DecodeFSDefault(filename);
674     if (filename_ob == NULL) {
675         goto failed;
676     }
677     code_ob = PyBytes_FromStringAndSize((const char *)assert0, 6);
678     if (code_ob == NULL) {
679         goto failed;
680     }
681     linetable_ob = PyBytes_FromStringAndSize((const char *)linetable, 2);
682     if (linetable_ob == NULL) {
683         goto failed;
684     }
685 
686 #define emptystring (PyObject *)&_Py_SINGLETON(bytes_empty)
687     struct _PyCodeConstructor con = {
688         .filename = filename_ob,
689         .name = funcname_ob,
690         .qualname = funcname_ob,
691         .code = code_ob,
692         .firstlineno = firstlineno,
693         .linetable = linetable_ob,
694         .consts = nulltuple,
695         .names = nulltuple,
696         .localsplusnames = nulltuple,
697         .localspluskinds = emptystring,
698         .exceptiontable = emptystring,
699         .stacksize = 1,
700     };
701     result = _PyCode_New(&con);
702 
703 failed:
704     Py_XDECREF(nulltuple);
705     Py_XDECREF(funcname_ob);
706     Py_XDECREF(filename_ob);
707     Py_XDECREF(code_ob);
708     Py_XDECREF(linetable_ob);
709     return result;
710 }
711 
712 
713 /******************
714  * source location tracking (co_lines/co_positions)
715  ******************/
716 
717 /* Use co_linetable to compute the line number from a bytecode index, addrq.  See
718    lnotab_notes.txt for the details of the lnotab representation.
719 */
720 
721 int
_PyCode_CreateLineArray(PyCodeObject * co)722 _PyCode_CreateLineArray(PyCodeObject *co)
723 {
724     assert(co->_co_linearray == NULL);
725     PyCodeAddressRange bounds;
726     int size;
727     int max_line = 0;
728     _PyCode_InitAddressRange(co, &bounds);
729     while(_PyLineTable_NextAddressRange(&bounds)) {
730         if (bounds.ar_line > max_line) {
731             max_line = bounds.ar_line;
732         }
733     }
734     if (max_line < (1 << 15)) {
735         size = 2;
736     }
737     else {
738         size = 4;
739     }
740     co->_co_linearray = PyMem_Malloc(Py_SIZE(co)*size);
741     if (co->_co_linearray == NULL) {
742         PyErr_NoMemory();
743         return -1;
744     }
745     co->_co_linearray_entry_size = size;
746     _PyCode_InitAddressRange(co, &bounds);
747     while(_PyLineTable_NextAddressRange(&bounds)) {
748         int start = bounds.ar_start / sizeof(_Py_CODEUNIT);
749         int end = bounds.ar_end / sizeof(_Py_CODEUNIT);
750         for (int index = start; index < end; index++) {
751             assert(index < (int)Py_SIZE(co));
752             if (size == 2) {
753                 assert(((int16_t)bounds.ar_line) == bounds.ar_line);
754                 ((int16_t *)co->_co_linearray)[index] = bounds.ar_line;
755             }
756             else {
757                 assert(size == 4);
758                 ((int32_t *)co->_co_linearray)[index] = bounds.ar_line;
759             }
760         }
761     }
762     return 0;
763 }
764 
765 int
PyCode_Addr2Line(PyCodeObject * co,int addrq)766 PyCode_Addr2Line(PyCodeObject *co, int addrq)
767 {
768     if (addrq < 0) {
769         return co->co_firstlineno;
770     }
771     assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
772     if (co->_co_linearray) {
773         return _PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT));
774     }
775     PyCodeAddressRange bounds;
776     _PyCode_InitAddressRange(co, &bounds);
777     return _PyCode_CheckLineNumber(addrq, &bounds);
778 }
779 
780 void
_PyLineTable_InitAddressRange(const char * linetable,Py_ssize_t length,int firstlineno,PyCodeAddressRange * range)781 _PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range)
782 {
783     range->opaque.lo_next = (const uint8_t *)linetable;
784     range->opaque.limit = range->opaque.lo_next + length;
785     range->ar_start = -1;
786     range->ar_end = 0;
787     range->opaque.computed_line = firstlineno;
788     range->ar_line = -1;
789 }
790 
791 int
_PyCode_InitAddressRange(PyCodeObject * co,PyCodeAddressRange * bounds)792 _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds)
793 {
794     assert(co->co_linetable != NULL);
795     const char *linetable = PyBytes_AS_STRING(co->co_linetable);
796     Py_ssize_t length = PyBytes_GET_SIZE(co->co_linetable);
797     _PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds);
798     return bounds->ar_line;
799 }
800 
801 /* Update *bounds to describe the first and one-past-the-last instructions in
802    the same line as lasti.  Return the number of that line, or -1 if lasti is out of bounds. */
803 int
_PyCode_CheckLineNumber(int lasti,PyCodeAddressRange * bounds)804 _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds)
805 {
806     while (bounds->ar_end <= lasti) {
807         if (!_PyLineTable_NextAddressRange(bounds)) {
808             return -1;
809         }
810     }
811     while (bounds->ar_start > lasti) {
812         if (!_PyLineTable_PreviousAddressRange(bounds)) {
813             return -1;
814         }
815     }
816     return bounds->ar_line;
817 }
818 
819 static int
is_no_line_marker(uint8_t b)820 is_no_line_marker(uint8_t b)
821 {
822     return (b >> 3) == 0x1f;
823 }
824 
825 
826 #define ASSERT_VALID_BOUNDS(bounds) \
827     assert(bounds->opaque.lo_next <=  bounds->opaque.limit && \
828         (bounds->ar_line == -1 || bounds->ar_line == bounds->opaque.computed_line) && \
829         (bounds->opaque.lo_next == bounds->opaque.limit || \
830         (*bounds->opaque.lo_next) & 128))
831 
832 static int
next_code_delta(PyCodeAddressRange * bounds)833 next_code_delta(PyCodeAddressRange *bounds)
834 {
835     assert((*bounds->opaque.lo_next) & 128);
836     return (((*bounds->opaque.lo_next) & 7) + 1) * sizeof(_Py_CODEUNIT);
837 }
838 
839 static int
previous_code_delta(PyCodeAddressRange * bounds)840 previous_code_delta(PyCodeAddressRange *bounds)
841 {
842     if (bounds->ar_start == 0) {
843         // If we looking at the first entry, the
844         // "previous" entry has an implicit length of 1.
845         return 1;
846     }
847     const uint8_t *ptr = bounds->opaque.lo_next-1;
848     while (((*ptr) & 128) == 0) {
849         ptr--;
850     }
851     return (((*ptr) & 7) + 1) * sizeof(_Py_CODEUNIT);
852 }
853 
854 static int
read_byte(PyCodeAddressRange * bounds)855 read_byte(PyCodeAddressRange *bounds)
856 {
857     return *bounds->opaque.lo_next++;
858 }
859 
860 static int
read_varint(PyCodeAddressRange * bounds)861 read_varint(PyCodeAddressRange *bounds)
862 {
863     unsigned int read = read_byte(bounds);
864     unsigned int val = read & 63;
865     unsigned int shift = 0;
866     while (read & 64) {
867         read = read_byte(bounds);
868         shift += 6;
869         val |= (read & 63) << shift;
870     }
871     return val;
872 }
873 
874 static int
read_signed_varint(PyCodeAddressRange * bounds)875 read_signed_varint(PyCodeAddressRange *bounds)
876 {
877     unsigned int uval = read_varint(bounds);
878     if (uval & 1) {
879         return -(int)(uval >> 1);
880     }
881     else {
882         return uval >> 1;
883     }
884 }
885 
886 static void
retreat(PyCodeAddressRange * bounds)887 retreat(PyCodeAddressRange *bounds)
888 {
889     ASSERT_VALID_BOUNDS(bounds);
890     assert(bounds->ar_start >= 0);
891     do {
892         bounds->opaque.lo_next--;
893     } while (((*bounds->opaque.lo_next) & 128) == 0);
894     bounds->opaque.computed_line -= get_line_delta(bounds->opaque.lo_next);
895     bounds->ar_end = bounds->ar_start;
896     bounds->ar_start -= previous_code_delta(bounds);
897     if (is_no_line_marker(bounds->opaque.lo_next[-1])) {
898         bounds->ar_line = -1;
899     }
900     else {
901         bounds->ar_line = bounds->opaque.computed_line;
902     }
903     ASSERT_VALID_BOUNDS(bounds);
904 }
905 
906 static void
advance(PyCodeAddressRange * bounds)907 advance(PyCodeAddressRange *bounds)
908 {
909     ASSERT_VALID_BOUNDS(bounds);
910     bounds->opaque.computed_line += get_line_delta(bounds->opaque.lo_next);
911     if (is_no_line_marker(*bounds->opaque.lo_next)) {
912         bounds->ar_line = -1;
913     }
914     else {
915         bounds->ar_line = bounds->opaque.computed_line;
916     }
917     bounds->ar_start = bounds->ar_end;
918     bounds->ar_end += next_code_delta(bounds);
919     do {
920         bounds->opaque.lo_next++;
921     } while (bounds->opaque.lo_next < bounds->opaque.limit &&
922         ((*bounds->opaque.lo_next) & 128) == 0);
923     ASSERT_VALID_BOUNDS(bounds);
924 }
925 
926 static void
advance_with_locations(PyCodeAddressRange * bounds,int * endline,int * column,int * endcolumn)927 advance_with_locations(PyCodeAddressRange *bounds, int *endline, int *column, int *endcolumn)
928 {
929     ASSERT_VALID_BOUNDS(bounds);
930     int first_byte = read_byte(bounds);
931     int code = (first_byte >> 3) & 15;
932     bounds->ar_start = bounds->ar_end;
933     bounds->ar_end = bounds->ar_start + ((first_byte & 7) + 1) * sizeof(_Py_CODEUNIT);
934     switch(code) {
935         case PY_CODE_LOCATION_INFO_NONE:
936             bounds->ar_line = *endline = -1;
937             *column =  *endcolumn = -1;
938             break;
939         case PY_CODE_LOCATION_INFO_LONG:
940         {
941             bounds->opaque.computed_line += read_signed_varint(bounds);
942             bounds->ar_line = bounds->opaque.computed_line;
943             *endline = bounds->ar_line + read_varint(bounds);
944             *column = read_varint(bounds)-1;
945             *endcolumn = read_varint(bounds)-1;
946             break;
947         }
948         case PY_CODE_LOCATION_INFO_NO_COLUMNS:
949         {
950             /* No column */
951             bounds->opaque.computed_line += read_signed_varint(bounds);
952             *endline = bounds->ar_line = bounds->opaque.computed_line;
953             *column = *endcolumn = -1;
954             break;
955         }
956         case PY_CODE_LOCATION_INFO_ONE_LINE0:
957         case PY_CODE_LOCATION_INFO_ONE_LINE1:
958         case PY_CODE_LOCATION_INFO_ONE_LINE2:
959         {
960             /* one line form */
961             int line_delta = code - 10;
962             bounds->opaque.computed_line += line_delta;
963             *endline = bounds->ar_line = bounds->opaque.computed_line;
964             *column = read_byte(bounds);
965             *endcolumn = read_byte(bounds);
966             break;
967         }
968         default:
969         {
970             /* Short forms */
971             int second_byte = read_byte(bounds);
972             assert((second_byte & 128) == 0);
973             *endline = bounds->ar_line = bounds->opaque.computed_line;
974             *column = code << 3 | (second_byte >> 4);
975             *endcolumn = *column + (second_byte & 15);
976         }
977     }
978     ASSERT_VALID_BOUNDS(bounds);
979 }
980 int
PyCode_Addr2Location(PyCodeObject * co,int addrq,int * start_line,int * start_column,int * end_line,int * end_column)981 PyCode_Addr2Location(PyCodeObject *co, int addrq,
982                      int *start_line, int *start_column,
983                      int *end_line, int *end_column)
984 {
985     if (addrq < 0) {
986         *start_line = *end_line = co->co_firstlineno;
987         *start_column = *end_column = 0;
988         return 1;
989     }
990     assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
991     PyCodeAddressRange bounds;
992     _PyCode_InitAddressRange(co, &bounds);
993     _PyCode_CheckLineNumber(addrq, &bounds);
994     retreat(&bounds);
995     advance_with_locations(&bounds, end_line, start_column, end_column);
996     *start_line = bounds.ar_line;
997     return 1;
998 }
999 
1000 
1001 static inline int
at_end(PyCodeAddressRange * bounds)1002 at_end(PyCodeAddressRange *bounds) {
1003     return bounds->opaque.lo_next >= bounds->opaque.limit;
1004 }
1005 
1006 int
_PyLineTable_PreviousAddressRange(PyCodeAddressRange * range)1007 _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range)
1008 {
1009     if (range->ar_start <= 0) {
1010         return 0;
1011     }
1012     retreat(range);
1013     assert(range->ar_end > range->ar_start);
1014     return 1;
1015 }
1016 
1017 int
_PyLineTable_NextAddressRange(PyCodeAddressRange * range)1018 _PyLineTable_NextAddressRange(PyCodeAddressRange *range)
1019 {
1020     if (at_end(range)) {
1021         return 0;
1022     }
1023     advance(range);
1024     assert(range->ar_end > range->ar_start);
1025     return 1;
1026 }
1027 
1028 int
_PyLineTable_StartsLine(PyCodeAddressRange * range)1029 _PyLineTable_StartsLine(PyCodeAddressRange *range)
1030 {
1031     if (range->ar_start <= 0) {
1032         return 0;
1033     }
1034     const uint8_t *ptr = range->opaque.lo_next;
1035     do {
1036         ptr--;
1037     } while (((*ptr) & 128) == 0);
1038     int code = ((*ptr)>> 3) & 15;
1039     switch(code) {
1040         case PY_CODE_LOCATION_INFO_LONG:
1041             return 0;
1042         case PY_CODE_LOCATION_INFO_NO_COLUMNS:
1043         case PY_CODE_LOCATION_INFO_NONE:
1044             return ptr[1] != 0;
1045         case PY_CODE_LOCATION_INFO_ONE_LINE0:
1046             return 0;
1047         case PY_CODE_LOCATION_INFO_ONE_LINE1:
1048         case PY_CODE_LOCATION_INFO_ONE_LINE2:
1049             return 1;
1050         default:
1051             return 0;
1052     }
1053 }
1054 
1055 static int
emit_pair(PyObject ** bytes,int * offset,int a,int b)1056 emit_pair(PyObject **bytes, int *offset, int a, int b)
1057 {
1058     Py_ssize_t len = PyBytes_GET_SIZE(*bytes);
1059     if (*offset + 2 >= len) {
1060         if (_PyBytes_Resize(bytes, len * 2) < 0)
1061             return 0;
1062     }
1063     unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(*bytes);
1064     lnotab += *offset;
1065     *lnotab++ = a;
1066     *lnotab++ = b;
1067     *offset += 2;
1068     return 1;
1069 }
1070 
1071 static int
emit_delta(PyObject ** bytes,int bdelta,int ldelta,int * offset)1072 emit_delta(PyObject **bytes, int bdelta, int ldelta, int *offset)
1073 {
1074     while (bdelta > 255) {
1075         if (!emit_pair(bytes, offset, 255, 0)) {
1076             return 0;
1077         }
1078         bdelta -= 255;
1079     }
1080     while (ldelta > 127) {
1081         if (!emit_pair(bytes, offset, bdelta, 127)) {
1082             return 0;
1083         }
1084         bdelta = 0;
1085         ldelta -= 127;
1086     }
1087     while (ldelta < -128) {
1088         if (!emit_pair(bytes, offset, bdelta, -128)) {
1089             return 0;
1090         }
1091         bdelta = 0;
1092         ldelta += 128;
1093     }
1094     return emit_pair(bytes, offset, bdelta, ldelta);
1095 }
1096 
1097 static PyObject *
decode_linetable(PyCodeObject * code)1098 decode_linetable(PyCodeObject *code)
1099 {
1100     PyCodeAddressRange bounds;
1101     PyObject *bytes;
1102     int table_offset = 0;
1103     int code_offset = 0;
1104     int line = code->co_firstlineno;
1105     bytes = PyBytes_FromStringAndSize(NULL, 64);
1106     if (bytes == NULL) {
1107         return NULL;
1108     }
1109     _PyCode_InitAddressRange(code, &bounds);
1110     while (_PyLineTable_NextAddressRange(&bounds)) {
1111         if (bounds.opaque.computed_line != line) {
1112             int bdelta = bounds.ar_start - code_offset;
1113             int ldelta = bounds.opaque.computed_line - line;
1114             if (!emit_delta(&bytes, bdelta, ldelta, &table_offset)) {
1115                 Py_DECREF(bytes);
1116                 return NULL;
1117             }
1118             code_offset = bounds.ar_start;
1119             line = bounds.opaque.computed_line;
1120         }
1121     }
1122     _PyBytes_Resize(&bytes, table_offset);
1123     return bytes;
1124 }
1125 
1126 
1127 typedef struct {
1128     PyObject_HEAD
1129     PyCodeObject *li_code;
1130     PyCodeAddressRange li_line;
1131 } lineiterator;
1132 
1133 
1134 static void
lineiter_dealloc(lineiterator * li)1135 lineiter_dealloc(lineiterator *li)
1136 {
1137     Py_DECREF(li->li_code);
1138     Py_TYPE(li)->tp_free(li);
1139 }
1140 
1141 static PyObject *
lineiter_next(lineiterator * li)1142 lineiter_next(lineiterator *li)
1143 {
1144     PyCodeAddressRange *bounds = &li->li_line;
1145     if (!_PyLineTable_NextAddressRange(bounds)) {
1146         return NULL;
1147     }
1148     PyObject *start = NULL;
1149     PyObject *end = NULL;
1150     PyObject *line = NULL;
1151     PyObject *result = PyTuple_New(3);
1152     start = PyLong_FromLong(bounds->ar_start);
1153     end = PyLong_FromLong(bounds->ar_end);
1154     if (bounds->ar_line < 0) {
1155         Py_INCREF(Py_None);
1156         line = Py_None;
1157     }
1158     else {
1159         line = PyLong_FromLong(bounds->ar_line);
1160     }
1161     if (result == NULL || start == NULL || end == NULL || line == NULL) {
1162         goto error;
1163     }
1164     PyTuple_SET_ITEM(result, 0, start);
1165     PyTuple_SET_ITEM(result, 1, end);
1166     PyTuple_SET_ITEM(result, 2, line);
1167     return result;
1168 error:
1169     Py_XDECREF(start);
1170     Py_XDECREF(end);
1171     Py_XDECREF(line);
1172     Py_XDECREF(result);
1173     return result;
1174 }
1175 
1176 static PyTypeObject LineIterator = {
1177     PyVarObject_HEAD_INIT(&PyType_Type, 0)
1178     "line_iterator",                    /* tp_name */
1179     sizeof(lineiterator),               /* tp_basicsize */
1180     0,                                  /* tp_itemsize */
1181     /* methods */
1182     (destructor)lineiter_dealloc,       /* tp_dealloc */
1183     0,                                  /* tp_vectorcall_offset */
1184     0,                                  /* tp_getattr */
1185     0,                                  /* tp_setattr */
1186     0,                                  /* tp_as_async */
1187     0,                                  /* tp_repr */
1188     0,                                  /* tp_as_number */
1189     0,                                  /* tp_as_sequence */
1190     0,                                  /* tp_as_mapping */
1191     0,                                  /* tp_hash */
1192     0,                                  /* tp_call */
1193     0,                                  /* tp_str */
1194     0,                                  /* tp_getattro */
1195     0,                                  /* tp_setattro */
1196     0,                                  /* tp_as_buffer */
1197     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
1198     0,                                  /* tp_doc */
1199     0,                                  /* tp_traverse */
1200     0,                                  /* tp_clear */
1201     0,                                  /* tp_richcompare */
1202     0,                                  /* tp_weaklistoffset */
1203     PyObject_SelfIter,                  /* tp_iter */
1204     (iternextfunc)lineiter_next,        /* tp_iternext */
1205     0,                                  /* tp_methods */
1206     0,                                  /* tp_members */
1207     0,                                  /* tp_getset */
1208     0,                                  /* tp_base */
1209     0,                                  /* tp_dict */
1210     0,                                  /* tp_descr_get */
1211     0,                                  /* tp_descr_set */
1212     0,                                  /* tp_dictoffset */
1213     0,                                  /* tp_init */
1214     0,                                  /* tp_alloc */
1215     0,                                  /* tp_new */
1216     PyObject_Del,                       /* tp_free */
1217 };
1218 
1219 static lineiterator *
new_linesiterator(PyCodeObject * code)1220 new_linesiterator(PyCodeObject *code)
1221 {
1222     lineiterator *li = (lineiterator *)PyType_GenericAlloc(&LineIterator, 0);
1223     if (li == NULL) {
1224         return NULL;
1225     }
1226     Py_INCREF(code);
1227     li->li_code = code;
1228     _PyCode_InitAddressRange(code, &li->li_line);
1229     return li;
1230 }
1231 
1232 /* co_positions iterator object. */
1233 typedef struct {
1234     PyObject_HEAD
1235     PyCodeObject* pi_code;
1236     PyCodeAddressRange pi_range;
1237     int pi_offset;
1238     int pi_endline;
1239     int pi_column;
1240     int pi_endcolumn;
1241 } positionsiterator;
1242 
1243 static void
positionsiter_dealloc(positionsiterator * pi)1244 positionsiter_dealloc(positionsiterator* pi)
1245 {
1246     Py_DECREF(pi->pi_code);
1247     Py_TYPE(pi)->tp_free(pi);
1248 }
1249 
1250 static PyObject*
_source_offset_converter(int * value)1251 _source_offset_converter(int* value) {
1252     if (*value == -1) {
1253         Py_RETURN_NONE;
1254     }
1255     return PyLong_FromLong(*value);
1256 }
1257 
1258 static PyObject*
positionsiter_next(positionsiterator * pi)1259 positionsiter_next(positionsiterator* pi)
1260 {
1261     if (pi->pi_offset >= pi->pi_range.ar_end) {
1262         assert(pi->pi_offset == pi->pi_range.ar_end);
1263         if (at_end(&pi->pi_range)) {
1264             return NULL;
1265         }
1266         advance_with_locations(&pi->pi_range, &pi->pi_endline, &pi->pi_column, &pi->pi_endcolumn);
1267     }
1268     pi->pi_offset += 2;
1269     return Py_BuildValue("(O&O&O&O&)",
1270         _source_offset_converter, &pi->pi_range.ar_line,
1271         _source_offset_converter, &pi->pi_endline,
1272         _source_offset_converter, &pi->pi_column,
1273         _source_offset_converter, &pi->pi_endcolumn);
1274 }
1275 
1276 static PyTypeObject PositionsIterator = {
1277     PyVarObject_HEAD_INIT(&PyType_Type, 0)
1278     "positions_iterator",               /* tp_name */
1279     sizeof(positionsiterator),          /* tp_basicsize */
1280     0,                                  /* tp_itemsize */
1281     /* methods */
1282     (destructor)positionsiter_dealloc,  /* tp_dealloc */
1283     0,                                  /* tp_vectorcall_offset */
1284     0,                                  /* tp_getattr */
1285     0,                                  /* tp_setattr */
1286     0,                                  /* tp_as_async */
1287     0,                                  /* tp_repr */
1288     0,                                  /* tp_as_number */
1289     0,                                  /* tp_as_sequence */
1290     0,                                  /* tp_as_mapping */
1291     0,                                  /* tp_hash */
1292     0,                                  /* tp_call */
1293     0,                                  /* tp_str */
1294     0,                                  /* tp_getattro */
1295     0,                                  /* tp_setattro */
1296     0,                                  /* tp_as_buffer */
1297     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
1298     0,                                  /* tp_doc */
1299     0,                                  /* tp_traverse */
1300     0,                                  /* tp_clear */
1301     0,                                  /* tp_richcompare */
1302     0,                                  /* tp_weaklistoffset */
1303     PyObject_SelfIter,                  /* tp_iter */
1304     (iternextfunc)positionsiter_next,   /* tp_iternext */
1305     0,                                  /* tp_methods */
1306     0,                                  /* tp_members */
1307     0,                                  /* tp_getset */
1308     0,                                  /* tp_base */
1309     0,                                  /* tp_dict */
1310     0,                                  /* tp_descr_get */
1311     0,                                  /* tp_descr_set */
1312     0,                                  /* tp_dictoffset */
1313     0,                                  /* tp_init */
1314     0,                                  /* tp_alloc */
1315     0,                                  /* tp_new */
1316     PyObject_Del,                       /* tp_free */
1317 };
1318 
1319 static PyObject*
code_positionsiterator(PyCodeObject * code,PyObject * Py_UNUSED (args))1320 code_positionsiterator(PyCodeObject* code, PyObject* Py_UNUSED(args))
1321 {
1322     positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&PositionsIterator, 0);
1323     if (pi == NULL) {
1324         return NULL;
1325     }
1326     Py_INCREF(code);
1327     pi->pi_code = code;
1328     _PyCode_InitAddressRange(code, &pi->pi_range);
1329     pi->pi_offset = pi->pi_range.ar_end;
1330     return (PyObject*)pi;
1331 }
1332 
1333 
1334 /******************
1335  * "extra" frame eval info (see PEP 523)
1336  ******************/
1337 
1338 /* Holder for co_extra information */
1339 typedef struct {
1340     Py_ssize_t ce_size;
1341     void *ce_extras[1];
1342 } _PyCodeObjectExtra;
1343 
1344 
1345 int
_PyCode_GetExtra(PyObject * code,Py_ssize_t index,void ** extra)1346 _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
1347 {
1348     if (!PyCode_Check(code)) {
1349         PyErr_BadInternalCall();
1350         return -1;
1351     }
1352 
1353     PyCodeObject *o = (PyCodeObject*) code;
1354     _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra;
1355 
1356     if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) {
1357         *extra = NULL;
1358         return 0;
1359     }
1360 
1361     *extra = co_extra->ce_extras[index];
1362     return 0;
1363 }
1364 
1365 
1366 int
_PyCode_SetExtra(PyObject * code,Py_ssize_t index,void * extra)1367 _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
1368 {
1369     PyInterpreterState *interp = _PyInterpreterState_GET();
1370 
1371     if (!PyCode_Check(code) || index < 0 ||
1372             index >= interp->co_extra_user_count) {
1373         PyErr_BadInternalCall();
1374         return -1;
1375     }
1376 
1377     PyCodeObject *o = (PyCodeObject*) code;
1378     _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra;
1379 
1380     if (co_extra == NULL || co_extra->ce_size <= index) {
1381         Py_ssize_t i = (co_extra == NULL ? 0 : co_extra->ce_size);
1382         co_extra = PyMem_Realloc(
1383                 co_extra,
1384                 sizeof(_PyCodeObjectExtra) +
1385                 (interp->co_extra_user_count-1) * sizeof(void*));
1386         if (co_extra == NULL) {
1387             return -1;
1388         }
1389         for (; i < interp->co_extra_user_count; i++) {
1390             co_extra->ce_extras[i] = NULL;
1391         }
1392         co_extra->ce_size = interp->co_extra_user_count;
1393         o->co_extra = co_extra;
1394     }
1395 
1396     if (co_extra->ce_extras[index] != NULL) {
1397         freefunc free = interp->co_extra_freefuncs[index];
1398         if (free != NULL) {
1399             free(co_extra->ce_extras[index]);
1400         }
1401     }
1402 
1403     co_extra->ce_extras[index] = extra;
1404     return 0;
1405 }
1406 
1407 
1408 /******************
1409  * other PyCodeObject accessor functions
1410  ******************/
1411 
1412 PyObject *
_PyCode_GetVarnames(PyCodeObject * co)1413 _PyCode_GetVarnames(PyCodeObject *co)
1414 {
1415     return get_localsplus_names(co, CO_FAST_LOCAL, co->co_nlocals);
1416 }
1417 
1418 PyObject *
PyCode_GetVarnames(PyCodeObject * code)1419 PyCode_GetVarnames(PyCodeObject *code)
1420 {
1421     return _PyCode_GetVarnames(code);
1422 }
1423 
1424 PyObject *
_PyCode_GetCellvars(PyCodeObject * co)1425 _PyCode_GetCellvars(PyCodeObject *co)
1426 {
1427     return get_localsplus_names(co, CO_FAST_CELL, co->co_ncellvars);
1428 }
1429 
1430 PyObject *
PyCode_GetCellvars(PyCodeObject * code)1431 PyCode_GetCellvars(PyCodeObject *code)
1432 {
1433     return _PyCode_GetCellvars(code);
1434 }
1435 
1436 PyObject *
_PyCode_GetFreevars(PyCodeObject * co)1437 _PyCode_GetFreevars(PyCodeObject *co)
1438 {
1439     return get_localsplus_names(co, CO_FAST_FREE, co->co_nfreevars);
1440 }
1441 
1442 PyObject *
PyCode_GetFreevars(PyCodeObject * code)1443 PyCode_GetFreevars(PyCodeObject *code)
1444 {
1445     return _PyCode_GetFreevars(code);
1446 }
1447 
1448 static void
deopt_code(_Py_CODEUNIT * instructions,Py_ssize_t len)1449 deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
1450 {
1451     for (int i = 0; i < len; i++) {
1452         _Py_CODEUNIT instruction = instructions[i];
1453         int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)];
1454         int caches = _PyOpcode_Caches[opcode];
1455         instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction));
1456         while (caches--) {
1457             instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0);
1458         }
1459     }
1460 }
1461 
1462 PyObject *
_PyCode_GetCode(PyCodeObject * co)1463 _PyCode_GetCode(PyCodeObject *co)
1464 {
1465     if (co->_co_code != NULL) {
1466         return Py_NewRef(co->_co_code);
1467     }
1468     PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co),
1469                                                _PyCode_NBYTES(co));
1470     if (code == NULL) {
1471         return NULL;
1472     }
1473     deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co));
1474     assert(co->_co_code == NULL);
1475     co->_co_code = Py_NewRef(code);
1476     return code;
1477 }
1478 
1479 PyObject *
PyCode_GetCode(PyCodeObject * co)1480 PyCode_GetCode(PyCodeObject *co)
1481 {
1482     return _PyCode_GetCode(co);
1483 }
1484 
1485 /******************
1486  * PyCode_Type
1487  ******************/
1488 
1489 /*[clinic input]
1490 class code "PyCodeObject *" "&PyCode_Type"
1491 [clinic start generated code]*/
1492 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=78aa5d576683bb4b]*/
1493 
1494 /*[clinic input]
1495 @classmethod
1496 code.__new__ as code_new
1497 
1498     argcount: int
1499     posonlyargcount: int
1500     kwonlyargcount: int
1501     nlocals: int
1502     stacksize: int
1503     flags: int
1504     codestring as code: object(subclass_of="&PyBytes_Type")
1505     constants as consts: object(subclass_of="&PyTuple_Type")
1506     names: object(subclass_of="&PyTuple_Type")
1507     varnames: object(subclass_of="&PyTuple_Type")
1508     filename: unicode
1509     name: unicode
1510     qualname: unicode
1511     firstlineno: int
1512     linetable: object(subclass_of="&PyBytes_Type")
1513     exceptiontable: object(subclass_of="&PyBytes_Type")
1514     freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = ()
1515     cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = ()
1516     /
1517 
1518 Create a code object.  Not for the faint of heart.
1519 [clinic start generated code]*/
1520 
1521 static PyObject *
code_new_impl(PyTypeObject * type,int argcount,int posonlyargcount,int kwonlyargcount,int nlocals,int stacksize,int flags,PyObject * code,PyObject * consts,PyObject * names,PyObject * varnames,PyObject * filename,PyObject * name,PyObject * qualname,int firstlineno,PyObject * linetable,PyObject * exceptiontable,PyObject * freevars,PyObject * cellvars)1522 code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount,
1523               int kwonlyargcount, int nlocals, int stacksize, int flags,
1524               PyObject *code, PyObject *consts, PyObject *names,
1525               PyObject *varnames, PyObject *filename, PyObject *name,
1526               PyObject *qualname, int firstlineno, PyObject *linetable,
1527               PyObject *exceptiontable, PyObject *freevars,
1528               PyObject *cellvars)
1529 /*[clinic end generated code: output=069fa20d299f9dda input=e31da3c41ad8064a]*/
1530 {
1531     PyObject *co = NULL;
1532     PyObject *ournames = NULL;
1533     PyObject *ourvarnames = NULL;
1534     PyObject *ourfreevars = NULL;
1535     PyObject *ourcellvars = NULL;
1536 
1537     if (PySys_Audit("code.__new__", "OOOiiiiii",
1538                     code, filename, name, argcount, posonlyargcount,
1539                     kwonlyargcount, nlocals, stacksize, flags) < 0) {
1540         goto cleanup;
1541     }
1542 
1543     if (argcount < 0) {
1544         PyErr_SetString(
1545             PyExc_ValueError,
1546             "code: argcount must not be negative");
1547         goto cleanup;
1548     }
1549 
1550     if (posonlyargcount < 0) {
1551         PyErr_SetString(
1552             PyExc_ValueError,
1553             "code: posonlyargcount must not be negative");
1554         goto cleanup;
1555     }
1556 
1557     if (kwonlyargcount < 0) {
1558         PyErr_SetString(
1559             PyExc_ValueError,
1560             "code: kwonlyargcount must not be negative");
1561         goto cleanup;
1562     }
1563     if (nlocals < 0) {
1564         PyErr_SetString(
1565             PyExc_ValueError,
1566             "code: nlocals must not be negative");
1567         goto cleanup;
1568     }
1569 
1570     ournames = validate_and_copy_tuple(names);
1571     if (ournames == NULL)
1572         goto cleanup;
1573     ourvarnames = validate_and_copy_tuple(varnames);
1574     if (ourvarnames == NULL)
1575         goto cleanup;
1576     if (freevars)
1577         ourfreevars = validate_and_copy_tuple(freevars);
1578     else
1579         ourfreevars = PyTuple_New(0);
1580     if (ourfreevars == NULL)
1581         goto cleanup;
1582     if (cellvars)
1583         ourcellvars = validate_and_copy_tuple(cellvars);
1584     else
1585         ourcellvars = PyTuple_New(0);
1586     if (ourcellvars == NULL)
1587         goto cleanup;
1588 
1589     co = (PyObject *)PyCode_NewWithPosOnlyArgs(argcount, posonlyargcount,
1590                                                kwonlyargcount,
1591                                                nlocals, stacksize, flags,
1592                                                code, consts, ournames,
1593                                                ourvarnames, ourfreevars,
1594                                                ourcellvars, filename,
1595                                                name, qualname, firstlineno,
1596                                                linetable,
1597                                                exceptiontable
1598                                               );
1599   cleanup:
1600     Py_XDECREF(ournames);
1601     Py_XDECREF(ourvarnames);
1602     Py_XDECREF(ourfreevars);
1603     Py_XDECREF(ourcellvars);
1604     return co;
1605 }
1606 
1607 static void
code_dealloc(PyCodeObject * co)1608 code_dealloc(PyCodeObject *co)
1609 {
1610     if (co->co_extra != NULL) {
1611         PyInterpreterState *interp = _PyInterpreterState_GET();
1612         _PyCodeObjectExtra *co_extra = co->co_extra;
1613 
1614         for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
1615             freefunc free_extra = interp->co_extra_freefuncs[i];
1616 
1617             if (free_extra != NULL) {
1618                 free_extra(co_extra->ce_extras[i]);
1619             }
1620         }
1621 
1622         PyMem_Free(co_extra);
1623     }
1624 
1625     Py_XDECREF(co->co_consts);
1626     Py_XDECREF(co->co_names);
1627     Py_XDECREF(co->co_localsplusnames);
1628     Py_XDECREF(co->co_localspluskinds);
1629     Py_XDECREF(co->co_filename);
1630     Py_XDECREF(co->co_name);
1631     Py_XDECREF(co->co_qualname);
1632     Py_XDECREF(co->co_linetable);
1633     Py_XDECREF(co->co_exceptiontable);
1634     Py_XDECREF(co->_co_code);
1635     if (co->co_weakreflist != NULL) {
1636         PyObject_ClearWeakRefs((PyObject*)co);
1637     }
1638     if (co->_co_linearray) {
1639         PyMem_Free(co->_co_linearray);
1640     }
1641     if (co->co_warmup == 0) {
1642         _Py_QuickenedCount--;
1643     }
1644     PyObject_Free(co);
1645 }
1646 
1647 static PyObject *
code_repr(PyCodeObject * co)1648 code_repr(PyCodeObject *co)
1649 {
1650     int lineno;
1651     if (co->co_firstlineno != 0)
1652         lineno = co->co_firstlineno;
1653     else
1654         lineno = -1;
1655     if (co->co_filename && PyUnicode_Check(co->co_filename)) {
1656         return PyUnicode_FromFormat(
1657             "<code object %U at %p, file \"%U\", line %d>",
1658             co->co_name, co, co->co_filename, lineno);
1659     } else {
1660         return PyUnicode_FromFormat(
1661             "<code object %U at %p, file ???, line %d>",
1662             co->co_name, co, lineno);
1663     }
1664 }
1665 
1666 static PyObject *
code_richcompare(PyObject * self,PyObject * other,int op)1667 code_richcompare(PyObject *self, PyObject *other, int op)
1668 {
1669     PyCodeObject *co, *cp;
1670     int eq;
1671     PyObject *consts1, *consts2;
1672     PyObject *res;
1673 
1674     if ((op != Py_EQ && op != Py_NE) ||
1675         !PyCode_Check(self) ||
1676         !PyCode_Check(other)) {
1677         Py_RETURN_NOTIMPLEMENTED;
1678     }
1679 
1680     co = (PyCodeObject *)self;
1681     cp = (PyCodeObject *)other;
1682 
1683     eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
1684     if (!eq) goto unequal;
1685     eq = co->co_argcount == cp->co_argcount;
1686     if (!eq) goto unequal;
1687     eq = co->co_posonlyargcount == cp->co_posonlyargcount;
1688     if (!eq) goto unequal;
1689     eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
1690     if (!eq) goto unequal;
1691     eq = co->co_flags == cp->co_flags;
1692     if (!eq) goto unequal;
1693     eq = co->co_firstlineno == cp->co_firstlineno;
1694     if (!eq) goto unequal;
1695     eq = Py_SIZE(co) == Py_SIZE(cp);
1696     if (!eq) {
1697         goto unequal;
1698     }
1699     for (int i = 0; i < Py_SIZE(co); i++) {
1700         _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i];
1701         _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i];
1702         _Py_SET_OPCODE(co_instr, _PyOpcode_Deopt[_Py_OPCODE(co_instr)]);
1703         _Py_SET_OPCODE(cp_instr, _PyOpcode_Deopt[_Py_OPCODE(cp_instr)]);
1704         eq = co_instr == cp_instr;
1705         if (!eq) {
1706             goto unequal;
1707         }
1708         i += _PyOpcode_Caches[_Py_OPCODE(co_instr)];
1709     }
1710 
1711     /* compare constants */
1712     consts1 = _PyCode_ConstantKey(co->co_consts);
1713     if (!consts1)
1714         return NULL;
1715     consts2 = _PyCode_ConstantKey(cp->co_consts);
1716     if (!consts2) {
1717         Py_DECREF(consts1);
1718         return NULL;
1719     }
1720     eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
1721     Py_DECREF(consts1);
1722     Py_DECREF(consts2);
1723     if (eq <= 0) goto unequal;
1724 
1725     eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
1726     if (eq <= 0) goto unequal;
1727     eq = PyObject_RichCompareBool(co->co_localsplusnames,
1728                                   cp->co_localsplusnames, Py_EQ);
1729     if (eq <= 0) goto unequal;
1730     eq = PyObject_RichCompareBool(co->co_linetable, cp->co_linetable, Py_EQ);
1731     if (eq <= 0) {
1732         goto unequal;
1733     }
1734     eq = PyObject_RichCompareBool(co->co_exceptiontable,
1735                                   cp->co_exceptiontable, Py_EQ);
1736     if (eq <= 0) {
1737         goto unequal;
1738     }
1739 
1740     if (op == Py_EQ)
1741         res = Py_True;
1742     else
1743         res = Py_False;
1744     goto done;
1745 
1746   unequal:
1747     if (eq < 0)
1748         return NULL;
1749     if (op == Py_NE)
1750         res = Py_True;
1751     else
1752         res = Py_False;
1753 
1754   done:
1755     Py_INCREF(res);
1756     return res;
1757 }
1758 
1759 static Py_hash_t
code_hash(PyCodeObject * co)1760 code_hash(PyCodeObject *co)
1761 {
1762     Py_hash_t h, h0, h1, h2, h3;
1763     h0 = PyObject_Hash(co->co_name);
1764     if (h0 == -1) return -1;
1765     h1 = PyObject_Hash(co->co_consts);
1766     if (h1 == -1) return -1;
1767     h2 = PyObject_Hash(co->co_names);
1768     if (h2 == -1) return -1;
1769     h3 = PyObject_Hash(co->co_localsplusnames);
1770     if (h3 == -1) return -1;
1771     Py_hash_t h4 = PyObject_Hash(co->co_linetable);
1772     if (h4 == -1) {
1773         return -1;
1774     }
1775     Py_hash_t h5 = PyObject_Hash(co->co_exceptiontable);
1776     if (h5 == -1) {
1777         return -1;
1778     }
1779     h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^
1780         co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^
1781         co->co_flags;
1782     if (h == -1) h = -2;
1783     return h;
1784 }
1785 
1786 
1787 #define OFF(x) offsetof(PyCodeObject, x)
1788 
1789 static PyMemberDef code_memberlist[] = {
1790     {"co_argcount",        T_INT,    OFF(co_argcount),        READONLY},
1791     {"co_posonlyargcount", T_INT,    OFF(co_posonlyargcount), READONLY},
1792     {"co_kwonlyargcount",  T_INT,    OFF(co_kwonlyargcount),  READONLY},
1793     {"co_stacksize",       T_INT,    OFF(co_stacksize),       READONLY},
1794     {"co_flags",           T_INT,    OFF(co_flags),           READONLY},
1795     {"co_nlocals",         T_INT,    OFF(co_nlocals),         READONLY},
1796     {"co_consts",          T_OBJECT, OFF(co_consts),          READONLY},
1797     {"co_names",           T_OBJECT, OFF(co_names),           READONLY},
1798     {"co_filename",        T_OBJECT, OFF(co_filename),        READONLY},
1799     {"co_name",            T_OBJECT, OFF(co_name),            READONLY},
1800     {"co_qualname",        T_OBJECT, OFF(co_qualname),        READONLY},
1801     {"co_firstlineno",     T_INT,    OFF(co_firstlineno),     READONLY},
1802     {"co_linetable",       T_OBJECT, OFF(co_linetable),       READONLY},
1803     {"co_exceptiontable",  T_OBJECT, OFF(co_exceptiontable),  READONLY},
1804     {NULL}      /* Sentinel */
1805 };
1806 
1807 
1808 static PyObject *
code_getlnotab(PyCodeObject * code,void * closure)1809 code_getlnotab(PyCodeObject *code, void *closure)
1810 {
1811     return decode_linetable(code);
1812 }
1813 
1814 static PyObject *
code_getvarnames(PyCodeObject * code,void * closure)1815 code_getvarnames(PyCodeObject *code, void *closure)
1816 {
1817     return _PyCode_GetVarnames(code);
1818 }
1819 
1820 static PyObject *
code_getcellvars(PyCodeObject * code,void * closure)1821 code_getcellvars(PyCodeObject *code, void *closure)
1822 {
1823     return _PyCode_GetCellvars(code);
1824 }
1825 
1826 static PyObject *
code_getfreevars(PyCodeObject * code,void * closure)1827 code_getfreevars(PyCodeObject *code, void *closure)
1828 {
1829     return _PyCode_GetFreevars(code);
1830 }
1831 
1832 static PyObject *
code_getcodeadaptive(PyCodeObject * code,void * closure)1833 code_getcodeadaptive(PyCodeObject *code, void *closure)
1834 {
1835     return PyBytes_FromStringAndSize(code->co_code_adaptive,
1836                                      _PyCode_NBYTES(code));
1837 }
1838 
1839 static PyObject *
code_getcode(PyCodeObject * code,void * closure)1840 code_getcode(PyCodeObject *code, void *closure)
1841 {
1842     return _PyCode_GetCode(code);
1843 }
1844 
1845 static PyGetSetDef code_getsetlist[] = {
1846     {"co_lnotab",         (getter)code_getlnotab,       NULL, NULL},
1847     {"_co_code_adaptive", (getter)code_getcodeadaptive, NULL, NULL},
1848     // The following old names are kept for backward compatibility.
1849     {"co_varnames",       (getter)code_getvarnames,     NULL, NULL},
1850     {"co_cellvars",       (getter)code_getcellvars,     NULL, NULL},
1851     {"co_freevars",       (getter)code_getfreevars,     NULL, NULL},
1852     {"co_code",           (getter)code_getcode,         NULL, NULL},
1853     {0}
1854 };
1855 
1856 
1857 static PyObject *
code_sizeof(PyCodeObject * co,PyObject * Py_UNUSED (args))1858 code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args))
1859 {
1860     Py_ssize_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co));
1861 
1862     _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra;
1863     if (co_extra != NULL) {
1864         res += sizeof(_PyCodeObjectExtra) +
1865                (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]);
1866     }
1867 
1868     return PyLong_FromSsize_t(res);
1869 }
1870 
1871 static PyObject *
code_linesiterator(PyCodeObject * code,PyObject * Py_UNUSED (args))1872 code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args))
1873 {
1874     return (PyObject *)new_linesiterator(code);
1875 }
1876 
1877 /*[clinic input]
1878 code.replace
1879 
1880     *
1881     co_argcount: int(c_default="self->co_argcount") = -1
1882     co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1
1883     co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1
1884     co_nlocals: int(c_default="self->co_nlocals") = -1
1885     co_stacksize: int(c_default="self->co_stacksize") = -1
1886     co_flags: int(c_default="self->co_flags") = -1
1887     co_firstlineno: int(c_default="self->co_firstlineno") = -1
1888     co_code: PyBytesObject(c_default="NULL") = None
1889     co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None
1890     co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None
1891     co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
1892     co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
1893     co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
1894     co_filename: unicode(c_default="self->co_filename") = None
1895     co_name: unicode(c_default="self->co_name") = None
1896     co_qualname: unicode(c_default="self->co_qualname") = None
1897     co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None
1898     co_exceptiontable: PyBytesObject(c_default="(PyBytesObject *)self->co_exceptiontable") = None
1899 
1900 Return a copy of the code object with new values for the specified fields.
1901 [clinic start generated code]*/
1902 
1903 static PyObject *
code_replace_impl(PyCodeObject * self,int co_argcount,int co_posonlyargcount,int co_kwonlyargcount,int co_nlocals,int co_stacksize,int co_flags,int co_firstlineno,PyBytesObject * co_code,PyObject * co_consts,PyObject * co_names,PyObject * co_varnames,PyObject * co_freevars,PyObject * co_cellvars,PyObject * co_filename,PyObject * co_name,PyObject * co_qualname,PyBytesObject * co_linetable,PyBytesObject * co_exceptiontable)1904 code_replace_impl(PyCodeObject *self, int co_argcount,
1905                   int co_posonlyargcount, int co_kwonlyargcount,
1906                   int co_nlocals, int co_stacksize, int co_flags,
1907                   int co_firstlineno, PyBytesObject *co_code,
1908                   PyObject *co_consts, PyObject *co_names,
1909                   PyObject *co_varnames, PyObject *co_freevars,
1910                   PyObject *co_cellvars, PyObject *co_filename,
1911                   PyObject *co_name, PyObject *co_qualname,
1912                   PyBytesObject *co_linetable,
1913                   PyBytesObject *co_exceptiontable)
1914 /*[clinic end generated code: output=b6cd9988391d5711 input=f6f68e03571f8d7c]*/
1915 {
1916 #define CHECK_INT_ARG(ARG) \
1917         if (ARG < 0) { \
1918             PyErr_SetString(PyExc_ValueError, \
1919                             #ARG " must be a positive integer"); \
1920             return NULL; \
1921         }
1922 
1923     CHECK_INT_ARG(co_argcount);
1924     CHECK_INT_ARG(co_posonlyargcount);
1925     CHECK_INT_ARG(co_kwonlyargcount);
1926     CHECK_INT_ARG(co_nlocals);
1927     CHECK_INT_ARG(co_stacksize);
1928     CHECK_INT_ARG(co_flags);
1929     CHECK_INT_ARG(co_firstlineno);
1930 
1931 #undef CHECK_INT_ARG
1932 
1933     PyObject *code = NULL;
1934     if (co_code == NULL) {
1935         code = _PyCode_GetCode(self);
1936         if (code == NULL) {
1937             return NULL;
1938         }
1939         co_code = (PyBytesObject *)code;
1940     }
1941 
1942     if (PySys_Audit("code.__new__", "OOOiiiiii",
1943                     co_code, co_filename, co_name, co_argcount,
1944                     co_posonlyargcount, co_kwonlyargcount, co_nlocals,
1945                     co_stacksize, co_flags) < 0) {
1946         return NULL;
1947     }
1948 
1949     PyCodeObject *co = NULL;
1950     PyObject *varnames = NULL;
1951     PyObject *cellvars = NULL;
1952     PyObject *freevars = NULL;
1953     if (co_varnames == NULL) {
1954         varnames = get_localsplus_names(self, CO_FAST_LOCAL, self->co_nlocals);
1955         if (varnames == NULL) {
1956             goto error;
1957         }
1958         co_varnames = varnames;
1959     }
1960     if (co_cellvars == NULL) {
1961         cellvars = get_localsplus_names(self, CO_FAST_CELL, self->co_ncellvars);
1962         if (cellvars == NULL) {
1963             goto error;
1964         }
1965         co_cellvars = cellvars;
1966     }
1967     if (co_freevars == NULL) {
1968         freevars = get_localsplus_names(self, CO_FAST_FREE, self->co_nfreevars);
1969         if (freevars == NULL) {
1970             goto error;
1971         }
1972         co_freevars = freevars;
1973     }
1974 
1975     co = PyCode_NewWithPosOnlyArgs(
1976         co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
1977         co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names,
1978         co_varnames, co_freevars, co_cellvars, co_filename, co_name,
1979         co_qualname, co_firstlineno,
1980         (PyObject*)co_linetable, (PyObject*)co_exceptiontable);
1981 
1982 error:
1983     Py_XDECREF(code);
1984     Py_XDECREF(varnames);
1985     Py_XDECREF(cellvars);
1986     Py_XDECREF(freevars);
1987     return (PyObject *)co;
1988 }
1989 
1990 /*[clinic input]
1991 code._varname_from_oparg
1992 
1993     oparg: int
1994 
1995 (internal-only) Return the local variable name for the given oparg.
1996 
1997 WARNING: this method is for internal use only and may change or go away.
1998 [clinic start generated code]*/
1999 
2000 static PyObject *
code__varname_from_oparg_impl(PyCodeObject * self,int oparg)2001 code__varname_from_oparg_impl(PyCodeObject *self, int oparg)
2002 /*[clinic end generated code: output=1fd1130413184206 input=c5fa3ee9bac7d4ca]*/
2003 {
2004     PyObject *name = PyTuple_GetItem(self->co_localsplusnames, oparg);
2005     if (name == NULL) {
2006         return NULL;
2007     }
2008     Py_INCREF(name);
2009     return name;
2010 }
2011 
2012 /* XXX code objects need to participate in GC? */
2013 
2014 static struct PyMethodDef code_methods[] = {
2015     {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
2016     {"co_lines", (PyCFunction)code_linesiterator, METH_NOARGS},
2017     {"co_positions", (PyCFunction)code_positionsiterator, METH_NOARGS},
2018     CODE_REPLACE_METHODDEF
2019     CODE__VARNAME_FROM_OPARG_METHODDEF
2020     {NULL, NULL}                /* sentinel */
2021 };
2022 
2023 
2024 PyTypeObject PyCode_Type = {
2025     PyVarObject_HEAD_INIT(&PyType_Type, 0)
2026     "code",
2027     offsetof(PyCodeObject, co_code_adaptive),
2028     sizeof(_Py_CODEUNIT),
2029     (destructor)code_dealloc,           /* tp_dealloc */
2030     0,                                  /* tp_vectorcall_offset */
2031     0,                                  /* tp_getattr */
2032     0,                                  /* tp_setattr */
2033     0,                                  /* tp_as_async */
2034     (reprfunc)code_repr,                /* tp_repr */
2035     0,                                  /* tp_as_number */
2036     0,                                  /* tp_as_sequence */
2037     0,                                  /* tp_as_mapping */
2038     (hashfunc)code_hash,                /* tp_hash */
2039     0,                                  /* tp_call */
2040     0,                                  /* tp_str */
2041     PyObject_GenericGetAttr,            /* tp_getattro */
2042     0,                                  /* tp_setattro */
2043     0,                                  /* tp_as_buffer */
2044     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
2045     code_new__doc__,                    /* tp_doc */
2046     0,                                  /* tp_traverse */
2047     0,                                  /* tp_clear */
2048     code_richcompare,                   /* tp_richcompare */
2049     offsetof(PyCodeObject, co_weakreflist),     /* tp_weaklistoffset */
2050     0,                                  /* tp_iter */
2051     0,                                  /* tp_iternext */
2052     code_methods,                       /* tp_methods */
2053     code_memberlist,                    /* tp_members */
2054     code_getsetlist,                    /* tp_getset */
2055     0,                                  /* tp_base */
2056     0,                                  /* tp_dict */
2057     0,                                  /* tp_descr_get */
2058     0,                                  /* tp_descr_set */
2059     0,                                  /* tp_dictoffset */
2060     0,                                  /* tp_init */
2061     0,                                  /* tp_alloc */
2062     code_new,                           /* tp_new */
2063 };
2064 
2065 
2066 /******************
2067  * other API
2068  ******************/
2069 
2070 PyObject*
_PyCode_ConstantKey(PyObject * op)2071 _PyCode_ConstantKey(PyObject *op)
2072 {
2073     PyObject *key;
2074 
2075     /* Py_None and Py_Ellipsis are singletons. */
2076     if (op == Py_None || op == Py_Ellipsis
2077        || PyLong_CheckExact(op)
2078        || PyUnicode_CheckExact(op)
2079           /* code_richcompare() uses _PyCode_ConstantKey() internally */
2080        || PyCode_Check(op))
2081     {
2082         /* Objects of these types are always different from object of other
2083          * type and from tuples. */
2084         Py_INCREF(op);
2085         key = op;
2086     }
2087     else if (PyBool_Check(op) || PyBytes_CheckExact(op)) {
2088         /* Make booleans different from integers 0 and 1.
2089          * Avoid BytesWarning from comparing bytes with strings. */
2090         key = PyTuple_Pack(2, Py_TYPE(op), op);
2091     }
2092     else if (PyFloat_CheckExact(op)) {
2093         double d = PyFloat_AS_DOUBLE(op);
2094         /* all we need is to make the tuple different in either the 0.0
2095          * or -0.0 case from all others, just to avoid the "coercion".
2096          */
2097         if (d == 0.0 && copysign(1.0, d) < 0.0)
2098             key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2099         else
2100             key = PyTuple_Pack(2, Py_TYPE(op), op);
2101     }
2102     else if (PyComplex_CheckExact(op)) {
2103         Py_complex z;
2104         int real_negzero, imag_negzero;
2105         /* For the complex case we must make complex(x, 0.)
2106            different from complex(x, -0.) and complex(0., y)
2107            different from complex(-0., y), for any x and y.
2108            All four complex zeros must be distinguished.*/
2109         z = PyComplex_AsCComplex(op);
2110         real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
2111         imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
2112         /* use True, False and None singleton as tags for the real and imag
2113          * sign, to make tuples different */
2114         if (real_negzero && imag_negzero) {
2115             key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
2116         }
2117         else if (imag_negzero) {
2118             key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
2119         }
2120         else if (real_negzero) {
2121             key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2122         }
2123         else {
2124             key = PyTuple_Pack(2, Py_TYPE(op), op);
2125         }
2126     }
2127     else if (PyTuple_CheckExact(op)) {
2128         Py_ssize_t i, len;
2129         PyObject *tuple;
2130 
2131         len = PyTuple_GET_SIZE(op);
2132         tuple = PyTuple_New(len);
2133         if (tuple == NULL)
2134             return NULL;
2135 
2136         for (i=0; i < len; i++) {
2137             PyObject *item, *item_key;
2138 
2139             item = PyTuple_GET_ITEM(op, i);
2140             item_key = _PyCode_ConstantKey(item);
2141             if (item_key == NULL) {
2142                 Py_DECREF(tuple);
2143                 return NULL;
2144             }
2145 
2146             PyTuple_SET_ITEM(tuple, i, item_key);
2147         }
2148 
2149         key = PyTuple_Pack(2, tuple, op);
2150         Py_DECREF(tuple);
2151     }
2152     else if (PyFrozenSet_CheckExact(op)) {
2153         Py_ssize_t pos = 0;
2154         PyObject *item;
2155         Py_hash_t hash;
2156         Py_ssize_t i, len;
2157         PyObject *tuple, *set;
2158 
2159         len = PySet_GET_SIZE(op);
2160         tuple = PyTuple_New(len);
2161         if (tuple == NULL)
2162             return NULL;
2163 
2164         i = 0;
2165         while (_PySet_NextEntry(op, &pos, &item, &hash)) {
2166             PyObject *item_key;
2167 
2168             item_key = _PyCode_ConstantKey(item);
2169             if (item_key == NULL) {
2170                 Py_DECREF(tuple);
2171                 return NULL;
2172             }
2173 
2174             assert(i < len);
2175             PyTuple_SET_ITEM(tuple, i, item_key);
2176             i++;
2177         }
2178         set = PyFrozenSet_New(tuple);
2179         Py_DECREF(tuple);
2180         if (set == NULL)
2181             return NULL;
2182 
2183         key = PyTuple_Pack(2, set, op);
2184         Py_DECREF(set);
2185         return key;
2186     }
2187     else {
2188         /* for other types, use the object identifier as a unique identifier
2189          * to ensure that they are seen as unequal. */
2190         PyObject *obj_id = PyLong_FromVoidPtr(op);
2191         if (obj_id == NULL)
2192             return NULL;
2193 
2194         key = PyTuple_Pack(2, obj_id, op);
2195         Py_DECREF(obj_id);
2196     }
2197     return key;
2198 }
2199 
2200 void
_PyStaticCode_Dealloc(PyCodeObject * co)2201 _PyStaticCode_Dealloc(PyCodeObject *co)
2202 {
2203     if (co->co_warmup == 0) {
2204          _Py_QuickenedCount--;
2205     }
2206     deopt_code(_PyCode_CODE(co), Py_SIZE(co));
2207     co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
2208     PyMem_Free(co->co_extra);
2209     Py_CLEAR(co->_co_code);
2210     co->co_extra = NULL;
2211     if (co->co_weakreflist != NULL) {
2212         PyObject_ClearWeakRefs((PyObject *)co);
2213         co->co_weakreflist = NULL;
2214     }
2215     if (co->_co_linearray) {
2216         PyMem_Free(co->_co_linearray);
2217         co->_co_linearray = NULL;
2218     }
2219 }
2220 
2221 int
_PyStaticCode_InternStrings(PyCodeObject * co)2222 _PyStaticCode_InternStrings(PyCodeObject *co)
2223 {
2224     int res = intern_strings(co->co_names);
2225     if (res < 0) {
2226         return -1;
2227     }
2228     res = intern_string_constants(co->co_consts, NULL);
2229     if (res < 0) {
2230         return -1;
2231     }
2232     res = intern_strings(co->co_localsplusnames);
2233     if (res < 0) {
2234         return -1;
2235     }
2236     return 0;
2237 }
2238