Coverage Report

Created: 2025-11-30 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/compile.c
Line
Count
Source
1
/*
2
 * This file compiles an abstract syntax tree (AST) into Python bytecode.
3
 *
4
 * The primary entry point is _PyAST_Compile(), which returns a
5
 * PyCodeObject.  The compiler makes several passes to build the code
6
 * object:
7
 *   1. Checks for future statements.  See future.c
8
 *   2. Builds a symbol table.  See symtable.c.
9
 *   3. Generate an instruction sequence. See compiler_mod() in this file, which
10
 *      calls functions from codegen.c.
11
 *   4. Generate a control flow graph and run optimizations on it.  See flowgraph.c.
12
 *   5. Assemble the basic blocks into final code.  See optimize_and_assemble() in
13
 *      this file, and assembler.c.
14
 *
15
 */
16
17
#include "Python.h"
18
#include "pycore_ast.h"           // PyAST_Check()
19
#include "pycore_code.h"
20
#include "pycore_compile.h"
21
#include "pycore_flowgraph.h"     // _PyCfg_FromInstructionSequence()
22
#include "pycore_pystate.h"       // _Py_GetConfig()
23
#include "pycore_runtime.h"       // _Py_ID()
24
#include "pycore_setobject.h"     // _PySet_NextEntry()
25
#include "pycore_stats.h"
26
#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString()
27
28
#include "cpython/code.h"
29
30
#include <stdbool.h>
31
32
33
#undef SUCCESS
34
#undef ERROR
35
230k
#define SUCCESS 0
36
1
#define ERROR -1
37
38
#define RETURN_IF_ERROR(X)  \
39
83.0k
    do {                    \
40
83.0k
        if ((X) == -1) {    \
41
0
            return ERROR;   \
42
0
        }                   \
43
83.0k
    } while (0)
44
45
typedef _Py_SourceLocation location;
46
typedef _PyJumpTargetLabel jump_target_label;
47
typedef _PyInstructionSequence instr_sequence;
48
typedef struct _PyCfgBuilder cfg_builder;
49
typedef _PyCompile_FBlockInfo fblockinfo;
50
typedef enum _PyCompile_FBlockType fblocktype;
51
52
/* The following items change on entry and exit of code blocks.
53
   They must be saved and restored when returning to a block.
54
*/
55
struct compiler_unit {
56
    PySTEntryObject *u_ste;
57
58
    int u_scope_type;
59
60
    PyObject *u_private;            /* for private name mangling */
61
    PyObject *u_static_attributes;  /* for class: attributes accessed via self.X */
62
    PyObject *u_deferred_annotations; /* AnnAssign nodes deferred to the end of compilation */
63
    PyObject *u_conditional_annotation_indices;  /* indices of annotations that are conditionally executed (or -1 for unconditional annotations) */
64
    long u_next_conditional_annotation_index;  /* index of the next conditional annotation */
65
66
    instr_sequence *u_instr_sequence; /* codegen output */
67
    instr_sequence *u_stashed_instr_sequence; /* temporarily stashed parent instruction sequence */
68
69
    int u_nfblocks;
70
    int u_in_inlined_comp;
71
    int u_in_conditional_block;
72
73
    _PyCompile_FBlockInfo u_fblock[CO_MAXBLOCKS];
74
75
    _PyCompile_CodeUnitMetadata u_metadata;
76
};
77
78
/* This struct captures the global state of a compilation.
79
80
The u pointer points to the current compilation unit, while units
81
for enclosing blocks are stored in c_stack.     The u and c_stack are
82
managed by _PyCompile_EnterScope() and _PyCompile_ExitScope().
83
84
Note that we don't track recursion levels during compilation - the
85
task of detecting and rejecting excessive levels of nesting is
86
handled by the symbol analysis pass.
87
88
*/
89
90
typedef struct _PyCompiler {
91
    PyObject *c_filename;
92
    struct symtable *c_st;
93
    _PyFutureFeatures c_future;  /* module's __future__ */
94
    PyCompilerFlags c_flags;
95
96
    int c_optimize;              /* optimization level */
97
    int c_interactive;           /* true if in interactive mode */
98
    PyObject *c_const_cache;     /* Python dict holding all constants,
99
                                    including names tuple */
100
    struct compiler_unit *u;     /* compiler state for current block */
101
    PyObject *c_stack;           /* Python list holding compiler_unit ptrs */
102
103
    bool c_save_nested_seqs;     /* if true, construct recursive instruction sequences
104
                                  * (including instructions for nested code objects)
105
                                  */
106
    int c_disable_warning;
107
    PyObject *c_module;
108
} compiler;
109
110
static int
111
compiler_setup(compiler *c, mod_ty mod, PyObject *filename,
112
               PyCompilerFlags *flags, int optimize, PyArena *arena,
113
               PyObject *module)
114
447
{
115
447
    PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
116
117
447
    c->c_const_cache = PyDict_New();
118
447
    if (!c->c_const_cache) {
119
0
        return ERROR;
120
0
    }
121
122
447
    c->c_stack = PyList_New(0);
123
447
    if (!c->c_stack) {
124
0
        return ERROR;
125
0
    }
126
127
447
    c->c_filename = Py_NewRef(filename);
128
447
    if (!_PyFuture_FromAST(mod, filename, &c->c_future)) {
129
0
        return ERROR;
130
0
    }
131
447
    c->c_module = Py_XNewRef(module);
132
447
    if (!flags) {
133
84
        flags = &local_flags;
134
84
    }
135
447
    int merged = c->c_future.ff_features | flags->cf_flags;
136
447
    c->c_future.ff_features = merged;
137
447
    flags->cf_flags = merged;
138
447
    c->c_flags = *flags;
139
447
    c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
140
447
    c->c_save_nested_seqs = false;
141
142
447
    if (!_PyAST_Preprocess(mod, arena, filename, c->c_optimize, merged,
143
447
                           0, 1, module))
144
0
    {
145
0
        return ERROR;
146
0
    }
147
447
    c->c_st = _PySymtable_Build(mod, filename, &c->c_future);
148
447
    if (c->c_st == NULL) {
149
0
        if (!PyErr_Occurred()) {
150
0
            PyErr_SetString(PyExc_SystemError, "no symtable");
151
0
        }
152
0
        return ERROR;
153
0
    }
154
447
    return SUCCESS;
155
447
}
156
157
static void
158
compiler_free(compiler *c)
159
447
{
160
447
    if (c->c_st) {
161
447
        _PySymtable_Free(c->c_st);
162
447
    }
163
447
    Py_XDECREF(c->c_filename);
164
447
    Py_XDECREF(c->c_module);
165
447
    Py_XDECREF(c->c_const_cache);
166
447
    Py_XDECREF(c->c_stack);
167
447
    PyMem_Free(c);
168
447
}
169
170
static compiler*
171
new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
172
             int optimize, PyArena *arena, PyObject *module)
