Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Objects/codeobject.c
Line
Count
Source (jump to first uncovered line)
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
all_name_chars(PyObject *o)
22
{
23
    const unsigned char *s, *e;
24
25
    if (!PyUnicode_IS_ASCII(o))
  Branch (25:9): [True: 7.74k, False: 1.36M]
26
        return 0;
27
28
    s = PyUnicode_1BYTE_DATA(o);
29
    e = s + PyUnicode_GET_LENGTH(o);
30
    for (; s != e; 
s++7.78M
) {
  Branch (30:12): [True: 8.30M, False: 845k]
31
        if (!Py_ISALNUM(*s) && 
*s != '_'982k
)
  Branch (31:13): [True: 982k, False: 7.32M]
  Branch (31:32): [True: 523k, False: 458k]
32
            return 0;
33
    }
34
    return 1;
35
}
36
37
static int
38
intern_strings(PyObject *tuple)
39
{
40
    Py_ssize_t i;
41
42
    for (i = 
PyTuple_GET_SIZE955k
(tuple); --i >= 0; ) {
  Branch (42:39): [True: 3.86M, False: 955k]
43
        PyObject *v = PyTuple_GET_ITEM(tuple, i);
44
        if (v == NULL || !PyUnicode_CheckExact(v)) {
  Branch (44:13): [True: 0, False: 3.86M]
  Branch (44:26): [True: 0, False: 3.86M]
45
            PyErr_SetString(PyExc_SystemError,
46
                            "non-string found in code slot");
47
            return -1;
48
        }
49
        PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]);
50
    }
51
    return 0;
52
}
53
54
/* Intern selected string constants */
55
static int
56
intern_string_constants(PyObject *tuple, int *modified)
57
{
58
    for (Py_ssize_t i = 
PyTuple_GET_SIZE657k
(tuple); --i >= 0; ) {
  Branch (58:50): [True: 2.98M, False: 657k]
59
        PyObject *v = PyTuple_GET_ITEM(tuple, i);
60
        if (PyUnicode_CheckExact(v)) {
61
            if (PyUnicode_READY(v) == -1) {
  Branch (61:17): [True: 0, False: 1.37M]
62
                return -1;
63
            }
64
65
            if (all_name_chars(v)) {
  Branch (65:17): [True: 845k, False: 531k]
66
                PyObject *w = v;
67
                PyUnicode_InternInPlace(&v);
68
                if (w != v) {
  Branch (68:21): [True: 19.1k, False: 825k]
69
                    PyTuple_SET_ITEM(tuple, i, v);
70
                    if (modified) {
  Branch (70:25): [True: 199, False: 18.9k]
71
                        *modified = 1;
72
                    }
73
                }
74
            }
75
        }
76
        else if (PyTuple_CheckExact(v)) {
77
            if (intern_string_constants(v, NULL) < 0) {
  Branch (77:17): [True: 0, False: 179k]
78
                return -1;
79
            }
80
        }
81
        else if (PyFrozenSet_CheckExact(v)) {
82
            PyObject *w = v;
83
            PyObject *tmp = PySequence_Tuple(v);
84
            if (tmp == NULL) {
  Branch (84:17): [True: 0, False: 541]
85
                return -1;
86
            }
87
            int tmp_modified = 0;
88
            if (intern_string_constants(tmp, &tmp_modified) < 0) {
  Branch (88:17): [True: 0, False: 541]
89
                Py_DECREF(tmp);
90
                return -1;
91
            }
92
            if (tmp_modified) {
  Branch (92:17): [True: 61, False: 480]
93
                v = PyFrozenSet_New(tmp);
94
                if (v == NULL) {
  Branch (94:21): [True: 0, False: 61]
95
                    Py_DECREF(tmp);
96
                    return -1;
97
                }
98
99
                PyTuple_SET_ITEM(tuple, i, v);
100
                Py_DECREF(w);
101
                if (modified) {
  Branch (101:21): [True: 0, False: 61]
102
                    *modified = 1;
103
                }
104
            }
105
            Py_DECREF(tmp);
106
        }
107
    }
108
    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
validate_and_copy_tuple(PyObject *tup)
116
{
117
    PyObject *newtuple;
118
    PyObject *item;
119
    Py_ssize_t i, len;
120
121
    len = PyTuple_GET_SIZE(tup);
122
    newtuple = PyTuple_New(len);
123
    if (newtuple == NULL)
  Branch (123:9): [True: 0, False: 12]
124
        return NULL;
125
126
    
for (i = 0; 12
i < len;
i++2
) {
  Branch (126:17): [True: 2, False: 12]
127
        item = PyTuple_GET_ITEM(tup, i);
128
        if (PyUnicode_CheckExact(item)) {
129
            Py_INCREF(item);
130
        }
131
        else if (!PyUnicode_Check(item)) {
  Branch (131:18): [True: 0, False: 0]
132
            PyErr_Format(
133
                PyExc_TypeError,
134
                "name tuples must contain only "
135
                "strings, not '%.500s'",
136
                Py_TYPE(item)->tp_name);
137
            Py_DECREF(newtuple);
138
            return NULL;
139
        }
140
        else {
141
            item = _PyUnicode_Copy(item);
142
            if (item == NULL) {
  Branch (142:17): [True: 0, False: 0]
143
                Py_DECREF(newtuple);
144
                return NULL;
145
            }
146
        }
147
        PyTuple_SET_ITEM(newtuple, i, item);
148
    }
149
150
    return newtuple;
151
}
152
153
154
/******************
155
 * _PyCode_New()
156
 ******************/
157
158
// This is also used in compile.c.
159
void
160
_Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
161
                        PyObject *names, PyObject *kinds)
162
{
163
    Py_INCREF(name);
164
    PyTuple_SET_ITEM(names, offset, name);
165
    _PyLocals_SetKind(kinds, offset, kind);
166
}
167
168
static void
169
get_localsplus_counts(PyObject *names, PyObject *kinds,
170
                      int *pnlocals, int *pnplaincellvars, int *pncellvars,
171
                      int *pnfreevars)
172
{
173
    int nlocals = 0;
174
    int nplaincellvars = 0;
175
    int ncellvars = 0;
176
    int nfreevars = 0;
177
    Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
178
    for (int i = 0; i < nlocalsplus; 
i++1.24M
) {
  Branch (178:21): [True: 1.24M, False: 526k]
179
        _PyLocals_Kind kind = _PyLocals_GetKind(kinds, i);
180
        if (kind & CO_FAST_LOCAL) {
  Branch (180:13): [True: 1.15M, False: 93.6k]
181
            nlocals += 1;
182
            if (kind & CO_FAST_CELL) {
  Branch (182:17): [True: 19.6k, False: 1.13M]
183
                ncellvars += 1;
184
            }
185
        }
186
        else if (kind & CO_FAST_CELL) {
  Branch (186:18): [True: 26.7k, False: 66.8k]
187
            ncellvars += 1;
188
            nplaincellvars += 1;
189
        }
190
        else if (kind & CO_FAST_FREE) {
  Branch (190:18): [True: 66.8k, False: 0]
191
            nfreevars += 1;
192
        }
193
    }
194
    if (pnlocals != NULL) {
  Branch (194:9): [True: 526k, False: 0]
195
        *pnlocals = nlocals;
196
    }
197
    if (pnplaincellvars != NULL) {
  Branch (197:9): [True: 263k, False: 263k]
198
        *pnplaincellvars = nplaincellvars;
199
    }
200
    if (pncellvars != NULL) {
  Branch (200:9): [True: 263k, False: 263k]
201
        *pncellvars = ncellvars;
202
    }
203
    if (pnfreevars != NULL) {
  Branch (203:9): [True: 263k, False: 263k]
204
        *pnfreevars = nfreevars;
205
    }
206
}
207
208
static PyObject *
209
get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num)
210
{
211
    PyObject *names = PyTuple_New(num);
212
    if (names == NULL) {
  Branch (212:9): [True: 0, False: 3.35k]
213
        return NULL;
214
    }
215
    int index = 0;
216
    for (int offset = 0; offset < co->co_nlocalsplus; 
offset++10.2k
) {
  Branch (216:26): [True: 10.2k, False: 3.35k]
217
        _PyLocals_Kind k = _PyLocals_GetKind(co->co_localspluskinds, offset);
218
        if ((k & kind) == 0) {
  Branch (218:13): [True: 479, False: 9.74k]
219
            continue;
220
        }
221
        assert(index < num);
222
        PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, offset);
223
        Py_INCREF(name);
224
        PyTuple_SET_ITEM(names, index, name);
225
        index += 1;
226
    }
227
    assert(index == num);
228
    return names;
