Coverage Report

Created: 2025-08-26 06:26

/src/cpython/Objects/codeobject.c
Line
Count
Source (jump to first uncovered line)
1
#include "Python.h"
2
#include "opcode.h"
3
4
#include "pycore_code.h"          // _PyCodeConstructor
5
#include "pycore_function.h"      // _PyFunction_ClearCodeByVersion()
6
#include "pycore_hashtable.h"     // _Py_hashtable_t
7
#include "pycore_index_pool.h"    // _PyIndexPool_Fini()
8
#include "pycore_initconfig.h"    // _PyStatus_OK()
9
#include "pycore_interp.h"        // PyInterpreterState.co_extra_freefuncs
10
#include "pycore_interpframe.h"   // FRAME_SPECIALS_SIZE
11
#include "pycore_opcode_metadata.h" // _PyOpcode_Caches
12
#include "pycore_opcode_utils.h"  // RESUME_AT_FUNC_START
13
#include "pycore_optimizer.h"     // _Py_ExecutorDetach
14
#include "pycore_pymem.h"         // _PyMem_FreeDelayed()
15
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
16
#include "pycore_setobject.h"     // _PySet_NextEntry()
17
#include "pycore_tuple.h"         // _PyTuple_ITEMS()
18
#include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal()
19
#include "pycore_uniqueid.h"      // _PyObject_AssignUniqueId()
20
#include "pycore_weakref.h"       // FT_CLEAR_WEAKREFS()
21
22
#include "clinic/codeobject.c.h"
23
#include <stdbool.h>
24
25
26
#define INITIAL_SPECIALIZED_CODE_SIZE 16
27
28
static const char *
29
0
code_event_name(PyCodeEvent event) {
30
0
    switch (event) {
31
0
        #define CASE(op)                \
32
0
        case PY_CODE_EVENT_##op:         \
33
0
            return "PY_CODE_EVENT_" #op;
34
0
        PY_FOREACH_CODE_EVENT(CASE)
35
0
        #undef CASE
36
0
    }
37
0
    Py_UNREACHABLE();
38
0
}
39
40
static void
41
notify_code_watchers(PyCodeEvent event, PyCodeObject *co)
42
40.9k
{
43
40.9k
    assert(Py_REFCNT(co) > 0);
44
40.9k
    PyInterpreterState *interp = _PyInterpreterState_GET();
45
40.9k
    assert(interp->_initialized);
46
40.9k
    uint8_t bits = interp->active_code_watchers;
47
40.9k
    int i = 0;
48
40.9k
    while (bits) {
49
0
        assert(i < CODE_MAX_WATCHERS);
50
0
        if (bits & 1) {
51
0
            PyCode_WatchCallback cb = interp->code_watchers[i];
52
            // callback must be non-null if the watcher bit is set
53
0
            assert(cb != NULL);
54
0
            if (cb(event, co) < 0) {
55
0
                PyErr_FormatUnraisable(
56
0
                    "Exception ignored in %s watcher callback for %R",
57
0
                    code_event_name(event), co);
58
0
            }
59
0
        }
60
0
        i++;
61
0
        bits >>= 1;
62
0
    }
63
40.9k
}
64
65
int
66
PyCode_AddWatcher(PyCode_WatchCallback callback)
67
0
{
68
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
69
0
    assert(interp->_initialized);
70
71
0
    for (int i = 0; i < CODE_MAX_WATCHERS; i++) {
72
0
        if (!interp->code_watchers[i]) {
73
0
            interp->code_watchers[i] = callback;
74
0
            interp->active_code_watchers |= (1 << i);
75
0
            return i;
76
0
        }
77
0
    }
78
79
0
    PyErr_SetString(PyExc_RuntimeError, "no more code watcher IDs available");
80
0
    return -1;
81
0
}
82
83
static inline int
84
validate_watcher_id(PyInterpreterState *interp, int watcher_id)
85
0
{
86
0
    if (watcher_id < 0 || watcher_id >= CODE_MAX_WATCHERS) {
87
0
        PyErr_Format(PyExc_ValueError, "Invalid code watcher ID %d", watcher_id);
88
0
        return -1;
89
0
    }
90
0
    if (!interp->code_watchers[watcher_id]) {
91
0
        PyErr_Format(PyExc_ValueError, "No code watcher set for ID %d", watcher_id);
92
0
        return -1;
93
0
    }
94
0
    return 0;
95
0
}
96
97
int
98
PyCode_ClearWatcher(int watcher_id)
99
0
{
100
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
101
0
    assert(interp->_initialized);
102
0
    if (validate_watcher_id(interp, watcher_id) < 0) {
103
0
        return -1;
104
0
    }
105
0
    interp->code_watchers[watcher_id] = NULL;
106
0
    interp->active_code_watchers &= ~(1 << watcher_id);
107
0
    return 0;
108
0
}
109
110
/******************
111
 * generic helpers
112
 ******************/
113
114
38.8k
#define _PyCodeObject_CAST(op)  (assert(PyCode_Check(op)), (PyCodeObject *)(op))
115
116
static int
117
should_intern_string(PyObject *o)
118
103k
{
119
#ifdef Py_GIL_DISABLED
120
    // The free-threaded build interns (and immortalizes) all string constants
121
    return 1;
122
#else
123
    // compute if s matches [a-zA-Z0-9_]
124
103k
    const unsigned char *s, *e;
125
126
103k
    if (!PyUnicode_IS_ASCII(o))
127
3.43k
        return 0;
128
129
100k
    s = PyUnicode_1BYTE_DATA(o);
130
100k
    e = s + PyUnicode_GET_LENGTH(o);
131
784k
    for (; s != e; s++) {
132
725k
        if (!Py_ISALNUM(*s) && *s != '_')
133
41.5k
            return 0;
134
725k
    }
135
58.9k
    return 1;
136
100k
#endif
137
100k
}
138
139
#ifdef Py_GIL_DISABLED
140
static PyObject *intern_one_constant(PyObject *op);
141
142
// gh-130851: In the free threading build, we intern and immortalize most
143
// constants, except code objects. However, users can generate code objects
144
// with arbitrary co_consts. We don't want to immortalize or intern unexpected
145
// constants or tuples/sets containing unexpected constants.
146
static int
147
should_immortalize_constant(PyObject *v)
148
{
149
    // Only immortalize containers if we've already immortalized all their
150
    // elements.
151
    if (PyTuple_CheckExact(v)) {
152
        for (Py_ssize_t i = PyTuple_GET_SIZE(v); --i >= 0; ) {
153
            if (!_Py_IsImmortal(PyTuple_GET_ITEM(v, i))) {
154
                return 0;
155
            }
156
        }
157
        return 1;
158
    }
159
    else if (PyFrozenSet_CheckExact(v)) {
160
        PyObject *item;
161
        Py_hash_t hash;
162
        Py_ssize_t pos = 0;
163
        while (_PySet_NextEntry(v, &pos, &item, &hash)) {
164
            if (!_Py_IsImmortal(item)) {
165
                return 0;
166
            }
167
        }
168
        return 1;
169
    }
170
    else if (PySlice_Check(v)) {
171
        PySliceObject *slice = (PySliceObject *)v;
172
        return (_Py_IsImmortal(slice->start) &&
173
                _Py_IsImmortal(slice->stop) &&
174
                _Py_IsImmortal(slice->step));
175
    }
176
    return (PyLong_CheckExact(v) || PyFloat_CheckExact(v) ||
177
            PyComplex_Check(v) || PyBytes_CheckExact(v));
178
}
179
#endif
180
181
static int
182
intern_strings(PyObject *tuple)
183
65.6k
{
184
65.6k
    PyInterpreterState *interp = _PyInterpreterState_GET();
185
65.6k
    Py_ssize_t i;
186
187
376k
    for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
188
310k
        PyObject *v = PyTuple_GET_ITEM(tuple, i);
189
310k
        if (v == NULL || !PyUnicode_CheckExact(v)) {
190
0
            PyErr_SetString(PyExc_SystemError,
191
0
                            "non-string found in code slot");
192
0
            return -1;
193
0
        }
194
310k
        _PyUnicode_InternImmortal(interp, &_PyTuple_ITEMS(tuple)[i]);
195
310k
    }
196
65.6k
    return 0;
197
65.6k
}
198
199
/* Intern constants. In the default build, this interns selected string
200
   constants. In the free-threaded build, this also interns non-string
201
   constants. */
202
static int
203
intern_constants(PyObject *tuple, int *modified)
204
48.3k
{
205
48.3k
    PyInterpreterState *interp = _PyInterpreterState_GET();
206
247k
    for (Py_ssize_t i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
207
198k
        PyObject *v = PyTuple_GET_ITEM(tuple, i);
208
198k
        if (PyUnicode_CheckExact(v)) {
209
103k
            if (should_intern_string(v)) {
210
58.9k
                PyObject *w = v;
211
58.9k
                _PyUnicode_InternMortal(interp, &v);
212
58.9k
                if (w != v) {
213
3.86k
                    PyTuple_SET_ITEM(tuple, i, v);
214
3.86k
                    if (modified) {
215
51
                        *modified = 1;
216
51
                    }
217
3.86k
                }
218
58.9k
            }
219
103k
        }
220
94.9k
        else if (PyTuple_CheckExact(v)) {
221
15.3k
            if (intern_constants(v, NULL) < 0) {
222
0
                return -1;
223
0
            }
224
15.3k
        }
225
79.5k
        else if (PyFrozenSet_CheckExact(v)) {
226
179
            PyObject *w = v;
227
179
            PyObject *tmp = PySequence_Tuple(v);
228
179
            if (tmp == NULL) {
229
0
                return -1;
230
0
            }
231
179
            int tmp_modified = 0;
232
179
            if (intern_constants(tmp, &tmp_modified) < 0) {
233
0
                Py_DECREF(tmp);
234
0
                return -1;
235
0
            }
236
179
            if (tmp_modified) {
237
20
                v = PyFrozenSet_New(tmp);
238
20
                if (v == NULL) {
239
0
                    Py_DECREF(tmp);
240
0
                    return -1;
241
0
                }
242
243
20
                PyTuple_SET_ITEM(tuple, i, v);
244
20
                Py_DECREF(w);
245
20
                if (modified) {
246
0
                    *modified = 1;
247
0
                }
248
20
            }
249
179
            Py_DECREF(tmp);
250
179
        }
251
#ifdef Py_GIL_DISABLED
252
        else if (PySlice_Check(v)) {
253
            PySliceObject *slice = (PySliceObject *)v;
254
            PyObject *tmp = PyTuple_New(3);
255
            if (tmp == NULL) {
256
                return -1;
257
            }
258
            PyTuple_SET_ITEM(tmp, 0, Py_NewRef(slice->start));
259
            PyTuple_SET_ITEM(tmp, 1, Py_NewRef(slice->stop));
260
            PyTuple_SET_ITEM(tmp, 2, Py_NewRef(slice->step));
261
            int tmp_modified = 0;
262
            if (intern_constants(tmp, &tmp_modified) < 0) {
263
                Py_DECREF(tmp);
264
                return -1;
265
            }
266
            if (tmp_modified) {
267
                v = PySlice_New(PyTuple_GET_ITEM(tmp, 0),
268
                                PyTuple_GET_ITEM(tmp, 1),
269
                                PyTuple_GET_ITEM(tmp, 2));
270
                if (v == NULL) {
271
                    Py_DECREF(tmp);
272
                    return -1;
273
                }
274
                PyTuple_SET_ITEM(tuple, i, v);
275
                Py_DECREF(slice);
276
                if (modified) {
277
                    *modified = 1;
278
                }
279
            }
280
            Py_DECREF(tmp);
281
        }
282
283
        // Intern non-string constants in the free-threaded build
284
        _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
285
        if (!_Py_IsImmortal(v) && !PyUnicode_CheckExact(v) &&
286
            should_immortalize_constant(v) &&
287
            !tstate->suppress_co_const_immortalization)
288
        {
289
            PyObject *interned = intern_one_constant(v);
290
            if (interned == NULL) {
291
                return -1;
292
            }
293
            else if (interned != v) {
294
                PyTuple_SET_ITEM(tuple, i, interned);
295
                Py_SETREF(v, interned);
296
                if (modified) {
297
                    *modified = 1;
298
                }
299
            }
300
        }
301
#endif
302
198k
    }
303
48.3k
    return 0;
304
48.3k
}
305
306
/* Return a shallow copy of a tuple that is
307
   guaranteed to contain exact strings, by converting string subclasses
308
   to exact strings and complaining if a non-string is found. */
309
static PyObject*
310
validate_and_copy_tuple(PyObject *tup)
311
0
{
312
0
    PyObject *newtuple;
313
0
    PyObject *item;
314
0
    Py_ssize_t i, len;
315
316
0
    len = PyTuple_GET_SIZE(tup);
317
0
    newtuple = PyTuple_New(len);
318
0
    if (newtuple == NULL)
319
0
        return NULL;
320
321
0
    for (i = 0; i < len; i++) {
322
0
        item = PyTuple_GET_ITEM(tup, i);
323
0
        if (PyUnicode_CheckExact(item)) {
324
0
            Py_INCREF(item);
325
0
        }
326
0
        else if (!PyUnicode_Check(item)) {
327
0
            PyErr_Format(
328
0
                PyExc_TypeError,
329
0
                "name tuples must contain only "
330
0
                "strings, not '%.500s'",
331
0
                Py_TYPE(item)->tp_name);
332
0
            Py_DECREF(newtuple);
333
0
            return NULL;
334
0
        }
335
0
        else {
336
0
            item = _PyUnicode_Copy(item);
337
0
            if (item == NULL) {
338
0
                Py_DECREF(newtuple);
339
0
                return NULL;
340
0
            }
341
0
        }
342
0
        PyTuple_SET_ITEM(newtuple, i, item);
343
0
    }
344
345
0
    return newtuple;
346
0
}
347
348
static int
349
init_co_cached(PyCodeObject *self)
350
6.17k
{
351
6.17k
    _PyCoCached *cached = FT_ATOMIC_LOAD_PTR(self->_co_cached);
352
6.17k
    if (cached != NULL) {
353
0
        return 0;
354
0
    }
355
356
6.17k
    Py_BEGIN_CRITICAL_SECTION(self);
357
6.17k
    cached = self->_co_cached;
358
6.17k
    if (cached == NULL) {
359
6.17k
        cached = PyMem_New(_PyCoCached, 1);
360
6.17k
        if (cached == NULL) {
361
0
            PyErr_NoMemory();
362
0
        }
363
6.17k
        else {
364
6.17k
            cached->_co_code = NULL;
365
6.17k
            cached->_co_cellvars = NULL;
366
6.17k
            cached->_co_freevars = NULL;
367
6.17k
            cached->_co_varnames = NULL;
368
6.17k
            FT_ATOMIC_STORE_PTR(self->_co_cached, cached);
369
6.17k
        }
370
6.17k
    }
371
6.17k
    Py_END_CRITICAL_SECTION();
372
6.17k
    return cached != NULL ? 0 : -1;
373
6.17k
}
374
375
/******************
376
 * _PyCode_New()
377
 ******************/
378
379
// This is also used in compile.c.
380
void
381
_Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
382
                        PyObject *names, PyObject *kinds)
383
19.8k
{
384
19.8k
    PyTuple_SET_ITEM(names, offset, Py_NewRef(name));
385
19.8k
    _PyLocals_SetKind(kinds, offset, kind);
386
19.8k
}
387
388
static void
389
get_localsplus_counts(PyObject *names, PyObject *kinds,
390
                      int *pnlocals, int *pncellvars,
391
                      int *pnfreevars)
392
65.6k
{
393
65.6k
    int nlocals = 0;
394
65.6k
    int ncellvars = 0;
395
65.6k
    int nfreevars = 0;
396
65.6k
    Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
397
262k
    for (int i = 0; i < nlocalsplus; i++) {
398
196k
        _PyLocals_Kind kind = _PyLocals_GetKind(kinds, i);
399
196k
        if (kind & CO_FAST_LOCAL) {
400
180k
            nlocals += 1;
401
180k
            if (kind & CO_FAST_CELL) {
402
2.34k
                ncellvars += 1;
403
2.34k
            }
404
180k
        }
405
16.0k
        else if (kind & CO_FAST_CELL) {
406
8.74k
            ncellvars += 1;
407
8.74k
        }
408
7.35k
        else if (kind & CO_FAST_FREE) {
409
7.35k
            nfreevars += 1;
410
7.35k
        }
411
196k
    }
412
65.6k
    if (pnlocals != NULL) {
413
65.6k
        *pnlocals = nlocals;
414
65.6k
    }
415
65.6k
    if (pncellvars != NULL) {
416
32.8k
        *pncellvars = ncellvars;
417
32.8k
    }
418
65.6k
    if (pnfreevars != NULL) {
419
32.8k
        *pnfreevars = nfreevars;
420
32.8k
    }
421
65.6k
}
422
423
static PyObject *
424
get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num)
425
8
{
426
8
    PyObject *names = PyTuple_New(num);
427
8
    if (names == NULL) {
428
0
        return NULL;
429
0
    }
430
8
    int index = 0;
431
96
    for (int offset = 0; offset < co->co_nlocalsplus; offset++) {
432
88
        _PyLocals_Kind k = _PyLocals_GetKind(co->co_localspluskinds, offset);
433
88
        if ((k & kind) == 0) {
434
8
            continue;
435
8
        }
436
80
        assert(index < num);
437
80
        PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, offset);
438
80
        PyTuple_SET_ITEM(names, index, Py_NewRef(name));
439
80
        index += 1;
440
80
    }
441
8
    assert(index == num);
442
8
    return names;
443
8
}
444
445
int
446
_PyCode_Validate(struct _PyCodeConstructor *con)
447
32.8k
{
448
    /* Check argument types */
449
32.8k
    if (con->argcount < con->posonlyargcount || con->posonlyargcount < 0 ||
450
32.8k
        con->kwonlyargcount < 0 ||
451
32.8k
        con->stacksize < 0 || con->flags < 0 ||
452
32.8k
        con->code == NULL || !PyBytes_Check(con->code) ||
453
32.8k
        con->consts == NULL || !PyTuple_Check(con->consts) ||
454
32.8k
        con->names == NULL || !PyTuple_Check(con->names) ||
455
32.8k
        con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) ||
456
32.8k
        con->localspluskinds == NULL || !PyBytes_Check(con->localspluskinds) ||
457
32.8k
        PyTuple_GET_SIZE(con->localsplusnames)
458
32.8k
            != PyBytes_GET_SIZE(con->localspluskinds) ||
459
32.8k
        con->name == NULL || !PyUnicode_Check(con->name) ||
460
32.8k
        con->qualname == NULL || !PyUnicode_Check(con->qualname) ||
461
32.8k
        con->filename == NULL || !PyUnicode_Check(con->filename) ||
462
32.8k
        con->linetable == NULL || !PyBytes_Check(con->linetable) ||
463
32.8k
        con->exceptiontable == NULL || !PyBytes_Check(con->exceptiontable)
464
32.8k
        ) {
465
0
        PyErr_BadInternalCall();
466
0
        return -1;
467
0
    }