173
447
{
174
447
    compiler *c = PyMem_Calloc(1, sizeof(compiler));
175
447
    if (c == NULL) {
176
0
        return NULL;
177
0
    }
178
447
    if (compiler_setup(c, mod, filename, pflags, optimize, arena, module) < 0) {
179
0
        compiler_free(c);
180
0
        return NULL;
181
0
    }
182
447
    return c;
183
447
}
184
185
static void
186
compiler_unit_free(struct compiler_unit *u)
187
8.45k
{
188
8.45k
    Py_CLEAR(u->u_instr_sequence);
189
8.45k
    Py_CLEAR(u->u_stashed_instr_sequence);
190
8.45k
    Py_CLEAR(u->u_ste);
191
8.45k
    Py_CLEAR(u->u_metadata.u_name);
192
8.45k
    Py_CLEAR(u->u_metadata.u_qualname);
193
8.45k
    Py_CLEAR(u->u_metadata.u_consts);
194
8.45k
    Py_CLEAR(u->u_metadata.u_names);
195
8.45k
    Py_CLEAR(u->u_metadata.u_varnames);
196
8.45k
    Py_CLEAR(u->u_metadata.u_freevars);
197
8.45k
    Py_CLEAR(u->u_metadata.u_cellvars);
198
8.45k
    Py_CLEAR(u->u_metadata.u_fasthidden);
199
8.45k
    Py_CLEAR(u->u_private);
200
8.45k
    Py_CLEAR(u->u_static_attributes);
201
8.45k
    Py_CLEAR(u->u_deferred_annotations);
202
8.45k
    Py_CLEAR(u->u_conditional_annotation_indices);
203
8.45k
    PyMem_Free(u);
204
8.45k
}
205
206
22.5k
#define CAPSULE_NAME "compile.c compiler unit"
207
208
int
209
_PyCompile_MaybeAddStaticAttributeToClass(compiler *c, expr_ty e)
210
19.0k
{
211
19.0k
    assert(e->kind == Attribute_kind);
212
19.0k
    expr_ty attr_value = e->v.Attribute.value;
213
19.0k
    if (attr_value->kind != Name_kind ||
214
17.6k
        e->v.Attribute.ctx != Store ||
215
2.52k
        !_PyUnicode_EqualToASCIIString(attr_value->v.Name.id, "self"))
216
17.2k
    {
217
17.2k
        return SUCCESS;
218
17.2k
    }
219
1.80k
    Py_ssize_t stack_size = PyList_GET_SIZE(c->c_stack);
220
1.81k
    for (Py_ssize_t i = stack_size - 1; i >= 0; i--) {
221
1.80k
        PyObject *capsule = PyList_GET_ITEM(c->c_stack, i);
222
1.80k
        struct compiler_unit *u = (struct compiler_unit *)PyCapsule_GetPointer(
223
1.80k
                                                              capsule, CAPSULE_NAME);
224
1.80k
        assert(u);
225
1.80k
        if (u->u_scope_type == COMPILE_SCOPE_CLASS) {
226
1.80k
            assert(u->u_static_attributes);
227
1.80k
            RETURN_IF_ERROR(PySet_Add(u->u_static_attributes, e->v.Attribute.attr));
228
1.80k
            break;
229
1.80k
        }
230
1.80k
    }
231
1.80k
    return SUCCESS;
232
1.80k
}
233
234
static int
235
compiler_set_qualname(compiler *c)
236
8.00k
{
237
8.00k
    Py_ssize_t stack_size;
238
8.00k
    struct compiler_unit *u = c->u;
239
8.00k
    PyObject *name, *base;
240
241
8.00k
    base = NULL;
242
8.00k
    stack_size = PyList_GET_SIZE(c->c_stack);
243
8.00k
    assert(stack_size >= 1);
244
8.00k
    if (stack_size > 1) {
245
4.70k
        int scope, force_global = 0;
246
4.70k
        struct compiler_unit *parent;
247
4.70k
        PyObject *mangled, *capsule;
248
249
4.70k
        capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
250
4.70k
        parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
251
4.70k
        assert(parent);
252
4.70k
        if (parent->u_scope_type == COMPILE_SCOPE_ANNOTATIONS) {
253
            /* The parent is an annotation scope, so we need to
254
               look at the grandparent. */
255
9
            if (stack_size == 2) {
256
                // If we're immediately within the module, we can skip
257
                // the rest and just set the qualname to be the same as name.
258
7
                u->u_metadata.u_qualname = Py_NewRef(u->u_metadata.u_name);
259
7
                return SUCCESS;
260
7
            }
261
2
            capsule = PyList_GET_ITEM(c->c_stack, stack_size - 2);
262
2
            parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
263
2
            assert(parent);
264
2
        }
265
266
4.70k
        if (u->u_scope_type == COMPILE_SCOPE_FUNCTION
267
475
            || u->u_scope_type == COMPILE_SCOPE_ASYNC_FUNCTION
268
4.24k
            || u->u_scope_type == COMPILE_SCOPE_CLASS) {
269
4.24k
            assert(u->u_metadata.u_name);
270
4.24k
            mangled = _Py_Mangle(parent->u_private, u->u_metadata.u_name);
271
4.24k
            if (!mangled) {
272
0
                return ERROR;
273
0
            }
274
275
4.24k
            scope = _PyST_GetScope(parent->u_ste, mangled);
276
4.24k
            Py_DECREF(mangled);
277
4.24k
            RETURN_IF_ERROR(scope);
278
4.24k
            assert(scope != GLOBAL_IMPLICIT);
279
4.24k
            if (scope == GLOBAL_EXPLICIT)
280
0
                force_global = 1;
281
4.24k
        }
282
283
4.70k
        if (!force_global) {
284
4.70k
            if (parent->u_scope_type == COMPILE_SCOPE_FUNCTION
285
4.06k
                || parent->u_scope_type == COMPILE_SCOPE_ASYNC_FUNCTION
286
4.06k
                || parent->u_scope_type == COMPILE_SCOPE_LAMBDA)
287
641
            {
288
641
                _Py_DECLARE_STR(dot_locals, ".<locals>");
289
641
                base = PyUnicode_Concat(parent->u_metadata.u_qualname,
290
641
                                        &_Py_STR(dot_locals));
291
641
                if (base == NULL) {
292
0
                    return ERROR;
293
0
                }
294
641
            }
295
4.06k
            else {
296
4.06k
                base = Py_NewRef(parent->u_metadata.u_qualname);
297
4.06k
            }
298
4.70k
        }
299
4.70k
    }
300
301
8.00k
    if (base != NULL) {
302
4.70k
        name = PyUnicode_Concat(base, _Py_LATIN1_CHR('.'));
303
4.70k
        Py_DECREF(base);
304
4.70k
        if (name == NULL) {
305
0
            return ERROR;
306
0
        }
307
4.70k
        PyUnicode_Append(&name, u->u_metadata.u_name);
308
4.70k
        if (name == NULL) {
309
0
            return ERROR;
310
0
        }
311
4.70k
    }
312
3.29k
    else {
313
3.29k
        name = Py_NewRef(u->u_metadata.u_name);
314
3.29k
    }
315
8.00k
    u->u_metadata.u_qualname = name;
316
317
8.00k
    return SUCCESS;
318
8.00k
}
319
320
/* Merge const *o* and return constant key object.
321
 * If recursive, insert all elements if o is a tuple or frozen set.
322
 */