229
}
230
231
int
232
_PyCode_Validate(struct _PyCodeConstructor *con)
233
{
234
    /* Check argument types */
235
    if (con->argcount < con->posonlyargcount || con->posonlyargcount < 0 ||
  Branch (235:9): [True: 0, False: 263k]
  Branch (235:49): [True: 0, False: 263k]
236
        con->kwonlyargcount < 0 ||
  Branch (236:9): [True: 0, False: 263k]
237
        con->stacksize < 0 || con->flags < 0 ||
  Branch (237:9): [True: 0, False: 263k]
  Branch (237:31): [True: 0, False: 263k]
238
        con->code == NULL || !PyBytes_Check(con->code) ||
  Branch (238:9): [True: 0, False: 263k]
  Branch (238:30): [True: 0, False: 263k]
239
        con->consts == NULL || !PyTuple_Check(con->consts) ||
  Branch (239:9): [True: 0, False: 263k]
  Branch (239:32): [True: 0, False: 263k]
240
        con->names == NULL || !PyTuple_Check(con->names) ||
  Branch (240:9): [True: 0, False: 263k]
  Branch (240:31): [True: 0, False: 263k]
241
        con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) ||
  Branch (241:9): [True: 0, False: 263k]
  Branch (241:41): [True: 0, False: 263k]
242
        con->localspluskinds == NULL || !PyBytes_Check(con->localspluskinds) ||
  Branch (242:9): [True: 0, False: 263k]
  Branch (242:41): [True: 0, False: 263k]
243
        PyTuple_GET_SIZE(con->localsplusnames)
  Branch (243:9): [True: 0, False: 263k]
244
            != PyBytes_GET_SIZE(con->localspluskinds) ||
245
        con->name == NULL || !PyUnicode_Check(con->name) ||
  Branch (245:9): [True: 0, False: 263k]
  Branch (245:30): [True: 0, False: 263k]
246
        con->qualname == NULL || !PyUnicode_Check(con->qualname) ||
  Branch (246:9): [True: 0, False: 263k]
  Branch (246:34): [True: 0, False: 263k]
247
        con->filename == NULL || !PyUnicode_Check(con->filename) ||
  Branch (247:9): [True: 0, False: 263k]
  Branch (247:34): [True: 0, False: 263k]
248
        con->linetable == NULL || !PyBytes_Check(con->linetable) ||
  Branch (248:9): [True: 0, False: 263k]
  Branch (248:35): [True: 0, False: 263k]
249
        con->exceptiontable == NULL || !PyBytes_Check(con->exceptiontable)
  Branch (249:9): [True: 0, False: 263k]
  Branch (249:40): [True: 0, False: 263k]
250
        ) {
251
        PyErr_BadInternalCall();
252
        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
    if (PyBytes_GET_SIZE(con->code) > INT_MAX) {
  Branch (258:9): [True: 0, False: 263k]
259
        PyErr_SetString(PyExc_OverflowError,
260
                        "code: co_code larger than INT_MAX");
261
        return -1;
262
    }
263
    if (PyBytes_GET_SIZE(con->code) % sizeof(_Py_CODEUNIT) != 0 ||
  Branch (263:9): [True: 0, False: 263k]
264
        !_Py_IS_ALIGNED(PyBytes_AS_STRING(con->code), sizeof(_Py_CODEUNIT))
  Branch (264:9): [True: 0, False: 263k]
265
        ) {
266
        PyErr_SetString(PyExc_ValueError, "code: co_code is malformed");
267
        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
    get_localsplus_counts(con->localsplusnames, con->localspluskinds,
275
                          &nlocals, NULL, NULL, NULL);
276
    int nplainlocals = nlocals -
277
                       con->argcount -
278
                       con->kwonlyargcount -
279
                       ((con->flags & CO_VARARGS) != 0) -
280
                       ((con->flags & CO_VARKEYWORDS) != 0);
281
    if (nplainlocals < 0) {
  Branch (281:9): [True: 0, False: 263k]
282
        PyErr_SetString(PyExc_ValueError, "code: co_varnames is too small");
283
        return -1;
284
    }
285
286
    return 0;
287
}
288
289
static void
290
init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
291
{
292
    int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames);
293
    int nlocals, nplaincellvars, ncellvars, nfreevars;
294
    get_localsplus_counts(con->localsplusnames, con->localspluskinds,
295
                          &nlocals, &nplaincellvars, &ncellvars, &nfreevars);
296
297
    Py_INCREF(con->filename);
298
    co->co_filename = con->filename;
299
    Py_INCREF(con->name);
300
    co->co_name = con->name;
301
    Py_INCREF(con->qualname);
302
    co->co_qualname = con->qualname;
303
    co->co_flags = con->flags;
304
305
    co->co_firstlineno = con->firstlineno;
306
    Py_INCREF(con->linetable);
307
    co->co_linetable = con->linetable;
308
309
    Py_INCREF(con->consts);
310
    co->co_consts = con->consts;
311
    Py_INCREF(con->names);
312
    co->co_names = con->names;
313
314
    Py_INCREF(con->localsplusnames);
315
    co->co_localsplusnames = con->localsplusnames;
316
    Py_INCREF(con->localspluskinds);
317
    co->co_localspluskinds = con->localspluskinds;
318
319
    co->co_argcount = con->argcount;
320
    co->co_posonlyargcount = con->posonlyargcount;
321
    co->co_kwonlyargcount = con->kwonlyargcount;
322
323
    co->co_stacksize = con->stacksize;
324
325
    Py_INCREF(con->exceptiontable);
326
    co->co_exceptiontable = con->exceptiontable;
327
328
    /* derived values */
329
    co->co_nlocalsplus = nlocalsplus;
330
    co->co_nlocals = nlocals;
331
    co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
332
    co->co_nplaincellvars = nplaincellvars;
333
    co->co_ncellvars = ncellvars;
334
    co->co_nfreevars = nfreevars;
335
336
    /* not set */
337
    co->co_weakreflist = NULL;
338
    co->co_extra = NULL;
339
    co->_co_code = NULL;
340
341
    co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
342
    co->_co_linearray_entry_size = 0;
343
    co->_co_linearray = NULL;
344
    memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code),
345
           PyBytes_GET_SIZE(con->code));
346
    int entry_point = 0;
347
    while (entry_point < Py_SIZE(co) &&
  Branch (347:12): [True: 327k, False: 0]
348
        _Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) {
  Branch (348:9): [True: 64.3k, False: 263k]
349
        entry_point++;
350
    }
351
    co->_co_firsttraceable = entry_point;
352
}
353
354
static int
355
scan_varint(const uint8_t *ptr)
356
{
357
    unsigned int read = *ptr++;
358
    unsigned int val = read & 63;
359
    unsigned int shift = 0;
360
    while (read & 64) {
  Branch (360:12): [True: 234k, False: 36.3M]
361
        read = *ptr++;
362
        shift += 6;
363
        val |= (read & 63) << shift;
364
    }
365
    return val;
366
}
367
368
static int
369
scan_signed_varint(const uint8_t *ptr)
370
{
371
    unsigned int uval = scan_varint(ptr);
372
    if (uval & 1) {
  Branch (372:9): [True: 3.41M, False: 32.9M]
373
        return -(int)(uval >> 1);
374
    }
375
    else {
376
        return uval >> 1;
377
    }
378
}
379
380
static int
381
get_line_delta(const uint8_t *ptr)
382
{
383
    int code = ((*ptr) >> 3) & 15;
384
    switch (code) {
385
        case PY_CODE_LOCATION_INFO_NONE:
  Branch (385:9): [True: 1.26M, False: 155M]
386
            return 0;
387
        case PY_CODE_LOCATION_INFO_NO_COLUMNS:
  Branch (387:9): [True: 9.99M, False: 146M]
388
        case PY_CODE_LOCATION_INFO_LONG:
  Branch (388:9): [True: 26.3M, False: 130M]
389
            return scan_signed_varint(ptr+1);
390
        case PY_CODE_LOCATION_INFO_ONE_LINE0:
  Branch (390:9): [True: 31.2M, False: 125M]
391
            return 0;
392
        case PY_CODE_LOCATION_INFO_ONE_LINE1:
  Branch (392:9): [True: 15.0M, False: 141M]
393
            return 1;
394
        case PY_CODE_LOCATION_INFO_ONE_LINE2:
  Branch (394:9): [True: 2.75M, False: 153M]
395
            return 2;
396
        default:
  Branch (396:9): [True: 69.6M, False: 86.7M]
397
            /* Same line */
398
            return 0;
399
    }
400
}
401
402
static PyObject *
403
remove_column_info(PyObject *locations)
404
{
405
    int offset = 0;
406
    const uint8_t *data = (const uint8_t *)PyBytes_AS_STRING(locations);
407
    PyObject *res = PyBytes_FromStringAndSize(NULL, 32);
408
    if (res == NULL) {
  Branch (408:9): [True: 0, False: 2.35k]
409
        PyErr_NoMemory();
410
        return NULL;
411
    }
412
    uint8_t *output = (uint8_t *)PyBytes_AS_STRING(res);
413
    while (offset < PyBytes_GET_SIZE(locations)) {
  Branch (413:12): [True: 114k, False: 2.35k]
414
        Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
415
        if (write_offset + 16 >= PyBytes_GET_SIZE(res)) {
  Branch (415:13): [True: 3.54k, False: 111k]
416
            if (_PyBytes_Resize(&res, PyBytes_GET_SIZE(res) * 2) < 0) {
  Branch (416:17): [True: 0, False: 3.54k]
417
                return NULL;
418
            }
419
            output = (uint8_t *)PyBytes_AS_STRING(res) + write_offset;
420
        }
421
        int code = (data[offset] >> 3) & 15;
422
        if (code == PY_CODE_LOCATION_INFO_NONE) {
  Branch (422:13): [True: 2.21k, False: 112k]
423
            *output++ = data[offset];
424
        }
425
        else {
426
            int blength = (data[offset] & 7)+1;
427
            output += write_location_entry_start(
428
                output, PY_CODE_LOCATION_INFO_NO_COLUMNS, blength);
429
            int ldelta = get_line_delta(&data[offset]);
430
            output += write_signed_varint(output, ldelta);
431
        }
432
        offset++;
433
        while (offset < PyBytes_GET_SIZE(locations) &&
  Branch (433:16): [True: 341k, False: 2.35k]
434
            
(data[offset] & 128) == 0341k
) {
  Branch (434:13): [True: 229k, False: 112k]
435
            offset++;
436
        }
437
    }
438
    Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
439
    if (_PyBytes_Resize(&res, write_offset)) {
  Branch (439:9): [True: 0, False: 2.35k]
440
        return NULL;
441
    }
442
    return res;
443
}
444
445
/* The caller is responsible for ensuring that the given data is valid. */
446
447
PyCodeObject *
448
_PyCode_New(struct _PyCodeConstructor *con)
449
{
450
    /* Ensure that strings are ready Unicode string */
451
    if (PyUnicode_READY(con->name) < 0) {
  Branch (451:9): [True: 0, False: 263k]
452
        return NULL;
453
    }
454
    if (PyUnicode_READY(con->qualname) < 0) {
  Branch (454:9): [True: 0, False: 263k]
455
        return NULL;
456
    }
457
    if (PyUnicode_READY(con->filename) < 0) {
  Branch (457:9): [True: 0, False: 263k]
458
        return NULL;
459
    }
460
461
    if (intern_strings(con->names) < 0) {
  Branch (461:9): [True: 0, False: 263k]
462
        return NULL;
463
    }
464
    if (intern_string_constants(con->consts, NULL) < 0) {
  Branch (464:9): [True: 0, False: 263k]
465
        return NULL;
466
    }
467
    if (intern_strings(con->localsplusnames) < 0) {
  Branch (467:9): [True: 0, False: 263k]
468
        return NULL;
469
    }
470
471
    PyObject *replacement_locations = NULL;
472
    // Compact the linetable if we are opted out of debug
473
    // ranges.
474
    if (!_Py_GetConfig()->code_debug_ranges) {
  Branch (474:9): [True: 2.35k, False: 261k]
475
        replacement_locations = remove_column_info(con->linetable);
476
        if (replacement_locations == NULL) {
  Branch (476:13): [True: 0, False: 2.35k]
477
            return NULL;
478
        }
479
        con->linetable = replacement_locations;
480
    }
481
482
    Py_ssize_t size = PyBytes_GET_SIZE(con->code) / sizeof(_Py_CODEUNIT);
483
    PyCodeObject *co = PyObject_NewVar(PyCodeObject, &PyCode_Type, size);
484
    if (co == NULL) {
  Branch (484:9): [True: 0, False: 263k]
485
        Py_XDECREF(replacement_locations);
486
        PyErr_NoMemory();
487
        return NULL;
488
    }
489
    init_code(co, con);
490
    Py_XDECREF(replacement_locations);
491
    return co;
492
}
493
494
495
/******************
496
 * the legacy "constructors"
497
 ******************/