468
469
    /* Make sure that code is indexable with an int, this is
470
       a long running assumption in ceval.c and many parts of
471
       the interpreter. */
472
32.8k
    if (PyBytes_GET_SIZE(con->code) > INT_MAX) {
473
0
        PyErr_SetString(PyExc_OverflowError,
474
0
                        "code: co_code larger than INT_MAX");
475
0
        return -1;
476
0
    }
477
32.8k
    if (PyBytes_GET_SIZE(con->code) % sizeof(_Py_CODEUNIT) != 0 ||
478
32.8k
        !_Py_IS_ALIGNED(PyBytes_AS_STRING(con->code), sizeof(_Py_CODEUNIT))
479
32.8k
        ) {
480
0
        PyErr_SetString(PyExc_ValueError, "code: co_code is malformed");
481
0
        return -1;
482
0
    }
483
484
    /* Ensure that the co_varnames has enough names to cover the arg counts.
485
     * Note that totalargs = nlocals - nplainlocals.  We check nplainlocals
486
     * here to avoid the possibility of overflow (however remote). */
487
32.8k
    int nlocals;
488
32.8k
    get_localsplus_counts(con->localsplusnames, con->localspluskinds,
489
32.8k
                          &nlocals, NULL, NULL);
490
32.8k
    int nplainlocals = nlocals -
491
32.8k
                       con->argcount -
492
32.8k
                       con->kwonlyargcount -
493
32.8k
                       ((con->flags & CO_VARARGS) != 0) -
494
32.8k
                       ((con->flags & CO_VARKEYWORDS) != 0);
495
32.8k
    if (nplainlocals < 0) {
496
0
        PyErr_SetString(PyExc_ValueError, "code: co_varnames is too small");
497
0
        return -1;
498
0
    }
499
500
32.8k
    return 0;
501
32.8k
}
502
503
extern void
504
_PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters);
505
506
#ifdef Py_GIL_DISABLED
507
static _PyCodeArray * _PyCodeArray_New(Py_ssize_t size);
508
#endif
509
510
static int
511
init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
512
32.8k
{
513
32.8k
    int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames);
514
32.8k
    int nlocals, ncellvars, nfreevars;
515
32.8k
    get_localsplus_counts(con->localsplusnames, con->localspluskinds,
516
32.8k
                          &nlocals, &ncellvars, &nfreevars);
517
32.8k
    if (con->stacksize == 0) {
518
2
        con->stacksize = 1;
519
2
    }
520
521
32.8k
    PyInterpreterState *interp = _PyInterpreterState_GET();
522
32.8k
    co->co_filename = Py_NewRef(con->filename);
523
32.8k
    co->co_name = Py_NewRef(con->name);
524
32.8k
    co->co_qualname = Py_NewRef(con->qualname);
525
32.8k
    _PyUnicode_InternMortal(interp, &co->co_filename);
526
32.8k
    _PyUnicode_InternMortal(interp, &co->co_name);
527
32.8k
    _PyUnicode_InternMortal(interp, &co->co_qualname);
528
32.8k
    co->co_flags = con->flags;
529
530
32.8k
    co->co_firstlineno = con->firstlineno;
531
32.8k
    co->co_linetable = Py_NewRef(con->linetable);
532
533
32.8k
    co->co_consts = Py_NewRef(con->consts);
534
32.8k
    co->co_names = Py_NewRef(con->names);
535
536
32.8k
    co->co_localsplusnames = Py_NewRef(con->localsplusnames);
537
32.8k
    co->co_localspluskinds = Py_NewRef(con->localspluskinds);
538
539
32.8k
    co->co_argcount = con->argcount;
540
32.8k
    co->co_posonlyargcount = con->posonlyargcount;
541
32.8k
    co->co_kwonlyargcount = con->kwonlyargcount;
542
543
32.8k
    co->co_stacksize = con->stacksize;
544
545
32.8k
    co->co_exceptiontable = Py_NewRef(con->exceptiontable);
546
547
    /* derived values */
548
32.8k
    co->co_nlocalsplus = nlocalsplus;
549
32.8k
    co->co_nlocals = nlocals;
550
32.8k
    co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
551
32.8k
    co->co_ncellvars = ncellvars;
552
32.8k
    co->co_nfreevars = nfreevars;
553
32.8k
    FT_MUTEX_LOCK(&interp->func_state.mutex);
554
32.8k
    co->co_version = interp->func_state.next_version;
555
32.8k
    if (interp->func_state.next_version != 0) {
556
32.8k
        interp->func_state.next_version++;
557
32.8k
    }
558
32.8k
    FT_MUTEX_UNLOCK(&interp->func_state.mutex);
559
32.8k
    co->_co_monitoring = NULL;
560
32.8k
    co->_co_instrumentation_version = 0;
561
    /* not set */
562
32.8k
    co->co_weakreflist = NULL;
563
32.8k
    co->co_extra = NULL;
564
32.8k
    co->_co_cached = NULL;
565
32.8k
    co->co_executors = NULL;
566
567
32.8k
    memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code),
568
32.8k
           PyBytes_GET_SIZE(con->code));
569
#ifdef Py_GIL_DISABLED
570
    co->co_tlbc = _PyCodeArray_New(INITIAL_SPECIALIZED_CODE_SIZE);
571
    if (co->co_tlbc == NULL) {
572
        return -1;
573
    }
574
    co->co_tlbc->entries[0] = co->co_code_adaptive;
575
#endif
576
32.8k
    int entry_point = 0;
577
43.8k
    while (entry_point < Py_SIZE(co) &&
578
43.8k
        _PyCode_CODE(co)[entry_point].op.code != RESUME) {
579
11.0k
        entry_point++;
580
11.0k
    }
581
32.8k
    co->_co_firsttraceable = entry_point;
582
#ifdef Py_GIL_DISABLED
583
    _PyCode_Quicken(_PyCode_CODE(co), Py_SIZE(co), interp->config.tlbc_enabled);
584
#else
585
32.8k
    _PyCode_Quicken(_PyCode_CODE(co), Py_SIZE(co), 1);
586
32.8k
#endif
587
32.8k
    notify_code_watchers(PY_CODE_EVENT_CREATE, co);
588
32.8k
    return 0;
589
32.8k
}
590
591
static int
592
scan_varint(const uint8_t *ptr)
593
4.55k
{
594
4.55k
    unsigned int read = *ptr++;
595
4.55k
    unsigned int val = read & 63;
596
4.55k
    unsigned int shift = 0;
597
4.55k
    while (read & 64) {
598
0
        read = *ptr++;
599
0
        shift += 6;
600
0
        val |= (read & 63) << shift;
601
0
    }
602
4.55k
    return val;
603
4.55k
}
604
605
static int
606
scan_signed_varint(const uint8_t *ptr)
607
4.55k
{
608
4.55k
    unsigned int uval = scan_varint(ptr);
609
4.55k
    if (uval & 1) {
610
2.27k
        return -(int)(uval >> 1);
611
2.27k
    }
612
2.27k
    else {
613
2.27k
        return uval >> 1;
614
2.27k
    }
615
4.55k
}
616
617
static int
618
get_line_delta(const uint8_t *ptr)
619
100k
{
620
100k
    int code = ((*ptr) >> 3) & 15;
621
100k
    switch (code) {
622
0
        case PY_CODE_LOCATION_INFO_NONE:
623
0
            return 0;
624
0
        case PY_CODE_LOCATION_INFO_NO_COLUMNS:
625
4.55k
        case PY_CODE_LOCATION_INFO_LONG:
626
4.55k
            return scan_signed_varint(ptr+1);
627
25.0k
        case PY_CODE_LOCATION_INFO_ONE_LINE0:
628
25.0k
            return 0;
629
27.3k
        case PY_CODE_LOCATION_INFO_ONE_LINE1:
630
27.3k
            return 1;
631
2.27k
        case PY_CODE_LOCATION_INFO_ONE_LINE2:
632
2.27k
            return 2;
633
41.0k
        default:
634
            /* Same line */
635
41.0k
            return 0;
636
100k
    }
637
100k
}
638
639
static PyObject *
640
remove_column_info(PyObject *locations)
641
0
{
642
0
    Py_ssize_t offset = 0;
643
0
    const uint8_t *data = (const uint8_t *)PyBytes_AS_STRING(locations);
644
0
    PyObject *res = PyBytes_FromStringAndSize(NULL, 32);
645
0
    if (res == NULL) {
646
0
        PyErr_NoMemory();
647
0
        return NULL;
648
0
    }
649
0
    uint8_t *output = (uint8_t *)PyBytes_AS_STRING(res);
650
0
    while (offset < PyBytes_GET_SIZE(locations)) {
651
0
        Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
652
0
        if (write_offset + 16 >= PyBytes_GET_SIZE(res)) {
653
0
            if (_PyBytes_Resize(&res, PyBytes_GET_SIZE(res) * 2) < 0) {
654
0
                return NULL;
655
0
            }
656
0
            output = (uint8_t *)PyBytes_AS_STRING(res) + write_offset;
657
0
        }
658
0
        int code = (data[offset] >> 3) & 15;
659
0
        if (code == PY_CODE_LOCATION_INFO_NONE) {
660
0
            *output++ = data[offset];
661
0
        }
662
0
        else {
663
0
            int blength = (data[offset] & 7)+1;
664
0
            output += write_location_entry_start(
665
0
                output, PY_CODE_LOCATION_INFO_NO_COLUMNS, blength);
666
0
            int ldelta = get_line_delta(&data[offset]);
667
0
            output += write_signed_varint(output, ldelta);
668
0
        }
669
0
        offset++;
670
0
        while (offset < PyBytes_GET_SIZE(locations) &&
671
0
            (data[offset] & 128) == 0) {
672
0
            offset++;
673
0
        }
674
0
    }
675
0
    Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
676
0
    if (_PyBytes_Resize(&res, write_offset)) {
677
0
        return NULL;
678
0
    }
679
0
    return res;
680
0
}
681
682
static int
683
intern_code_constants(struct _PyCodeConstructor *con)
684
32.8k
{
685
#ifdef Py_GIL_DISABLED
686
    PyInterpreterState *interp = _PyInterpreterState_GET();
687
    struct _py_code_state *state = &interp->code_state;
688
    FT_MUTEX_LOCK(&state->mutex);
689
#endif
690
32.8k
    if (intern_strings(con->names) < 0) {
691
0
        goto error;
692
0
    }
693
32.8k
    if (intern_constants(con->consts, NULL) < 0) {
694
0
        goto error;
695
0
    }
696
32.8k
    if (intern_strings(con->localsplusnames) < 0) {
697
0
        goto error;
698
0
    }
699
32.8k
    FT_MUTEX_UNLOCK(&state->mutex);
700
32.8k
    return 0;
701
702
0
error:
703
0
    FT_MUTEX_UNLOCK(&state->mutex);
704
0
    return -1;
705
32.8k
}
706
707
/* The caller is responsible for ensuring that the given data is valid. */
708
709
PyCodeObject *
710
_PyCode_New(struct _PyCodeConstructor *con)
711
32.8k
{
712
32.8k
    if (intern_code_constants(con) < 0) {
713
0
        return NULL;
714
0
    }
715
716
32.8k
    PyObject *replacement_locations = NULL;
717
    // Compact the linetable if we are opted out of debug
718
    // ranges.
719
32.8k
    if (!_Py_GetConfig()->code_debug_ranges) {
720
0
        replacement_locations = remove_column_info(con->linetable);
721
0
        if (replacement_locations == NULL) {
722
0
            return NULL;
723
0
        }
724
0
        con->linetable = replacement_locations;
725
0
    }
726
727
32.8k
    Py_ssize_t size = PyBytes_GET_SIZE(con->code) / sizeof(_Py_CODEUNIT);
728
32.8k
    PyCodeObject *co;
729
#ifdef Py_GIL_DISABLED
730
    co = PyObject_GC_NewVar(PyCodeObject, &PyCode_Type, size);
731
#else
732
32.8k
    co = PyObject_NewVar(PyCodeObject, &PyCode_Type, size);
733
32.8k
#endif
734
32.8k
    if (co == NULL) {
735
0
        Py_XDECREF(replacement_locations);
736
0
        PyErr_NoMemory();
737
0
        return NULL;
738
0
    }
739
740
32.8k
    if (init_code(co, con) < 0) {
741
0
        Py_DECREF(co);
742
0
        return NULL;
743
0
    }
744
745
#ifdef Py_GIL_DISABLED
746
    co->_co_unique_id = _PyObject_AssignUniqueId((PyObject *)co);
747
    _PyObject_GC_TRACK(co);
748
#endif
749
32.8k
    Py_XDECREF(replacement_locations);
750
32.8k
    return co;
751
32.8k
}
752
753
754
/******************
755
 * the legacy "constructors"
756
 ******************/
757
758
PyCodeObject *
759
PyUnstable_Code_NewWithPosOnlyArgs(
760
                          int argcount, int posonlyargcount, int kwonlyargcount,
761
                          int nlocals, int stacksize, int flags,
762
                          PyObject *code, PyObject *consts, PyObject *names,
763
                          PyObject *varnames, PyObject *freevars, PyObject *cellvars,
764
                          PyObject *filename, PyObject *name,
765
                          PyObject *qualname, int firstlineno,
766
                          PyObject *linetable,
767
                          PyObject *exceptiontable)
768
0
{
769
0
    PyCodeObject *co = NULL;
770
0
    PyObject *localsplusnames = NULL;
771
0
    PyObject *localspluskinds = NULL;
772
773
0
    if (varnames == NULL || !PyTuple_Check(varnames) ||
774
0
        cellvars == NULL || !PyTuple_Check(cellvars) ||
775
0
        freevars == NULL || !PyTuple_Check(freevars)
776
0
        ) {
777
0
        PyErr_BadInternalCall();
778
0
        return NULL;
779
0
    }
780
781
    // Set the "fast locals plus" info.
782
0
    int nvarnames = (int)PyTuple_GET_SIZE(varnames);
783
0
    int ncellvars = (int)PyTuple_GET_SIZE(cellvars);
784
0
    int nfreevars = (int)PyTuple_GET_SIZE(freevars);
785
0
    int nlocalsplus = nvarnames + ncellvars + nfreevars;
786
0
    localsplusnames = PyTuple_New(nlocalsplus);
787
0
    if (localsplusnames == NULL) {
788
0
        goto error;
789
0
    }
790
0
    localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
791
0
    if (localspluskinds == NULL) {
792
0
        goto error;
793
0
    }
794
0
    int  offset = 0;
795
0
    for (int i = 0; i < nvarnames; i++, offset++) {
796
0
        PyObject *name = PyTuple_GET_ITEM(varnames, i);
797
0
        _Py_set_localsplus_info(offset, name, CO_FAST_LOCAL,
798
0
                               localsplusnames, localspluskinds);
799
0
    }
800
0
    for (int i = 0; i < ncellvars; i++, offset++) {
801
0
        PyObject *name = PyTuple_GET_ITEM(cellvars, i);
802
0
        int argoffset = -1;
803
0
        for (int j = 0; j < nvarnames; j++) {
804
0
            int cmp = PyUnicode_Compare(PyTuple_GET_ITEM(varnames, j),
805
0
                                        name);
806
0
            assert(!PyErr_Occurred());
807
0
            if (cmp == 0) {
808
0
                argoffset = j;
809
0
                break;
810
0
            }
811
0
        }
812
0
        if (argoffset >= 0) {
813
            // Merge the localsplus indices.
814
0
            nlocalsplus -= 1;
815
0
            offset -= 1;
816
0
            _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, argoffset);
817
0
            _PyLocals_SetKind(localspluskinds, argoffset, kind | CO_FAST_CELL);
818
0
            continue;
819
0
        }
820
0
        _Py_set_localsplus_info(offset, name, CO_FAST_CELL,
821
0
                               localsplusnames, localspluskinds);
822
0
    }
823
0
    for (int i = 0; i < nfreevars; i++, offset++) {
824
0
        PyObject *name = PyTuple_GET_ITEM(freevars, i);
825
0
        _Py_set_localsplus_info(offset, name, CO_FAST_FREE,
826
0
                               localsplusnames, localspluskinds);
827
0
    }
828
829
    // gh-110543: Make sure the CO_FAST_HIDDEN flag is set correctly.
830
0
    if (!(flags & CO_OPTIMIZED)) {
831
0
        Py_ssize_t code_len = PyBytes_GET_SIZE(code);
832
0
        _Py_CODEUNIT *code_data = (_Py_CODEUNIT *)PyBytes_AS_STRING(code);
833
0
        Py_ssize_t num_code_units = code_len / sizeof(_Py_CODEUNIT);
834
0
        int extended_arg = 0;
835
0
        for (int i = 0; i < num_code_units; i += 1 + _PyOpcode_Caches[code_data[i].op.code]) {
836
0
            _Py_CODEUNIT *instr = &code_data[i];
837
0
            uint8_t opcode = instr->op.code;
838
0
            if (opcode == EXTENDED_ARG) {
839
0
                extended_arg = extended_arg << 8 | instr->op.arg;
840
0
                continue;
841
0
            }
842
0
            if (opcode == LOAD_FAST_AND_CLEAR) {
843
0
                int oparg = extended_arg << 8 | instr->op.arg;
844
0
                if (oparg >= nlocalsplus) {
845
0
                    PyErr_Format(PyExc_ValueError,
846
0
                                "code: LOAD_FAST_AND_CLEAR oparg %d out of range",
847
0
                                oparg);
848
0
                    goto error;
849
0
                }
850
0
                _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, oparg);
851
0
                _PyLocals_SetKind(localspluskinds, oparg, kind | CO_FAST_HIDDEN);
852
0
            }
853
0
            extended_arg = 0;
854
0
        }
855
0
    }
856
857
    // If any cells were args then nlocalsplus will have shrunk.
858
0
    if (nlocalsplus != PyTuple_GET_SIZE(localsplusnames)) {
859
0
        if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0
860
0
                || _PyBytes_Resize(&localspluskinds, nlocalsplus) < 0) {
861
0
            goto error;
862
0
        }
863
0
    }
864
865
0
    struct _PyCodeConstructor con = {
866
0
        .filename = filename,
867
0
        .name = name,
868
0
        .qualname = qualname,
869
0
        .flags = flags,
870
871
0
        .code = code,
872
0
        .firstlineno = firstlineno,
873
0
        .linetable = linetable,
874
875
0
        .consts = consts,
876
0
        .names = names,
877
878
0
        .localsplusnames = localsplusnames,
879
0
        .localspluskinds = localspluskinds,
880
881
0
        .argcount = argcount,
882
0
        .posonlyargcount = posonlyargcount,
883
0
        .kwonlyargcount = kwonlyargcount,
884
885
0
        .stacksize = stacksize,
886
887
0
        .exceptiontable = exceptiontable,
888
0
    };
889
890
0
    if (_PyCode_Validate(&con) < 0) {
891
0
        goto error;
892
0
    }
893
0
    assert(PyBytes_GET_SIZE(code) % sizeof(_Py_CODEUNIT) == 0);
894
0
    assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(code), sizeof(_Py_CODEUNIT)));