323
static PyObject*
324
const_cache_insert(PyObject *const_cache, PyObject *o, bool recursive)
325
144k
{
326
144k
    assert(PyDict_CheckExact(const_cache));
327
    // None and Ellipsis are immortal objects, and key is the singleton.
328
    // No need to merge object and key.
329
144k
    if (o == Py_None || o == Py_Ellipsis) {
330
17.1k
        return o;
331
17.1k
    }
332
333
127k
    PyObject *key = _PyCode_ConstantKey(o);
334
127k
    if (key == NULL) {
335
0
        return NULL;
336
0
    }
337
338
127k
    PyObject *t;
339
127k
    int res = PyDict_SetDefaultRef(const_cache, key, key, &t);
340
127k
    if (res != 0) {
341
        // o was not inserted into const_cache. t is either the existing value
342
        // or NULL (on error).
343
48.8k
        Py_DECREF(key);
344
48.8k
        return t;
345
48.8k
    }
346
79.0k
    Py_DECREF(t);
347
348
79.0k
    if (!recursive) {
349
35.9k
        return key;
350
35.9k
    }
351
352
    // We registered o in const_cache.
353
    // When o is a tuple or frozenset, we want to merge its
354
    // items too.
355
43.0k
    if (PyTuple_CheckExact(o)) {
356
1.47k
        Py_ssize_t len = PyTuple_GET_SIZE(o);
357
5.06k
        for (Py_ssize_t i = 0; i < len; i++) {
358
3.59k
            PyObject *item = PyTuple_GET_ITEM(o, i);
359
3.59k
            PyObject *u = const_cache_insert(const_cache, item, recursive);
360
3.59k
            if (u == NULL) {
361
0
                Py_DECREF(key);
362
0
                return NULL;
363
0
            }
364
365
            // See _PyCode_ConstantKey()
366
3.59k
            PyObject *v;  // borrowed
367
3.59k
            if (PyTuple_CheckExact(u)) {
368
0
                v = PyTuple_GET_ITEM(u, 1);
369
0
            }
370
3.59k
            else {
371
3.59k
                v = u;
372
3.59k
            }
373
3.59k
            if (v != item) {
374
254
                PyTuple_SET_ITEM(o, i, Py_NewRef(v));
375
254
                Py_DECREF(item);
376
254
            }
377
378
3.59k
            Py_DECREF(u);
379
3.59k
        }
380
1.47k
    }
381
41.5k
    else if (PyFrozenSet_CheckExact(o)) {
382
        // *key* is tuple. And its first item is frozenset of
383
        // constant keys.
384
        // See _PyCode_ConstantKey() for detail.
385
0
        assert(PyTuple_CheckExact(key));
386
0
        assert(PyTuple_GET_SIZE(key) == 2);
387
388
0
        Py_ssize_t len = PySet_GET_SIZE(o);
389
0
        if (len == 0) {  // empty frozenset should not be re-created.
390
0
            return key;
391
0
        }
392
0
        PyObject *tuple = PyTuple_New(len);
393
0
        if (tuple == NULL) {
394
0
            Py_DECREF(key);
395
0
            return NULL;
396
0
        }
397
0
        Py_ssize_t i = 0, pos = 0;
398
0
        PyObject *item;
399
0
        Py_hash_t hash;
400
0
        while (_PySet_NextEntry(o, &pos, &item, &hash)) {
401
0
            PyObject *k = const_cache_insert(const_cache, item, recursive);
402
0
            if (k == NULL) {
403
0
                Py_DECREF(tuple);
404
0
                Py_DECREF(key);
405
0
                return NULL;
406
0
            }
407
0
            PyObject *u;
408
0
            if (PyTuple_CheckExact(k)) {
409
0
                u = Py_NewRef(PyTuple_GET_ITEM(k, 1));
410
0
                Py_DECREF(k);
411
0
            }
412
0
            else {
413
0
                u = k;
414
0
            }
415
0
            PyTuple_SET_ITEM(tuple, i, u);  // Steals reference of u.
416
0
            i++;
417
0
        }
418
419
        // Instead of rewriting o, we create new frozenset and embed in the
420
        // key tuple.  Caller should get merged frozenset from the key tuple.
421
0
        PyObject *new = PyFrozenSet_New(tuple);
422
0
        Py_DECREF(tuple);
423
0
        if (new == NULL) {
424
0
            Py_DECREF(key);
425
0
            return NULL;
426
0
        }
427
0
        assert(PyTuple_GET_ITEM(key, 1) == o);
428
0
        Py_DECREF(o);
429
0
        PyTuple_SET_ITEM(key, 1, new);
430
0
    }
431
432
43.0k
    return key;
433
43.0k
}
434
435
static PyObject*
436
merge_consts_recursive(PyObject *const_cache, PyObject *o)
437
87.6k
{
438
87.6k
    return const_cache_insert(const_cache, o, true);
439
87.6k
}
440
441
Py_ssize_t
442
_PyCompile_DictAddObj(PyObject *dict, PyObject *o)
443
255k
{
444
255k
    PyObject *v;
445
255k
    Py_ssize_t arg;
446
447
255k
    if (PyDict_GetItemRef(dict, o, &v) < 0) {
448
0
        return ERROR;
449
0
    }
450
255k
    if (!v) {
451
127k
        arg = PyDict_GET_SIZE(dict);
452
127k
        v = PyLong_FromSsize_t(arg);
453
127k
        if (!v) {
454
0
            return ERROR;
455
0
        }
456
127k
        if (PyDict_SetItem(dict, o, v) < 0) {
457
0
            Py_DECREF(v);
458
0
            return ERROR;
459
0
        }
460
127k
    }
461
127k
    else
462
127k
        arg = PyLong_AsLong(v);
463
255k
    Py_DECREF(v);
464
255k
    return arg;
465
255k
}
466
467
Py_ssize_t
468
_PyCompile_AddConst(compiler *c, PyObject *o)
469
87.6k
{
470
87.6k
    PyObject *key = merge_consts_recursive(c->c_const_cache, o);
471
87.6k
    if (key == NULL) {
472
0
        return ERROR;
473
0
    }
474
475
87.6k
    Py_ssize_t arg = _PyCompile_DictAddObj(c->u->u_metadata.u_consts, key);
476
87.6k
    Py_DECREF(key);
477
87.6k
    return arg;
478
87.6k
}
479
480
static PyObject *
481
list2dict(PyObject *list)
482
8.45k
{
483
8.45k
    Py_ssize_t i, n;
484
8.45k
    PyObject *v, *k;
485
8.45k
    PyObject *dict = PyDict_New();
486
8.45k
    if (!dict) return NULL;
487
488
8.45k
    n = PyList_Size(list);
489
22.1k
    for (i = 0; i < n; i++) {
490
13.6k
        v = PyLong_FromSsize_t(i);
491
13.6k
        if (!v) {
492
0
            Py_DECREF(dict);
493
0
            return NULL;
494
0
        }
495
13.6k
        k = PyList_GET_ITEM(list, i);
496
13.6k
        if (PyDict_SetItem(dict, k, v) < 0) {
497
0
            Py_DECREF(v);
498
0
            Py_DECREF(dict);
499
0
            return NULL;
500
0
        }
501
13.6k
        Py_DECREF(v);
502
13.6k
    }
503
8.45k
    return dict;
504
8.45k
}
505
506
/* Return new dict containing names from src that match scope(s).
507
508
src is a symbol table dictionary.  If the scope of a name matches
509
either scope_type or flag is set, insert it into the new dict.  The
510
values are integers, starting at offset and increasing by one for
511
each key.
512
*/
513
514
static PyObject *
515
dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
516
16.9k
{
517
16.9k
    Py_ssize_t i = offset, num_keys, key_i;
518
16.9k
    PyObject *k, *v, *dest = PyDict_New();
519
16.9k
    PyObject *sorted_keys;
520
521
16.9k
    assert(offset >= 0);
522
16.9k
    if (dest == NULL)
523
0
        return NULL;
524
525
    /* Sort the keys so that we have a deterministic order on the indexes
526
       saved in the returned dictionary.  These indexes are used as indexes
527
       into the free and cell var storage.  Therefore if they aren't
528
       deterministic, then the generated bytecode is not deterministic.
529
    */
530
16.9k
    sorted_keys = PyDict_Keys(src);
531
16.9k
    if (sorted_keys == NULL) {
532
0
        Py_DECREF(dest);
533
0
        return NULL;
534
0
    }
535
16.9k
    if (PyList_Sort(sorted_keys) != 0) {
536
0
        Py_DECREF(sorted_keys);
537
0
        Py_DECREF(dest);
538
0
        return NULL;
539
0
    }
540
16.9k
    num_keys = PyList_GET_SIZE(sorted_keys);
541
542
123k
    for (key_i = 0; key_i < num_keys; key_i++) {
543
106k
        k = PyList_GET_ITEM(sorted_keys, key_i);
544
106k
        v = PyDict_GetItemWithError(src, k);
545
106k
        if (!v) {
546
0
            if (!PyErr_Occurred()) {
547
0
                PyErr_SetObject(PyExc_KeyError, k);
548
0
            }
549
0
            Py_DECREF(sorted_keys);
550
0
            Py_DECREF(dest);
551
0
            return NULL;
552
0
        }
553
106k
        long vi = PyLong_AsLong(v);
554
106k
        if (vi == -1 && PyErr_Occurred()) {
555
0
            Py_DECREF(sorted_keys);
556
0
            Py_DECREF(dest);
557
0
            return NULL;
558
0
        }
559
106k
        if (SYMBOL_TO_SCOPE(vi) == scope_type || vi & flag) {
560
1.57k
            PyObject *item = PyLong_FromSsize_t(i);
561
1.57k
            if (item == NULL) {
562
0
                Py_DECREF(sorted_keys);
563
0
                Py_DECREF(dest);
564
0
                return NULL;
565
0
            }
566
1.57k
            i++;
567
1.57k
            if (PyDict_SetItem(dest, k, item) < 0) {
568
0
                Py_DECREF(sorted_keys);
569
0
                Py_DECREF(item);
570
0
                Py_DECREF(dest);
571
0
                return NULL;
572
0
            }
573
1.57k
            Py_DECREF(item);
574
1.57k
        }
575
106k
    }
576
16.9k
    Py_DECREF(sorted_keys);
577
16.9k
    return dest;
578
16.9k
}
579
580
int
581
_PyCompile_EnterScope(compiler *c, identifier name, int scope_type,
582
                       void *key, int lineno, PyObject *private,
583
                      _PyCompile_CodeUnitMetadata *umd)
584
8.45k
{
585
8.45k
    struct compiler_unit *u;
586
8.45k
    u = (struct compiler_unit *)PyMem_Calloc(1, sizeof(struct compiler_unit));
587
8.45k
    if (!u) {
588
0
        PyErr_NoMemory();
589
0
        return ERROR;
590
0
    }
591
8.45k
    u->u_scope_type = scope_type;
592
8.45k
    if (umd != NULL) {
593
6.71k
        u->u_metadata = *umd;
594
6.71k
    }
595
1.73k
    else {
596
1.73k
        u->u_metadata.u_argcount = 0;
597
1.73k
        u->u_metadata.u_posonlyargcount = 0;
598
1.73k
        u->u_metadata.u_kwonlyargcount = 0;
599
1.73k
    }
600
8.45k
    u->u_ste = _PySymtable_Lookup(c->c_st, key);
601
8.45k
    if (!u->u_ste) {
602
0
        compiler_unit_free(u);
603
0
        return ERROR;
604
0
    }
605
8.45k
    u->u_metadata.u_name = Py_NewRef(name);
606
8.45k
    u->u_metadata.u_varnames = list2dict(u->u_ste->ste_varnames);
607
8.45k
    if (!u->u_metadata.u_varnames) {
608
0
        compiler_unit_free(u);
609
0
        return ERROR;
610
0
    }
611
8.45k
    u->u_metadata.u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, DEF_COMP_CELL, 0);
612
8.45k
    if (!u->u_metadata.u_cellvars) {
613
0
        compiler_unit_free(u);
614
0
        return ERROR;
615
0
    }
616
8.45k
    if (u->u_ste->ste_needs_class_closure) {
617
        /* Cook up an implicit __class__ cell. */
618
111
        Py_ssize_t res;
619
111
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS);
620
111
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__class__));
621
111
        if (res < 0) {
622
0
            compiler_unit_free(u);
623
0
            return ERROR;
624
0
        }
625
111
    }
626
8.45k
    if (u->u_ste->ste_needs_classdict) {
627
        /* Cook up an implicit __classdict__ cell. */
628
786
        Py_ssize_t res;
629
786
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS);
630
786
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__classdict__));
631
786
        if (res < 0) {
632
0
            compiler_unit_free(u);
633
0
            return ERROR;
634
0
        }
635
786
    }
636
8.45k
    if (u->u_ste->ste_has_conditional_annotations) {
637
        /* Cook up an implicit __conditional__annotations__ cell */
638
1
        Py_ssize_t res;
639
1
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS || u->u_scope_type == COMPILE_SCOPE_MODULE);
640
1
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__conditional_annotations__));
641
1
        if (res < 0) {
642
0
            compiler_unit_free(u);
643
0
            return ERROR;
644
0
        }
645
1
    }
646
647
8.45k
    u->u_metadata.u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
648
8.45k
                               PyDict_GET_SIZE(u->u_metadata.u_cellvars));
649
8.45k
    if (!u->u_metadata.u_freevars) {
650
0
        compiler_unit_free(u);
651
0
        return ERROR;
652
0
    }
653
654
8.45k
    u->u_metadata.u_fasthidden = PyDict_New();
655
8.45k
    if (!u->u_metadata.u_fasthidden) {
656
0
        compiler_unit_free(u);
657
0
        return ERROR;
658
0
    }
659
660
8.45k
    u->u_nfblocks = 0;
661
8.45k
    u->u_in_inlined_comp = 0;