498
499
PyCodeObject *
500
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
    PyCodeObject *co = NULL;
510
    PyObject *localsplusnames = NULL;
511
    PyObject *localspluskinds = NULL;
512
513
    if (varnames == NULL || !PyTuple_Check(varnames) ||
  Branch (513:9): [True: 0, False: 70]
  Branch (513:29): [True: 0, False: 70]
514
        cellvars == NULL || !PyTuple_Check(cellvars) ||
  Branch (514:9): [True: 0, False: 70]
  Branch (514:29): [True: 0, False: 70]
515
        freevars == NULL || !PyTuple_Check(freevars)
  Branch (515:9): [True: 0, False: 70]
  Branch (515:29): [True: 0, False: 70]
516
        ) {
517
        PyErr_BadInternalCall();
518
        return NULL;
519
    }
520
521
    // Set the "fast locals plus" info.
522
    int nvarnames = (int)PyTuple_GET_SIZE(varnames);
523
    int ncellvars = (int)PyTuple_GET_SIZE(cellvars);
524
    int nfreevars = (int)PyTuple_GET_SIZE(freevars);
525
    int nlocalsplus = nvarnames + ncellvars + nfreevars;
526
    localsplusnames = PyTuple_New(nlocalsplus);
527
    if (localsplusnames == NULL) {
  Branch (527:9): [True: 0, False: 70]
528
        goto error;
529
    }
530
    localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
531
    if (localspluskinds == NULL) {
  Branch (531:9): [True: 0, False: 70]
532
        goto error;
533
    }
534
    int  offset = 0;
535
    for (int i = 0; i < nvarnames; 
i++, offset++53
) {
  Branch (535:21): [True: 53, False: 70]
536
        PyObject *name = PyTuple_GET_ITEM(varnames, i);
537
        _Py_set_localsplus_info(offset, name, CO_FAST_LOCAL,
538
                               localsplusnames, localspluskinds);
539
    }
540
    for (int i = 0; i < ncellvars; 
i++, offset++2
) {
  Branch (540:21): [True: 2, False: 70]
541
        PyObject *name = PyTuple_GET_ITEM(cellvars, i);
542
        int argoffset = -1;
543
        for (int j = 0; j < nvarnames; 
j++1
) {
  Branch (543:25): [True: 2, False: 1]
544
            int cmp = PyUnicode_Compare(PyTuple_GET_ITEM(varnames, j),
545
                                        name);
546
            assert(!PyErr_Occurred());
547
            if (cmp == 0) {
  Branch (547:17): [True: 1, False: 1]
548
                argoffset = j;
549
                break;
550
            }
551
        }
552
        if (argoffset >= 0) {
  Branch (552:13): [True: 1, False: 1]
553
            // Merge the localsplus indices.
554
            nlocalsplus -= 1;
555
            offset -= 1;
556
            _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, argoffset);
557
            _PyLocals_SetKind(localspluskinds, argoffset, kind | CO_FAST_CELL);
558
            continue;
559
        }
560
        _Py_set_localsplus_info(offset, name, CO_FAST_CELL,
561
                               localsplusnames, localspluskinds);
562
    }
563
    for (int i = 0; i < nfreevars; 
i++, offset++7
) {
  Branch (563:21): [True: 7, False: 70]
564
        PyObject *name = PyTuple_GET_ITEM(freevars, i);
565
        _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
    if (nlocalsplus != PyTuple_GET_SIZE(localsplusnames)) {
  Branch (569:9): [True: 1, False: 69]
570
        if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0
  Branch (570:13): [True: 0, False: 1]
571
                || _PyBytes_Resize(&localspluskinds, nlocalsplus) < 0) {
  Branch (571:20): [True: 0, False: 1]
572
            goto error;
573
        }
574
    }
575
576
    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
    if (_PyCode_Validate(&con) < 0) {
  Branch (601:9): [True: 0, False: 70]
602
        goto error;
603
    }
604
    assert(PyBytes_GET_SIZE(code) % sizeof(_Py_CODEUNIT) == 0);
605
    assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(code), sizeof(_Py_CODEUNIT)));
606
    if (nlocals != PyTuple_GET_SIZE(varnames)) {
  Branch (606:9): [True: 4, False: 66]
607
        PyErr_SetString(PyExc_ValueError,
608
                        "code: co_nlocals != len(co_varnames)");
609
        goto error;
610
    }
611
612
    co = _PyCode_New(&con);
613
    if (co == NULL) {
  Branch (613:9): [True: 0, False: 66]
614
        goto error;
615
    }
616
617
error:
618
    Py_XDECREF(localsplusnames);
619
    Py_XDECREF(localspluskinds);
620
    return co;
621
}
622
623
PyCodeObject *
624
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
    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
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
649
{
650
    PyObject *nulltuple = NULL;
651
    PyObject *filename_ob = NULL;
652
    PyObject *funcname_ob = NULL;
653
    PyObject *code_ob = NULL;
654
    PyCodeObject *result = NULL;
655
656
    nulltuple = PyTuple_New(0);
657
    if (nulltuple == NULL) {
  Branch (657:9): [True: 0, False: 32]
658
        goto failed;
659
    }
660
    funcname_ob = PyUnicode_FromString(funcname);
661
    if (funcname_ob == NULL) {
  Branch (661:9): [True: 0, False: 32]
662
        goto failed;
663
    }
664
    filename_ob = PyUnicode_DecodeFSDefault(filename);
665
    if (filename_ob == NULL) {
  Branch (665:9): [True: 0, False: 32]
666
        goto failed;
667
    }
668
    code_ob = PyBytes_FromStringAndSize(assert0, 6);
669
    if (code_ob == NULL) {
  Branch (669:9): [True: 0, False: 32]
670
        goto failed;
671
    }
672
673
#define emptystring (PyObject *)&_Py_SINGLETON(bytes_empty)
674
    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
    result = _PyCode_New(&con);
689
690
failed:
691
    Py_XDECREF(nulltuple);
692
    Py_XDECREF(funcname_ob);
693
    Py_XDECREF(filename_ob);
694
    Py_XDECREF(code_ob);
695
    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
_PyCode_CreateLineArray(PyCodeObject *co)
709
{
710
    assert(co->_co_linearray == NULL);
711
    PyCodeAddressRange bounds;
712
    int size;
713
    int max_line = 0;
714
    _PyCode_InitAddressRange(co, &bounds);
715
    while(_PyLineTable_NextAddressRange(&bounds)) {
  Branch (715:11): [True: 60.9k, False: 1.71k]
716
        if (bounds.ar_line > max_line) {
  Branch (716:13): [True: 11.6k, False: 49.3k]
717
            max_line = bounds.ar_line;
718
        }
719
    }
720
    if (max_line < (1 << 15)) {
  Branch (720:9): [True: 1.71k, False: 0]
721
        size = 2;
722
    }
723
    else {
724
        size = 4;
725
    }
726
    co->_co_linearray = PyMem_Malloc(Py_SIZE(co)*size);
727
    if (co->_co_linearray == NULL) {
  Branch (727:9): [True: 0, False: 1.71k]
728
        PyErr_NoMemory();
729
        return -1;
730
    }
731
    co->_co_linearray_entry_size = size;
732
    _PyCode_InitAddressRange(co, &bounds);
733
    while(_PyLineTable_NextAddressRange(&bounds)) {
  Branch (733:11): [True: 60.9k, False: 1.71k]
734
        int start = bounds.ar_start / sizeof(_Py_CODEUNIT);
735
        int end = bounds.ar_end / sizeof(_Py_CODEUNIT);
736
        for (int index = start; index < end; 
index++145k
) {
  Branch (736:33): [True: 145k, False: 60.9k]
737
            assert(index < (int)Py_SIZE(co));
738
            if (size == 2) {
  Branch (738:17): [True: 145k, False: 0]
739
                assert(((int16_t)bounds.ar_line) == bounds.ar_line);
740
                ((int16_t *)co->_co_linearray)[index] = bounds.ar_line;
741
            }
742
            else {
743
                assert(size == 4);
744
                ((int32_t *)co->_co_linearray)[index] = bounds.ar_line;
745
            }
746
        }
747
    }
748
    return 0;
749
}
750
751
int
752
PyCode_Addr2Line(PyCodeObject *co, int addrq)
753
{
754
    if (addrq < 0) {
  Branch (754:9): [True: 0, False: 6.93M]
755
        return co->co_firstlineno;
756
    }
757
    assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
758
    if (co->_co_linearray) {
  Branch (758:9): [True: 914k, False: 6.02M]
759
        return _PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT));
760
    }