895
0
    if (nlocals != PyTuple_GET_SIZE(varnames)) {
896
0
        PyErr_SetString(PyExc_ValueError,
897
0
                        "code: co_nlocals != len(co_varnames)");
898
0
        goto error;
899
0
    }
900
901
0
    co = _PyCode_New(&con);
902
0
    if (co == NULL) {
903
0
        goto error;
904
0
    }
905
906
0
error:
907
0
    Py_XDECREF(localsplusnames);
908
0
    Py_XDECREF(localspluskinds);
909
0
    return co;
910
0
}
911
912
PyCodeObject *
913
PyUnstable_Code_New(int argcount, int kwonlyargcount,
914
           int nlocals, int stacksize, int flags,
915
           PyObject *code, PyObject *consts, PyObject *names,
916
           PyObject *varnames, PyObject *freevars, PyObject *cellvars,
917
           PyObject *filename, PyObject *name, PyObject *qualname,
918
           int firstlineno,
919
           PyObject *linetable,
920
           PyObject *exceptiontable)
921
0
{
922
0
    return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals,
923
0
                                     stacksize, flags, code, consts, names,
924
0
                                     varnames, freevars, cellvars, filename,
925
0
                                     name, qualname, firstlineno,
926
0
                                     linetable,
927
0
                                     exceptiontable);
928
0
}
929
930
// NOTE: When modifying the construction of PyCode_NewEmpty, please also change
931
// test.test_code.CodeLocationTest.test_code_new_empty to keep it in sync!
932
933
static const uint8_t assert0[6] = {
934
    RESUME, RESUME_AT_FUNC_START,
935
    LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR,
936
    RAISE_VARARGS, 1
937
};
938
939
static const uint8_t linetable[2] = {
940
    (1 << 7)  // New entry.
941
    | (PY_CODE_LOCATION_INFO_NO_COLUMNS << 3)
942
    | (3 - 1),  // Three code units.
943
    0,  // Offset from co_firstlineno.
944
};
945
946
PyCodeObject *
947
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
948
0
{
949
0
    PyObject *nulltuple = NULL;
950
0
    PyObject *filename_ob = NULL;
951
0
    PyObject *funcname_ob = NULL;
952
0
    PyObject *code_ob = NULL;
953
0
    PyObject *linetable_ob = NULL;
954
0
    PyCodeObject *result = NULL;
955
956
0
    nulltuple = PyTuple_New(0);
957
0
    if (nulltuple == NULL) {
958
0
        goto failed;
959
0
    }
960
0
    funcname_ob = PyUnicode_FromString(funcname);
961
0
    if (funcname_ob == NULL) {
962
0
        goto failed;
963
0
    }
964
0
    filename_ob = PyUnicode_DecodeFSDefault(filename);
965
0
    if (filename_ob == NULL) {
966
0
        goto failed;
967
0
    }
968
0
    code_ob = PyBytes_FromStringAndSize((const char *)assert0, 6);
969
0
    if (code_ob == NULL) {
970
0
        goto failed;
971
0
    }
972
0
    linetable_ob = PyBytes_FromStringAndSize((const char *)linetable, 2);
973
0
    if (linetable_ob == NULL) {
974
0
        goto failed;
975
0
    }
976
977
0
#define emptystring (PyObject *)&_Py_SINGLETON(bytes_empty)
978
0
    struct _PyCodeConstructor con = {
979
0
        .filename = filename_ob,
980
0
        .name = funcname_ob,
981
0
        .qualname = funcname_ob,
982
0
        .code = code_ob,
983
0
        .firstlineno = firstlineno,
984
0
        .linetable = linetable_ob,
985
0
        .consts = nulltuple,
986
0
        .names = nulltuple,
987
0
        .localsplusnames = nulltuple,
988
0
        .localspluskinds = emptystring,
989
0
        .exceptiontable = emptystring,
990
0
        .stacksize = 1,
991
0
    };
992
0
    result = _PyCode_New(&con);
993
994
0
failed:
995
0
    Py_XDECREF(nulltuple);
996
0
    Py_XDECREF(funcname_ob);
997
0
    Py_XDECREF(filename_ob);
998
0
    Py_XDECREF(code_ob);
999
0
    Py_XDECREF(linetable_ob);
1000
0
    return result;
1001
0
}
1002
1003
1004
/******************
1005
 * source location tracking (co_lines/co_positions)
1006
 ******************/
1007
1008
int
1009
PyCode_Addr2Line(PyCodeObject *co, int addrq)
1010
2.27k
{
1011
2.27k
    if (addrq < 0) {
1012
0
        return co->co_firstlineno;
1013
0
    }
1014
2.27k
    if (co->_co_monitoring && co->_co_monitoring->lines) {
1015
0
        return _Py_Instrumentation_GetLine(co, addrq/sizeof(_Py_CODEUNIT));
1016
0
    }
1017
2.27k
    assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
1018
2.27k
    PyCodeAddressRange bounds;
1019
2.27k
    _PyCode_InitAddressRange(co, &bounds);
1020
2.27k
    return _PyCode_CheckLineNumber(addrq, &bounds);
1021
2.27k
}
1022
1023
void
1024
_PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range)
1025
2.27k
{
1026
2.27k
    range->opaque.lo_next = (const uint8_t *)linetable;
1027
2.27k
    range->opaque.limit = range->opaque.lo_next + length;
1028
2.27k
    range->ar_start = -1;
1029
2.27k
    range->ar_end = 0;
1030
2.27k
    range->opaque.computed_line = firstlineno;
1031
2.27k
    range->ar_line = -1;
1032
2.27k
}
1033
1034
int
1035
_PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds)
1036
2.27k
{
1037
2.27k
    assert(co->co_linetable != NULL);
1038
2.27k
    const char *linetable = PyBytes_AS_STRING(co->co_linetable);
1039
2.27k
    Py_ssize_t length = PyBytes_GET_SIZE(co->co_linetable);
1040
2.27k
    _PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds);
1041
2.27k
    return bounds->ar_line;
1042
2.27k
}
1043
1044
/* Update *bounds to describe the first and one-past-the-last instructions in
1045
   the same line as lasti.  Return the number of that line, or -1 if lasti is out of bounds. */
1046
int
1047
_PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds)
1048
2.27k
{
1049
102k
    while (bounds->ar_end <= lasti) {
1050
100k
        if (!_PyLineTable_NextAddressRange(bounds)) {
1051
0
            return -1;
1052
0
        }
1053
100k
    }
1054
2.27k
    while (bounds->ar_start > lasti) {
1055
0
        if (!_PyLineTable_PreviousAddressRange(bounds)) {
1056
0
            return -1;
1057
0
        }
1058
0
    }
1059
2.27k
    return bounds->ar_line;
1060
2.27k
}
1061
1062
static int
1063
is_no_line_marker(uint8_t b)
1064
100k
{
1065
100k
    return (b >> 3) == 0x1f;
1066
100k
}
1067
1068
1069
#define ASSERT_VALID_BOUNDS(bounds) \
1070
200k
    assert(bounds->opaque.lo_next <=  bounds->opaque.limit && \
1071
200k
        (bounds->ar_line == -1 || bounds->ar_line == bounds->opaque.computed_line) && \
1072
200k
        (bounds->opaque.lo_next == bounds->opaque.limit || \
1073
200k
        (*bounds->opaque.lo_next) & 128))
1074
1075
static int
1076
next_code_delta(PyCodeAddressRange *bounds)
1077
100k
{
1078
100k
    assert((*bounds->opaque.lo_next) & 128);
1079
100k
    return (((*bounds->opaque.lo_next) & 7) + 1) * sizeof(_Py_CODEUNIT);
1080
100k
}
1081
1082
static int
1083
previous_code_delta(PyCodeAddressRange *bounds)
1084
0
{
1085
0
    if (bounds->ar_start == 0) {
1086
        // If we looking at the first entry, the
1087
        // "previous" entry has an implicit length of 1.
1088
0
        return 1;
1089
0
    }
1090
0
    const uint8_t *ptr = bounds->opaque.lo_next-1;
1091
0
    while (((*ptr) & 128) == 0) {
1092
0
        ptr--;
1093
0
    }
1094
0
    return (((*ptr) & 7) + 1) * sizeof(_Py_CODEUNIT);
1095
0
}
1096
1097
static int
1098
read_byte(PyCodeAddressRange *bounds)
1099
0
{
1100
0
    return *bounds->opaque.lo_next++;
1101
0
}
1102
1103
static int
1104
read_varint(PyCodeAddressRange *bounds)
1105
0
{
1106
0
    unsigned int read = read_byte(bounds);
1107
0
    unsigned int val = read & 63;
1108
0
    unsigned int shift = 0;
1109
0
    while (read & 64) {
1110
0
        read = read_byte(bounds);
1111
0
        shift += 6;
1112
0
        val |= (read & 63) << shift;
1113
0
    }
1114
0
    return val;
1115
0
}
1116
1117
static int
1118
read_signed_varint(PyCodeAddressRange *bounds)
1119
0
{
1120
0
    unsigned int uval = read_varint(bounds);
1121
0
    if (uval & 1) {
1122
0
        return -(int)(uval >> 1);
1123
0
    }
1124
0
    else {
1125
0
        return uval >> 1;
1126
0
    }
1127
0
}
1128
1129
static void
1130
retreat(PyCodeAddressRange *bounds)
1131
0
{
1132
0
    ASSERT_VALID_BOUNDS(bounds);
1133
0
    assert(bounds->ar_start >= 0);
1134
0
    do {
1135
0
        bounds->opaque.lo_next--;
1136
0
    } while (((*bounds->opaque.lo_next) & 128) == 0);
1137
0
    bounds->opaque.computed_line -= get_line_delta(bounds->opaque.lo_next);
1138
0
    bounds->ar_end = bounds->ar_start;
1139
0
    bounds->ar_start -= previous_code_delta(bounds);
1140
0
    if (is_no_line_marker(bounds->opaque.lo_next[-1])) {
1141
0
        bounds->ar_line = -1;
1142
0
    }
1143
0
    else {
1144
0
        bounds->ar_line = bounds->opaque.computed_line;
1145
0
    }
1146
0
    ASSERT_VALID_BOUNDS(bounds);
1147
0
}
1148
1149
static void
1150
advance(PyCodeAddressRange *bounds)
1151
100k
{
1152
100k
    ASSERT_VALID_BOUNDS(bounds);
1153
100k
    bounds->opaque.computed_line += get_line_delta(bounds->opaque.lo_next);
1154
100k
    if (is_no_line_marker(*bounds->opaque.lo_next)) {
1155
0
        bounds->ar_line = -1;
1156
0
    }
1157
100k
    else {
1158
100k
        bounds->ar_line = bounds->opaque.computed_line;
1159
100k
    }
1160
100k
    bounds->ar_start = bounds->ar_end;
1161
100k
    bounds->ar_end += next_code_delta(bounds);
1162
271k
    do {
1163
271k
        bounds->opaque.lo_next++;
1164
271k
    } while (bounds->opaque.lo_next < bounds->opaque.limit &&
1165
271k
        ((*bounds->opaque.lo_next) & 128) == 0);
1166
100k
    ASSERT_VALID_BOUNDS(bounds);
1167
100k
}
1168
1169
static void
1170
advance_with_locations(PyCodeAddressRange *bounds, int *endline, int *column, int *endcolumn)
1171
0
{
1172
0
    ASSERT_VALID_BOUNDS(bounds);
1173
0
    int first_byte = read_byte(bounds);
1174
0
    int code = (first_byte >> 3) & 15;
1175
0
    bounds->ar_start = bounds->ar_end;
1176
0
    bounds->ar_end = bounds->ar_start + ((first_byte & 7) + 1) * sizeof(_Py_CODEUNIT);
1177
0
    switch(code) {
1178
0
        case PY_CODE_LOCATION_INFO_NONE:
1179
0
            bounds->ar_line = *endline = -1;
1180
0
            *column =  *endcolumn = -1;
1181
0
            break;
1182
0
        case PY_CODE_LOCATION_INFO_LONG:
1183
0
        {
1184
0
            bounds->opaque.computed_line += read_signed_varint(bounds);
1185
0
            bounds->ar_line = bounds->opaque.computed_line;
1186
0
            *endline = bounds->ar_line + read_varint(bounds);
1187
0
            *column = read_varint(bounds)-1;
1188
0
            *endcolumn = read_varint(bounds)-1;
1189
0
            break;
1190
0
        }
1191
0
        case PY_CODE_LOCATION_INFO_NO_COLUMNS:
1192
0
        {
1193
            /* No column */
1194
0
            bounds->opaque.computed_line += read_signed_varint(bounds);
1195
0
            *endline = bounds->ar_line = bounds->opaque.computed_line;
1196
0
            *column = *endcolumn = -1;
1197
0
            break;
1198
0
        }
1199
0
        case PY_CODE_LOCATION_INFO_ONE_LINE0:
1200
0
        case PY_CODE_LOCATION_INFO_ONE_LINE1:
1201
0
        case PY_CODE_LOCATION_INFO_ONE_LINE2:
1202
0
        {
1203
            /* one line form */
1204
0
            int line_delta = code - 10;
1205
0
            bounds->opaque.computed_line += line_delta;
1206
0
            *endline = bounds->ar_line = bounds->opaque.computed_line;
1207
0
            *column = read_byte(bounds);
1208
0
            *endcolumn = read_byte(bounds);
1209
0
            break;
1210
0
        }
1211
0
        default:
1212
0
        {
1213
            /* Short forms */
1214
0
            int second_byte = read_byte(bounds);
1215
0
            assert((second_byte & 128) == 0);
1216
0
            *endline = bounds->ar_line = bounds->opaque.computed_line;
1217
0
            *column = code << 3 | (second_byte >> 4);
1218
0
            *endcolumn = *column + (second_byte & 15);
1219
0
        }
1220
0
    }
1221
0
    ASSERT_VALID_BOUNDS(bounds);
1222
0
}
1223
int
1224
PyCode_Addr2Location(PyCodeObject *co, int addrq,
1225
                     int *start_line, int *start_column,
1226
                     int *end_line, int *end_column)