662
8.45k
    u->u_metadata.u_firstlineno = lineno;
663
8.45k
    u->u_metadata.u_consts = PyDict_New();
664
8.45k
    if (!u->u_metadata.u_consts) {
665
0
        compiler_unit_free(u);
666
0
        return ERROR;
667
0
    }
668
8.45k
    u->u_metadata.u_names = PyDict_New();
669
8.45k
    if (!u->u_metadata.u_names) {
670
0
        compiler_unit_free(u);
671
0
        return ERROR;
672
0
    }
673
674
8.45k
    u->u_deferred_annotations = NULL;
675
8.45k
    u->u_conditional_annotation_indices = NULL;
676
8.45k
    u->u_next_conditional_annotation_index = 0;
677
8.45k
    if (scope_type == COMPILE_SCOPE_CLASS) {
678
1.28k
        u->u_static_attributes = PySet_New(0);
679
1.28k
        if (!u->u_static_attributes) {
680
0
            compiler_unit_free(u);
681
0
            return ERROR;
682
0
        }
683
1.28k
    }
684
7.16k
    else {
685
7.16k
        u->u_static_attributes = NULL;
686
7.16k
    }
687
688
8.45k
    u->u_instr_sequence = (instr_sequence*)_PyInstructionSequence_New();
689
8.45k
    if (!u->u_instr_sequence) {
690
0
        compiler_unit_free(u);
691
0
        return ERROR;
692
0
    }
693
8.45k
    u->u_stashed_instr_sequence = NULL;
694
695
    /* Push the old compiler_unit on the stack. */
696
8.45k
    if (c->u) {
697
8.00k
        PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL);
698
8.00k
        if (!capsule || PyList_Append(c->c_stack, capsule) < 0) {
699
0
            Py_XDECREF(capsule);
700
0
            compiler_unit_free(u);
701
0
            return ERROR;
702
0
        }
703
8.00k
        Py_DECREF(capsule);
704
8.00k
        if (private == NULL) {
705
6.71k
            private = c->u->u_private;
706
6.71k
        }
707
8.00k
    }
708
709
8.45k
    u->u_private = Py_XNewRef(private);
710
711
8.45k
    c->u = u;
712
8.45k
    if (scope_type != COMPILE_SCOPE_MODULE) {
713
8.00k
        RETURN_IF_ERROR(compiler_set_qualname(c));
714
8.00k
    }
715
8.45k
    return SUCCESS;
716
8.45k
}
717
718
void
719
_PyCompile_ExitScope(compiler *c)
720
8.45k
{
721
    // Don't call PySequence_DelItem() with an exception raised
722
8.45k
    PyObject *exc = PyErr_GetRaisedException();
723
724
8.45k
    instr_sequence *nested_seq = NULL;
725
8.45k
    if (c->c_save_nested_seqs) {
726
0
        nested_seq = c->u->u_instr_sequence;
727
0
        Py_INCREF(nested_seq);
728
0
    }
729
8.45k
    compiler_unit_free(c->u);
730
    /* Restore c->u to the parent unit. */
731
8.45k
    Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1;
732
8.45k
    if (n >= 0) {
733
8.00k
        PyObject *capsule = PyList_GET_ITEM(c->c_stack, n);
734
8.00k
        c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
735
8.00k
        assert(c->u);
736
        /* we are deleting from a list so this really shouldn't fail */
737
8.00k
        if (PySequence_DelItem(c->c_stack, n) < 0) {
738
0
            PyErr_FormatUnraisable("Exception ignored while removing "
739
0
                                   "the last compiler stack item");
740
0
        }
741
8.00k
        if (nested_seq != NULL) {
742
0
            if (_PyInstructionSequence_AddNested(c->u->u_instr_sequence, nested_seq) < 0) {
743
0
                PyErr_FormatUnraisable("Exception ignored while appending "
744
0
                                       "nested instruction sequence");
745
0
            }
746
0
        }
747
8.00k
    }
748
447
    else {
749
447
        c->u = NULL;
750
447
    }
751
8.45k
    Py_XDECREF(nested_seq);
752
753
8.45k
    PyErr_SetRaisedException(exc);
754
8.45k
}
755
756
/*
757
 * Frame block handling functions
758
 */
759
760
int
761
_PyCompile_PushFBlock(compiler *c, location loc,
762
                     fblocktype t, jump_target_label block_label,
763
                     jump_target_label exit, void *datum)
764
6.87k
{
765
6.87k
    fblockinfo *f;
766
6.87k
    if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
767
0
        return _PyCompile_Error(c, loc, "too many statically nested blocks");
768
0
    }
769
6.87k
    f = &c->u->u_fblock[c->u->u_nfblocks++];
770
6.87k
    f->fb_type = t;
771
6.87k
    f->fb_block = block_label;
772
6.87k
    f->fb_loc = loc;
773
6.87k
    f->fb_exit = exit;
774
6.87k
    f->fb_datum = datum;
775
6.87k
    if (t == COMPILE_FBLOCK_FINALLY_END) {
776
75
        c->c_disable_warning++;
777
75
    }
778
6.87k
    return SUCCESS;
779
6.87k
}
780
781
void
782
_PyCompile_PopFBlock(compiler *c, fblocktype t, jump_target_label block_label)
783
6.87k
{
784
6.87k
    struct compiler_unit *u = c->u;
785
6.87k
    assert(u->u_nfblocks > 0);
786
6.87k
    u->u_nfblocks--;
787
6.87k
    assert(u->u_fblock[u->u_nfblocks].fb_type == t);
788
6.87k
    assert(SAME_JUMP_TARGET_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label));
789
6.87k
    if (t == COMPILE_FBLOCK_FINALLY_END) {
790
75
        c->c_disable_warning--;
791
75
    }
792
6.87k
}
793
794
fblockinfo *
795
_PyCompile_TopFBlock(compiler *c)
796
8.82k
{
797
8.82k
    if (c->u->u_nfblocks == 0) {
798
6.70k
        return NULL;
799
6.70k
    }
800
2.11k
    return &c->u->u_fblock[c->u->u_nfblocks - 1];
801
8.82k
}
802
803
void
804
_PyCompile_DeferredAnnotations(compiler *c,
805
                               PyObject **deferred_annotations,
806
                               PyObject **conditional_annotation_indices)