761
    PyCodeAddressRange bounds;
762
    _PyCode_InitAddressRange(co, &bounds);
763
    return _PyCode_CheckLineNumber(addrq, &bounds);
764
}
765
766
void
767
_PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range)
768
{
769
    range->opaque.lo_next = (const uint8_t *)linetable;
770
    range->opaque.limit = range->opaque.lo_next + length;
771
    range->ar_start = -1;
772
    range->ar_end = 0;
773
    range->opaque.computed_line = firstlineno;
774
    range->ar_line = -1;
775
}
776
777
int
778
_PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds)
779
{
780
    assert(co->co_linetable != NULL);
781
    const char *linetable = PyBytes_AS_STRING(co->co_linetable);
782
    Py_ssize_t length = PyBytes_GET_SIZE(co->co_linetable);
783
    _PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds);
784
    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
_PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds)
791
{
792
    while (bounds->ar_end <= lasti) {
  Branch (792:12): [True: 155M, False: 6.02M]
793
        if (!_PyLineTable_NextAddressRange(bounds)) {
  Branch (793:13): [True: 1, False: 155M]
794
            return -1;
795
        }
796
    }
797
    while (bounds->ar_start > lasti) {
  Branch (797:12): [True: 0, False: 6.02M]
798
        if (!_PyLineTable_PreviousAddressRange(bounds)) {
  Branch (798:13): [True: 0, False: 0]
799
            return -1;
800
        }
801
    }
802
    return bounds->ar_line;
803
}
804
805
static int
806
is_no_line_marker(uint8_t b)
807
{
808
    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
next_code_delta(PyCodeAddressRange *bounds)
820
{
821
    assert((*bounds->opaque.lo_next) & 128);
822
    return (((*bounds->opaque.lo_next) & 7) + 1) * sizeof(_Py_CODEUNIT);
823
}
824
825
static int
826
previous_code_delta(PyCodeAddressRange *bounds)
827
{
828
    if (bounds->ar_start == 0) {
  Branch (828:9): [True: 1, False: 254]
829
        // If we looking at the first entry, the
830
        // "previous" entry has an implicit length of 1.
831
        return 1;
832
    }
833
    const uint8_t *ptr = bounds->opaque.lo_next-1;
834
    while (((*ptr) & 128) == 0) {
  Branch (834:12): [True: 390, False: 254]
835
        ptr--;
836
    }
837
    return (((*ptr) & 7) + 1) * sizeof(_Py_CODEUNIT);
838
}
839
840
static int
841
read_byte(PyCodeAddressRange *bounds)
842
{
843
    return *bounds->opaque.lo_next++;
844
}
845
846
static int
847
read_varint(PyCodeAddressRange *bounds)
848
{
849
    unsigned int read = read_byte(bounds);
850
    unsigned int val = read & 63;
851
    unsigned int shift = 0;
852
    while (read & 64) {
  Branch (852:12): [True: 55.3k, False: 189k]
853
        read = read_byte(bounds);
854
        shift += 6;
855
        val |= (read & 63) << shift;
856
    }
857
    return val;
858
}
859
860
static int
861
read_signed_varint(PyCodeAddressRange *bounds)
862
{
863
    unsigned int uval = read_varint(bounds);
864
    if (uval & 1) {
  Branch (864:9): [True: 3.62k, False: 43.9k]
865
        return -(int)(uval >> 1);
866
    }
867
    else {
868
        return uval >> 1;
869
    }
870
}
871
872
static void
873
retreat(PyCodeAddressRange *bounds)
874
{
875
    ASSERT_VALID_BOUNDS(bounds);
876
    assert(bounds->ar_start >= 0);
877
    do {
878
        bounds->opaque.lo_next--;
879
    } while (((*bounds->opaque.lo_next) & 128) == 0);
  Branch (879:14): [True: 381, False: 255]
880
    bounds->opaque.computed_line -= get_line_delta(bounds->opaque.lo_next);
881
    bounds->ar_end = bounds->ar_start;
882
    bounds->ar_start -= previous_code_delta(bounds);
883
    if (is_no_line_marker(bounds->opaque.lo_next[-1])) {
  Branch (883:9): [True: 1, False: 254]
884
        bounds->ar_line = -1;
885
    }
886
    else {
887
        bounds->ar_line = bounds->opaque.computed_line;
888
    }
889
    ASSERT_VALID_BOUNDS(bounds);
890
}
891
892
static void
893
advance(PyCodeAddressRange *bounds)
894
{
895
    ASSERT_VALID_BOUNDS(bounds);
896
    bounds->opaque.computed_line += get_line_delta(bounds->opaque.lo_next);
897
    if (is_no_line_marker(*bounds->opaque.lo_next)) {
  Branch (897:9): [True: 1.26M, False: 155M]
898
        bounds->ar_line = -1;
899
    }
900
    else {
901
        bounds->ar_line = bounds->opaque.computed_line;
902
    }
903
    bounds->ar_start = bounds->ar_end;
904
    bounds->ar_end += next_code_delta(bounds);
905
    do {
906
        bounds->opaque.lo_next++;
907
    } while (bounds->opaque.lo_next < bounds->opaque.limit &&
  Branch (907:14): [True: 443M, False: 44.1k]
908
        
((*bounds->opaque.lo_next) & 128) == 0443M
);
  Branch (908:9): [True: 287M, False: 156M]
909
    ASSERT_VALID_BOUNDS(bounds);
910
}
911
912
static void
913
advance_with_locations(PyCodeAddressRange *bounds, int *endline, int *column, int *endcolumn)
914
{
915
    ASSERT_VALID_BOUNDS(bounds);
916
    int first_byte = read_byte(bounds);
917
    int code = (first_byte >> 3) & 15;
918
    bounds->ar_start = bounds->ar_end;
919
    bounds->ar_end = bounds->ar_start + ((first_byte & 7) + 1) * sizeof(_Py_CODEUNIT);
920
    switch(code) {
921
        case PY_CODE_LOCATION_INFO_NONE:
  Branch (921:9): [True: 5.11k, False: 336k]
922
            bounds->ar_line = *endline = -1;
923
            *column =  *endcolumn = -1;
924
            break;
925
        case PY_CODE_LOCATION_INFO_LONG:
  Branch (925:9): [True: 47.2k, False: 294k]
926
        {
927
            bounds->opaque.computed_line += read_signed_varint(bounds);
928
            bounds->ar_line = bounds->opaque.computed_line;
929
            *endline = bounds->ar_line + read_varint(bounds);
930
            *column = read_varint(bounds)-1;
931
            *endcolumn = read_varint(bounds)-1;
932
            break;
933
        }
934
        case PY_CODE_LOCATION_INFO_NO_COLUMNS:
  Branch (934:9): [True: 289, False: 341k]
935
        {
936
            /* No column */
937
            bounds->opaque.computed_line += read_signed_varint(bounds);
938
            *endline = bounds->ar_line = bounds->opaque.computed_line;
939
            *column = *endcolumn = -1;
940
            break;
941
        }
942
        case PY_CODE_LOCATION_INFO_ONE_LINE0:
  Branch (942:9): [True: 54.6k, False: 287k]
943
        case PY_CODE_LOCATION_INFO_ONE_LINE1:
  Branch (943:9): [True: 75.6k, False: 266k]
944
        case PY_CODE_LOCATION_INFO_ONE_LINE2:
  Branch (944:9): [True: 6.28k, False: 335k]
945
        {
946
            /* one line form */
947
            int line_delta = code - 10;
948
            bounds->opaque.computed_line += line_delta;
949
            *endline = bounds->ar_line = bounds->opaque.computed_line;
950
            *column = read_byte(bounds);
951
            *endcolumn = read_byte(bounds);
952
            break;
953
        }
954
        default:
  Branch (954:9): [True: 152k, False: 189k]
955
        {
956
            /* Short forms */
957
            int second_byte = read_byte(bounds);
958
            assert((second_byte & 128) == 0);
959
            *endline = bounds->ar_line = bounds->opaque.computed_line;
960
            *column = code << 3 | (second_byte >> 4);
961
            *endcolumn = *column + (second_byte & 15);
962
        }
963
    }
964
    ASSERT_VALID_BOUNDS(bounds);
965
}
966
int
967
PyCode_Addr2Location(PyCodeObject *co, int addrq,
968
                     int *start_line, int *start_column,
969
                     int *end_line, int *end_column)
970
{
971
    if (addrq < 0) {
  Branch (971:9): [True: 0, False: 255]
972
        *start_line = *end_line = co->co_firstlineno;
973
        *start_column = *end_column = 0;
974
    }
975
    assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
976
    PyCodeAddressRange bounds;
977
    _PyCode_InitAddressRange(co, &bounds);
978
    _PyCode_CheckLineNumber(addrq, &bounds);
979
    retreat(&bounds);
980
    advance_with_locations(&bounds, end_line, start_column, end_column);
981
    *start_line = bounds.ar_line;
982
    return 1;
983
}
984
985
986
static inline int
987
at_end(PyCodeAddressRange *bounds) {
988
    return bounds->opaque.lo_next >= bounds->opaque.limit;
989
}
990
991
int
992
_PyLineTable_PreviousAddressRange(PyCodeAddressRange *range)
993
{
994
    if (range->ar_start <= 0) {
  Branch (994:9): [True: 0, False: 0]
995
        return 0;
996
    }
997
    retreat(range);
998
    assert(range->ar_end > range->ar_start);
999
    return 1;
1000
}
1001
1002
int
1003
_PyLineTable_NextAddressRange(PyCodeAddressRange *range)
1004
{
1005
    if (at_end(range)) {
  Branch (1005:9): [True: 8.14k, False: 156M]
1006
        return 0;
1007
    }
1008
    advance(range);
1009
    assert(range->ar_end > range->ar_start);
1010
    return 1;
1011
}
1012
1013
int
1014
_PyLineTable_StartsLine(PyCodeAddressRange *range)
1015
{
1016
    if (range->ar_start <= 0) {
  Branch (1016:9): [True: 0, False: 0]
1017
        return 0;
1018
    }
1019
    const uint8_t *ptr = range->opaque.lo_next;
1020
    do {
1021
        ptr--;
1022
    } while (((*ptr) & 128) == 0);
  Branch (1022:14): [True: 0, False: 0]
1023
    int code = ((*ptr)>> 3) & 15;
1024
    switch(code) {
1025
        case PY_CODE_LOCATION_INFO_LONG:
  Branch (1025:9): [True: 0, False: 0]
1026
            return 0;
1027
        case PY_CODE_LOCATION_INFO_NO_COLUMNS:
  Branch (1027:9): [True: 0, False: 0]
1028
        case PY_CODE_LOCATION_INFO_NONE:
  Branch (1028:9): [True: 0, False: 0]
1029
            return ptr[1] != 0;
1030
        case PY_CODE_LOCATION_INFO_ONE_LINE0:
  Branch (1030:9): [True: 0, False: 0]
1031
            return 0;
1032
        case PY_CODE_LOCATION_INFO_ONE_LINE1:
  Branch (1032:9): [True: 0, False: 0]
1033
        case PY_CODE_LOCATION_INFO_ONE_LINE2:
  Branch (1033:9): [True: 0, False: 0]
1034
            return 1;
1035
        default:
  Branch (1035:9): [True: 0, False: 0]
1036
            return 0;
1037
    }
1038
}
1039
1040
static int
1041
emit_pair(PyObject **bytes, int *offset, int a, int b)
1042
{
1043
    Py_ssize_t len = PyBytes_GET_SIZE(*bytes);
1044
    if (*offset + 2 >= len) {
  Branch (1044:9): [True: 0, False: 0]
1045
        if (_PyBytes_Resize(bytes, len * 2) < 0)
  Branch (1045:13): [True: 0, False: 0]
1046
            return 0;
1047
    }
1048
    unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(*bytes);
1049
    lnotab += *offset;
1050
    *lnotab++ = a;
1051
    *lnotab++ = b;
1052
    *offset += 2;
1053
    return 1;
1054
}
1055
1056
static int
1057
emit_delta(PyObject **bytes, int bdelta, int ldelta, int *offset)
1058
{
1059
    while (bdelta > 255) {
  Branch (1059:12): [True: 0, False: 0]
1060
        if (!emit_pair(bytes, offset, 255, 0)) {
  Branch (1060:13): [True: 0, False: 0]
1061
            return 0;
1062
        }
1063
        bdelta -= 255;
1064
    }
1065
    while (ldelta > 127) {
  Branch (1065:12): [True: 0, False: 0]
1066
        if (!emit_pair(bytes, offset, bdelta, 127)) {
  Branch (1066:13): [True: 0, False: 0]
1067
            return 0;
1068
        }
1069
        bdelta = 0;
1070
        ldelta -= 127;
1071
    }
1072
    while (ldelta < -128) {
  Branch (1072:12): [True: 0, False: 0]
1073
        if (!emit_pair(bytes, offset, bdelta, -128)) {
  Branch (1073:13): [True: 0, False: 0]
1074
            return 0;
1075
        }
1076
        bdelta = 0;
1077
        ldelta += 128;
1078
    }
1079
    return emit_pair(bytes, offset, bdelta, ldelta);
1080
}
1081
1082
static PyObject *
1083
decode_linetable(PyCodeObject *code)
1084
{
1085
    PyCodeAddressRange bounds;
1086
    PyObject *bytes;
1087
    int table_offset = 0;
1088
    int code_offset = 0;
1089
    int line = code->co_firstlineno;
1090
    bytes = PyBytes_FromStringAndSize(NULL, 64);
1091
    if (bytes == NULL) {
  Branch (1091:9): [True: 0, False: 0]
1092
        return NULL;
1093
    }
1094
    _PyCode_InitAddressRange(code, &bounds);
1095
    while (_PyLineTable_NextAddressRange(&bounds)) {
  Branch (1095:12): [True: 0, False: 0]
1096
        if (bounds.opaque.computed_line != line) {
  Branch (1096:13): [True: 0, False: 0]
1097
            int bdelta = bounds.ar_start - code_offset;
1098
            int ldelta = bounds.opaque.computed_line - line;
1099
            if (!emit_delta(&bytes, bdelta, ldelta, &table_offset)) {
  Branch (1099:17): [True: 0, False: 0]
1100
                Py_DECREF(bytes);
1101
                return NULL;
1102
            }
1103
            code_offset = bounds.ar_start;
1104
            line = bounds.opaque.computed_line;
1105
        }
1106
    }
1107
    _PyBytes_Resize(&bytes, table_offset);
1108
    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
lineiter_dealloc(lineiterator *li)
1121
{
1122
    Py_DECREF(li->li_code);
1123
    Py_TYPE(li)->tp_free(li);
1124
}
1125
1126
static PyObject *
1127
lineiter_next(lineiterator *li)
1128
{
1129
    PyCodeAddressRange *bounds = &li->li_line;
1130
    if (!_PyLineTable_NextAddressRange(bounds)) {
  Branch (1130:9): [True: 4.61k, False: 184k]
1131
        return NULL;
1132
    }
1133
    PyObject *start = NULL;
1134
    PyObject *end = NULL;
1135
    PyObject *line = NULL;
1136
    PyObject *result = PyTuple_New(3);
1137
    start = PyLong_FromLong(bounds->ar_start);
1138
    end = PyLong_FromLong(bounds->ar_end);
1139
    if (bounds->ar_line < 0) {
  Branch (1139:9): [True: 2.52k, False: 182k]
1140
        Py_INCREF(Py_None);
1141
        line = Py_None;
1142
    }
1143
    else {
1144
        line = PyLong_FromLong(bounds->ar_line);
1145
    }
1146
    if (result == NULL || start == NULL || end == NULL || line == NULL) {
  Branch (1146:9): [True: 0, False: 184k]
  Branch (1146:27): [True: 0, False: 184k]
  Branch (1146:44): [True: 0, False: 184k]
  Branch (1146:59): [True: 0, False: 184k]
1147
        goto error;
1148
    }
1149
    PyTuple_SET_ITEM(result, 0, start);
1150
    PyTuple_SET_ITEM(result, 1, end);
1151
    PyTuple_SET_ITEM(result, 2, line);
1152
    return result;
1153
error:
1154
    Py_XDECREF(start);
1155
    Py_XDECREF(end);
1156
    Py_XDECREF(line);
1157
    Py_XDECREF(result);
1158
    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
new_linesiterator(PyCodeObject *code)
1206
{
1207
    lineiterator *li = (lineiterator *)PyType_GenericAlloc(&_PyLineIterator, 0);
1208
    if (li == NULL) {
  Branch (1208:9): [True: 0, False: 4.61k]
1209
        return NULL;
1210
    }
1211
    Py_INCREF(code);
1212
    li->li_code = code;
1213
    _PyCode_InitAddressRange(code, &li->li_line);
1214
    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
positionsiter_dealloc(positionsiterator* pi)
1230
{
1231
    Py_DECREF(pi->pi_code);
1232
    Py_TYPE(pi)->tp_free(pi);
1233
}
1234
1235
static PyObject*
1236
_source_offset_converter(int* value) {
1237
    if (*value == -1) {
  Branch (1237:9): [True: 21.0k, False: 2.66M]
1238
        Py_RETURN_NONE;
1239
    }
1240
    return PyLong_FromLong(*value);
1241
}
1242
1243
static PyObject*
1244
positionsiter_next(positionsiterator* pi)
1245
{
1246
    if (pi->pi_offset >= pi->pi_range.ar_end) {
  Branch (1246:9): [True: 341k, False: 329k]
1247
        assert(pi->pi_offset == pi->pi_range.ar_end);
1248
        if (at_end(&pi->pi_range)) {
  Branch (1248:13): [True: 26, False: 341k]
1249
            return NULL;
1250
        }
1251
        advance_with_locations(&pi->pi_range, &pi->pi_endline, &pi->pi_column, &pi->pi_endcolumn);
1252
    }
1253
    pi->pi_offset += 2;
1254
    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
code_positionsiterator(PyCodeObject* code, PyObject* Py_UNUSED(args))
1306
{
1307
    positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&_PyPositionsIterator, 0);
1308
    if (pi == NULL) {
  Branch (1308:9): [True: 0, False: 8.41k]
1309
        return NULL;
1310
    }
1311
    Py_INCREF(code);
1312
    pi->pi_code = code;
1313
    _PyCode_InitAddressRange(code, &pi->pi_range);
1314
    pi->pi_offset = pi->pi_range.ar_end;
1315
    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
_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
1332
{
1333
    if (!PyCode_Check(code)) {
  Branch (1333:9): [True: 1, False: 2]
1334
        PyErr_BadInternalCall();
1335
        return -1;
1336
    }
1337
1338
    PyCodeObject *o = (PyCodeObject*) code;
1339
    _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra;
1340
1341
    if (co_extra == NULL || 
co_extra->ce_size <= index1
) {
  Branch (1341:9): [True: 1, False: 1]
  Branch (1341:29): [True: 0, False: 1]
1342
        *extra = NULL;
1343
        return 0;
1344
    }
1345
1346
    *extra = co_extra->ce_extras[index];
1347
    return 0;
1348
}
1349
1350
1351
int
1352
_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
1353
{
1354
    PyInterpreterState *interp = _PyInterpreterState_GET();
1355
1356
    if (!PyCode_Check(code) || 
index < 05
||
  Branch (1356:9): [True: 1, False: 5]
  Branch (1356:32): [True: 0, False: 5]
1357
            
index >= interp->co_extra_user_count5
) {
  Branch (1357:13): [True: 1, False: 4]
1358
        PyErr_BadInternalCall();
1359
        return -1;
1360
    }
1361
1362
    PyCodeObject *o = (PyCodeObject*) code;
1363
    _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra;
1364
1365
    if (co_extra == NULL || 
co_extra->ce_size <= index1
) {
  Branch (1365:9): [True: 3, False: 1]
  Branch (1365:29): [True: 0, False: 1]
1366
        Py_ssize_t i = (co_extra == NULL ? 0 : 
co_extra->ce_size0
);
  Branch (1366:25): [True: 3, False: 0]
1367
        co_extra = PyMem_Realloc(
1368
                co_extra,
1369
                sizeof(_PyCodeObjectExtra) +
1370
                (interp->co_extra_user_count-1) * sizeof(void*));
1371
        if (co_extra == NULL) {
  Branch (1371:13): [True: 0, False: 3]
1372
            return -1;
1373
        }
1374
        
for (; 3
i < interp->co_extra_user_count;
i++3
) {
  Branch (1374:16): [True: 3, False: 3]
1375
            co_extra->ce_extras[i] = NULL;
1376
        }
1377
        co_extra->ce_size = interp->co_extra_user_count;
1378
        o->co_extra = co_extra;
1379
    }
1380
1381
    if (co_extra->ce_extras[index] != NULL) {
  Branch (1381:9): [True: 1, False: 3]
1382
        freefunc free = interp->co_extra_freefuncs[index];
1383
        if (free != NULL) {
  Branch (1383:13): [True: 1, False: 0]
1384
            free(co_extra->ce_extras[index]);
1385
        }
1386
    }
1387
1388
    co_extra->ce_extras[index] = extra;
1389
    return 0;
1390
}
1391
1392
1393
/******************
1394
 * other PyCodeObject accessor functions
1395
 ******************/
1396
1397
PyObject *
1398
_PyCode_GetVarnames(PyCodeObject *co)
1399
{
1400
    return get_localsplus_names(co, CO_FAST_LOCAL, co->co_nlocals);
1401
}
1402
1403
PyObject *
1404
_PyCode_GetCellvars(PyCodeObject *co)
1405
{
1406
    return get_localsplus_names(co, CO_FAST_CELL, co->co_ncellvars);
1407
}
1408
1409
PyObject *
1410
_PyCode_GetFreevars(PyCodeObject *co)
1411
{
1412
    return get_localsplus_names(co, CO_FAST_FREE, co->co_nfreevars);
1413
}
1414
1415
static void
1416
deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
1417
{
1418
    for (int i = 0; i < len; 
i++3.10M
) {
  Branch (1418:21): [True: 3.10M, False: 82.9k]
1419
        _Py_CODEUNIT instruction = instructions[i];
1420
        int opcode = _PyOpcode_Original[_Py_OPCODE(instruction)];
1421
        int caches = _PyOpcode_Caches[opcode];
1422
        instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction));
1423
        while (caches--) {
  Branch (1423:16): [True: 4.10M, False: 3.10M]
1424
            instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0);
1425
        }
1426
    }
1427
}
1428
1429
PyObject *
1430
_PyCode_GetCode(PyCodeObject *co)
1431
{
1432
    if (co->_co_code != NULL) {
  Branch (1432:9): [True: 3.03k, False: 3.50k]
1433
        return Py_NewRef(co->_co_code);
1434
    }
1435
    PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co),
1436
                                               _PyCode_NBYTES(co));
1437
    if (code == NULL) {
  Branch (1437:9): [True: 0, False: 3.50k]
1438
        return NULL;
1439
    }
1440
    deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co));
