Coverage Report

Created: 2026-03-23 06:45

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