1227
0
{
1228
0
    if (addrq < 0) {
1229
0
        *start_line = *end_line = co->co_firstlineno;
1230
0
        *start_column = *end_column = 0;
1231
0
        return 1;
1232
0
    }
1233
0
    assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
1234
0
    PyCodeAddressRange bounds;
1235
0
    _PyCode_InitAddressRange(co, &bounds);
1236
0
    _PyCode_CheckLineNumber(addrq, &bounds);
1237
0
    retreat(&bounds);
1238
0
    advance_with_locations(&bounds, end_line, start_column, end_column);
1239
0
    *start_line = bounds.ar_line;
1240
0
    return 1;
1241
0
}
1242
1243
1244
static inline int
1245
100k
at_end(PyCodeAddressRange *bounds) {
1246
100k
    return bounds->opaque.lo_next >= bounds->opaque.limit;
1247
100k
}
1248
1249
int
1250
_PyLineTable_PreviousAddressRange(PyCodeAddressRange *range)
1251
0
{
1252
0
    if (range->ar_start <= 0) {
1253
0
        return 0;
1254
0
    }
1255
0
    retreat(range);
1256
0
    assert(range->ar_end > range->ar_start);
1257
0
    return 1;
1258
0
}
1259
1260
int
1261
_PyLineTable_NextAddressRange(PyCodeAddressRange *range)
1262
100k
{
1263
100k
    if (at_end(range)) {
1264
0
        return 0;
1265
0
    }
1266
100k
    advance(range);
1267
100k
    assert(range->ar_end > range->ar_start);
1268
100k
    return 1;
1269
100k
}
1270
1271
static int
1272
emit_pair(PyObject **bytes, int *offset, int a, int b)
1273
0
{
1274
0
    Py_ssize_t len = PyBytes_GET_SIZE(*bytes);
1275
0
    if (*offset + 2 >= len) {
1276
0
        if (_PyBytes_Resize(bytes, len * 2) < 0)
1277
0
            return 0;
1278
0
    }
1279
0
    unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(*bytes);
1280
0
    lnotab += *offset;
1281
0
    *lnotab++ = a;
1282
0
    *lnotab++ = b;
1283
0
    *offset += 2;
1284
0
    return 1;
1285
0
}
1286
1287
static int
1288
emit_delta(PyObject **bytes, int bdelta, int ldelta, int *offset)
1289
0
{
1290
0
    while (bdelta > 255) {
1291
0
        if (!emit_pair(bytes, offset, 255, 0)) {
1292
0
            return 0;
1293
0
        }
1294
0
        bdelta -= 255;
1295
0
    }
1296
0
    while (ldelta > 127) {
1297
0
        if (!emit_pair(bytes, offset, bdelta, 127)) {
1298
0
            return 0;
1299
0
        }
1300
0
        bdelta = 0;
1301
0
        ldelta -= 127;
1302
0
    }
1303
0
    while (ldelta < -128) {
1304
0
        if (!emit_pair(bytes, offset, bdelta, -128)) {
1305
0
            return 0;
1306
0
        }
1307
0
        bdelta = 0;
1308
0
        ldelta += 128;
1309
0
    }
1310
0
    return emit_pair(bytes, offset, bdelta, ldelta);
1311
0
}
1312
1313
static PyObject *
1314
decode_linetable(PyCodeObject *code)
1315
0
{
1316
0
    PyCodeAddressRange bounds;
1317
0
    PyObject *bytes;
1318
0
    int table_offset = 0;
1319
0
    int code_offset = 0;
1320
0
    int line = code->co_firstlineno;
1321
0
    bytes = PyBytes_FromStringAndSize(NULL, 64);
1322
0
    if (bytes == NULL) {
1323
0
        return NULL;
1324
0
    }
1325
0
    _PyCode_InitAddressRange(code, &bounds);
1326
0
    while (_PyLineTable_NextAddressRange(&bounds)) {
1327
0
        if (bounds.opaque.computed_line != line) {
1328
0
            int bdelta = bounds.ar_start - code_offset;
1329
0
            int ldelta = bounds.opaque.computed_line - line;
1330
0
            if (!emit_delta(&bytes, bdelta, ldelta, &table_offset)) {
1331
0
                Py_DECREF(bytes);
1332
0
                return NULL;
1333
0
            }
1334
0
            code_offset = bounds.ar_start;
1335
0
            line = bounds.opaque.computed_line;
1336
0
        }
1337
0
    }
1338
0
    _PyBytes_Resize(&bytes, table_offset);
1339
0
    return bytes;
1340
0
}
1341
1342
1343
typedef struct {
1344
    PyObject_HEAD
1345
    PyCodeObject *li_code;
1346
    PyCodeAddressRange li_line;
1347
} lineiterator;
1348
1349
1350
static void
1351
lineiter_dealloc(PyObject *self)
1352
0
{
1353
0
    lineiterator *li = (lineiterator*)self;
1354
0
    Py_DECREF(li->li_code);
1355
0
    Py_TYPE(li)->tp_free(li);
1356
0
}
1357
1358
static PyObject *
1359
0
_source_offset_converter(void *arg) {
1360
0
    int *value = (int*)arg;
1361
0
    if (*value == -1) {
1362
0
        Py_RETURN_NONE;
1363
0
    }
1364
0
    return PyLong_FromLong(*value);
1365
0
}
1366
1367
static PyObject *
1368
lineiter_next(PyObject *self)
1369
0
{
1370
0
    lineiterator *li = (lineiterator*)self;
1371
0
    PyCodeAddressRange *bounds = &li->li_line;
1372
0
    if (!_PyLineTable_NextAddressRange(bounds)) {
1373
0
        return NULL;
1374
0
    }
1375
0
    int start = bounds->ar_start;
1376
0
    int line = bounds->ar_line;
1377
    // Merge overlapping entries:
1378
0
    while (_PyLineTable_NextAddressRange(bounds)) {
1379
0
        if (bounds->ar_line != line) {
1380
0
            _PyLineTable_PreviousAddressRange(bounds);
1381
0
            break;
1382
0
        }
1383
0
    }
1384
0
    return Py_BuildValue("iiO&", start, bounds->ar_end,
1385
0
                         _source_offset_converter, &line);
1386
0
}
1387
1388
PyTypeObject _PyLineIterator = {
1389
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
1390
    "line_iterator",                    /* tp_name */
1391
    sizeof(lineiterator),               /* tp_basicsize */
1392
    0,                                  /* tp_itemsize */
1393
    /* methods */
1394
    lineiter_dealloc,                   /* tp_dealloc */
1395
    0,                                  /* tp_vectorcall_offset */
1396
    0,                                  /* tp_getattr */
1397
    0,                                  /* tp_setattr */
1398
    0,                                  /* tp_as_async */
1399
    0,                                  /* tp_repr */
1400
    0,                                  /* tp_as_number */
1401
    0,                                  /* tp_as_sequence */
1402
    0,                                  /* tp_as_mapping */
1403
    0,                                  /* tp_hash */
1404
    0,                                  /* tp_call */
1405
    0,                                  /* tp_str */
1406
    0,                                  /* tp_getattro */
1407
    0,                                  /* tp_setattro */
1408
    0,                                  /* tp_as_buffer */
1409
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
1410
    0,                                  /* tp_doc */
1411
    0,                                  /* tp_traverse */
1412
    0,                                  /* tp_clear */
1413
    0,                                  /* tp_richcompare */
1414
    0,                                  /* tp_weaklistoffset */
1415
    PyObject_SelfIter,                  /* tp_iter */
1416
    lineiter_next,                      /* tp_iternext */
1417
    0,                                  /* tp_methods */
1418
    0,                                  /* tp_members */
1419
    0,                                  /* tp_getset */
1420
    0,                                  /* tp_base */
1421
    0,                                  /* tp_dict */
1422
    0,                                  /* tp_descr_get */
1423
    0,                                  /* tp_descr_set */
1424
    0,                                  /* tp_dictoffset */
1425
    0,                                  /* tp_init */
1426
    0,                                  /* tp_alloc */
1427
    0,                                  /* tp_new */
1428
    PyObject_Free,                      /* tp_free */
1429
};
1430
1431
static lineiterator *
1432
new_linesiterator(PyCodeObject *code)
1433
0
{
1434
0
    lineiterator *li = (lineiterator *)PyType_GenericAlloc(&_PyLineIterator, 0);
1435
0
    if (li == NULL) {
1436
0
        return NULL;
1437
0
    }
1438
0
    li->li_code = (PyCodeObject*)Py_NewRef(code);
1439
0
    _PyCode_InitAddressRange(code, &li->li_line);
1440
0
    return li;
1441
0
}
1442
1443
/* co_positions iterator object. */
1444
typedef struct {
1445
    PyObject_HEAD
1446
    PyCodeObject* pi_code;
1447
    PyCodeAddressRange pi_range;
1448
    int pi_offset;
1449
    int pi_endline;
1450
    int pi_column;
1451
    int pi_endcolumn;
1452
} positionsiterator;
1453
1454
static void
1455
positionsiter_dealloc(PyObject *self)
1456
0
{
1457
0
    positionsiterator *pi = (positionsiterator*)self;
1458
0
    Py_DECREF(pi->pi_code);
1459
0
    Py_TYPE(pi)->tp_free(pi);
1460
0
}
1461
1462
static PyObject*
1463
positionsiter_next(PyObject *self)
1464
0
{
1465
0
    positionsiterator *pi = (positionsiterator*)self;
1466
0
    if (pi->pi_offset >= pi->pi_range.ar_end) {
1467
0
        assert(pi->pi_offset == pi->pi_range.ar_end);
1468
0
        if (at_end(&pi->pi_range)) {
1469
0
            return NULL;
1470
0
        }
1471
0
        advance_with_locations(&pi->pi_range, &pi->pi_endline, &pi->pi_column, &pi->pi_endcolumn);
1472
0
    }
1473
0
    pi->pi_offset += 2;
1474
0
    return Py_BuildValue("(O&O&O&O&)",
1475
0
        _source_offset_converter, &pi->pi_range.ar_line,
1476
0
        _source_offset_converter, &pi->pi_endline,
1477
0
        _source_offset_converter, &pi->pi_column,
1478
0
        _source_offset_converter, &pi->pi_endcolumn);
1479
0
}
1480
1481
PyTypeObject _PyPositionsIterator = {
1482
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
1483
    "positions_iterator",               /* tp_name */
1484
    sizeof(positionsiterator),          /* tp_basicsize */
1485
    0,                                  /* tp_itemsize */
1486
    /* methods */
1487
    positionsiter_dealloc,              /* tp_dealloc */
1488
    0,                                  /* tp_vectorcall_offset */
1489
    0,                                  /* tp_getattr */
1490
    0,                                  /* tp_setattr */
1491
    0,                                  /* tp_as_async */
1492
    0,                                  /* tp_repr */
1493
    0,                                  /* tp_as_number */
1494
    0,                                  /* tp_as_sequence */
1495
    0,                                  /* tp_as_mapping */
1496
    0,                                  /* tp_hash */
1497
    0,                                  /* tp_call */
1498
    0,                                  /* tp_str */
1499
    0,                                  /* tp_getattro */
1500
    0,                                  /* tp_setattro */
1501
    0,                                  /* tp_as_buffer */
1502
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
1503
    0,                                  /* tp_doc */
1504
    0,                                  /* tp_traverse */
1505
    0,                                  /* tp_clear */
1506
    0,                                  /* tp_richcompare */
1507
    0,                                  /* tp_weaklistoffset */
1508
    PyObject_SelfIter,                  /* tp_iter */
1509
    positionsiter_next,                 /* tp_iternext */
1510
    0,                                  /* tp_methods */
1511
    0,                                  /* tp_members */
1512
    0,                                  /* tp_getset */
1513
    0,                                  /* tp_base */
1514
    0,                                  /* tp_dict */
1515
    0,                                  /* tp_descr_get */
1516
    0,                                  /* tp_descr_set */
1517
    0,                                  /* tp_dictoffset */
1518
    0,                                  /* tp_init */
1519
    0,                                  /* tp_alloc */
1520
    0,                                  /* tp_new */
1521
    PyObject_Free,                      /* tp_free */
1522
};
1523
1524
static PyObject*
1525
code_positionsiterator(PyObject *self, PyObject* Py_UNUSED(args))
1526
0
{
1527
0
    PyCodeObject *code = (PyCodeObject*)self;
1528
0
    positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&_PyPositionsIterator, 0);
1529
0
    if (pi == NULL) {
1530
0
        return NULL;
1531
0
    }
1532
0
    pi->pi_code = (PyCodeObject*)Py_NewRef(code);
1533
0
    _PyCode_InitAddressRange(code, &pi->pi_range);
1534
0
    pi->pi_offset = pi->pi_range.ar_end;
1535
0
    return (PyObject*)pi;
1536
0
}
1537
1538
1539
/******************
1540
 * "extra" frame eval info (see PEP 523)
1541
 ******************/
1542
1543
/* Holder for co_extra information */
1544
typedef struct {
1545
    Py_ssize_t ce_size;
1546
    void *ce_extras[1];
1547
} _PyCodeObjectExtra;
1548
1549
1550
int
1551
PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
1552
0
{
1553
0
    if (!PyCode_Check(code)) {
1554
0
        PyErr_BadInternalCall();
1555
0
        return -1;
1556
0
    }
1557
1558
0
    PyCodeObject *o = (PyCodeObject*) code;
1559
0
    _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra;
1560
1561
0
    if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) {
1562
0
        *extra = NULL;
1563
0
        return 0;
1564
0
    }
1565
1566
0
    *extra = co_extra->ce_extras[index];
1567
0
    return 0;
1568
0
}
1569
1570
1571
int
1572
PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
1573
0
{
1574
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
1575
1576
0
    if (!PyCode_Check(code) || index < 0 ||
1577
0
            index >= interp->co_extra_user_count) {
1578
0
        PyErr_BadInternalCall();
1579
0
        return -1;
1580
0
    }
1581
1582
0
    PyCodeObject *o = (PyCodeObject*) code;
1583
0
    _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra;
1584
1585
0
    if (co_extra == NULL || co_extra->ce_size <= index) {
1586
0
        Py_ssize_t i = (co_extra == NULL ? 0 : co_extra->ce_size);
1587
0
        co_extra = PyMem_Realloc(
1588
0
                co_extra,
1589
0
                sizeof(_PyCodeObjectExtra) +
1590
0
                (interp->co_extra_user_count-1) * sizeof(void*));
1591
0
        if (co_extra == NULL) {
1592
0
            return -1;
1593
0
        }
1594
0
        for (; i < interp->co_extra_user_count; i++) {
1595
0
            co_extra->ce_extras[i] = NULL;
1596
0
        }
1597
0
        co_extra->ce_size = interp->co_extra_user_count;
1598
0
        o->co_extra = co_extra;
1599
0
    }
1600
1601
0
    if (co_extra->ce_extras[index] != NULL) {
1602
0
        freefunc free = interp->co_extra_freefuncs[index];
1603
0
        if (free != NULL) {
1604
0
            free(co_extra->ce_extras[index]);
1605
0
        }
1606
0
    }
1607
1608
0
    co_extra->ce_extras[index] = extra;
1609
0
    return 0;
1610
0
}
1611
1612
1613
/******************
1614
 * other PyCodeObject accessor functions
1615
 ******************/
1616
1617
static PyObject *
1618
get_cached_locals(PyCodeObject *co, PyObject **cached_field,
1619
    _PyLocals_Kind kind, int num)
1620
8
{
1621
8
    assert(cached_field != NULL);
1622
8
    assert(co->_co_cached != NULL);
1623
8
    PyObject *varnames = FT_ATOMIC_LOAD_PTR(*cached_field);
1624
8
    if (varnames != NULL) {
1625
0
        return Py_NewRef(varnames);
1626
0
    }
1627
1628
8
    Py_BEGIN_CRITICAL_SECTION(co);
1629
8
    varnames = *cached_field;
1630
8
    if (varnames == NULL) {
1631
8
        varnames = get_localsplus_names(co, kind, num);
1632
8
        if (varnames != NULL) {
1633
8
            FT_ATOMIC_STORE_PTR(*cached_field, varnames);
1634
8
        }
1635
8
    }
1636
8
    Py_END_CRITICAL_SECTION();
1637
8
    return Py_XNewRef(varnames);
1638
8
}
1639
1640
PyObject *
1641
_PyCode_GetVarnames(PyCodeObject *co)
1642
8
{
1643
8
    if (init_co_cached(co)) {
1644
0
        return NULL;
1645
0
    }
1646
8
    return get_cached_locals(co, &co->_co_cached->_co_varnames, CO_FAST_LOCAL, co->co_nlocals);
1647
8
}
1648
1649
PyObject *
1650
PyCode_GetVarnames(PyCodeObject *code)
1651
0
{
1652
0
    return _PyCode_GetVarnames(code);
1653
0
}
1654
1655
PyObject *
1656
_PyCode_GetCellvars(PyCodeObject *co)
1657
0
{
1658
0
    if (init_co_cached(co)) {
1659
0
        return NULL;
1660
0
    }
1661
0
    return get_cached_locals(co, &co->_co_cached->_co_cellvars, CO_FAST_CELL, co->co_ncellvars);
1662
0
}
1663
1664
PyObject *
1665
PyCode_GetCellvars(PyCodeObject *code)
1666
0
{
1667
0
    return _PyCode_GetCellvars(code);
1668
0
}
1669
1670
PyObject *
1671
_PyCode_GetFreevars(PyCodeObject *co)
1672
0
{
1673
0
    if (init_co_cached(co)) {
1674
0
        return NULL;
1675
0
    }
1676
0
    return get_cached_locals(co, &co->_co_cached->_co_freevars, CO_FAST_FREE, co->co_nfreevars);
1677
0
}
1678
1679
PyObject *
1680
PyCode_GetFreevars(PyCodeObject *code)
1681
0
{
1682
0
    return _PyCode_GetFreevars(code);
1683
0
}
1684
1685
1686
0
#define GET_OPARG(co, i, initial) (initial)
1687
// We may want to move these macros to pycore_opcode_utils.h
1688
// and use them in Python/bytecodes.c.
1689
#define LOAD_GLOBAL_NAME_INDEX(oparg) ((oparg)>>1)
1690
0
#define LOAD_ATTR_NAME_INDEX(oparg) ((oparg)>>1)
1691
1692
#ifndef Py_DEBUG
1693
0
#define GETITEM(v, i) PyTuple_GET_ITEM((v), (i))
1694
#else
1695
static inline PyObject *
1696
GETITEM(PyObject *v, Py_ssize_t i)
1697
{
1698
    assert(PyTuple_Check(v));
1699
    assert(i >= 0);
1700
    assert(i < PyTuple_GET_SIZE(v));
1701
    assert(PyTuple_GET_ITEM(v, i) != NULL);
1702
    return PyTuple_GET_ITEM(v, i);
1703
}
1704
#endif
1705
1706
static int
1707
identify_unbound_names(PyThreadState *tstate, PyCodeObject *co,
1708
                       PyObject *globalnames, PyObject *attrnames,
1709
                       PyObject *globalsns, PyObject *builtinsns,
1710
                       struct co_unbound_counts *counts, int *p_numdupes)
1711
0
{
1712
    // This function is inspired by inspect.getclosurevars().
1713
    // It would be nicer if we had something similar to co_localspluskinds,
1714
    // but for co_names.
1715
0
    assert(globalnames != NULL);
1716
0
    assert(PySet_Check(globalnames));
1717
0
    assert(PySet_GET_SIZE(globalnames) == 0 || counts != NULL);
1718
0
    assert(attrnames != NULL);
1719
0
    assert(PySet_Check(attrnames));
1720
0
    assert(PySet_GET_SIZE(attrnames) == 0 || counts != NULL);
1721
0
    assert(globalsns == NULL || PyDict_Check(globalsns));
1722
0
    assert(builtinsns == NULL || PyDict_Check(builtinsns));
1723
0
    assert(counts == NULL || counts->total == 0);
1724
0
    struct co_unbound_counts unbound = {0};
1725
0
    int numdupes = 0;
1726
0
    Py_ssize_t len = Py_SIZE(co);
1727
0
    for (int i = 0; i < len; i += _PyInstruction_GetLength(co, i)) {
1728
0
        _Py_CODEUNIT inst = _Py_GetBaseCodeUnit(co, i);
1729
0
        if (inst.op.code == LOAD_ATTR) {
1730
0
            int oparg = GET_OPARG(co, i, inst.op.arg);
1731
0
            int index = LOAD_ATTR_NAME_INDEX(oparg);
1732
0
            PyObject *name = GETITEM(co->co_names, index);
1733
0
            if (PySet_Contains(attrnames, name)) {
1734
0
                if (_PyErr_Occurred(tstate)) {
1735
0
                    return -1;
1736
0
                }
1737
0
                continue;
1738
0
            }
1739
0
            unbound.total += 1;
1740
0
            unbound.numattrs += 1;
1741
0
            if (PySet_Add(attrnames, name) < 0) {
1742
0
                return -1;
1743
0
            }
1744
0
            if (PySet_Contains(globalnames, name)) {
1745
0
                if (_PyErr_Occurred(tstate)) {
1746
0
                    return -1;
1747
0
                }
1748
0
                numdupes += 1;
1749
0
            }
1750
0
        }
1751
0
        else if (inst.op.code == LOAD_GLOBAL) {
1752
0
            int oparg = GET_OPARG(co, i, inst.op.arg);
1753
0
            int index = LOAD_ATTR_NAME_INDEX(oparg);
1754
0
            PyObject *name = GETITEM(co->co_names, index);
1755
0
            if (PySet_Contains(globalnames, name)) {
1756
0
                if (_PyErr_Occurred(tstate)) {
1757
0
                    return -1;
1758
0
                }
1759
0
                continue;
1760
0
            }
1761
0
            unbound.total += 1;
1762
0
            unbound.globals.total += 1;
1763
0
            if (globalsns != NULL && PyDict_Contains(globalsns, name)) {
1764
0
                if (_PyErr_Occurred(tstate)) {
1765
0
                    return -1;
1766
0
                }
1767
0
                unbound.globals.numglobal += 1;
1768
0
            }
1769
0
            else if (builtinsns != NULL && PyDict_Contains(builtinsns, name)) {
1770
0
                if (_PyErr_Occurred(tstate)) {
1771
0
                    return -1;
1772
0
                }
1773
0
                unbound.globals.numbuiltin += 1;
1774
0
            }
1775
0
            else {
1776
0
                unbound.globals.numunknown += 1;
1777
0
            }
1778
0
            if (PySet_Add(globalnames, name) < 0) {
1779
0
                return -1;
1780
0
            }
1781
0
            if (PySet_Contains(attrnames, name)) {
1782
0
                if (_PyErr_Occurred(tstate)) {
1783
0
                    return -1;
1784
0
                }
1785
0
                numdupes += 1;
1786
0
            }
1787
0
        }
1788
0
    }
1789
0
    if (counts != NULL) {
1790
0
        *counts = unbound;
1791
0
    }
1792
0
    if (p_numdupes != NULL) {
1793
0
        *p_numdupes = numdupes;
1794
0
    }
1795
0
    return 0;
1796
0
}
1797
1798
1799
void
1800
_PyCode_GetVarCounts(PyCodeObject *co, _PyCode_var_counts_t *counts)
1801
0
{
1802
0
    assert(counts != NULL);
1803
1804
    // Count the locals, cells, and free vars.
1805
0
    struct co_locals_counts locals = {0};
1806
0
    int numfree = 0;
1807
0
    PyObject *kinds = co->co_localspluskinds;
1808
0
    Py_ssize_t numlocalplusfree = PyBytes_GET_SIZE(kinds);
1809
0
    for (int i = 0; i < numlocalplusfree; i++) {
1810
0
        _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i);
1811
0
        if (kind & CO_FAST_FREE) {
1812
0
            assert(!(kind & CO_FAST_LOCAL));
1813
0
            assert(!(kind & CO_FAST_HIDDEN));
1814
0
            assert(!(kind & CO_FAST_ARG));
1815
0
            numfree += 1;
1816
0
        }
1817
0
        else {
1818
            // Apparently not all non-free vars a CO_FAST_LOCAL.
1819
0
            assert(kind);
1820
0
            locals.total += 1;
1821
0
            if (kind & CO_FAST_ARG) {
1822
0
                locals.args.total += 1;
1823
0
                if (kind & CO_FAST_ARG_VAR) {
1824
0
                    if (kind & CO_FAST_ARG_POS) {
1825
0
                        assert(!(kind & CO_FAST_ARG_KW));
1826
0
                        assert(!locals.args.varargs);
1827
0
                        locals.args.varargs = 1;
1828
0
                    }
1829
0
                    else {
1830
0
                        assert(kind & CO_FAST_ARG_KW);
1831
0
                        assert(!locals.args.varkwargs);
1832
0
                        locals.args.varkwargs = 1;
1833
0
                    }
1834
0
                }
1835
0
                else if (kind & CO_FAST_ARG_POS) {
1836
0
                    if (kind & CO_FAST_ARG_KW) {
1837
0
                        locals.args.numposorkw += 1;
1838
0
                    }
1839
0
                    else {
1840
0
                        locals.args.numposonly += 1;
1841
0
                    }
1842
0
                }
1843
0
                else {
1844
0
                    assert(kind & CO_FAST_ARG_KW);
1845
0
                    locals.args.numkwonly += 1;
1846
0
                }
1847
0
                if (kind & CO_FAST_CELL) {
1848
0
                    locals.cells.total += 1;
1849
0
                    locals.cells.numargs += 1;
1850
0
                }
1851
                // Args are never hidden currently.
1852
0
                assert(!(kind & CO_FAST_HIDDEN));
1853
0
            }
1854
0
            else {
1855
0
                if (kind & CO_FAST_CELL) {
1856
0
                    locals.cells.total += 1;
1857
0
                    locals.cells.numothers += 1;
1858
0
                    if (kind & CO_FAST_HIDDEN) {
1859
0
                        locals.hidden.total += 1;
1860
0
                        locals.hidden.numcells += 1;
1861
0
                    }
1862
0
                }
1863
0
                else {
1864
0
                    locals.numpure += 1;
1865
0
                    if (kind & CO_FAST_HIDDEN) {
1866
0
                        locals.hidden.total += 1;
1867
0
                        locals.hidden.numpure += 1;
1868
0
                    }
1869
0
                }
1870
0
            }
1871
0
        }
1872
0
    }