807
1.63k
{
808
1.63k
    *deferred_annotations = Py_XNewRef(c->u->u_deferred_annotations);
809
1.63k
    *conditional_annotation_indices = Py_XNewRef(c->u->u_conditional_annotation_indices);
810
1.63k
}
811
812
static location
813
start_location(asdl_stmt_seq *stmts)
814
361
{
815
361
    if (asdl_seq_LEN(stmts) > 0) {
816
        /* Set current line number to the line number of first statement.
817
         * This way line number for SETUP_ANNOTATIONS will always
818
         * coincide with the line number of first "real" statement in module.
819
         * If body is empty, then lineno will be set later in the assembly stage.
820
         */
821
358
        stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
822
358
        return SRC_LOCATION_FROM_AST(st);
823
358
    }
824
3
    return (const _Py_SourceLocation){1, 1, 0, 0};
825
361
}
826
827
static int
828
compiler_codegen(compiler *c, mod_ty mod)
829
447
{
830
447
    RETURN_IF_ERROR(_PyCodegen_EnterAnonymousScope(c, mod));
831
447
    assert(c->u->u_scope_type == COMPILE_SCOPE_MODULE);
832
447
    switch (mod->kind) {
833
361
    case Module_kind: {
834
361
        asdl_stmt_seq *stmts = mod->v.Module.body;
835
361
        RETURN_IF_ERROR(_PyCodegen_Module(c, start_location(stmts), stmts, false));
836
361
        break;
837
361
    }
838
361
    case Interactive_kind: {
839
0
        c->c_interactive = 1;
840
0
        asdl_stmt_seq *stmts = mod->v.Interactive.body;
841
0
        RETURN_IF_ERROR(_PyCodegen_Module(c, start_location(stmts), stmts, true));
842
0
        break;
843
0
    }
844
86
    case Expression_kind: {
845
86
        RETURN_IF_ERROR(_PyCodegen_Expression(c, mod->v.Expression.body));
846
86
        break;
847
86
    }
848
86
    default: {
849
0
        PyErr_Format(PyExc_SystemError,
850
0
                     "module kind %d should not be possible",
851
0
                     mod->kind);
852
0
        return ERROR;
853
86
    }}
854
447
    return SUCCESS;
855
447
}
856
857
static PyCodeObject *
858
compiler_mod(compiler *c, mod_ty mod)
859
447
{
860
447
    PyCodeObject *co = NULL;
861
447
    int addNone = mod->kind != Expression_kind;
862
447
    if (compiler_codegen(c, mod) < 0) {
863
0
        goto finally;
864
0
    }
865
447
    co = _PyCompile_OptimizeAndAssemble(c, addNone);
866
447
finally:
867
447
    _PyCompile_ExitScope(c);
868
447
    return co;
869
447
}
870
871
int
872
_PyCompile_GetRefType(compiler *c, PyObject *name)
873
1.26k
{
874
1.26k
    if (c->u->u_scope_type == COMPILE_SCOPE_CLASS &&
875
302
        (_PyUnicode_EqualToASCIIString(name, "__class__") ||
876
79
         _PyUnicode_EqualToASCIIString(name, "__classdict__") ||
877
292
         _PyUnicode_EqualToASCIIString(name, "__conditional_annotations__"))) {
878
292
        return CELL;
879
292
    }
880
975
    PySTEntryObject *ste = c->u->u_ste;
881
975
    int scope = _PyST_GetScope(ste, name);
882
975
    if (scope == 0) {
883
0
        PyErr_Format(PyExc_SystemError,
884
0
                     "_PyST_GetScope(name=%R) failed: "
885
0
                     "unknown scope in unit %S (%R); "
886
0
                     "symbols: %R; locals: %R; "
887
0
                     "globals: %R",
888
0
                     name,
889
0
                     c->u->u_metadata.u_name, ste->ste_id,
890
0
                     ste->ste_symbols, c->u->u_metadata.u_varnames,
891
0
                     c->u->u_metadata.u_names);
892
0
        return ERROR;
893
0
    }
894
975
    return scope;
895
975
}
896
897
static int
898
dict_lookup_arg(PyObject *dict, PyObject *name)
899
1.94k
{
900
1.94k
    PyObject *v = PyDict_GetItemWithError(dict, name);
901
1.94k
    if (v == NULL) {
902
0
        return ERROR;
903
0
    }
904
1.94k
    return PyLong_AsLong(v);
905
1.94k
}
906
907
int
908
_PyCompile_LookupCellvar(compiler *c, PyObject *name)
909
897
{
910
897
    assert(c->u->u_metadata.u_cellvars);
911
897
    return dict_lookup_arg(c->u->u_metadata.u_cellvars, name);
912
897
}
913
914
int
915
_PyCompile_LookupArg(compiler *c, PyCodeObject *co, PyObject *name)
916
1.05k
{
917
    /* Special case: If a class contains a method with a
918
     * free variable that has the same name as a method,
919
     * the name will be considered free *and* local in the
920
     * class.  It should be handled by the closure, as
921
     * well as by the normal name lookup logic.
922
     */
923
1.05k
    int reftype = _PyCompile_GetRefType(c, name);
924
1.05k
    if (reftype == -1) {
925
0
        return ERROR;
926
0
    }
927
1.05k
    int arg;
928
1.05k
    if (reftype == CELL) {
929
1.00k
        arg = dict_lookup_arg(c->u->u_metadata.u_cellvars, name);
930
1.00k
    }
931
49
    else {
932
49
        arg = dict_lookup_arg(c->u->u_metadata.u_freevars, name);
933
49
    }
934
1.05k
    if (arg == -1 && !PyErr_Occurred()) {
935
0
        PyObject *freevars = _PyCode_GetFreevars(co);
936
0
        if (freevars == NULL) {
937
0
            PyErr_Clear();
938
0
        }
939
0
        PyErr_Format(PyExc_SystemError,
940
0
            "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
941
0
            "freevars of code %S: %R",
942
0
            name,
943
0
            reftype,
944
0
            c->u->u_metadata.u_name,
945
0
            co->co_name,
946
0
            freevars);
947
0
        Py_XDECREF(freevars);
948
0
        return ERROR;
949
0
    }
950
1.05k
    return arg;
951
1.05k
}
952
953
PyObject *
954
_PyCompile_StaticAttributesAsTuple(compiler *c)
955
1.28k
{
956
1.28k
    assert(c->u->u_static_attributes);
957
1.28k
    PyObject *static_attributes_unsorted = PySequence_List(c->u->u_static_attributes);
958
1.28k
    if (static_attributes_unsorted == NULL) {
959
0
        return NULL;
960
0
    }
961
1.28k
    if (PyList_Sort(static_attributes_unsorted) != 0) {
962
0
        Py_DECREF(static_attributes_unsorted);
963
0
        return NULL;
964
0
    }
965
1.28k
    PyObject *static_attributes = PySequence_Tuple(static_attributes_unsorted);
966
1.28k
    Py_DECREF(static_attributes_unsorted);
967
1.28k
    return static_attributes;
968
1.28k
}
969
970
int
971
_PyCompile_ResolveNameop(compiler *c, PyObject *mangled, int scope,
972
                          _PyCompile_optype *optype, Py_ssize_t *arg)
973
132k
{
974
132k
    PyObject *dict = c->u->u_metadata.u_names;
975
132k
    *optype = COMPILE_OP_NAME;
976
977
132k
    assert(scope >= 0);
978
132k
    switch (scope) {
979
1.54k
    case FREE:
980
1.54k
        dict = c->u->u_metadata.u_freevars;
981
1.54k
        *optype = COMPILE_OP_DEREF;
982
1.54k
        break;
983
1.07k
    case CELL:
984
1.07k
        dict = c->u->u_metadata.u_cellvars;
985
1.07k
        *optype = COMPILE_OP_DEREF;
986
1.07k
        break;
987
96.9k
    case LOCAL:
988
96.9k
        if (_PyST_IsFunctionLike(c->u->u_ste)) {
989
81.8k
            *optype = COMPILE_OP_FAST;
990
81.8k
        }
991
15.0k
        else {
992
15.0k
            PyObject *item;
993
15.0k
            RETURN_IF_ERROR(PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, mangled,
994
15.0k
                                              &item));
995
15.0k
            if (item == Py_True) {
996
60
                *optype = COMPILE_OP_FAST;
997
60
            }
998
15.0k
            Py_XDECREF(item);
999
15.0k
        }
1000
96.9k
        break;
1001
96.9k
    case GLOBAL_IMPLICIT:
1002
25.1k
        if (_PyST_IsFunctionLike(c->u->u_ste)) {
1003
22.2k
            *optype = COMPILE_OP_GLOBAL;
1004
22.2k
        }
1005
25.1k
        break;
1006
181
    case GLOBAL_EXPLICIT:
1007
181
        *optype = COMPILE_OP_GLOBAL;
1008
181
        break;
1009
7.97k
    default:
1010
        /* scope can be 0 */
1011
7.97k
        break;
1012
132k
    }
1013
132k
    if (*optype != COMPILE_OP_FAST) {
1014
50.9k
        *arg = _PyCompile_DictAddObj(dict, mangled);
1015
50.9k
        RETURN_IF_ERROR(*arg);
1016
50.9k
    }
1017
132k
    return SUCCESS;
1018
132k
}
1019
1020
int
1021
_PyCompile_TweakInlinedComprehensionScopes(compiler *c, location loc,
1022
                                            PySTEntryObject *entry,
1023
                                            _PyCompile_InlinedComprehensionState *state)
1024
259
{
1025
259
    int in_class_block = (c->u->u_ste->ste_type == ClassBlock) && !c->u->u_in_inlined_comp;
1026
259
    c->u->u_in_inlined_comp++;
1027
1028
259
    PyObject *k, *v;
1029
259
    Py_ssize_t pos = 0;
1030
1.11k
    while (PyDict_Next(entry->ste_symbols, &pos, &k, &v)) {
1031
858
        long symbol = PyLong_AsLong(v);
1032
858
        assert(symbol >= 0 || PyErr_Occurred());
1033
858
        RETURN_IF_ERROR(symbol);
1034
858
        long scope = SYMBOL_TO_SCOPE(symbol);
1035
1036
858
        long outsymbol = _PyST_GetSymbol(c->u->u_ste, k);
1037
858
        RETURN_IF_ERROR(outsymbol);
1038
858
        long outsc = SYMBOL_TO_SCOPE(outsymbol);
1039
1040
        // If a name has different scope inside than outside the comprehension,
1041
        // we need to temporarily handle it with the right scope while
1042
        // compiling the comprehension. If it's free in the comprehension
1043
        // scope, no special handling; it should be handled the same as the
1044
        // enclosing scope. (If it's free in outer scope and cell in inner
1045
        // scope, we can't treat it as both cell and free in the same function,
1046
        // but treating it as free throughout is fine; it's *_DEREF
1047
        // either way.)
1048
858
        if ((scope != outsc && scope != FREE && !(scope == CELL && outsc == FREE))
1049
585
                || in_class_block) {
1050
273
            if (state->temp_symbols == NULL) {
1051
259
                state->temp_symbols = PyDict_New();
1052
259
                if (state->temp_symbols == NULL) {
1053
0
                    return ERROR;
1054
0
                }
1055
259
            }
1056
            // update the symbol to the in-comprehension version and save
1057
            // the outer version; we'll restore it after running the
1058
            // comprehension
1059
273
            if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v) < 0) {
1060
0
                return ERROR;
1061
0
            }
1062
273
            PyObject *outv = PyLong_FromLong(outsymbol);
1063
273
            if (outv == NULL) {
1064
0
                return ERROR;
1065
0
            }
1066
273
            int res = PyDict_SetItem(state->temp_symbols, k, outv);
1067
273
            Py_DECREF(outv);
1068
273
            RETURN_IF_ERROR(res);
1069
273
        }
1070
        // locals handling for names bound in comprehension (DEF_LOCAL |
1071
        // DEF_NONLOCAL occurs in assignment expression to nonlocal)
1072
858
        if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) {
1073
342
            if (!_PyST_IsFunctionLike(c->u->u_ste)) {
1074
                // non-function scope: override this name to use fast locals
1075
24
                PyObject *orig;
1076
24
                if (PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, k, &orig) < 0) {
1077
0
                    return ERROR;
1078
0
                }
1079
24
                assert(orig == NULL || orig == Py_True || orig == Py_False);
1080
24
                if (orig != Py_True) {
1081
24
                    if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_True) < 0) {
1082
0
                        return ERROR;
1083
0
                    }