1441
    assert(co->_co_code == NULL);
1442
    co->_co_code = Py_NewRef(code);
1443
    return code;
1444
}
1445
1446
PyObject *
1447
PyCode_GetCode(PyCodeObject *co)
1448
{
1449
    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
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
    PyObject *co = NULL;
1499
    PyObject *ournames = NULL;
1500
    PyObject *ourvarnames = NULL;
1501
    PyObject *ourfreevars = NULL;
1502
    PyObject *ourcellvars = NULL;
1503
1504
    if (PySys_Audit("code.__new__", "OOOiiiiii",
  Branch (1504:9): [True: 0, False: 3]
1505
                    code, filename, name, argcount, posonlyargcount,
1506
                    kwonlyargcount, nlocals, stacksize, flags) < 0) {
1507
        goto cleanup;
1508
    }
1509
1510
    if (argcount < 0) {
  Branch (1510:9): [True: 0, False: 3]
1511
        PyErr_SetString(
1512
            PyExc_ValueError,
1513
            "code: argcount must not be negative");
1514
        goto cleanup;
1515
    }
1516
1517
    if (posonlyargcount < 0) {
  Branch (1517:9): [True: 0, False: 3]
1518
        PyErr_SetString(
1519
            PyExc_ValueError,
1520
            "code: posonlyargcount must not be negative");
1521
        goto cleanup;
1522
    }
1523
1524
    if (kwonlyargcount < 0) {
  Branch (1524:9): [True: 0, False: 3]
1525
        PyErr_SetString(
1526
            PyExc_ValueError,
1527
            "code: kwonlyargcount must not be negative");
1528
        goto cleanup;
1529
    }
1530
    if (nlocals < 0) {
  Branch (1530:9): [True: 0, False: 3]
1531
        PyErr_SetString(
1532
            PyExc_ValueError,
1533
            "code: nlocals must not be negative");
1534
        goto cleanup;
1535
    }
1536
1537
    ournames = validate_and_copy_tuple(names);
1538
    if (ournames == NULL)
  Branch (1538:9): [True: 0, False: 3]
1539
        goto cleanup;
1540
    ourvarnames = validate_and_copy_tuple(varnames);
1541
    if (ourvarnames == NULL)
  Branch (1541:9): [True: 0, False: 3]
1542
        goto cleanup;
1543
    if (freevars)
  Branch (1543:9): [True: 3, False: 0]
1544
        ourfreevars = validate_and_copy_tuple(freevars);
1545
    else
1546
        ourfreevars = PyTuple_New(0);
1547
    if (ourfreevars == NULL)
  Branch (1547:9): [True: 0, False: 3]
1548
        goto cleanup;
1549
    if (cellvars)
  Branch (1549:9): [True: 3, False: 0]
1550
        ourcellvars = validate_and_copy_tuple(cellvars);
1551
    else
1552
        ourcellvars = PyTuple_New(0);
1553
    if (ourcellvars == NULL)
  Branch (1553:9): [True: 0, False: 3]
1554
        goto cleanup;
1555
1556
    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
  cleanup:
1567
    Py_XDECREF(ournames);
1568
    Py_XDECREF(ourvarnames);
1569
    Py_XDECREF(ourfreevars);
1570
    Py_XDECREF(ourcellvars);
1571
    return co;
1572
}
1573
1574
static void
1575
code_dealloc(PyCodeObject *co)
1576
{
1577
    if (co->co_extra != NULL) {
  Branch (1577:9): [True: 3, False: 261k]
1578
        PyInterpreterState *interp = _PyInterpreterState_GET();
1579
        _PyCodeObjectExtra *co_extra = co->co_extra;
1580
1581
        for (Py_ssize_t i = 0; i < co_extra->ce_size; 
i++3
) {
  Branch (1581:32): [True: 3, False: 3]
1582
            freefunc free_extra = interp->co_extra_freefuncs[i];
1583
1584
            if (free_extra != NULL) {
  Branch (1584:17): [True: 3, False: 0]
1585
                free_extra(co_extra->ce_extras[i]);
1586
            }
1587
        }
1588
1589
        PyMem_Free(co_extra);
1590
    }
1591
1592
    Py_XDECREF(co->co_consts);
1593
    Py_XDECREF(co->co_names);
1594
    Py_XDECREF(co->co_localsplusnames);
1595
    Py_XDECREF(co->co_localspluskinds);
1596
    Py_XDECREF(co->co_filename);
1597
    Py_XDECREF(co->co_name);
1598
    Py_XDECREF(co->co_qualname);
1599
    Py_XDECREF(co->co_linetable);
1600
    Py_XDECREF(co->co_exceptiontable);
1601
    Py_XDECREF(co->_co_code);
1602
    if (co->co_weakreflist != NULL) {
  Branch (1602:9): [True: 1, False: 261k]
1603
        PyObject_ClearWeakRefs((PyObject*)co);
1604
    }
1605
    if (co->_co_linearray) {
  Branch (1605:9): [True: 1.62k, False: 259k]
1606
        PyMem_Free(co->_co_linearray);
1607
    }
1608
    if (co->co_warmup == 0) {
  Branch (1608:9): [True: 24.6k, False: 236k]
1609
        _Py_QuickenedCount--;
1610
    }
1611
    PyObject_Free(co);
1612
}
1613
1614
static PyObject *
1615
code_repr(PyCodeObject *co)
1616
{
1617
    int lineno;
1618
    if (co->co_firstlineno != 0)
  Branch (1618:9): [True: 59, False: 0]
1619
        lineno = co->co_firstlineno;
1620
    else
1621
        lineno = -1;
1622
    if (co->co_filename && PyUnicode_Check(co->co_filename)) {
  Branch (1622:9): [True: 59, False: 0]
1623
        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
        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
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
    if ((op != Py_EQ && 
op != 97
Py_NE97
) ||
  Branch (1641:10): [True: 97, False: 26.9k]
  Branch (1641:25): [True: 0, False: 97]
1642
        !PyCode_Check(self) ||
  Branch (1642:9): [True: 0, False: 27.0k]
1643
        !PyCode_Check(other)) {
  Branch (1643:9): [True: 0, False: 27.0k]
1644
        Py_RETURN_NOTIMPLEMENTED;
1645
    }
1646
1647
    co = (PyCodeObject *)self;
1648
    cp = (PyCodeObject *)other;
1649
1650
    eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
1651
    if (!eq) 
goto unequal23.3k
;
  Branch (1651:9): [True: 23.3k, False: 3.70k]
1652
    eq = co->co_argcount == cp->co_argcount;
1653
    if (!eq) 
goto unequal1
;
  Branch (1653:9): [True: 1, False: 3.70k]
1654
    eq = co->co_posonlyargcount == cp->co_posonlyargcount;
1655
    if (!eq) 
goto unequal0
;
  Branch (1655:9): [True: 0, False: 3.70k]
1656
    eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
1657
    if (!eq) 
goto unequal0
;
  Branch (1657:9): [True: 0, False: 3.70k]
1658
    eq = co->co_flags == cp->co_flags;
1659
    if (!eq) 
goto unequal0
;
  Branch (1659:9): [True: 0, False: 3.70k]
1660
    eq = co->co_firstlineno == cp->co_firstlineno;
1661
    if (!eq) 
goto unequal1.43k
;
  Branch (1661:9): [True: 1.43k, False: 2.27k]
1662
    eq = Py_SIZE(co) == Py_SIZE(cp);
1663
    if (!eq) {
  Branch (1663:9): [True: 0, False: 2.27k]
1664
        goto unequal;
1665
    }
1666
    
for (int i = 0; 2.27k
i < Py_SIZE(co);
i++65.3k
) {
  Branch (1666:21): [True: 65.3k, False: 2.27k]
1667
        _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i];
1668
        _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i];
1669
        _Py_SET_OPCODE(co_instr, _PyOpcode_Deopt[_Py_OPCODE(co_instr)]);
1670
        _Py_SET_OPCODE(cp_instr, _PyOpcode_Deopt[_Py_OPCODE(cp_instr)]);
1671
        eq = co_instr == cp_instr;
1672
        if (!eq) {
  Branch (1672:13): [True: 0, False: 65.3k]
1673
            goto unequal;
1674
        }
1675
        i += _PyOpcode_Caches[_Py_OPCODE(co_instr)];
1676
    }