1873
0
    assert(locals.args.total == (
1874
0
            co->co_argcount + co->co_kwonlyargcount
1875
0
            + !!(co->co_flags & CO_VARARGS)
1876
0
            + !!(co->co_flags & CO_VARKEYWORDS)));
1877
0
    assert(locals.args.numposonly == co->co_posonlyargcount);
1878
0
    assert(locals.args.numposonly + locals.args.numposorkw == co->co_argcount);
1879
0
    assert(locals.args.numkwonly == co->co_kwonlyargcount);
1880
0
    assert(locals.cells.total == co->co_ncellvars);
1881
0
    assert(locals.args.total + locals.numpure == co->co_nlocals);
1882
0
    assert(locals.total + locals.cells.numargs == co->co_nlocals + co->co_ncellvars);
1883
0
    assert(locals.total + numfree == co->co_nlocalsplus);
1884
0
    assert(numfree == co->co_nfreevars);
1885
1886
    // Get the unbound counts.
1887
0
    assert(PyTuple_GET_SIZE(co->co_names) >= 0);
1888
0
    assert(PyTuple_GET_SIZE(co->co_names) < INT_MAX);
1889
0
    int numunbound = (int)PyTuple_GET_SIZE(co->co_names);
1890
0
    struct co_unbound_counts unbound = {
1891
0
        .total = numunbound,
1892
        // numglobal and numattrs can be set later
1893
        // with _PyCode_SetUnboundVarCounts().
1894
0
        .numunknown = numunbound,
1895
0
    };
1896
1897
    // "Return" the result.
1898
0
    *counts = (_PyCode_var_counts_t){
1899
0
        .total = locals.total + numfree + unbound.total,
1900
0
        .locals = locals,
1901
0
        .numfree = numfree,
1902
0
        .unbound = unbound,
1903
0
    };
1904
0
}
1905
1906
int
1907
_PyCode_SetUnboundVarCounts(PyThreadState *tstate,
1908
                            PyCodeObject *co, _PyCode_var_counts_t *counts,
1909
                            PyObject *globalnames, PyObject *attrnames,
1910
                            PyObject *globalsns, PyObject *builtinsns)
1911
0
{
1912
0
    int res = -1;
1913
0
    PyObject *globalnames_owned = NULL;
1914
0
    PyObject *attrnames_owned = NULL;
1915
1916
    // Prep the name sets.
1917
0
    if (globalnames == NULL) {
1918
0
        globalnames_owned = PySet_New(NULL);
1919
0
        if (globalnames_owned == NULL) {
1920
0
            goto finally;
1921
0
        }
1922
0
        globalnames = globalnames_owned;
1923
0
    }
1924
0
    else if (!PySet_Check(globalnames)) {
1925
0
        _PyErr_Format(tstate, PyExc_TypeError,
1926
0
                     "expected a set for \"globalnames\", got %R", globalnames);
1927
0
        goto finally;
1928
0
    }
1929
0
    if (attrnames == NULL) {
1930
0
        attrnames_owned = PySet_New(NULL);
1931
0
        if (attrnames_owned == NULL) {
1932
0
            goto finally;
1933
0
        }
1934
0
        attrnames = attrnames_owned;
1935
0
    }
1936
0
    else if (!PySet_Check(attrnames)) {
1937
0
        _PyErr_Format(tstate, PyExc_TypeError,
1938
0
                     "expected a set for \"attrnames\", got %R", attrnames);
1939
0
        goto finally;
1940
0
    }
1941
1942
    // Fill in unbound.globals and unbound.numattrs.
1943
0
    struct co_unbound_counts unbound = {0};
1944
0
    int numdupes = 0;
1945
0
    Py_BEGIN_CRITICAL_SECTION(co);
1946
0
    res = identify_unbound_names(
1947
0
            tstate, co, globalnames, attrnames, globalsns, builtinsns,
1948
0
            &unbound, &numdupes);
1949
0
    Py_END_CRITICAL_SECTION();
1950
0
    if (res < 0) {
1951
0
        goto finally;
1952
0
    }
1953
0
    assert(unbound.numunknown == 0);
1954
0
    assert(unbound.total - numdupes <= counts->unbound.total);
1955
0
    assert(counts->unbound.numunknown == counts->unbound.total);
1956
    // There may be a name that is both a global and an attr.
1957
0
    int totalunbound = counts->unbound.total + numdupes;
1958
0
    unbound.numunknown = totalunbound - unbound.total;
1959
0
    unbound.total = totalunbound;
1960
0
    counts->unbound = unbound;
1961
0
    counts->total += numdupes;
1962
0
    res = 0;
1963
1964
0
finally:
1965
0
    Py_XDECREF(globalnames_owned);
1966
0
    Py_XDECREF(attrnames_owned);
1967
0
    return res;
1968
0
}
1969
1970
1971
int
1972
_PyCode_CheckNoInternalState(PyCodeObject *co, const char **p_errmsg)
1973
0
{
1974
0
    const char *errmsg = NULL;
1975
    // We don't worry about co_executors, co_instrumentation,
1976
    // or co_monitoring.  They are essentially ephemeral.
1977
0
    if (co->co_extra != NULL) {
1978
0
        errmsg = "only basic code objects are supported";
1979
0
    }
1980
1981
0
    if (errmsg != NULL) {
1982
0
        if (p_errmsg != NULL) {
1983
0
            *p_errmsg = errmsg;
1984
0
        }
1985
0
        return 0;
1986
0
    }
1987
0
    return 1;
1988
0
}
1989
1990
int
1991
_PyCode_CheckNoExternalState(PyCodeObject *co, _PyCode_var_counts_t *counts,
1992
                             const char **p_errmsg)
1993
0
{
1994
0
    const char *errmsg = NULL;
1995
0
    if (counts->numfree > 0) {  // It's a closure.
1996
0
        errmsg = "closures not supported";
1997
0
    }
1998
0
    else if (counts->unbound.globals.numglobal > 0) {
1999
0
        errmsg = "globals not supported";
2000
0
    }
2001
0
    else if (counts->unbound.globals.numbuiltin > 0
2002
0
             && counts->unbound.globals.numunknown > 0)
2003
0
    {
2004
0
        errmsg = "globals not supported";
2005
0
    }
2006
    // Otherwise we don't check counts.unbound.globals.numunknown since we can't
2007
    // distinguish beween globals and builtins here.
2008
2009
0
    if (errmsg != NULL) {
2010
0
        if (p_errmsg != NULL) {
2011
0
            *p_errmsg = errmsg;
2012
0
        }
2013
0
        return 0;
2014
0
    }
2015
0
    return 1;
2016
0
}
2017
2018
int
2019
_PyCode_VerifyStateless(PyThreadState *tstate,
2020
                        PyCodeObject *co, PyObject *globalnames,
2021
                        PyObject *globalsns, PyObject *builtinsns)
2022
0
{
2023
0
    const char *errmsg;
2024
0
   _PyCode_var_counts_t counts = {0};
2025
0
    _PyCode_GetVarCounts(co, &counts);
2026
0
    if (_PyCode_SetUnboundVarCounts(
2027
0
                            tstate, co, &counts, globalnames, NULL,
2028
0
                            globalsns, builtinsns) < 0)
2029
0
    {
2030
0
        return -1;
2031
0
    }
2032
    // We may consider relaxing the internal state constraints
2033
    // if it becomes a problem.
2034
0
    if (!_PyCode_CheckNoInternalState(co, &errmsg)) {
2035
0
        _PyErr_SetString(tstate, PyExc_ValueError, errmsg);
2036
0
        return -1;
2037
0
    }
2038
0
    if (builtinsns != NULL) {
2039
        // Make sure the next check will fail for globals,
2040
        // even if there aren't any builtins.
2041
0
        counts.unbound.globals.numbuiltin += 1;
2042
0
    }
2043
0
    if (!_PyCode_CheckNoExternalState(co, &counts, &errmsg)) {
2044
0
        _PyErr_SetString(tstate, PyExc_ValueError, errmsg);
2045
0
        return -1;
2046
0
    }
2047
    // Note that we don't check co->co_flags & CO_NESTED for anything here.
2048
0
    return 0;
2049
0
}
2050
2051
2052
int
2053
_PyCode_CheckPureFunction(PyCodeObject *co, const char **p_errmsg)
2054
0
{
2055
0
    const char *errmsg = NULL;
2056
0
    if (co->co_flags & CO_GENERATOR) {
2057
0
        errmsg = "generators not supported";
2058
0
    }
2059
0
    else if (co->co_flags & CO_COROUTINE) {
2060
0
        errmsg = "coroutines not supported";
2061
0
    }
2062
0
    else if (co->co_flags & CO_ITERABLE_COROUTINE) {
2063
0
        errmsg = "coroutines not supported";
2064
0
    }
2065
0
    else if (co->co_flags & CO_ASYNC_GENERATOR) {
2066
0
        errmsg = "generators not supported";
2067
0
    }
2068
2069
0
    if (errmsg != NULL) {
2070
0
        if (p_errmsg != NULL) {
2071
0
            *p_errmsg = errmsg;
2072
0
        }
2073
0
        return 0;
2074
0
    }
2075
0
    return 1;
2076
0
}
2077
2078
/* Here "value" means a non-None value, since a bare return is identical
2079
 * to returning None explicitly.  Likewise a missing return statement
2080
 * at the end of the function is turned into "return None". */
2081
static int
2082
code_returns_only_none(PyCodeObject *co)
2083
0
{
2084
0
    if (!_PyCode_CheckPureFunction(co, NULL)) {
2085
0
        return 0;
2086
0
    }
2087
0
    int len = (int)Py_SIZE(co);
2088
0
    assert(len > 0);
2089
2090
    // The last instruction either returns or raises.  We can take advantage
2091
    // of that for a quick exit.
2092
0
    _Py_CODEUNIT final = _Py_GetBaseCodeUnit(co, len-1);
2093
2094
    // Look up None in co_consts.
2095
0
    Py_ssize_t nconsts = PyTuple_Size(co->co_consts);
2096
0
    int none_index = 0;
2097
0
    for (; none_index < nconsts; none_index++) {
2098
0
        if (PyTuple_GET_ITEM(co->co_consts, none_index) == Py_None) {
2099
0
            break;
2100
0
        }
2101
0
    }
2102
0
    if (none_index == nconsts) {
2103
        // None wasn't there, which means there was no implicit return,
2104
        // "return", or "return None".
2105
2106
        // That means there must be
2107
        // an explicit return (non-None), or it only raises.
2108
0
        if (IS_RETURN_OPCODE(final.op.code)) {
2109
            // It was an explicit return (non-None).
2110
0
            return 0;
2111
0
        }
2112
        // It must end with a raise then.  We still have to walk the
2113
        // bytecode to see if there's any explicit return (non-None).
2114
0
        assert(IS_RAISE_OPCODE(final.op.code));
2115
0
        for (int i = 0; i < len; i += _PyInstruction_GetLength(co, i)) {
2116
0
            _Py_CODEUNIT inst = _Py_GetBaseCodeUnit(co, i);
2117
0
            if (IS_RETURN_OPCODE(inst.op.code)) {
2118
                // We alraedy know it isn't returning None.
2119
0
                return 0;
2120
0
            }
2121
0
        }
2122
        // It must only raise.
2123
0
    }
2124
0
    else {
2125
        // Walk the bytecode, looking for RETURN_VALUE.
2126
0
        for (int i = 0; i < len; i += _PyInstruction_GetLength(co, i)) {
2127
0
            _Py_CODEUNIT inst = _Py_GetBaseCodeUnit(co, i);
2128
0
            if (IS_RETURN_OPCODE(inst.op.code)) {
2129
0
                assert(i != 0);
2130
                // Ignore it if it returns None.
2131
0
                _Py_CODEUNIT prev = _Py_GetBaseCodeUnit(co, i-1);
2132
0
                if (prev.op.code == LOAD_CONST) {
2133
                    // We don't worry about EXTENDED_ARG for now.
2134
0
                    if (prev.op.arg == none_index) {
2135
0
                        continue;
2136
0
                    }
2137
0
                }
2138
0
                return 0;
2139
0
            }
2140
0
        }
2141
0
    }
2142
0
    return 1;
2143
0
}
2144
2145
int
2146
_PyCode_ReturnsOnlyNone(PyCodeObject *co)
2147
0
{
2148
0
    int res;
2149
0
    Py_BEGIN_CRITICAL_SECTION(co);
2150
0
    res = code_returns_only_none(co);
2151
0
    Py_END_CRITICAL_SECTION();
2152
0
    return res;
2153
0
}
2154
2155
2156
#ifdef _Py_TIER2
2157
2158
static void
2159
clear_executors(PyCodeObject *co)
2160
{
2161
    assert(co->co_executors);
2162
    for (int i = 0; i < co->co_executors->size; i++) {
2163
        if (co->co_executors->executors[i]) {
2164
            _Py_ExecutorDetach(co->co_executors->executors[i]);
2165
            assert(co->co_executors->executors[i] == NULL);
2166
        }
2167
    }
2168
    PyMem_Free(co->co_executors);
2169
    co->co_executors = NULL;
2170
}
2171
2172
void
2173
_PyCode_Clear_Executors(PyCodeObject *code)
2174
{
2175
    clear_executors(code);
2176
}
2177
2178
#endif
2179
2180
static void
2181
deopt_code(PyCodeObject *code, _Py_CODEUNIT *instructions)
2182
6.16k
{
2183
6.16k
    Py_ssize_t len = Py_SIZE(code);
2184
336k
    for (int i = 0; i < len; i++) {
2185
330k
        _Py_CODEUNIT inst = _Py_GetBaseCodeUnit(code, i);
2186
330k
        assert(inst.op.code < MIN_SPECIALIZED_OPCODE);
2187
330k
        int caches = _PyOpcode_Caches[inst.op.code];
2188
330k
        instructions[i] = inst;
2189
708k
        for (int j = 1; j <= caches; j++) {
2190
377k
            instructions[i+j].cache = 0;
2191
377k
        }
2192
330k
        i += caches;
2193
330k
    }
2194
6.16k
}
2195
2196
PyObject *
2197
_PyCode_GetCode(PyCodeObject *co)
2198
6.16k
{
2199
6.16k
    if (init_co_cached(co)) {
2200
0
        return NULL;
2201
0
    }
2202
2203
6.16k
    _PyCoCached *cached = co->_co_cached;
2204
6.16k
    PyObject *code = FT_ATOMIC_LOAD_PTR(cached->_co_code);
2205
6.16k
    if (code != NULL) {
2206
0
        return Py_NewRef(code);
2207
0
    }
2208
2209
6.16k
    Py_BEGIN_CRITICAL_SECTION(co);
2210
6.16k
    code = cached->_co_code;
2211
6.16k
    if (code == NULL) {
2212
6.16k
        code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co),
2213
6.16k
                                         _PyCode_NBYTES(co));
2214
6.16k
        if (code != NULL) {
2215
6.16k
            deopt_code(co, (_Py_CODEUNIT *)PyBytes_AS_STRING(code));
2216
6.16k
            assert(cached->_co_code == NULL);
2217
6.16k
            FT_ATOMIC_STORE_PTR(cached->_co_code, code);
2218
6.16k
        }
2219
6.16k
    }
2220
6.16k
    Py_END_CRITICAL_SECTION();
2221
6.16k
    return Py_XNewRef(code);
2222
6.16k
}
2223
2224
PyObject *
2225
PyCode_GetCode(PyCodeObject *co)
2226
0
{
2227
0
    return _PyCode_GetCode(co);
2228
0
}
2229
2230
/******************
2231
 * PyCode_Type
2232
 ******************/
2233
2234
/*[clinic input]
2235
class code "PyCodeObject *" "&PyCode_Type"
2236
[clinic start generated code]*/
2237
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78aa5d576683bb4b]*/
2238
2239
/*[clinic input]
2240
@classmethod
2241
code.__new__ as code_new
2242
2243
    argcount: int
2244
    posonlyargcount: int
2245
    kwonlyargcount: int
2246
    nlocals: int
2247
    stacksize: int
2248
    flags: int
2249
    codestring as code: object(subclass_of="&PyBytes_Type")
2250
    constants as consts: object(subclass_of="&PyTuple_Type")
2251
    names: object(subclass_of="&PyTuple_Type")
2252
    varnames: object(subclass_of="&PyTuple_Type")
2253
    filename: unicode
2254
    name: unicode
2255
    qualname: unicode
2256
    firstlineno: int
2257
    linetable: object(subclass_of="&PyBytes_Type")
2258
    exceptiontable: object(subclass_of="&PyBytes_Type")
2259
    freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = ()
2260
    cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = ()
2261
    /
2262
2263
Create a code object.  Not for the faint of heart.
2264
[clinic start generated code]*/
2265
2266
static PyObject *
2267
code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount,
2268
              int kwonlyargcount, int nlocals, int stacksize, int flags,