1084
24
                    if (state->fast_hidden == NULL) {
1085
18
                        state->fast_hidden = PySet_New(NULL);
1086
18
                        if (state->fast_hidden == NULL) {
1087
0
                            return ERROR;
1088
0
                        }
1089
18
                    }
1090
24
                    if (PySet_Add(state->fast_hidden, k) < 0) {
1091
0
                        return ERROR;
1092
0
                    }
1093
24
                }
1094
24
            }
1095
342
        }
1096
858
    }
1097
259
    return SUCCESS;
1098
259
}
1099
1100
int
1101
_PyCompile_RevertInlinedComprehensionScopes(compiler *c, location loc,
1102
                                             _PyCompile_InlinedComprehensionState *state)
1103
259
{
1104
259
    c->u->u_in_inlined_comp--;
1105
259
    if (state->temp_symbols) {
1106
259
        PyObject *k, *v;
1107
259
        Py_ssize_t pos = 0;
1108
532
        while (PyDict_Next(state->temp_symbols, &pos, &k, &v)) {
1109
273
            if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v)) {
1110
0
                return ERROR;
1111
0
            }
1112
273
        }
1113
259
        Py_CLEAR(state->temp_symbols);
1114
259
    }
1115
259
    if (state->fast_hidden) {
1116
42
        while (PySet_Size(state->fast_hidden) > 0) {
1117
24
            PyObject *k = PySet_Pop(state->fast_hidden);
1118
24
            if (k == NULL) {
1119
0
                return ERROR;
1120
0
            }
1121
            // we set to False instead of clearing, so we can track which names
1122
            // were temporarily fast-locals and should use CO_FAST_HIDDEN
1123
24
            if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_False)) {
1124
0
                Py_DECREF(k);
1125
0
                return ERROR;
1126
0
            }
1127
24
            Py_DECREF(k);
1128
24
        }
1129
18
        Py_CLEAR(state->fast_hidden);
1130
18
    }
1131
259
    return SUCCESS;
1132
259
}
1133
1134
void
1135
_PyCompile_EnterConditionalBlock(struct _PyCompiler *c)
1136
13.8k
{
1137
13.8k
    c->u->u_in_conditional_block++;
1138
13.8k
}
1139
1140
void
1141
_PyCompile_LeaveConditionalBlock(struct _PyCompiler *c)
1142
13.8k
{
1143
13.8k
    assert(c->u->u_in_conditional_block > 0);
1144
13.8k
    c->u->u_in_conditional_block--;
1145
13.8k
}
1146
1147
int
1148
_PyCompile_AddDeferredAnnotation(compiler *c, stmt_ty s,
1149
                                 PyObject **conditional_annotation_index)
1150
72
{
1151
72
    if (c->u->u_deferred_annotations == NULL) {
1152
14
        c->u->u_deferred_annotations = PyList_New(0);
1153
14
        if (c->u->u_deferred_annotations == NULL) {
1154
0
            return ERROR;
1155
0
        }
1156
14
    }
1157
72
    if (c->u->u_conditional_annotation_indices == NULL) {
1158
14
        c->u->u_conditional_annotation_indices = PyList_New(0);
1159
14
        if (c->u->u_conditional_annotation_indices == NULL) {
1160
0
            return ERROR;
1161
0
        }
1162
14
    }
1163
72
    PyObject *ptr = PyLong_FromVoidPtr((void *)s);
1164
72
    if (ptr == NULL) {
1165
0
        return ERROR;
1166
0
    }
1167
72
    if (PyList_Append(c->u->u_deferred_annotations, ptr) < 0) {
1168
0
        Py_DECREF(ptr);
1169
0
        return ERROR;
1170
0
    }
1171
72
    Py_DECREF(ptr);
1172
72
    PyObject *index;
1173
72
    if (c->u->u_scope_type == COMPILE_SCOPE_MODULE || c->u->u_in_conditional_block) {
1174
1
        index = PyLong_FromLong(c->u->u_next_conditional_annotation_index);
1175
1
        if (index == NULL) {
1176
0
            return ERROR;
1177
0
        }
1178
1
        *conditional_annotation_index = Py_NewRef(index);
1179
1
        c->u->u_next_conditional_annotation_index++;
1180
1
    }
1181
71
    else {
1182
71
        index = PyLong_FromLong(-1);
1183
71
        if (index == NULL) {
1184
0
            return ERROR;
1185
0
        }
1186
71
    }
1187
72
    int rc = PyList_Append(c->u->u_conditional_annotation_indices, index);
1188
72
    Py_DECREF(index);
1189
72
    RETURN_IF_ERROR(rc);
1190
72
    return SUCCESS;
1191
72
}
1192
1193
/* Raises a SyntaxError and returns ERROR.
1194
 * If something goes wrong, a different exception may be raised.
1195
 */