1677
1678
    /* compare constants */
1679
    consts1 = _PyCode_ConstantKey(co->co_consts);
1680
    if (!consts1)
  Branch (1680:9): [True: 0, False: 2.27k]
1681
        return NULL;
1682
    consts2 = _PyCode_ConstantKey(cp->co_consts);
1683
    if (!consts2) {
  Branch (1683:9): [True: 0, False: 2.27k]
1684
        Py_DECREF(consts1);
1685
        return NULL;
1686
    }
1687
    eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
1688
    Py_DECREF(consts1);
1689
    Py_DECREF(consts2);
1690
    if (eq <= 0) 
goto unequal32
;
  Branch (1690:9): [True: 32, False: 2.24k]
1691
1692
    eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
1693
    if (eq <= 0) 
goto unequal0
;
  Branch (1693:9): [True: 0, False: 2.24k]
1694
    eq = PyObject_RichCompareBool(co->co_localsplusnames,
1695
                                  cp->co_localsplusnames, Py_EQ);
1696
    if (eq <= 0) 
goto unequal0
;
  Branch (1696:9): [True: 0, False: 2.24k]
1697
1698
    if (op == Py_EQ)
  Branch (1698:9): [True: 2.15k, False: 90]
1699
        res = Py_True;
1700
    else