2269
              PyObject *code, PyObject *consts, PyObject *names,
2270
              PyObject *varnames, PyObject *filename, PyObject *name,
2271
              PyObject *qualname, int firstlineno, PyObject *linetable,
2272
              PyObject *exceptiontable, PyObject *freevars,
2273
              PyObject *cellvars)
2274
/*[clinic end generated code: output=069fa20d299f9dda input=e31da3c41ad8064a]*/
2275
0
{
2276
0
    PyObject *co = NULL;
2277
0
    PyObject *ournames = NULL;
2278
0
    PyObject *ourvarnames = NULL;
2279
0
    PyObject *ourfreevars = NULL;
2280
0
    PyObject *ourcellvars = NULL;
2281
2282
0
    if (PySys_Audit("code.__new__", "OOOiiiiii",
2283
0
                    code, filename, name, argcount, posonlyargcount,
2284
0
                    kwonlyargcount, nlocals, stacksize, flags) < 0) {
2285
0
        goto cleanup;
2286
0
    }
2287
2288
0
    if (argcount < 0) {
2289
0
        PyErr_SetString(
2290
0
            PyExc_ValueError,
2291
0
            "code: argcount must not be negative");
2292
0
        goto cleanup;
2293
0
    }
2294
2295
0
    if (posonlyargcount < 0) {
2296
0
        PyErr_SetString(
2297
0
            PyExc_ValueError,
2298
0
            "code: posonlyargcount must not be negative");
2299
0
        goto cleanup;
2300
0
    }
2301
2302
0
    if (kwonlyargcount < 0) {
2303
0
        PyErr_SetString(
2304
0
            PyExc_ValueError,
2305
0
            "code: kwonlyargcount must not be negative");
2306
0
        goto cleanup;
2307
0
    }
2308
0
    if (nlocals < 0) {
2309
0
        PyErr_SetString(
2310
0
            PyExc_ValueError,
2311
0
            "code: nlocals must not be negative");
2312
0
        goto cleanup;
2313
0
    }
2314
2315
0
    ournames = validate_and_copy_tuple(names);
2316
0
    if (ournames == NULL)
2317
0
        goto cleanup;
2318
0
    ourvarnames = validate_and_copy_tuple(varnames);
2319
0
    if (ourvarnames == NULL)
2320
0
        goto cleanup;
2321
0
    if (freevars)
2322
0
        ourfreevars = validate_and_copy_tuple(freevars);
2323
0
    else
2324
0
        ourfreevars = PyTuple_New(0);
2325
0
    if (ourfreevars == NULL)
2326
0
        goto cleanup;
2327
0
    if (cellvars)
2328
0
        ourcellvars = validate_and_copy_tuple(cellvars);
2329
0
    else
2330
0
        ourcellvars = PyTuple_New(0);
2331
0
    if (ourcellvars == NULL)
2332
0
        goto cleanup;
2333
2334
0
    co = (PyObject *)PyCode_NewWithPosOnlyArgs(argcount, posonlyargcount,
2335
0
                                               kwonlyargcount,
2336
0
                                               nlocals, stacksize, flags,
2337
0
                                               code, consts, ournames,
2338
0
                                               ourvarnames, ourfreevars,
2339
0
                                               ourcellvars, filename,
2340
0
                                               name, qualname, firstlineno,
2341
0
                                               linetable,
2342
0
                                               exceptiontable
2343
0
                                              );
2344
0
  cleanup:
2345
0
    Py_XDECREF(ournames);
2346
0
    Py_XDECREF(ourvarnames);
2347
0
    Py_XDECREF(ourfreevars);
2348
0
    Py_XDECREF(ourcellvars);
2349
0
    return co;
2350
0
}
2351
2352
static void
2353
free_monitoring_data(_PyCoMonitoringData *data)
2354
8.09k
{
2355
8.09k
    if (data == NULL) {
2356
8.09k
        return;
2357
8.09k
    }
2358
0
    if (data->tools) {
2359
0
        PyMem_Free(data->tools);
2360
0
    }
2361
0
    if (data->lines) {
2362
0
        PyMem_Free(data->lines);
2363
0
    }
2364
0
    if (data->line_tools) {
2365
0
        PyMem_Free(data->line_tools);
2366
0
    }
2367
0
    if (data->per_instruction_opcodes) {
2368
0
        PyMem_Free(data->per_instruction_opcodes);
2369
0
    }
2370
0
    if (data->per_instruction_tools) {
2371
0
        PyMem_Free(data->per_instruction_tools);
2372
0
    }
2373
0
    PyMem_Free(data);
2374
0
}
2375
2376
static void
2377
code_dealloc(PyObject *self)
2378
8.09k
{
2379
8.09k
    PyThreadState *tstate = PyThreadState_GET();
2380
8.09k
    _Py_atomic_add_uint64(&tstate->interp->_code_object_generation, 1);
2381
8.09k
    PyCodeObject *co = _PyCodeObject_CAST(self);
2382
8.09k
    _PyObject_ResurrectStart(self);
2383
8.09k
    notify_code_watchers(PY_CODE_EVENT_DESTROY, co);
2384
8.09k
    if (_PyObject_ResurrectEnd(self)) {
2385
0
        return;
2386
0
    }
2387
2388
#ifdef Py_GIL_DISABLED
2389
    PyObject_GC_UnTrack(co);
2390
#endif
2391
2392
8.09k
    _PyFunction_ClearCodeByVersion(co->co_version);
2393
8.09k
    if (co->co_extra != NULL) {
2394
0
        PyInterpreterState *interp = _PyInterpreterState_GET();
2395
0
        _PyCodeObjectExtra *co_extra = co->co_extra;
2396
2397
0
        for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
2398
0
            freefunc free_extra = interp->co_extra_freefuncs[i];
2399
2400
0
            if (free_extra != NULL) {
2401
0
                free_extra(co_extra->ce_extras[i]);
2402
0
            }
2403
0
        }
2404
2405
0
        PyMem_Free(co_extra);
2406
0
    }
2407
#ifdef _Py_TIER2
2408
    if (co->co_executors != NULL) {
2409
        clear_executors(co);
2410
    }
2411
#endif
2412
2413
8.09k
    Py_XDECREF(co->co_consts);
2414
8.09k
    Py_XDECREF(co->co_names);
2415
8.09k
    Py_XDECREF(co->co_localsplusnames);
2416
8.09k
    Py_XDECREF(co->co_localspluskinds);
2417
8.09k
    Py_XDECREF(co->co_filename);
2418
8.09k
    Py_XDECREF(co->co_name);
2419
8.09k
    Py_XDECREF(co->co_qualname);
2420
8.09k
    Py_XDECREF(co->co_linetable);
2421
8.09k
    Py_XDECREF(co->co_exceptiontable);
2422
#ifdef Py_GIL_DISABLED
2423
    assert(co->_co_unique_id == _Py_INVALID_UNIQUE_ID);
2424
#endif
2425
8.09k
    if (co->_co_cached != NULL) {
2426
1.57k
        Py_XDECREF(co->_co_cached->_co_code);
2427
1.57k
        Py_XDECREF(co->_co_cached->_co_cellvars);
2428
1.57k
        Py_XDECREF(co->_co_cached->_co_freevars);
2429
1.57k
        Py_XDECREF(co->_co_cached->_co_varnames);
2430
1.57k
        PyMem_Free(co->_co_cached);
2431
1.57k
    }
2432
8.09k
    FT_CLEAR_WEAKREFS(self, co->co_weakreflist);
2433
8.09k
    free_monitoring_data(co->_co_monitoring);
2434
#ifdef Py_GIL_DISABLED
2435
    // The first element always points to the mutable bytecode at the end of
2436
    // the code object, which will be freed when the code object is freed.
2437
    for (Py_ssize_t i = 1; i < co->co_tlbc->size; i++) {
2438
        char *entry = co->co_tlbc->entries[i];
2439
        if (entry != NULL) {
2440
            PyMem_Free(entry);
2441
        }
2442
    }
2443
    PyMem_Free(co->co_tlbc);
2444
#endif
2445
8.09k
    PyObject_Free(co);
2446
8.09k
}
2447
2448
#ifdef Py_GIL_DISABLED
2449
static int
2450
code_traverse(PyObject *self, visitproc visit, void *arg)
2451
{
2452
    PyCodeObject *co = _PyCodeObject_CAST(self);
2453
    Py_VISIT(co->co_consts);
2454
    return 0;
2455
}
2456
#endif
2457
2458
static PyObject *
2459
code_repr(PyObject *self)
2460
0
{
2461
0
    PyCodeObject *co = _PyCodeObject_CAST(self);
2462
0
    int lineno;
2463
0
    if (co->co_firstlineno != 0)
2464
0
        lineno = co->co_firstlineno;
2465
0
    else
2466
0
        lineno = -1;
2467
0
    if (co->co_filename && PyUnicode_Check(co->co_filename)) {
2468
0
        return PyUnicode_FromFormat(
2469
0
            "<code object %U at %p, file \"%U\", line %d>",
2470
0
            co->co_name, co, co->co_filename, lineno);
2471
0
    } else {
2472
0
        return PyUnicode_FromFormat(
2473
0
            "<code object %U at %p, file ???, line %d>",
2474
0
            co->co_name, co, lineno);
2475
0
    }
2476
0
}
2477
2478
static PyObject *
2479
code_richcompare(PyObject *self, PyObject *other, int op)
2480
64
{
2481
64
    PyCodeObject *co, *cp;
2482
64
    int eq;
2483
64
    PyObject *consts1, *consts2;
2484
64
    PyObject *res;
2485
2486
64
    if ((op != Py_EQ && op != Py_NE) ||
2487
64
        !PyCode_Check(self) ||
2488
64
        !PyCode_Check(other)) {
2489
0
        Py_RETURN_NOTIMPLEMENTED;
2490
0
    }
2491
2492
64
    co = (PyCodeObject *)self;
2493
64
    cp = (PyCodeObject *)other;
2494
2495
64
    eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
2496
64
    if (!eq) goto unequal;
2497
64
    eq = co->co_argcount == cp->co_argcount;
2498
64
    if (!eq) goto unequal;
2499
64
    eq = co->co_posonlyargcount == cp->co_posonlyargcount;
2500
64
    if (!eq) goto unequal;
2501
64
    eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
2502
64
    if (!eq) goto unequal;
2503
64
    eq = co->co_flags == cp->co_flags;
2504
64
    if (!eq) goto unequal;
2505
64
    eq = co->co_firstlineno == cp->co_firstlineno;
2506
64
    if (!eq) goto unequal;
2507
64
    eq = Py_SIZE(co) == Py_SIZE(cp);
2508
64
    if (!eq) {
2509
0
        goto unequal;
2510
0
    }
2511
1.55k
    for (int i = 0; i < Py_SIZE(co); i++) {
2512
1.49k
        _Py_CODEUNIT co_instr = _Py_GetBaseCodeUnit(co, i);
2513
1.49k
        _Py_CODEUNIT cp_instr = _Py_GetBaseCodeUnit(cp, i);
2514
1.49k
        if (co_instr.cache != cp_instr.cache) {
2515
0
            goto unequal;
2516
0
        }
2517
1.49k
        i += _PyOpcode_Caches[co_instr.op.code];
2518
1.49k
    }
2519
2520
    /* compare constants */
2521
64
    consts1 = _PyCode_ConstantKey(co->co_consts);
2522
64
    if (!consts1)
2523
0
        return NULL;
2524
64
    consts2 = _PyCode_ConstantKey(cp->co_consts);
2525
64
    if (!consts2) {
2526
0
        Py_DECREF(consts1);
2527
0
        return NULL;
2528
0
    }
2529
64
    eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
2530
64
    Py_DECREF(consts1);
2531
64
    Py_DECREF(consts2);
2532
64
    if (eq <= 0) goto unequal;
2533
2534
64
    eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
2535
64
    if (eq <= 0) goto unequal;
2536
64
    eq = PyObject_RichCompareBool(co->co_localsplusnames,
2537
64
                                  cp->co_localsplusnames, Py_EQ);
2538
64
    if (eq <= 0) goto unequal;
2539
64
    eq = PyObject_RichCompareBool(co->co_linetable, cp->co_linetable, Py_EQ);
2540
64
    if (eq <= 0) {
2541
0
        goto unequal;
2542
0
    }
2543
64
    eq = PyObject_RichCompareBool(co->co_exceptiontable,
2544
64
                                  cp->co_exceptiontable, Py_EQ);
2545
64
    if (eq <= 0) {
2546
0
        goto unequal;
2547
0
    }
2548
2549
64
    if (op == Py_EQ)
2550
64
        res = Py_True;
2551
0
    else
2552
0
        res = Py_False;
2553
64
    goto done;
2554
2555
0
  unequal:
2556
0
    if (eq < 0)
2557
0
        return NULL;
2558
0
    if (op == Py_NE)
2559
0
        res = Py_True;
2560
0
    else
2561
0
        res = Py_False;
2562
2563
64
  done:
2564
64
    return Py_NewRef(res);
2565
0
}
2566
2567
static Py_hash_t
2568
code_hash(PyObject *self)
2569
30.7k
{
2570
30.7k
    PyCodeObject *co = _PyCodeObject_CAST(self);
2571
30.7k
    Py_uhash_t uhash = 20221211;
2572
3.01M
    #define SCRAMBLE_IN(H) do {       \
2573
3.01M
        uhash ^= (Py_uhash_t)(H);     \
2574
3.01M
        uhash *= PyHASH_MULTIPLIER;  \
2575
3.01M
    } while (0)
2576
184k
    #define SCRAMBLE_IN_HASH(EXPR) do {     \
2577
184k
        Py_hash_t h = PyObject_Hash(EXPR);  \
2578
184k
        if (h == -1) {                      \
2579
0
            return -1;                      \
2580
0
        }                                   \
2581
184k
        SCRAMBLE_IN(h);                     \
2582
184k
    } while (0)
2583
2584
30.7k
    SCRAMBLE_IN_HASH(co->co_name);
2585
30.7k
    SCRAMBLE_IN_HASH(co->co_consts);
2586
30.7k
    SCRAMBLE_IN_HASH(co->co_names);
2587
30.7k
    SCRAMBLE_IN_HASH(co->co_localsplusnames);
2588
30.7k
    SCRAMBLE_IN_HASH(co->co_linetable);
2589
30.7k
    SCRAMBLE_IN_HASH(co->co_exceptiontable);
2590
30.7k
    SCRAMBLE_IN(co->co_argcount);
2591
30.7k
    SCRAMBLE_IN(co->co_posonlyargcount);
2592
30.7k
    SCRAMBLE_IN(co->co_kwonlyargcount);
2593
30.7k
    SCRAMBLE_IN(co->co_flags);
2594
30.7k
    SCRAMBLE_IN(co->co_firstlineno);
2595
30.7k
    SCRAMBLE_IN(Py_SIZE(co));
2596
1.35M
    for (int i = 0; i < Py_SIZE(co); i++) {
2597
1.32M
        _Py_CODEUNIT co_instr = _Py_GetBaseCodeUnit(co, i);
2598
1.32M
        SCRAMBLE_IN(co_instr.op.code);
2599
1.32M
        SCRAMBLE_IN(co_instr.op.arg);
2600
1.32M
        i += _PyOpcode_Caches[co_instr.op.code];
2601
1.32M
    }
2602
30.7k
    if ((Py_hash_t)uhash == -1) {
2603
0
        return -2;
2604
0
    }
2605
30.7k
    return (Py_hash_t)uhash;
2606
30.7k
}
2607
2608
2609
#define OFF(x) offsetof(PyCodeObject, x)
2610
2611
static PyMemberDef code_memberlist[] = {
2612
    {"co_argcount",        Py_T_INT,     OFF(co_argcount),        Py_READONLY},
2613
    {"co_posonlyargcount", Py_T_INT,     OFF(co_posonlyargcount), Py_READONLY},
2614
    {"co_kwonlyargcount",  Py_T_INT,     OFF(co_kwonlyargcount),  Py_READONLY},
2615
    {"co_stacksize",       Py_T_INT,     OFF(co_stacksize),       Py_READONLY},
2616
    {"co_flags",           Py_T_INT,     OFF(co_flags),           Py_READONLY},
2617
    {"co_nlocals",         Py_T_INT,     OFF(co_nlocals),         Py_READONLY},
2618
    {"co_consts",          _Py_T_OBJECT, OFF(co_consts),          Py_READONLY},
2619
    {"co_names",           _Py_T_OBJECT, OFF(co_names),           Py_READONLY},
2620
    {"co_filename",        _Py_T_OBJECT, OFF(co_filename),        Py_READONLY},
2621
    {"co_name",            _Py_T_OBJECT, OFF(co_name),            Py_READONLY},
2622
    {"co_qualname",        _Py_T_OBJECT, OFF(co_qualname),        Py_READONLY},
2623
    {"co_firstlineno",     Py_T_INT,     OFF(co_firstlineno),     Py_READONLY},
2624
    {"co_linetable",       _Py_T_OBJECT, OFF(co_linetable),       Py_READONLY},
2625
    {"co_exceptiontable",  _Py_T_OBJECT, OFF(co_exceptiontable),  Py_READONLY},
2626
    {NULL}      /* Sentinel */
2627
};
2628
2629
2630
static PyObject *
2631
code_getlnotab(PyObject *self, void *closure)
2632
0
{
2633
0
    PyCodeObject *code = _PyCodeObject_CAST(self);
2634
0
    if (PyErr_WarnEx(PyExc_DeprecationWarning,
2635
0
                     "co_lnotab is deprecated, use co_lines instead.",
2636
0
                     1) < 0) {
2637
0
        return NULL;
2638
0
    }
2639
0
    return decode_linetable(code);
2640
0
}
2641
2642
static PyObject *
2643
code_getvarnames(PyObject *self, void *closure)
2644
8
{
2645
8
    PyCodeObject *code = _PyCodeObject_CAST(self);
2646
8
    return _PyCode_GetVarnames(code);
2647
8
}
2648
2649
static PyObject *
2650
code_getcellvars(PyObject *self, void *closure)
2651
0
{
2652
0
    PyCodeObject *code = _PyCodeObject_CAST(self);
2653
0
    return _PyCode_GetCellvars(code);
2654
0
}
2655
2656
static PyObject *
2657
code_getfreevars(PyObject *self, void *closure)
2658
0
{
2659
0
    PyCodeObject *code = _PyCodeObject_CAST(self);
2660
0
    return _PyCode_GetFreevars(code);
2661
0
}
2662
2663
static PyObject *
2664
code_getcodeadaptive(PyObject *self, void *closure)
2665
0
{
2666
0
    PyCodeObject *code = _PyCodeObject_CAST(self);
2667
0
    return PyBytes_FromStringAndSize(code->co_code_adaptive,
2668
0
                                     _PyCode_NBYTES(code));
2669
0
}
2670
2671
static PyObject *
2672
code_getcode(PyObject *self, void *closure)
2673
0
{
2674
0
    PyCodeObject *code = _PyCodeObject_CAST(self);
2675
0
    return _PyCode_GetCode(code);
2676
0
}
2677
2678
static PyGetSetDef code_getsetlist[] = {
2679
    {"co_lnotab",         code_getlnotab,       NULL, NULL},
2680
    {"_co_code_adaptive", code_getcodeadaptive, NULL, NULL},
2681
    // The following old names are kept for backward compatibility.
2682
    {"co_varnames",       code_getvarnames,     NULL, NULL},
2683
    {"co_cellvars",       code_getcellvars,     NULL, NULL},
2684
    {"co_freevars",       code_getfreevars,     NULL, NULL},
2685
    {"co_code",           code_getcode,         NULL, NULL},
2686
    {0}
2687
};
2688
2689
2690
static PyObject *
2691
code_sizeof(PyObject *self, PyObject *Py_UNUSED(args))
2692
0
{
2693
0
    PyCodeObject *co = _PyCodeObject_CAST(self);
2694
0
    size_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co));
