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