1701
        res = Py_False;
1702
    goto done;
1703
1704
  unequal:
1705
    if (eq < 0)
  Branch (1705:9): [True: 0, False: 24.7k]
1706
        return NULL;
1707
    if (op == Py_NE)
  Branch (1707:9): [True: 7, False: 24.7k]
1708
        res = Py_True;
1709
    else
1710
        res = Py_False;
1711
1712
  done:
1713
    Py_INCREF(res);
1714
    return res;
1715
}
1716
1717
static Py_hash_t
1718
code_hash(PyCodeObject *co)
1719
{
1720
    Py_hash_t h, h0, h1, h2, h3;
1721
    h0 = PyObject_Hash(co->co_name);
1722
    if (h0 == -1) 
return -10
;
  Branch (1722:9): [True: 0, False: 192k]
1723
    h1 = PyObject_Hash(co->co_consts);
1724
    if (h1 == -1) 
return -10
;
  Branch (1724:9): [True: 0, False: 192k]
1725
    h2 = PyObject_Hash(co->co_names);
1726
    if (h2 == -1) 
return -10
;
  Branch (1726:9): [True: 0, False: 192k]
1727
    h3 = PyObject_Hash(co->co_localsplusnames);
1728
    if (h3 == -1) 
return -10
;
  Branch (1728:9): [True: 0, False: 192k]
1729
    h = h0 ^ h1 ^ h2 ^ h3 ^
1730
        co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^
1731
        co->co_flags;
1732
    if (h == -1) 
h = -20
;
  Branch (1732:9): [True: 0, False: 192k]
1733
    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
code_getlnotab(PyCodeObject *code, void *closure)
1760
{
1761
    return decode_linetable(code);
1762
}
1763
1764
static PyObject *
1765
code_getvarnames(PyCodeObject *code, void *closure)
1766
{
1767
    return _PyCode_GetVarnames(code);
1768
}
1769
1770
static PyObject *
1771
code_getcellvars(PyCodeObject *code, void *closure)
1772
{
1773
    return _PyCode_GetCellvars(code);
1774
}
1775
1776
static PyObject *
1777
code_getfreevars(PyCodeObject *code, void *closure)
1778
{
1779
    return _PyCode_GetFreevars(code);
1780
}
1781
1782
static PyObject *
1783
code_getcodeadaptive(PyCodeObject *code, void *closure)
1784
{
1785
    return PyBytes_FromStringAndSize(code->co_code_adaptive,
1786
                                     _PyCode_NBYTES(code));
1787
}
1788
1789
static PyObject *
1790
code_getcode(PyCodeObject *code, void *closure)
1791
{
1792
    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
code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args))
1809
{
1810
    Py_ssize_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co));
1811
1812
    _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra;
1813
    if (co_extra != NULL) {
  Branch (1813:9): [True: 0, False: 3]
1814
        res += sizeof(_PyCodeObjectExtra) +
1815
               (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]);
1816
    }
1817
1818
    return PyLong_FromSsize_t(res);