2695
0
    _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra;
2696
0
    if (co_extra != NULL) {
2697
0
        res += sizeof(_PyCodeObjectExtra);
2698
0
        res += ((size_t)co_extra->ce_size - 1) * sizeof(co_extra->ce_extras[0]);
2699
0
    }
2700
0
    return PyLong_FromSize_t(res);
2701
0
}
2702
2703
static PyObject *
2704
code_linesiterator(PyObject *self, PyObject *Py_UNUSED(args))
2705
0
{
2706
0
    PyCodeObject *code = _PyCodeObject_CAST(self);
2707
0
    return (PyObject *)new_linesiterator(code);
2708
0
}
2709
2710
static PyObject *
2711
code_branchesiterator(PyObject *self, PyObject *Py_UNUSED(args))
2712
0
{
2713
0
    PyCodeObject *code = _PyCodeObject_CAST(self);
2714
0
    return _PyInstrumentation_BranchesIterator(code);
2715
0
}
2716
2717
/*[clinic input]
2718
@permit_long_summary
2719
@text_signature "($self, /, **changes)"
2720
code.replace
2721
2722
    *
2723
    co_argcount: int(c_default="((PyCodeObject *)self)->co_argcount") = unchanged
2724
    co_posonlyargcount: int(c_default="((PyCodeObject *)self)->co_posonlyargcount") = unchanged
2725
    co_kwonlyargcount: int(c_default="((PyCodeObject *)self)->co_kwonlyargcount") = unchanged
2726
    co_nlocals: int(c_default="((PyCodeObject *)self)->co_nlocals") = unchanged
2727
    co_stacksize: int(c_default="((PyCodeObject *)self)->co_stacksize") = unchanged
2728
    co_flags: int(c_default="((PyCodeObject *)self)->co_flags") = unchanged
2729
    co_firstlineno: int(c_default="((PyCodeObject *)self)->co_firstlineno") = unchanged
2730
    co_code: object(subclass_of="&PyBytes_Type", c_default="NULL") = unchanged
2731
    co_consts: object(subclass_of="&PyTuple_Type", c_default="((PyCodeObject *)self)->co_consts") = unchanged
2732
    co_names: object(subclass_of="&PyTuple_Type", c_default="((PyCodeObject *)self)->co_names") = unchanged
2733
    co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
2734
    co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
2735
    co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
2736
    co_filename: unicode(c_default="((PyCodeObject *)self)->co_filename") = unchanged
2737
    co_name: unicode(c_default="((PyCodeObject *)self)->co_name") = unchanged
2738
    co_qualname: unicode(c_default="((PyCodeObject *)self)->co_qualname") = unchanged
2739
    co_linetable: object(subclass_of="&PyBytes_Type", c_default="((PyCodeObject *)self)->co_linetable") = unchanged
2740
    co_exceptiontable: object(subclass_of="&PyBytes_Type", c_default="((PyCodeObject *)self)->co_exceptiontable") = unchanged
2741
2742
Return a copy of the code object with new values for the specified fields.
2743
[clinic start generated code]*/
2744
2745
static PyObject *
2746
code_replace_impl(PyCodeObject *self, int co_argcount,
2747
                  int co_posonlyargcount, int co_kwonlyargcount,
2748
                  int co_nlocals, int co_stacksize, int co_flags,
2749
                  int co_firstlineno, PyObject *co_code, PyObject *co_consts,
2750
                  PyObject *co_names, PyObject *co_varnames,
2751
                  PyObject *co_freevars, PyObject *co_cellvars,
2752
                  PyObject *co_filename, PyObject *co_name,
2753
                  PyObject *co_qualname, PyObject *co_linetable,
2754
                  PyObject *co_exceptiontable)
2755
/*[clinic end generated code: output=e75c48a15def18b9 input=e944fdac8b456114]*/
2756
0
{
2757
0
#define CHECK_INT_ARG(ARG) \
2758
0
        if (ARG < 0) { \
2759
0
            PyErr_SetString(PyExc_ValueError, \
2760
0
                            #ARG " must be a positive integer"); \
2761
0
            return NULL; \
2762
0
        }
2763
2764
0
    CHECK_INT_ARG(co_argcount);
2765
0
    CHECK_INT_ARG(co_posonlyargcount);
2766
0
    CHECK_INT_ARG(co_kwonlyargcount);
2767
0
    CHECK_INT_ARG(co_nlocals);
2768
0
    CHECK_INT_ARG(co_stacksize);
2769
0
    CHECK_INT_ARG(co_flags);
2770
0
    CHECK_INT_ARG(co_firstlineno);
2771
2772
0
#undef CHECK_INT_ARG
2773
2774
0
    PyObject *code = NULL;
2775
0
    if (co_code == NULL) {
2776
0
        code = _PyCode_GetCode(self);
2777
0
        if (code == NULL) {
2778
0
            return NULL;
2779
0
        }
2780
0
        co_code = code;
2781
0
    }
2782
2783
0
    if (PySys_Audit("code.__new__", "OOOiiiiii",
2784
0
                    co_code, co_filename, co_name, co_argcount,
2785
0
                    co_posonlyargcount, co_kwonlyargcount, co_nlocals,
2786
0
                    co_stacksize, co_flags) < 0) {
2787
0
        Py_XDECREF(code);
2788
0
        return NULL;
2789
0
    }
2790
2791
0
    PyCodeObject *co = NULL;
2792
0
    PyObject *varnames = NULL;
2793
0
    PyObject *cellvars = NULL;
2794
0
    PyObject *freevars = NULL;
2795
0
    if (co_varnames == NULL) {
2796
0
        varnames = get_localsplus_names(self, CO_FAST_LOCAL, self->co_nlocals);
2797
0
        if (varnames == NULL) {
2798
0
            goto error;
2799
0
        }
2800
0
        co_varnames = varnames;
2801
0
    }
2802
0
    if (co_cellvars == NULL) {
2803
0
        cellvars = get_localsplus_names(self, CO_FAST_CELL, self->co_ncellvars);
2804
0
        if (cellvars == NULL) {
2805
0
            goto error;
2806
0
        }
2807
0
        co_cellvars = cellvars;
2808
0
    }
2809
0
    if (co_freevars == NULL) {
2810
0
        freevars = get_localsplus_names(self, CO_FAST_FREE, self->co_nfreevars);
2811
0
        if (freevars == NULL) {
2812
0
            goto error;
2813
0
        }
2814
0
        co_freevars = freevars;
2815
0
    }
2816
2817
0
    co = PyCode_NewWithPosOnlyArgs(
2818
0
        co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
2819
0
        co_stacksize, co_flags, co_code, co_consts, co_names,
2820
0
        co_varnames, co_freevars, co_cellvars, co_filename, co_name,
2821
0
        co_qualname, co_firstlineno,
2822
0
        co_linetable, co_exceptiontable);
2823
2824
0
error:
2825
0
    Py_XDECREF(code);
2826
0
    Py_XDECREF(varnames);
2827
0
    Py_XDECREF(cellvars);
2828
0
    Py_XDECREF(freevars);
2829
0
    return (PyObject *)co;
2830
0
}
2831
2832
/*[clinic input]
2833
code._varname_from_oparg
2834
2835
    oparg: int
2836
2837
(internal-only) Return the local variable name for the given oparg.
2838
2839
WARNING: this method is for internal use only and may change or go away.
2840
[clinic start generated code]*/
2841
2842
static PyObject *
2843
code__varname_from_oparg_impl(PyCodeObject *self, int oparg)
2844
/*[clinic end generated code: output=1fd1130413184206 input=c5fa3ee9bac7d4ca]*/
2845
0
{
2846
0
    PyObject *name = PyTuple_GetItem(self->co_localsplusnames, oparg);
2847
0
    if (name == NULL) {
2848
0
        return NULL;
2849
0
    }
2850
0
    return Py_NewRef(name);
2851
0
}
2852
2853
/* XXX code objects need to participate in GC? */
2854
2855
static struct PyMethodDef code_methods[] = {
2856
    {"__sizeof__", code_sizeof, METH_NOARGS},
2857
    {"co_lines", code_linesiterator, METH_NOARGS},
2858
    {"co_branches", code_branchesiterator, METH_NOARGS},
2859
    {"co_positions", code_positionsiterator, METH_NOARGS},
2860
    CODE_REPLACE_METHODDEF
2861
    CODE__VARNAME_FROM_OPARG_METHODDEF
2862
    {"__replace__", _PyCFunction_CAST(code_replace), METH_FASTCALL|METH_KEYWORDS,
2863
     PyDoc_STR("__replace__($self, /, **changes)\n--\n\nThe same as replace().")},
2864
    {NULL, NULL}                /* sentinel */
2865
};
2866
2867
2868
PyTypeObject PyCode_Type = {
2869
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
2870
    "code",
2871
    offsetof(PyCodeObject, co_code_adaptive),
2872
    sizeof(_Py_CODEUNIT),
2873
    code_dealloc,                       /* tp_dealloc */
2874
    0,                                  /* tp_vectorcall_offset */
2875
    0,                                  /* tp_getattr */
2876
    0,                                  /* tp_setattr */
2877
    0,                                  /* tp_as_async */
2878
    code_repr,                          /* tp_repr */
2879
    0,                                  /* tp_as_number */
2880
    0,                                  /* tp_as_sequence */
2881
    0,                                  /* tp_as_mapping */
2882
    code_hash,                          /* tp_hash */
2883
    0,                                  /* tp_call */
2884
    0,                                  /* tp_str */
2885
    PyObject_GenericGetAttr,            /* tp_getattro */
2886
    0,                                  /* tp_setattro */
2887
    0,                                  /* tp_as_buffer */
2888
#ifdef Py_GIL_DISABLED
2889
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2890
#else
2891
    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
2892
#endif
2893
    code_new__doc__,                    /* tp_doc */
2894
#ifdef Py_GIL_DISABLED
2895
    code_traverse,                      /* tp_traverse */
2896
#else
2897
    0,                                  /* tp_traverse */
2898
#endif
2899
    0,                                  /* tp_clear */
2900
    code_richcompare,                   /* tp_richcompare */
2901
    offsetof(PyCodeObject, co_weakreflist),     /* tp_weaklistoffset */
2902
    0,                                  /* tp_iter */
2903
    0,                                  /* tp_iternext */
2904
    code_methods,                       /* tp_methods */
2905
    code_memberlist,                    /* tp_members */
2906
    code_getsetlist,                    /* tp_getset */
2907
    0,                                  /* tp_base */
2908
    0,                                  /* tp_dict */
2909
    0,                                  /* tp_descr_get */
2910
    0,                                  /* tp_descr_set */
2911
    0,                                  /* tp_dictoffset */
2912
    0,                                  /* tp_init */
2913
    0,                                  /* tp_alloc */
2914
    code_new,                           /* tp_new */
2915
};
2916
2917
2918
/******************
2919
 * other API
2920
 ******************/
2921
2922
PyObject*
2923
_PyCode_ConstantKey(PyObject *op)
2924
220k
{
2925
220k
    PyObject *key;
2926
2927
    /* Py_None and Py_Ellipsis are singletons. */
2928
220k
    if (op == Py_None || op == Py_Ellipsis
2929
220k
       || PyLong_CheckExact(op)
2930
220k
       || PyUnicode_CheckExact(op)
2931
          /* code_richcompare() uses _PyCode_ConstantKey() internally */
2932
220k
       || PyCode_Check(op))
2933
169k
    {
2934
        /* Objects of these types are always different from object of other
2935
         * type and from tuples. */
2936
169k
        key = Py_NewRef(op);
2937
169k
    }
2938
51.5k
    else if (PyBool_Check(op) || PyBytes_CheckExact(op)) {
2939
        /* Make booleans different from integers 0 and 1.
2940
         * Avoid BytesWarning from comparing bytes with strings. */
2941
23.6k
        key = PyTuple_Pack(2, Py_TYPE(op), op);
2942
23.6k
    }
2943
27.9k
    else if (PyFloat_CheckExact(op)) {
2944
267
        double d = PyFloat_AS_DOUBLE(op);
2945
        /* all we need is to make the tuple different in either the 0.0
2946
         * or -0.0 case from all others, just to avoid the "coercion".
2947
         */
2948
267
        if (d == 0.0 && copysign(1.0, d) < 0.0)
2949
0
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2950
267
        else
2951
267
            key = PyTuple_Pack(2, Py_TYPE(op), op);
2952
267
    }
2953
27.6k
    else if (PyComplex_CheckExact(op)) {
2954
0
        Py_complex z;
2955
0
        int real_negzero, imag_negzero;
2956
        /* For the complex case we must make complex(x, 0.)
2957
           different from complex(x, -0.) and complex(0., y)
2958
           different from complex(-0., y), for any x and y.
2959
           All four complex zeros must be distinguished.*/
2960
0
        z = PyComplex_AsCComplex(op);
2961
0
        real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
2962
0
        imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
2963
        /* use True, False and None singleton as tags for the real and imag
2964
         * sign, to make tuples different */
2965
0
        if (real_negzero && imag_negzero) {
2966
0
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
2967
0
        }
2968
0
        else if (imag_negzero) {
2969
0
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
2970
0
        }
2971
0
        else if (real_negzero) {
2972
0
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2973
0
        }
2974
0
        else {
2975
0
            key = PyTuple_Pack(2, Py_TYPE(op), op);
2976
0
        }
2977
0
    }
2978
27.6k
    else if (PyTuple_CheckExact(op)) {
2979
26.9k
        Py_ssize_t i, len;
2980
26.9k
        PyObject *tuple;
2981
2982
26.9k
        len = PyTuple_GET_SIZE(op);
2983
26.9k
        tuple = PyTuple_New(len);
2984
26.9k
        if (tuple == NULL)
2985
0
            return NULL;
2986
2987
141k
        for (i=0; i < len; i++) {
2988
114k
            PyObject *item, *item_key;
2989
2990
114k
            item = PyTuple_GET_ITEM(op, i);
2991
114k
            item_key = _PyCode_ConstantKey(item);
2992
114k
            if (item_key == NULL) {
2993
0
                Py_DECREF(tuple);
2994
0
                return NULL;
2995
0
            }
2996
2997
114k
            PyTuple_SET_ITEM(tuple, i, item_key);
2998
114k
        }
2999
3000
26.9k
        key = PyTuple_Pack(2, tuple, op);
3001
26.9k
        Py_DECREF(tuple);
3002
26.9k
    }
3003
731
    else if (PyFrozenSet_CheckExact(op)) {
3004
106
        Py_ssize_t pos = 0;
3005
106
        PyObject *item;
3006
106
        Py_hash_t hash;
3007
106
        Py_ssize_t i, len;
3008
106
        PyObject *tuple, *set;
3009
3010
106
        len = PySet_GET_SIZE(op);
3011
106
        tuple = PyTuple_New(len);
3012
106
        if (tuple == NULL)
3013
0
            return NULL;
3014
3015
106
        i = 0;
3016
672
        while (_PySet_NextEntry(op, &pos, &item, &hash)) {
3017
566
            PyObject *item_key;
3018
3019
566
            item_key = _PyCode_ConstantKey(item);
3020
566
            if (item_key == NULL) {
3021
0
                Py_DECREF(tuple);
3022
0
                return NULL;
3023
0
            }
3024
3025
566
            assert(i < len);
3026
566
            PyTuple_SET_ITEM(tuple, i, item_key);
3027
566
            i++;
3028
566
        }
3029
106
        set = PyFrozenSet_New(tuple);
3030
106
        Py_DECREF(tuple);
3031
106
        if (set == NULL)
3032
0
            return NULL;
3033
3034
106
        key = PyTuple_Pack(2, set, op);
3035
106
        Py_DECREF(set);
3036
106
        return key;
3037
106
    }
3038
625
    else if (PySlice_Check(op)) {
3039
625
        PySliceObject *slice = (PySliceObject *)op;
3040
625
        PyObject *start_key = NULL;
3041
625
        PyObject *stop_key = NULL;
3042
625
        PyObject *step_key = NULL;
3043
625
        key = NULL;
3044
3045
625
        start_key = _PyCode_ConstantKey(slice->start);
3046
625
        if (start_key == NULL) {
3047
0
            goto slice_exit;
3048
0
        }
3049
3050
625
        stop_key = _PyCode_ConstantKey(slice->stop);
3051
625
        if (stop_key == NULL) {
3052
0
            goto slice_exit;
3053
0
        }
3054
3055
625
        step_key = _PyCode_ConstantKey(slice->step);
3056
625
        if (step_key == NULL) {
3057
0
            goto slice_exit;
3058
0
        }
3059
3060
625
        PyObject *slice_key = PySlice_New(start_key, stop_key, step_key);
3061
625
        if (slice_key == NULL) {
3062
0
            goto slice_exit;
3063
0
        }
3064
3065
625
        key = PyTuple_Pack(2, slice_key, op);
3066
625
        Py_DECREF(slice_key);
3067
625
    slice_exit:
3068
625
        Py_XDECREF(start_key);
3069
625
        Py_XDECREF(stop_key);
3070
625
        Py_XDECREF(step_key);
3071
625
    }
3072
0
    else {
3073
        /* for other types, use the object identifier as a unique identifier
3074
         * to ensure that they are seen as unequal. */
3075
0
        PyObject *obj_id = PyLong_FromVoidPtr(op);
3076
0
        if (obj_id == NULL)
3077
0
            return NULL;
3078
3079
0
        key = PyTuple_Pack(2, obj_id, op);
3080
0
        Py_DECREF(obj_id);
3081
0
    }
3082
220k
    return key;
3083
220k
}
3084
3085
#ifdef Py_GIL_DISABLED
3086
static PyObject *
3087
intern_one_constant(PyObject *op)
3088
{
3089
    PyInterpreterState *interp = _PyInterpreterState_GET();
3090
    _Py_hashtable_t *consts = interp->code_state.constants;
3091
3092
    assert(!PyUnicode_CheckExact(op));  // strings are interned separately
3093
3094
    _Py_hashtable_entry_t *entry = _Py_hashtable_get_entry(consts, op);
3095
    if (entry == NULL) {
3096
        if (_Py_hashtable_set(consts, op, op) != 0) {
3097
            PyErr_NoMemory();
3098
            return NULL;
3099
        }
3100
3101
#ifdef Py_REF_DEBUG
3102
        Py_ssize_t refcnt = Py_REFCNT(op);
3103
        if (refcnt != 1) {
3104
            // Adjust the reftotal to account for the fact that we only
3105
            // restore a single reference in _PyCode_Fini.
3106
            _Py_AddRefTotal(_PyThreadState_GET(), -(refcnt - 1));
3107
        }
3108
#endif
3109
3110
        _Py_SetImmortal(op);
3111
        return op;
3112
    }
3113
3114
    assert(_Py_IsImmortal(entry->value));
3115
    return (PyObject *)entry->value;
3116
}
3117
3118
static int
3119
compare_constants(const void *key1, const void *key2)
3120
{
3121
    PyObject *op1 = (PyObject *)key1;
3122
    PyObject *op2 = (PyObject *)key2;
3123
    if (op1 == op2) {
3124
        return 1;
3125
    }
3126
    if (Py_TYPE(op1) != Py_TYPE(op2)) {
3127
        return 0;
3128
    }
3129
    // We compare container contents by identity because we have already
3130
    // internalized the items.
3131
    if (PyTuple_CheckExact(op1)) {
3132
        Py_ssize_t size = PyTuple_GET_SIZE(op1);
3133
        if (size != PyTuple_GET_SIZE(op2)) {
3134
            return 0;
3135
        }
3136
        for (Py_ssize_t i = 0; i < size; i++) {
3137
            if (PyTuple_GET_ITEM(op1, i) != PyTuple_GET_ITEM(op2, i)) {
3138
                return 0;
3139
            }
3140
        }
3141
        return 1;
3142
    }
3143
    else if (PyFrozenSet_CheckExact(op1)) {
3144
        if (PySet_GET_SIZE(op1) != PySet_GET_SIZE(op2)) {
3145
            return 0;
3146
        }
3147
        Py_ssize_t pos1 = 0, pos2 = 0;
3148
        PyObject *obj1, *obj2;
3149
        Py_hash_t hash1, hash2;
3150
        while ((_PySet_NextEntry(op1, &pos1, &obj1, &hash1)) &&
3151
               (_PySet_NextEntry(op2, &pos2, &obj2, &hash2)))
3152
        {
3153
            if (obj1 != obj2) {
3154
                return 0;
3155
            }
3156
        }
3157
        return 1;
3158
    }
3159
    else if (PySlice_Check(op1)) {
3160
        PySliceObject *s1 = (PySliceObject *)op1;
3161
        PySliceObject *s2 = (PySliceObject *)op2;
3162
        return (s1->start == s2->start &&
3163
                s1->stop  == s2->stop  &&
3164
                s1->step  == s2->step);
3165
    }
3166
    else if (PyBytes_CheckExact(op1) || PyLong_CheckExact(op1)) {
3167
        return PyObject_RichCompareBool(op1, op2, Py_EQ);
3168
    }
3169
    else if (PyFloat_CheckExact(op1)) {
3170
        // Ensure that, for example, +0.0 and -0.0 are distinct
3171
        double f1 = PyFloat_AS_DOUBLE(op1);
3172
        double f2 = PyFloat_AS_DOUBLE(op2);
3173
        return memcmp(&f1, &f2, sizeof(double)) == 0;
3174
    }
3175
    else if (PyComplex_CheckExact(op1)) {
3176
        Py_complex c1 = ((PyComplexObject *)op1)->cval;
3177
        Py_complex c2 = ((PyComplexObject *)op2)->cval;
3178
        return memcmp(&c1, &c2, sizeof(Py_complex)) == 0;
3179
    }
3180
    // gh-130851: Treat instances of unexpected types as distinct if they are
3181
    // not the same object.
3182
    return 0;
3183
}
3184
3185
static Py_uhash_t
3186
hash_const(const void *key)
3187
{
3188
    PyObject *op = (PyObject *)key;
3189
    if (PySlice_Check(op)) {
3190
        PySliceObject *s = (PySliceObject *)op;
3191
        PyObject *data[3] = { s->start, s->stop, s->step };
3192
        return Py_HashBuffer(&data, sizeof(data));
3193
    }
3194
    else if (PyTuple_CheckExact(op)) {
3195
        Py_ssize_t size = PyTuple_GET_SIZE(op);
3196
        PyObject **data = _PyTuple_ITEMS(op);
3197
        return Py_HashBuffer(data, sizeof(PyObject *) * size);
3198
    }
3199
    Py_hash_t h = PyObject_Hash(op);
3200
    if (h == -1) {
3201
        // gh-130851: Other than slice objects, every constant that the
3202
        // bytecode compiler generates is hashable. However, users can
3203
        // provide their own constants, when constructing code objects via
3204
        // types.CodeType(). If the user-provided constant is unhashable, we
3205
        // use the memory address of the object as a fallback hash value.
3206
        PyErr_Clear();
3207
        return (Py_uhash_t)(uintptr_t)key;
3208
    }
3209
    return (Py_uhash_t)h;
3210
}
3211
3212
static int
3213
clear_containers(_Py_hashtable_t *ht, const void *key, const void *value,
3214
                 void *user_data)
3215
{
3216
    // First clear containers to avoid recursive deallocation later on in
3217
    // destroy_key.
3218
    PyObject *op = (PyObject *)key;
3219
    if (PyTuple_CheckExact(op)) {
3220
        for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(op); i++) {
3221
            Py_CLEAR(_PyTuple_ITEMS(op)[i]);
3222
        }
3223
    }
3224
    else if (PySlice_Check(op)) {
3225
        PySliceObject *slice = (PySliceObject *)op;
3226
        Py_SETREF(slice->start, Py_None);
3227
        Py_SETREF(slice->stop, Py_None);
3228
        Py_SETREF(slice->step, Py_None);
3229
    }
3230
    else if (PyFrozenSet_CheckExact(op)) {
3231
        _PySet_ClearInternal((PySetObject *)op);
3232
    }
3233
    return 0;
3234
}
3235
3236
static void
3237
destroy_key(void *key)
3238
{
3239
    _Py_ClearImmortal(key);
3240
}
3241
#endif
3242
3243
PyStatus
3244
_PyCode_Init(PyInterpreterState *interp)
3245
16
{
3246
#ifdef Py_GIL_DISABLED
3247
    struct _py_code_state *state = &interp->code_state;
3248
    state->constants = _Py_hashtable_new_full(&hash_const, &compare_constants,
3249
                                              &destroy_key, NULL, NULL);
3250
    if (state->constants == NULL) {
3251
        return _PyStatus_NO_MEMORY();
3252
    }
3253
#endif
3254
16
    return _PyStatus_OK();
3255
16
}
3256
3257
void
3258
_PyCode_Fini(PyInterpreterState *interp)
3259
0
{
3260
#ifdef Py_GIL_DISABLED
3261
    // Free interned constants
3262
    struct _py_code_state *state = &interp->code_state;
3263
    if (state->constants) {
3264
        _Py_hashtable_foreach(state->constants, &clear_containers, NULL);
3265
        _Py_hashtable_destroy(state->constants);
3266
        state->constants = NULL;
3267
    }
3268
    _PyIndexPool_Fini(&interp->tlbc_indices);
3269
#endif
3270
0
}
3271
3272
#ifdef Py_GIL_DISABLED
3273
3274
// Thread-local bytecode (TLBC)
3275
//
3276
// Each thread specializes a thread-local copy of the bytecode, created on the
3277
// first RESUME, in free-threaded builds. All copies of the bytecode for a code
3278
// object are stored in the `co_tlbc` array. Threads reserve a globally unique
3279
// index identifying its copy of the bytecode in all `co_tlbc` arrays at thread
3280
// creation and release the index at thread destruction. The first entry in
3281
// every `co_tlbc` array always points to the "main" copy of the bytecode that
3282
// is stored at the end of the code object. This ensures that no bytecode is
3283
// copied for programs that do not use threads.
3284
//
3285
// Thread-local bytecode can be disabled at runtime by providing either `-X
3286
// tlbc=0` or `PYTHON_TLBC=0`. Disabling thread-local bytecode also disables
3287
// specialization. All threads share the main copy of the bytecode when
3288
// thread-local bytecode is disabled.
3289
//
3290
// Concurrent modifications to the bytecode made by the specializing
3291
// interpreter and instrumentation use atomics, with specialization taking care
3292
// not to overwrite an instruction that was instrumented concurrently.
3293
3294
int32_t
3295
_Py_ReserveTLBCIndex(PyInterpreterState *interp)
3296
{
3297
    if (interp->config.tlbc_enabled) {
3298
        return _PyIndexPool_AllocIndex(&interp->tlbc_indices);
3299
    }
3300
    // All threads share the main copy of the bytecode when TLBC is disabled
3301
    return 0;
3302
}
3303
3304
void
3305
_Py_ClearTLBCIndex(_PyThreadStateImpl *tstate)
3306
{
3307
    PyInterpreterState *interp = ((PyThreadState *)tstate)->interp;
3308
    if (interp->config.tlbc_enabled) {
3309
        _PyIndexPool_FreeIndex(&interp->tlbc_indices, tstate->tlbc_index);
3310
    }
3311
}
3312
3313
static _PyCodeArray *
3314
_PyCodeArray_New(Py_ssize_t size)
3315
{
3316
    _PyCodeArray *arr = PyMem_Calloc(
3317
        1, offsetof(_PyCodeArray, entries) + sizeof(void *) * size);
3318
    if (arr == NULL) {
3319
        PyErr_NoMemory();
3320
        return NULL;
3321
    }
3322
    arr->size = size;
3323
    return arr;
3324
}
3325
3326
// Get the underlying code unit, leaving instrumentation
3327
static _Py_CODEUNIT
3328
deopt_code_unit(PyCodeObject *code, int i)
3329
{
3330
    _Py_CODEUNIT *src_instr = _PyCode_CODE(code) + i;
3331
    _Py_CODEUNIT inst = {
3332
        .cache = FT_ATOMIC_LOAD_UINT16_RELAXED(*(uint16_t *)src_instr)};
3333
    int opcode = inst.op.code;
3334
    if (opcode < MIN_INSTRUMENTED_OPCODE) {
3335
        inst.op.code = _PyOpcode_Deopt[opcode];
3336
        assert(inst.op.code < MIN_SPECIALIZED_OPCODE);
3337
    }
3338
    // JIT should not be enabled with free-threading
3339
    assert(inst.op.code != ENTER_EXECUTOR);
3340
    return inst;
3341
}
3342
3343
static void
3344
copy_code(_Py_CODEUNIT *dst, PyCodeObject *co)
3345
{
3346
    int code_len = (int) Py_SIZE(co);
3347
    for (int i = 0; i < code_len; i += _PyInstruction_GetLength(co, i)) {
3348
        dst[i] = deopt_code_unit(co, i);
3349
    }
3350
    _PyCode_Quicken(dst, code_len, 1);
3351
}
3352
3353
static Py_ssize_t
3354
get_pow2_greater(Py_ssize_t initial, Py_ssize_t limit)
3355
{
3356
    // initial must be a power of two
3357
    assert(!(initial & (initial - 1)));
3358
    Py_ssize_t res = initial;
3359
    while (res && res < limit) {
3360
        res <<= 1;
3361
    }
3362
    return res;
3363
}
3364
3365
static _Py_CODEUNIT *
3366
create_tlbc_lock_held(PyCodeObject *co, Py_ssize_t idx)
3367
{
3368
    _PyCodeArray *tlbc = co->co_tlbc;
3369
    if (idx >= tlbc->size) {
3370
        Py_ssize_t new_size = get_pow2_greater(tlbc->size, idx + 1);
3371
        if (!new_size) {
3372
            PyErr_NoMemory();
3373
            return NULL;
3374
        }
3375
        _PyCodeArray *new_tlbc = _PyCodeArray_New(new_size);
3376
        if (new_tlbc == NULL) {
3377
            return NULL;
3378
        }
3379
        memcpy(new_tlbc->entries, tlbc->entries, tlbc->size * sizeof(void *));
3380
        _Py_atomic_store_ptr_release(&co->co_tlbc, new_tlbc);
3381
        _PyMem_FreeDelayed(tlbc, tlbc->size * sizeof(void *));
3382
        tlbc = new_tlbc;
3383
    }
3384
    char *bc = PyMem_Calloc(1, _PyCode_NBYTES(co));
3385
    if (bc == NULL) {
3386
        PyErr_NoMemory();
3387
        return NULL;
3388
    }
3389
    copy_code((_Py_CODEUNIT *) bc, co);
3390
    assert(tlbc->entries[idx] == NULL);
3391
    tlbc->entries[idx] = bc;
3392
    return (_Py_CODEUNIT *) bc;
3393
}
3394
3395
static _Py_CODEUNIT *
3396
get_tlbc_lock_held(PyCodeObject *co)
3397
{
3398
    _PyCodeArray *tlbc = co->co_tlbc;
3399
    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)PyThreadState_GET();
