LCOV - code coverage report
Current view: top level - Objects - codeobject.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 858 1055 81.3 %
Date: 2022-07-07 18:19:46 Functions: 65 72 90.3 %

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

Generated by: LCOV version 1.14