1819
}
1820
1821
static PyObject *
1822
code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args))
1823
{
1824
    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
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
    CHECK_INT_ARG(co_argcount);
1874
    CHECK_INT_ARG(co_posonlyargcount);
1875
    CHECK_INT_ARG(co_kwonlyargcount);
1876
    CHECK_INT_ARG(co_nlocals);
1877
    CHECK_INT_ARG(co_stacksize);
1878
    CHECK_INT_ARG(co_flags);
1879
    CHECK_INT_ARG(co_firstlineno);
1880
1881
#undef CHECK_INT_ARG
1882
1883
    PyObject *code = NULL;
1884
    if (co_code == NULL) {
  Branch (1884:9): [True: 65, False: 2]
1885
        code = _PyCode_GetCode(self);
1886
        if (code == NULL) {
  Branch (1886:13): [True: 0, False: 65]
1887
            return NULL;
1888
        }
1889
        co_code = (PyBytesObject *)code;
1890
    }
1891
1892
    if (PySys_Audit("code.__new__", "OOOiiiiii",
  Branch (1892:9): [True: 0, False: 67]
1893
                    co_code, co_filename, co_name, co_argcount,
1894
                    co_posonlyargcount, co_kwonlyargcount, co_nlocals,
1895
                    co_stacksize, co_flags) < 0) {
1896
        return NULL;
1897
    }
1898
1899
    PyCodeObject *co = NULL;
1900
    PyObject *varnames = NULL;
1901
    PyObject *cellvars = NULL;
1902
    PyObject *freevars = NULL;
1903
    if (co_varnames == NULL) {
  Branch (1903:9): [True: 65, False: 2]
1904
        varnames = get_localsplus_names(self, CO_FAST_LOCAL, self->co_nlocals);
1905
        if (varnames == NULL) {
  Branch (1905:13): [True: 0, False: 65]
1906
            goto error;
1907
        }
1908
        co_varnames = varnames;
1909
    }
1910
    if (co_cellvars == NULL) {
  Branch (1910:9): [True: 66, False: 1]
1911
        cellvars = get_localsplus_names(self, CO_FAST_CELL, self->co_ncellvars);
1912
        if (cellvars == NULL) {
  Branch (1912:13): [True: 0, False: 66]
1913
            goto error;
1914
        }
1915
        co_cellvars = cellvars;
1916
    }
1917
    if (co_freevars == NULL) {
  Branch (1917:9): [True: 65, False: 2]
1918
        freevars = get_localsplus_names(self, CO_FAST_FREE, self->co_nfreevars);
1919
        if (freevars == NULL) {
  Branch (1919:13): [True: 0, False: 65]
1920
            goto error;
1921
        }
1922
        co_freevars = freevars;
1923
    }
1924
1925
    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
error:
1933
    Py_XDECREF(code);
1934
    Py_XDECREF(varnames);
1935
    Py_XDECREF(cellvars);
1936
    Py_XDECREF(freevars);
1937
    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
code__varname_from_oparg_impl(PyCodeObject *self, int oparg)
1952
/*[clinic end generated code: output=1fd1130413184206 input=c5fa3ee9bac7d4ca]*/
1953
{
1954
    PyObject *name = PyTuple_GetItem(self->co_localsplusnames, oparg);
1955
    if (name == NULL) {
  Branch (1955:9): [True: 0, False: 8.94k]
1956
        return NULL;
1957
    }
1958
    Py_INCREF(name);
1959
    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
_PyCode_ConstantKey(PyObject *op)
2022
{
2023
    PyObject *key;
2024
2025
    /* Py_None and Py_Ellipsis are singletons. */
2026
    if (op == Py_None || 
op == 1.94M
Py_Ellipsis1.94M
  Branch (2026:9): [True: 41.5k, False: 1.94M]
  Branch (2026:26): [True: 439, False: 1.94M]
2027
       || PyLong_CheckExact(op)
2028
       || PyUnicode_CheckExact(op)
2029
          /* code_richcompare() uses _PyCode_ConstantKey() internally */
2030
       || 
PyCode_Check537k
(op))
2031
    {
2032
        /* Objects of these types are always different from object of other
2033
         * type and from tuples. */
2034
        Py_INCREF(op);
2035
        key = op;
2036
    }
2037
    else if (PyBool_Check(op) || 
PyBytes_CheckExact477k
(op)) {
2038
        /* Make booleans different from integers 0 and 1.
2039
         * Avoid BytesWarning from comparing bytes with strings. */
2040
        key = PyTuple_Pack(2, Py_TYPE(op), op);
2041
    }
2042
    else if (PyFloat_CheckExact(op)) {
2043
        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
        if (d == 0.0 && 
copysign(1.0, d) < 0.0339
)
  Branch (2047:13): [True: 339, False: 6.20k]
  Branch (2047:25): [True: 34, False: 305]
2048
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2049
        else
2050
            key = PyTuple_Pack(2, Py_TYPE(op), op);
2051
    }
2052
    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
        z = PyComplex_AsCComplex(op);
2060
        real_negzero = z.real == 0.0 && 
copysign(1.0, z.real) < 0.0476
;
  Branch (2060:24): [True: 476, False: 410]
  Branch (2060:41): [True: 80, False: 396]
2061
        imag_negzero = z.imag == 0.0 && 
copysign(1.0, z.imag) < 0.0262
;
  Branch (2061:24): [True: 262, False: 624]
  Branch (2061:41): [True: 52, False: 210]
2062
        /* use True, False and None singleton as tags for the real and imag
2063
         * sign, to make tuples different */
2064
        if (real_negzero && 
imag_negzero80
) {
  Branch (2064:13): [True: 80, False: 806]
  Branch (2064:29): [True: 52, False: 28]
2065
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
2066
        }
2067
        else if (imag_negzero) {
  Branch (2067:18): [True: 0, False: 834]
2068
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
2069
        }
2070
        else if (real_negzero) {
  Branch (2070:18): [True: 28, False: 806]
2071
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2072
        }
2073
        else {
2074
            key = PyTuple_Pack(2, Py_TYPE(op), op);
2075
        }
2076
    }
2077
    else if (PyTuple_CheckExact(op)) {
2078
        Py_ssize_t i, len;
2079
        PyObject *tuple;
2080
2081
        len = PyTuple_GET_SIZE(op);
2082
        tuple = PyTuple_New(len);
2083
        if (tuple == NULL)
  Branch (2083:13): [True: 0, False: 244k]
2084
            return NULL;
2085
2086
        
for (i=0; 244k
i < len;
i++955k
) {
  Branch (2086:19): [True: 955k, False: 244k]
2087
            PyObject *item, *item_key;
2088
2089
            item = PyTuple_GET_ITEM(op, i);
2090
            item_key = _PyCode_ConstantKey(item);
2091
            if (item_key == NULL) {
  Branch (2091:17): [True: 0, False: 955k]
2092
                Py_DECREF(tuple);
2093
                return NULL;
2094
            }
2095
2096
            PyTuple_SET_ITEM(tuple, i, item_key);
2097
        }
2098
2099
        key = PyTuple_Pack(2, tuple, op);
2100
        Py_DECREF(tuple);
2101
    }
2102
    else if (PyFrozenSet_CheckExact(op)) {
2103
        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
        len = PySet_GET_SIZE(op);
2110
        tuple = PyTuple_New(len);
2111
        if (tuple == NULL)
  Branch (2111:13): [True: 0, False: 277]
2112
            return NULL;
2113
2114
        i = 0;
2115
        while (_PySet_NextEntry(op, &pos, &item, &hash)) {
  Branch (2115:16): [True: 633, False: 277]
2116
            PyObject *item_key;
2117
2118
            item_key = _PyCode_ConstantKey(item);
2119
            if (item_key == NULL) {
  Branch (2119:17): [True: 0, False: 633]
2120
                Py_DECREF(tuple);
2121
                return NULL;
2122
            }
2123
2124
            assert(i < len);
2125
            PyTuple_SET_ITEM(tuple, i, item_key);
2126
            i++;
2127
        }
2128
        set = PyFrozenSet_New(tuple);
2129
        Py_DECREF(tuple);
2130
        if (set == NULL)
  Branch (2130:13): [True: 0, False: 277]
2131
            return NULL;
2132
2133
        key = PyTuple_Pack(2, set, op);
2134
        Py_DECREF(set);
2135
        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
        PyObject *obj_id = PyLong_FromVoidPtr(op);
2141
        if (obj_id == NULL)
  Branch (2141:13): [True: 0, False: 0]
2142
            return NULL;
2143
2144
        key = PyTuple_Pack(2, obj_id, op);
2145
        Py_DECREF(obj_id);
2146
    }
2147
    return key;
2148
}
2149
2150
void
2151
_PyStaticCode_Dealloc(PyCodeObject *co)
2152
{
2153
    if (co->co_warmup == 0) {
  Branch (2153:9): [True: 8.49k, False: 70.9k]
2154
         _Py_QuickenedCount--;
2155
    }
2156
    deopt_code(_PyCode_CODE(co), Py_SIZE(co));
2157
    co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
2158
    PyMem_Free(co->co_extra);
2159
    Py_CLEAR(co->_co_code);
2160
    co->co_extra = NULL;
2161
    if (co->co_weakreflist != NULL) {
  Branch (2161:9): [True: 0, False: 79.4k]
2162
        PyObject_ClearWeakRefs((PyObject *)co);
2163
        co->co_weakreflist = NULL;
2164
    }
2165
    if (co->_co_linearray) {
  Branch (2165:9): [True: 84, False: 79.3k]
2166
        PyMem_Free(co->_co_linearray);
2167
        co->_co_linearray = NULL;
2168
    }
2169
}
2170
2171
int
2172
_PyStaticCode_InternStrings(PyCodeObject *co)
2173
{
2174
    int res = intern_strings(co->co_names);
2175
    if (res < 0) {
  Branch (2175:9): [True: 0, False: 214k]
2176
        return -1;
2177
    }
2178
    res = intern_string_constants(co->co_consts, NULL);
2179
    if (res < 0) {
  Branch (2179:9): [True: 0, False: 214k]
2180
        return -1;
2181
    }
2182
    res = intern_strings(co->co_localsplusnames);
2183
    if (res < 0) {
  Branch (2183:9): [True: 0, False: 214k]
2184
        return -1;
2185
    }
2186
    return 0;
2187
}