3400
    int32_t idx = tstate->tlbc_index;
3401
    if (idx < tlbc->size && tlbc->entries[idx] != NULL) {
3402
        return (_Py_CODEUNIT *)tlbc->entries[idx];
3403
    }
3404
    return create_tlbc_lock_held(co, idx);
3405
}
3406
3407
_Py_CODEUNIT *
3408
_PyCode_GetTLBC(PyCodeObject *co)
3409
{
3410
    _Py_CODEUNIT *result;
3411
    Py_BEGIN_CRITICAL_SECTION(co);
3412
    result = get_tlbc_lock_held(co);
3413
    Py_END_CRITICAL_SECTION();
3414
    return result;
3415
}
3416
3417
// My kingdom for a bitset
3418
struct flag_set {
3419
    uint8_t *flags;
3420
    Py_ssize_t size;
3421
};
3422
3423
static inline int
3424
flag_is_set(struct flag_set *flags, Py_ssize_t idx)
3425
{
3426
    assert(idx >= 0);
3427
    return (idx < flags->size) && flags->flags[idx];
3428
}
3429
3430
// Set the flag for each tlbc index in use
3431
static int
3432
get_indices_in_use(PyInterpreterState *interp, struct flag_set *in_use)
3433
{
3434
    assert(interp->stoptheworld.world_stopped);
3435
    assert(in_use->flags == NULL);
3436
    int32_t max_index = 0;
3437
    _Py_FOR_EACH_TSTATE_BEGIN(interp, p) {
3438
        int32_t idx = ((_PyThreadStateImpl *) p)->tlbc_index;
3439
        if (idx > max_index) {
3440
            max_index = idx;
3441
        }
3442
    }
3443
    _Py_FOR_EACH_TSTATE_END(interp);
3444
    in_use->size = (size_t) max_index + 1;
3445
    in_use->flags = PyMem_Calloc(in_use->size, sizeof(*in_use->flags));
3446
    if (in_use->flags == NULL) {
3447
        return -1;
3448
    }
3449
    _Py_FOR_EACH_TSTATE_BEGIN(interp, p) {
3450
        in_use->flags[((_PyThreadStateImpl *) p)->tlbc_index] = 1;
3451
    }
3452
    _Py_FOR_EACH_TSTATE_END(interp);
3453
    return 0;
3454
}
3455
3456
struct get_code_args {
3457
    _PyObjectStack code_objs;
3458
    struct flag_set indices_in_use;
3459
    int err;
3460
};
3461
3462
static void
3463
clear_get_code_args(struct get_code_args *args)
3464
{
3465
    if (args->indices_in_use.flags != NULL) {
3466
        PyMem_Free(args->indices_in_use.flags);
3467
        args->indices_in_use.flags = NULL;
3468
    }
3469
    _PyObjectStack_Clear(&args->code_objs);
3470
}
3471
3472
static inline int
3473
is_bytecode_unused(_PyCodeArray *tlbc, Py_ssize_t idx,
3474
                   struct flag_set *indices_in_use)
3475
{
3476
    assert(idx > 0 && idx < tlbc->size);
3477
    return tlbc->entries[idx] != NULL && !flag_is_set(indices_in_use, idx);
3478
}
3479
3480
static int
3481
get_code_with_unused_tlbc(PyObject *obj, void *data)
3482
{
3483
    struct get_code_args *args = (struct get_code_args *) data;
3484
    if (!PyCode_Check(obj)) {
3485
        return 1;
3486
    }
3487
    PyCodeObject *co = (PyCodeObject *) obj;
3488
    _PyCodeArray *tlbc = co->co_tlbc;
3489
    // The first index always points at the main copy of the bytecode embedded
3490
    // in the code object.
3491
    for (Py_ssize_t i = 1; i < tlbc->size; i++) {
3492
        if (is_bytecode_unused(tlbc, i, &args->indices_in_use)) {
3493
            if (_PyObjectStack_Push(&args->code_objs, obj) < 0) {
3494
                args->err = -1;
3495
                return 0;
3496
            }
3497
            return 1;
3498
        }
3499
    }
3500
    return 1;
3501
}
3502
3503
static void
3504
free_unused_bytecode(PyCodeObject *co, struct flag_set *indices_in_use)
3505
{
3506
    _PyCodeArray *tlbc = co->co_tlbc;
3507
    // The first index always points at the main copy of the bytecode embedded
3508
    // in the code object.
3509
    for (Py_ssize_t i = 1; i < tlbc->size; i++) {
3510
        if (is_bytecode_unused(tlbc, i, indices_in_use)) {
3511
            PyMem_Free(tlbc->entries[i]);
3512
            tlbc->entries[i] = NULL;
3513
        }
3514
    }
3515
}
3516
3517
int
3518
_Py_ClearUnusedTLBC(PyInterpreterState *interp)
3519
{
3520
    struct get_code_args args = {
3521
        .code_objs = {NULL},
3522
        .indices_in_use = {NULL, 0},
3523
        .err = 0,
3524
    };
3525
    _PyEval_StopTheWorld(interp);
3526
    // Collect in-use tlbc indices
3527
    if (get_indices_in_use(interp, &args.indices_in_use) < 0) {
3528
        goto err;
3529
    }
3530
    // Collect code objects that have bytecode not in use by any thread
3531
    _PyGC_VisitObjectsWorldStopped(
3532
        interp, get_code_with_unused_tlbc, &args);
3533
    if (args.err < 0) {
3534
        goto err;
3535
    }
3536
    // Free unused bytecode. This must happen outside of gc_visit_heaps; it is
3537
    // unsafe to allocate or free any mimalloc managed memory when it's
3538
    // running.
3539
    PyObject *obj;
3540
    while ((obj = _PyObjectStack_Pop(&args.code_objs)) != NULL) {
3541
        free_unused_bytecode((PyCodeObject*) obj, &args.indices_in_use);
3542
    }
3543
    _PyEval_StartTheWorld(interp);
3544
    clear_get_code_args(&args);
3545
    return 0;
3546
3547
err:
3548
    _PyEval_StartTheWorld(interp);
3549
    clear_get_code_args(&args);
3550
    PyErr_NoMemory();
3551
    return -1;
3552
}
3553
3554
#endif