1196
int
1197
_PyCompile_Error(compiler *c, location loc, const char *format, ...)
1198
0
{
1199
0
    va_list vargs;
1200
0
    va_start(vargs, format);
1201
0
    PyObject *msg = PyUnicode_FromFormatV(format, vargs);
1202
0
    va_end(vargs);
1203
0
    if (msg == NULL) {
1204
0
        return ERROR;
1205
0
    }
1206
0
    _PyErr_RaiseSyntaxError(msg, c->c_filename, loc.lineno, loc.col_offset + 1,
1207
0
                            loc.end_lineno, loc.end_col_offset + 1);
1208
0
    Py_DECREF(msg);
1209
0
    return ERROR;
1210
0
}
1211
1212
/* Emits a SyntaxWarning and returns 0 on success.
1213
   If a SyntaxWarning raised as error, replaces it with a SyntaxError
1214
   and returns -1.
1215
*/
1216
int
1217
_PyCompile_Warn(compiler *c, location loc, const char *format, ...)
1218
0
{
1219
0
    if (c->c_disable_warning) {
1220
0
        return 0;
1221
0
    }
1222
0
    va_list vargs;
1223
0
    va_start(vargs, format);
1224
0
    PyObject *msg = PyUnicode_FromFormatV(format, vargs);
1225
0
    va_end(vargs);
1226
0
    if (msg == NULL) {
1227
0
        return ERROR;
1228
0
    }
1229
0
    int ret = _PyErr_EmitSyntaxWarning(msg, c->c_filename, loc.lineno, loc.col_offset + 1,
1230
0
                                       loc.end_lineno, loc.end_col_offset + 1,
1231
0
                                       c->c_module);
1232
0
    Py_DECREF(msg);
1233
0
    return ret;
1234
0
}
1235
1236
PyObject *
1237
_PyCompile_Mangle(compiler *c, PyObject *name)
1238
72
{
1239
72
    return _Py_Mangle(c->u->u_private, name);
1240
72
}
1241
1242
PyObject *
1243
_PyCompile_MaybeMangle(compiler *c, PyObject *name)
1244
166k
{
1245
166k
    return _Py_MaybeMangle(c->u->u_private, c->u->u_ste, name);
1246
166k
}
1247
1248
instr_sequence *
1249
_PyCompile_InstrSequence(compiler *c)
1250
590k
{
1251
590k
    return c->u->u_instr_sequence;
1252
590k
}
1253
1254
int
1255
_PyCompile_StartAnnotationSetup(struct _PyCompiler *c)
1256
1
{
1257
1
    instr_sequence *new_seq = (instr_sequence *)_PyInstructionSequence_New();
1258
1
    if (new_seq == NULL) {
1259
0
        return ERROR;
1260
0
    }
1261
1
    assert(c->u->u_stashed_instr_sequence == NULL);
1262
1
    c->u->u_stashed_instr_sequence = c->u->u_instr_sequence;
1263
1
    c->u->u_instr_sequence = new_seq;
1264
1
    return SUCCESS;
1265
1
}
1266
1267
int
1268
_PyCompile_EndAnnotationSetup(struct _PyCompiler *c)
1269
1
{
1270
1
    assert(c->u->u_stashed_instr_sequence != NULL);
1271
1
    instr_sequence *parent_seq = c->u->u_stashed_instr_sequence;
1272
1
    instr_sequence *anno_seq = c->u->u_instr_sequence;
1273
1
    c->u->u_stashed_instr_sequence = NULL;
1274
1
    c->u->u_instr_sequence = parent_seq;
1275
1
    if (_PyInstructionSequence_SetAnnotationsCode(parent_seq, anno_seq) == ERROR) {
1276
0
        Py_DECREF(anno_seq);
1277
0
        return ERROR;
1278
0
    }
1279
1
    return SUCCESS;
1280
1
}
1281
1282
1283
int
1284
_PyCompile_FutureFeatures(compiler *c)
1285
3.64k
{
1286
3.64k
    return c->c_future.ff_features;
1287
3.64k
}
1288
1289
struct symtable *
1290
_PyCompile_Symtable(compiler *c)
1291
16.7k
{
1292
16.7k
    return c->c_st;
1293
16.7k
}
1294
1295
PySTEntryObject *
1296
_PyCompile_SymtableEntry(compiler *c)
1297
189k
{
1298
189k
    return c->u->u_ste;
1299
189k
}
1300
1301
int
1302
_PyCompile_OptimizationLevel(compiler *c)
1303
194
{
1304
194
    return c->c_optimize;
1305
194
}
1306
1307
int
1308
_PyCompile_IsInteractiveTopLevel(compiler *c)
1309
6.07k
{
1310
6.07k
    assert(c->c_stack != NULL);
1311
6.07k
    assert(PyList_CheckExact(c->c_stack));
1312
6.07k
    bool is_nested_scope = PyList_GET_SIZE(c->c_stack) > 0;
1313
6.07k
    return c->c_interactive && !is_nested_scope;
1314
6.07k
}
1315
1316
int
1317
_PyCompile_ScopeType(compiler *c)
1318
228
{
1319
228
    return c->u->u_scope_type;
1320
228
}
1321
1322
int
1323
_PyCompile_IsInInlinedComp(compiler *c)
1324
3.05k
{
1325
3.05k
    return c->u->u_in_inlined_comp;
1326
3.05k
}
1327
1328
PyObject *
1329
_PyCompile_Qualname(compiler *c)
1330
1.28k
{
1331
1.28k
    assert(c->u->u_metadata.u_qualname);
1332
1.28k
    return c->u->u_metadata.u_qualname;
1333
1.28k
}
1334
1335
_PyCompile_CodeUnitMetadata *
1336
_PyCompile_Metadata(compiler *c)
1337
117k
{
1338
117k
    return &c->u->u_metadata;
1339
117k
}
1340
1341
// Merge *obj* with constant cache, without recursion.
1342
int
1343
_PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj)
1344
53.6k
{
1345
53.6k
    PyObject *key = const_cache_insert(const_cache, *obj, false);
1346
53.6k
    if (key == NULL) {
1347
0
        return ERROR;
1348
0
    }
1349
53.6k
    if (PyTuple_CheckExact(key)) {
1350
52.9k
        PyObject *item = PyTuple_GET_ITEM(key, 1);
1351
52.9k
        Py_SETREF(*obj, Py_NewRef(item));
1352
52.9k
        Py_DECREF(key);
1353
52.9k
    }
1354
771
    else {
1355
771
        Py_SETREF(*obj, key);
1356
771
    }
1357
53.6k
    return SUCCESS;
1358
53.6k
}
1359
1360
static PyObject *
1361
consts_dict_keys_inorder(PyObject *dict)
1362
8.45k
{
1363
8.45k
    PyObject *consts, *k, *v;
1364
8.45k
    Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
1365
1366
8.45k
    consts = PyList_New(size);   /* PyCode_Optimize() requires a list */
1367
8.45k
    if (consts == NULL)
1368
0
        return NULL;
1369
68.2k
    while (PyDict_Next(dict, &pos, &k, &v)) {
1370
59.7k
        assert(PyLong_CheckExact(v));
1371
59.7k
        i = PyLong_AsLong(v);
1372
        /* The keys of the dictionary can be tuples wrapping a constant.
1373
         * (see _PyCompile_DictAddObj and _PyCode_ConstantKey). In that case
1374
         * the object we want is always second. */
1375
59.7k
        if (PyTuple_CheckExact(k)) {
1376
4.85k
            k = PyTuple_GET_ITEM(k, 1);
1377
4.85k
        }
1378
59.7k
        assert(i < size);
1379
59.7k
        assert(i >= 0);
1380
59.7k
        PyList_SET_ITEM(consts, i, Py_NewRef(k));
1381
59.7k
    }
1382
8.45k
    return consts;
1383
8.45k
}
1384
1385
static int
1386
compute_code_flags(compiler *c)
1387
8.45k
{
1388
8.45k
    PySTEntryObject *ste = c->u->u_ste;
1389
8.45k
    int flags = 0;
1390
8.45k
    if (_PyST_IsFunctionLike(ste)) {
1391
6.72k
        flags |= CO_NEWLOCALS | CO_OPTIMIZED;
1392
6.72k
        if (ste->ste_nested)
1393
660
            flags |= CO_NESTED;
1394
6.72k
        if (ste->ste_generator && !ste->ste_coroutine)
1395
428
            flags |= CO_GENERATOR;
1396
6.72k
        if (ste->ste_generator && ste->ste_coroutine)
1397
1
            flags |= CO_ASYNC_GENERATOR;
1398
6.72k
        if (ste->ste_varargs)
1399
208
            flags |= CO_VARARGS;
1400
6.72k
        if (ste->ste_varkeywords)
1401
167
            flags |= CO_VARKEYWORDS;
1402
6.72k
        if (ste->ste_has_docstring)
1403
2.16k
            flags |= CO_HAS_DOCSTRING;
1404
6.72k
        if (ste->ste_method)
1405
3.97k
            flags |= CO_METHOD;
1406
6.72k
    }
1407
1408
8.45k
    if (ste->ste_coroutine && !ste->ste_generator) {
1409
15
        flags |= CO_COROUTINE;
1410
15
    }
1411
1412
    /* (Only) inherit compilerflags in PyCF_MASK */
1413
8.45k
    flags |= (c->c_flags.cf_flags & PyCF_MASK);
1414
1415
8.45k
    return flags;
1416
8.45k
}
1417
1418
static PyCodeObject *
1419
optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache,
1420
                                int code_flags, PyObject *filename)
1421
8.45k
{
1422
8.45k
    cfg_builder *g = NULL;
1423
8.45k
    instr_sequence optimized_instrs;
1424
8.45k
    memset(&optimized_instrs, 0, sizeof(instr_sequence));
1425
1426
8.45k
    PyCodeObject *co = NULL;
1427
8.45k
    PyObject *consts = consts_dict_keys_inorder(u->u_metadata.u_consts);
1428
8.45k
    if (consts == NULL) {
1429
0
        goto error;
1430
0
    }
1431
8.45k
    g = _PyCfg_FromInstructionSequence(u->u_instr_sequence);
1432
8.45k
    if (g == NULL) {
1433
0
        goto error;
1434
0
    }
1435
8.45k
    int nlocals = (int)PyDict_GET_SIZE(u->u_metadata.u_varnames);
1436
8.45k
    int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames);
1437
8.45k
    assert(u->u_metadata.u_firstlineno);
1438
1439
8.45k
    if (_PyCfg_OptimizeCodeUnit(g, consts, const_cache, nlocals,
1440
8.45k
                                nparams, u->u_metadata.u_firstlineno) < 0) {
1441
0
        goto error;
1442
0
    }
1443
1444
8.45k
    int stackdepth;
1445
8.45k
    int nlocalsplus;
1446
8.45k
    if (_PyCfg_OptimizedCfgToInstructionSequence(g, &u->u_metadata, code_flags,
1447
8.45k
                                                 &stackdepth, &nlocalsplus,
1448
8.45k
                                                 &optimized_instrs) < 0) {
1449
0
        goto error;
1450
0
    }
1451
1452
    /** Assembly **/
1453
8.45k
    co = _PyAssemble_MakeCodeObject(&u->u_metadata, const_cache, consts,
1454
8.45k
                                    stackdepth, &optimized_instrs, nlocalsplus,
1455
8.45k
                                    code_flags, filename);
1456
1457
8.45k
error:
1458
8.45k
    Py_XDECREF(consts);
1459
8.45k
    PyInstructionSequence_Fini(&optimized_instrs);
1460
8.45k
    _PyCfgBuilder_Free(g);
1461
8.45k
    return co;
1462
8.45k
}
1463
1464
1465
PyCodeObject *
1466
_PyCompile_OptimizeAndAssemble(compiler *c, int addNone)
1467
8.45k
{
1468
8.45k
    struct compiler_unit *u = c->u;
1469
8.45k
    PyObject *const_cache = c->c_const_cache;
1470
8.45k
    PyObject *filename = c->c_filename;
1471
1472
8.45k
    int code_flags = compute_code_flags(c);
1473
8.45k
    if (code_flags < 0) {
1474
0
        return NULL;
1475
0
    }
1476
1477
8.45k
    if (_PyCodegen_AddReturnAtEnd(c, addNone) < 0) {
1478
0
        return NULL;
1479
0
    }
1480
1481
8.45k
    return optimize_and_assemble_code_unit(u, const_cache, code_flags, filename);
1482
8.45k
}
1483
1484
PyCodeObject *
1485
_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
1486
               int optimize, PyArena *arena, PyObject *module)
1487
447
{
1488
447
    assert(!PyErr_Occurred());
1489
447
    compiler *c = new_compiler(mod, filename, pflags, optimize, arena, module);
1490
447
    if (c == NULL) {
1491
0
        return NULL;
1492
0
    }
1493
1494
447
    PyCodeObject *co = compiler_mod(c, mod);
1495
447
    compiler_free(c);
1496
447
    assert(co || PyErr_Occurred());
1497
447
    return co;
1498
447
}
1499
1500
int
1501
_PyCompile_AstPreprocess(mod_ty mod, PyObject *filename, PyCompilerFlags *cf,
1502
                         int optimize, PyArena *arena, int no_const_folding,
1503
                         PyObject *module)
1504
6.10k
{
1505
6.10k
    _PyFutureFeatures future;
1506
6.10k
    if (!_PyFuture_FromAST(mod, filename, &future)) {
1507
10
        return -1;
1508
10
    }
1509
6.09k
    int flags = future.ff_features | cf->cf_flags;
1510
6.09k
    if (optimize == -1) {
1511
6.09k
        optimize = _Py_GetConfig()->optimization_level;
1512
6.09k
    }
1513
6.09k
    if (!_PyAST_Preprocess(mod, arena, filename, optimize, flags,
1514
6.09k
                           no_const_folding, 0, module))
1515
0
    {
1516
0
        return -1;
1517
0
    }
1518
6.09k
    return 0;
1519
6.09k
}
1520
1521
// C implementation of inspect.cleandoc()
1522
//
1523
// Difference from inspect.cleandoc():
1524
// - Do not remove leading and trailing blank lines to keep lineno.
1525
PyObject *
1526
_PyCompile_CleanDoc(PyObject *doc)
1527
2.79k
{
1528
2.79k
    doc = PyObject_CallMethod(doc, "expandtabs", NULL);
1529
2.79k
    if (doc == NULL) {
1530
0
        return NULL;
1531
0
    }
1532
1533
2.79k
    Py_ssize_t doc_size;
1534
2.79k
    const char *doc_utf8 = PyUnicode_AsUTF8AndSize(doc, &doc_size);
1535
2.79k
    if (doc_utf8 == NULL) {
1536
0
        Py_DECREF(doc);
1537
0
        return NULL;
1538
0
    }
1539
2.79k
    const char *p = doc_utf8;
1540
2.79k
    const char *pend = p + doc_size;
1541
1542
    // First pass: find minimum indentation of any non-blank lines
1543
    // after first line.
1544
122k
    while (p < pend && *p++ != '\n') {
1545
120k
    }
1546
1547
2.79k
    Py_ssize_t margin = PY_SSIZE_T_MAX;
1548
18.5k
    while (p < pend) {
1549
15.7k
        const char *s = p;
1550
95.0k
        while (*p == ' ') p++;
1551
15.7k
        if (p < pend && *p != '\n') {
1552
10.4k
            margin = Py_MIN(margin, p - s);
1553
10.4k
        }
1554
519k
        while (p < pend && *p++ != '\n') {
1555
503k
        }
1556
15.7k
    }
1557
2.79k
    if (margin == PY_SSIZE_T_MAX) {
1558
947
        margin = 0;
1559
947
    }
1560
1561
    // Second pass: write cleandoc into buff.
1562
1563
    // copy first line without leading spaces.
1564
2.79k
    p = doc_utf8;
1565
2.92k
    while (*p == ' ') {
1566
136
        p++;
1567
136
    }
1568
2.79k
    if (p == doc_utf8 && margin == 0 ) {
1569
        // doc is already clean.
1570
949
        return doc;
1571
949
    }
1572
1573
1.84k
    char *buff = PyMem_Malloc(doc_size);
1574
1.84k
    if (buff == NULL){
1575
0
        Py_DECREF(doc);
1576
0
        PyErr_NoMemory();
1577
0
        return NULL;
1578
0
    }
1579
1580
1.84k
    char *w = buff;
1581
1582
79.2k
    while (p < pend) {
1583
79.2k
        int ch = *w++ = *p++;
1584
79.2k
        if (ch == '\n') {
1585
1.84k
            break;
1586
1.84k
        }
1587
79.2k
    }
1588
1589
    // copy subsequent lines without margin.
1590
15.8k
    while (p < pend) {
1591
76.7k
        for (Py_ssize_t i = 0; i < margin; i++, p++) {
1592
65.8k
            if (*p != ' ') {
1593
3.12k
                assert(*p == '\n' || *p == '\0');
1594
3.12k
                break;
1595
3.12k
            }
1596
65.8k
        }
1597
467k
        while (p < pend) {
1598
465k
            int ch = *w++ = *p++;
1599
465k
            if (ch == '\n') {
1600
12.2k
                break;
1601
12.2k
            }
1602
465k
        }
1603
14.0k
    }
1604
1605
1.84k
    Py_DECREF(doc);
1606
1.84k
    PyObject *res = PyUnicode_FromStringAndSize(buff, w - buff);
1607
1.84k
    PyMem_Free(buff);
1608
1.84k
    return res;
1609
1.84k
}
1610
1611
/* Access to compiler optimizations for unit tests.
1612
 *
1613
 * _PyCompile_CodeGen takes an AST, applies code-gen and
1614
 * returns the unoptimized CFG as an instruction list.
1615
 *
1616
 */
1617
PyObject *
1618
_PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
1619
                   int optimize, int compile_mode)
1620
0
{
1621
0
    PyObject *res = NULL;
1622
0
    PyObject *metadata = NULL;
1623
1624
0
    if (!PyAST_Check(ast)) {
1625
0
        PyErr_SetString(PyExc_TypeError, "expected an AST");
1626
0
        return NULL;
1627
0
    }
1628
1629
0
    PyArena *arena = _PyArena_New();
1630
0
    if (arena == NULL) {
1631
0
        return NULL;
1632
0
    }
1633
1634
0
    mod_ty mod = PyAST_obj2mod(ast, arena, compile_mode);
1635
0
    if (mod == NULL || !_PyAST_Validate(mod)) {
1636
0
        _PyArena_Free(arena);
1637
0
        return NULL;
1638
0
    }
1639
1640
0
    compiler *c = new_compiler(mod, filename, pflags, optimize, arena, NULL);
1641
0
    if (c == NULL) {
1642
0
        _PyArena_Free(arena);
1643
0
        return NULL;
1644
0
    }
1645
0
    c->c_save_nested_seqs = true;
1646
1647
0
    metadata = PyDict_New();
1648
0
    if (metadata == NULL) {
1649
0
        return NULL;
1650
0
    }
1651
1652
0
    if (compiler_codegen(c, mod) < 0) {
1653
0
        goto finally;
1654
0
    }
1655
1656
0
    _PyCompile_CodeUnitMetadata *umd = &c->u->u_metadata;
1657
1658
0
#define SET_METADATA_INT(key, value) do { \
1659
0
        PyObject *v = PyLong_FromLong((long)value); \
1660
0
        if (v == NULL) goto finally; \
1661
0
        int res = PyDict_SetItemString(metadata, key, v); \
1662
0
        Py_XDECREF(v); \
1663
0
        if (res < 0) goto finally; \
1664
0
    } while (0);
1665
1666
0
    SET_METADATA_INT("argcount", umd->u_argcount);
1667
0
    SET_METADATA_INT("posonlyargcount", umd->u_posonlyargcount);
1668
0
    SET_METADATA_INT("kwonlyargcount", umd->u_kwonlyargcount);
1669
0
#undef SET_METADATA_INT
1670
1671
0
    int addNone = mod->kind != Expression_kind;
1672
0
    if (_PyCodegen_AddReturnAtEnd(c, addNone) < 0) {
1673
0
        goto finally;
1674
0
    }
1675
1676
0
    if (_PyInstructionSequence_ApplyLabelMap(_PyCompile_InstrSequence(c)) < 0) {
1677
0
        return NULL;
1678
0
    }
1679
    /* Allocate a copy of the instruction sequence on the heap */
1680
0
    res = PyTuple_Pack(2, _PyCompile_InstrSequence(c), metadata);
1681
1682
0
finally:
1683
0
    Py_XDECREF(metadata);
1684
0
    _PyCompile_ExitScope(c);
1685
0
    compiler_free(c);
1686
0
    _PyArena_Free(arena);
1687
0
    return res;
1688
0
}
1689
1690
int _PyCfg_JumpLabelsToTargets(cfg_builder *g);
1691
1692
PyCodeObject *
1693
_PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename,
1694
                    PyObject *seq)
1695
0
{
1696
0
    if (!_PyInstructionSequence_Check(seq)) {
1697
0
        PyErr_SetString(PyExc_TypeError, "expected an instruction sequence");
1698
0
        return NULL;
1699
0
    }
1700
0
    cfg_builder *g = NULL;
1701
0
    PyCodeObject *co = NULL;
1702
0
    instr_sequence optimized_instrs;
1703
0
    memset(&optimized_instrs, 0, sizeof(instr_sequence));
1704
1705
0
    PyObject *const_cache = PyDict_New();
1706
0
    if (const_cache == NULL) {
1707
0
        return NULL;
1708
0
    }
1709
1710
0
    g = _PyCfg_FromInstructionSequence((instr_sequence*)seq);
1711
0
    if (g == NULL) {
1712
0
        goto error;
1713
0
    }
1714
1715
0
    if (_PyCfg_JumpLabelsToTargets(g) < 0) {
1716
0
        goto error;
1717
0
    }
1718
1719
0
    int code_flags = 0;
1720
0
    int stackdepth, nlocalsplus;
1721
0
    if (_PyCfg_OptimizedCfgToInstructionSequence(g, umd, code_flags,
1722
0
                                                 &stackdepth, &nlocalsplus,
1723
0
                                                 &optimized_instrs) < 0) {
1724
0
        goto error;
1725
0
    }
1726
1727
0
    PyObject *consts = consts_dict_keys_inorder(umd->u_consts);
1728
0
    if (consts == NULL) {
1729
0
        goto error;
1730
0
    }
1731
0
    co = _PyAssemble_MakeCodeObject(umd, const_cache,
1732
0
                                    consts, stackdepth, &optimized_instrs,
1733
0
                                    nlocalsplus, code_flags, filename);
1734
0
    Py_DECREF(consts);
1735
1736
0
error:
1737
0
    Py_DECREF(const_cache);
1738
0
    _PyCfgBuilder_Free(g);
1739
0
    PyInstructionSequence_Fini(&optimized_instrs);
1740
0
    return co;
1741
0
}
1742
1743
/* Retained for API compatibility.
1744
 * Optimization is now done in _PyCfg_OptimizeCodeUnit */
1745
1746
PyObject *
1747
PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts),
1748
                PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj))
1749
0
{
1750
0
    return Py_NewRef(code);
1751
0
}