Coverage Report

Created: 2026-02-26 06:53

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
100k
#define SUCCESS 0
36
0
#define ERROR -1
37
38
#define RETURN_IF_ERROR(X)  \
39
35.2k
    do {                    \
40
35.2k
        if ((X) == -1) {    \
41
0
            return ERROR;   \
42
0
        }                   \
43
35.2k
    } 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
588
{
115
588
    PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
116
117
588
    c->c_const_cache = PyDict_New();
118
588
    if (!c->c_const_cache) {
119
0
        return ERROR;
120
0
    }
121
122
588
    c->c_stack = PyList_New(0);
123
588
    if (!c->c_stack) {
124
0
        return ERROR;
125
0
    }
126
127
588
    c->c_filename = Py_NewRef(filename);
128
588
    if (!_PyFuture_FromAST(mod, filename, &c->c_future)) {
129
0
        return ERROR;
130
0
    }
131
588
    c->c_module = Py_XNewRef(module);
132
588
    if (!flags) {
133
96
        flags = &local_flags;
134
96
    }
135
588
    int merged = c->c_future.ff_features | flags->cf_flags;
136
588
    c->c_future.ff_features = merged;
137
588
    flags->cf_flags = merged;
138
588
    c->c_flags = *flags;
139
588
    c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
140
588
    c->c_save_nested_seqs = false;
141
142
588
    if (!_PyAST_Preprocess(mod, arena, filename, c->c_optimize, merged,
143
588
                           0, 1, module))
144
0
    {
145
0
        return ERROR;
146
0
    }
147
588
    c->c_st = _PySymtable_Build(mod, filename, &c->c_future);
148
588
    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
588
    return SUCCESS;
155
588
}
156
157
static void
158
compiler_free(compiler *c)
159
588
{
160
588
    if (c->c_st) {
161
588
        _PySymtable_Free(c->c_st);
162
588
    }
163
588
    Py_XDECREF(c->c_filename);
164
588
    Py_XDECREF(c->c_module);
165
588
    Py_XDECREF(c->c_const_cache);
166
588
    Py_XDECREF(c->c_stack);
167
588
    PyMem_Free(c);
168
588
}
169
170
static compiler*
171
new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
172
             int optimize, PyArena *arena, PyObject *module)
173
588
{
174
588
    compiler *c = PyMem_Calloc(1, sizeof(compiler));
175
588
    if (c == NULL) {
176
0
        return NULL;
177
0
    }
178
588
    if (compiler_setup(c, mod, filename, pflags, optimize, arena, module) < 0) {
179
0
        compiler_free(c);
180
0
        return NULL;
181
0
    }
182
588
    return c;
183
588
}
184
185
static void
186
compiler_unit_free(struct compiler_unit *u)
187
4.58k
{
188
4.58k
    Py_CLEAR(u->u_instr_sequence);
189
4.58k
    Py_CLEAR(u->u_stashed_instr_sequence);
190
4.58k
    Py_CLEAR(u->u_ste);
191
4.58k
    Py_CLEAR(u->u_metadata.u_name);
192
4.58k
    Py_CLEAR(u->u_metadata.u_qualname);
193
4.58k
    Py_CLEAR(u->u_metadata.u_consts);
194
4.58k
    Py_CLEAR(u->u_metadata.u_names);
195
4.58k
    Py_CLEAR(u->u_metadata.u_varnames);
196
4.58k
    Py_CLEAR(u->u_metadata.u_freevars);
197
4.58k
    Py_CLEAR(u->u_metadata.u_cellvars);
198
4.58k
    Py_CLEAR(u->u_metadata.u_fasthidden);
199
4.58k
    Py_CLEAR(u->u_private);
200
4.58k
    Py_CLEAR(u->u_static_attributes);
201
4.58k
    Py_CLEAR(u->u_deferred_annotations);
202
4.58k
    Py_CLEAR(u->u_conditional_annotation_indices);
203
4.58k
    PyMem_Free(u);
204
4.58k
}
205
206
11.6k
#define CAPSULE_NAME "compile.c compiler unit"
207
208
int
209
_PyCompile_MaybeAddStaticAttributeToClass(compiler *c, expr_ty e)
210
10.8k
{
211
10.8k
    assert(e->kind == Attribute_kind);
212
10.8k
    expr_ty attr_value = e->v.Attribute.value;
213
10.8k
    if (attr_value->kind != Name_kind ||
214
10.2k
        e->v.Attribute.ctx != Store ||
215
1.23k
        !_PyUnicode_EqualToASCIIString(attr_value->v.Name.id, "self"))
216
9.76k
    {
217
9.76k
        return SUCCESS;
218
9.76k
    }
219
1.06k
    Py_ssize_t stack_size = PyList_GET_SIZE(c->c_stack);
220
1.24k
    for (Py_ssize_t i = stack_size - 1; i >= 0; i--) {
221
1.15k
        PyObject *capsule = PyList_GET_ITEM(c->c_stack, i);
222
1.15k
        struct compiler_unit *u = (struct compiler_unit *)PyCapsule_GetPointer(
223
1.15k
                                                              capsule, CAPSULE_NAME);
224
1.15k
        assert(u);
225
1.15k
        if (u->u_scope_type == COMPILE_SCOPE_CLASS) {
226
977
            assert(u->u_static_attributes);
227
977
            RETURN_IF_ERROR(PySet_Add(u->u_static_attributes, e->v.Attribute.attr));
228
977
            break;
229
977
        }
230
1.15k
    }
231
1.06k
    return SUCCESS;
232
1.06k
}
233
234
static int
235
compiler_set_qualname(compiler *c)
236
3.99k
{
237
3.99k
    Py_ssize_t stack_size;
238
3.99k
    struct compiler_unit *u = c->u;
239
3.99k
    PyObject *name, *base;
240
241
3.99k
    base = NULL;
242
3.99k
    stack_size = PyList_GET_SIZE(c->c_stack);
243
3.99k
    assert(stack_size >= 1);
244
3.99k
    if (stack_size > 1) {
245
2.49k
        int scope, force_global = 0;
246
2.49k
        struct compiler_unit *parent;
247
2.49k
        PyObject *mangled, *capsule;
248
249
2.49k
        capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
250
2.49k
        parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
251
2.49k
        assert(parent);
252
2.49k
        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
0
            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
0
                u->u_metadata.u_qualname = Py_NewRef(u->u_metadata.u_name);
259
0
                return SUCCESS;
260
0
            }
261
0
            capsule = PyList_GET_ITEM(c->c_stack, stack_size - 2);
262
0
            parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
263
0
            assert(parent);
264
0
        }
265
266
2.49k
        if (u->u_scope_type == COMPILE_SCOPE_FUNCTION
267
249
            || u->u_scope_type == COMPILE_SCOPE_ASYNC_FUNCTION
268
2.36k
            || u->u_scope_type == COMPILE_SCOPE_CLASS) {
269
2.36k
            assert(u->u_metadata.u_name);
270
2.36k
            mangled = _Py_Mangle(parent->u_private, u->u_metadata.u_name);
271
2.36k
            if (!mangled) {
272
0
                return ERROR;
273
0
            }
274
275
2.36k
            scope = _PyST_GetScope(parent->u_ste, mangled);
276
2.36k
            Py_DECREF(mangled);
277
2.36k
            RETURN_IF_ERROR(scope);
278
2.36k
            assert(scope != GLOBAL_IMPLICIT);
279
2.36k
            if (scope == GLOBAL_EXPLICIT)
280
0
                force_global = 1;
281
2.36k
        }
282
283
2.49k
        if (!force_global) {
284
2.49k
            if (parent->u_scope_type == COMPILE_SCOPE_FUNCTION
285
1.83k
                || parent->u_scope_type == COMPILE_SCOPE_ASYNC_FUNCTION
286
1.81k
                || parent->u_scope_type == COMPILE_SCOPE_LAMBDA)
287
681
            {
288
681
                _Py_DECLARE_STR(dot_locals, ".<locals>");
289
681
                base = PyUnicode_Concat(parent->u_metadata.u_qualname,
290
681
                                        &_Py_STR(dot_locals));
291
681
                if (base == NULL) {
292
0
                    return ERROR;
293
0
                }
294
681
            }
295
1.81k
            else {
296
1.81k
                base = Py_NewRef(parent->u_metadata.u_qualname);
297
1.81k
            }
298
2.49k
        }
299
2.49k
    }
300
301
3.99k
    if (base != NULL) {
302
2.49k
        name = PyUnicode_Concat(base, _Py_LATIN1_CHR('.'));
303
2.49k
        Py_DECREF(base);
304
2.49k
        if (name == NULL) {
305
0
            return ERROR;
306
0
        }
307
2.49k
        PyUnicode_Append(&name, u->u_metadata.u_name);
308
2.49k
        if (name == NULL) {
309
0
            return ERROR;
310
0
        }
311
2.49k
    }
312
1.50k
    else {
313
1.50k
        name = Py_NewRef(u->u_metadata.u_name);
314
1.50k
    }
315
3.99k
    u->u_metadata.u_qualname = name;
316
317
3.99k
    return SUCCESS;
318
3.99k
}
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
72.3k
{
326
72.3k
    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
72.3k
    if (o == Py_None || o == Py_Ellipsis) {
330
8.90k
        return o;
331
8.90k
    }
332
333
63.4k
    PyObject *key = _PyCode_ConstantKey(o);
334
63.4k
    if (key == NULL) {
335
0
        return NULL;
336
0
    }
337
338
63.4k
    PyObject *t;
339
63.4k
    int res = PyDict_SetDefaultRef(const_cache, key, key, &t);
340
63.4k
    if (res != 0) {
341
        // o was not inserted into const_cache. t is either the existing value
342
        // or NULL (on error).
343
23.6k
        Py_DECREF(key);
344
23.6k
        return t;
345
23.6k
    }
346
39.7k
    Py_DECREF(t);
347
348
39.7k
    if (!recursive) {
349
20.0k
        return key;
350
20.0k
    }
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
19.7k
    if (PyTuple_CheckExact(o)) {
356
842
        Py_ssize_t len = PyTuple_GET_SIZE(o);
357
2.98k
        for (Py_ssize_t i = 0; i < len; i++) {
358
2.13k
            PyObject *item = PyTuple_GET_ITEM(o, i);
359
2.13k
            PyObject *u = const_cache_insert(const_cache, item, recursive);
360
2.13k
            if (u == NULL) {
361
0
                Py_DECREF(key);
362
0
                return NULL;
363
0
            }
364
365
            // See _PyCode_ConstantKey()
366
2.13k
            PyObject *v;  // borrowed
367
2.13k
            if (PyTuple_CheckExact(u)) {
368
0
                v = PyTuple_GET_ITEM(u, 1);
369
0
            }
370
2.13k
            else {
371
2.13k
                v = u;
372
2.13k
            }
373
2.13k
            if (v != item) {
374
112
                PyTuple_SET_ITEM(o, i, Py_NewRef(v));
375
112
                Py_DECREF(item);
376
112
            }
377
378
2.13k
            Py_DECREF(u);
379
2.13k
        }
380
842
    }
381
18.8k
    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
19.7k
    return key;
433
19.7k
}
434
435
static PyObject*
436
merge_consts_recursive(PyObject *const_cache, PyObject *o)
437
41.6k
{
438
41.6k
    return const_cache_insert(const_cache, o, true);
439
41.6k
}
440
441
Py_ssize_t
442
_PyCompile_DictAddObj(PyObject *dict, PyObject *o)
443
107k
{
444
107k
    PyObject *v;
445
107k
    Py_ssize_t arg;
446
447
107k
    if (PyDict_GetItemRef(dict, o, &v) < 0) {
448
0
        return ERROR;
449
0
    }
450
107k
    if (!v) {
451
56.5k
        arg = PyDict_GET_SIZE(dict);
452
56.5k
        v = PyLong_FromSsize_t(arg);
453
56.5k
        if (!v) {
454
0
            return ERROR;
455
0
        }
456
56.5k
        if (PyDict_SetItem(dict, o, v) < 0) {
457
0
            Py_DECREF(v);
458
0
            return ERROR;
459
0
        }
460
56.5k
    }
461
50.9k
    else
462
50.9k
        arg = PyLong_AsLong(v);
463
107k
    Py_DECREF(v);
464
107k
    return arg;
465
107k
}
466
467
Py_ssize_t
468
_PyCompile_AddConst(compiler *c, PyObject *o)
469
41.6k
{
470
41.6k
    PyObject *key = merge_consts_recursive(c->c_const_cache, o);
471
41.6k
    if (key == NULL) {
472
0
        return ERROR;
473
0
    }
474
475
41.6k
    Py_ssize_t arg = _PyCompile_DictAddObj(c->u->u_metadata.u_consts, key);
476
41.6k
    Py_DECREF(key);
477
41.6k
    return arg;
478
41.6k
}
479
480
static PyObject *
481
list2dict(PyObject *list)
482
4.58k
{
483
4.58k
    Py_ssize_t i, n;
484
4.58k
    PyObject *v, *k;
485
4.58k
    PyObject *dict = PyDict_New();
486
4.58k
    if (!dict) return NULL;
487
488
4.58k
    n = PyList_Size(list);
489
13.0k
    for (i = 0; i < n; i++) {
490
8.45k
        v = PyLong_FromSsize_t(i);
491
8.45k
        if (!v) {
492
0
            Py_DECREF(dict);
493
0
            return NULL;
494
0
        }
495
8.45k
        k = PyList_GET_ITEM(list, i);
496
8.45k
        if (PyDict_SetItem(dict, k, v) < 0) {
497
0
            Py_DECREF(v);
498
0
            Py_DECREF(dict);
499
0
            return NULL;
500
0
        }
501
8.45k
        Py_DECREF(v);
502
8.45k
    }
503
4.58k
    return dict;
504
4.58k
}
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
9.17k
{
517
9.17k
    Py_ssize_t i = offset, num_keys, key_i;
518
9.17k
    PyObject *k, *v, *dest = PyDict_New();
519
9.17k
    PyObject *sorted_keys;
520
521
9.17k
    assert(offset >= 0);
522
9.17k
    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
9.17k
    sorted_keys = PyDict_Keys(src);
531
9.17k
    if (sorted_keys == NULL) {
532
0
        Py_DECREF(dest);
533
0
        return NULL;
534
0
    }
535
9.17k
    if (PyList_Sort(sorted_keys) != 0) {
536
0
        Py_DECREF(sorted_keys);
537
0
        Py_DECREF(dest);
538
0
        return NULL;
539
0
    }
540
9.17k
    num_keys = PyList_GET_SIZE(sorted_keys);
541
542
54.7k
    for (key_i = 0; key_i < num_keys; key_i++) {
543
45.5k
        k = PyList_GET_ITEM(sorted_keys, key_i);
544
45.5k
        v = PyDict_GetItemWithError(src, k);
545
45.5k
        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
45.5k
        long vi = PyLong_AsLong(v);
554
45.5k
        if (vi == -1 && PyErr_Occurred()) {
555
0
            Py_DECREF(sorted_keys);
556
0
            Py_DECREF(dest);
557
0
            return NULL;
558
0
        }
559
45.5k
        if (SYMBOL_TO_SCOPE(vi) == scope_type || vi & flag) {
560
1.20k
            PyObject *item = PyLong_FromSsize_t(i);
561
1.20k
            if (item == NULL) {
562
0
                Py_DECREF(sorted_keys);
563
0
                Py_DECREF(dest);
564
0
                return NULL;
565
0
            }
566
1.20k
            i++;
567
1.20k
            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.20k
            Py_DECREF(item);
574
1.20k
        }
575
45.5k
    }
576
9.17k
    Py_DECREF(sorted_keys);
577
9.17k
    return dest;
578
9.17k
}
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
4.58k
{
585
4.58k
    struct compiler_unit *u;
586
4.58k
    u = (struct compiler_unit *)PyMem_Calloc(1, sizeof(struct compiler_unit));
587
4.58k
    if (!u) {
588
0
        PyErr_NoMemory();
589
0
        return ERROR;
590
0
    }
591
4.58k
    u->u_scope_type = scope_type;
592
4.58k
    if (umd != NULL) {
593
3.27k
        u->u_metadata = *umd;
594
3.27k
    }
595
1.31k
    else {
596
1.31k
        u->u_metadata.u_argcount = 0;
597
1.31k
        u->u_metadata.u_posonlyargcount = 0;
598
1.31k
        u->u_metadata.u_kwonlyargcount = 0;
599
1.31k
    }
600
4.58k
    u->u_ste = _PySymtable_Lookup(c->c_st, key);
601
4.58k
    if (!u->u_ste) {
602
0
        compiler_unit_free(u);
603
0
        return ERROR;
604
0
    }
605
4.58k
    u->u_metadata.u_name = Py_NewRef(name);
606
4.58k
    u->u_metadata.u_varnames = list2dict(u->u_ste->ste_varnames);
607
4.58k
    if (!u->u_metadata.u_varnames) {
608
0
        compiler_unit_free(u);
609
0
        return ERROR;
610
0
    }
611
4.58k
    u->u_metadata.u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, DEF_COMP_CELL, 0);
612
4.58k
    if (!u->u_metadata.u_cellvars) {
613
0
        compiler_unit_free(u);
614
0
        return ERROR;
615
0
    }
616
4.58k
    if (u->u_ste->ste_needs_class_closure) {
617
        /* Cook up an implicit __class__ cell. */
618
36
        Py_ssize_t res;
619
36
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS);
620
36
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__class__));
621
36
        if (res < 0) {
622
0
            compiler_unit_free(u);
623
0
            return ERROR;
624
0
        }
625
36
    }
626
4.58k
    if (u->u_ste->ste_needs_classdict) {
627
        /* Cook up an implicit __classdict__ cell. */
628
395
        Py_ssize_t res;
629
395
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS);
630
395
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__classdict__));
631
395
        if (res < 0) {
632
0
            compiler_unit_free(u);
633
0
            return ERROR;
634
0
        }
635
395
    }
636
4.58k
    if (u->u_ste->ste_has_conditional_annotations) {
637
        /* Cook up an implicit __conditional_annotations__ cell */
638
0
        Py_ssize_t res;
639
0
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS || u->u_scope_type == COMPILE_SCOPE_MODULE);
640
0
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__conditional_annotations__));
641
0
        if (res < 0) {
642
0
            compiler_unit_free(u);
643
0
            return ERROR;
644
0
        }
645
0
    }
646
647
4.58k
    u->u_metadata.u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
648
4.58k
                               PyDict_GET_SIZE(u->u_metadata.u_cellvars));
649
4.58k
    if (!u->u_metadata.u_freevars) {
650
0
        compiler_unit_free(u);
651
0
        return ERROR;
652
0
    }
653
654
4.58k
    u->u_metadata.u_fasthidden = PyDict_New();
655
4.58k
    if (!u->u_metadata.u_fasthidden) {
656
0
        compiler_unit_free(u);
657
0
        return ERROR;
658
0
    }
659
660
4.58k
    u->u_nfblocks = 0;
661
4.58k
    u->u_in_inlined_comp = 0;
662
4.58k
    u->u_metadata.u_firstlineno = lineno;
663
4.58k
    u->u_metadata.u_consts = PyDict_New();
664
4.58k
    if (!u->u_metadata.u_consts) {
665
0
        compiler_unit_free(u);
666
0
        return ERROR;
667
0
    }
668
4.58k
    u->u_metadata.u_names = PyDict_New();
669
4.58k
    if (!u->u_metadata.u_names) {
670
0
        compiler_unit_free(u);
671
0
        return ERROR;
672
0
    }
673
674
4.58k
    u->u_deferred_annotations = NULL;
675
4.58k
    u->u_conditional_annotation_indices = NULL;
676
4.58k
    u->u_next_conditional_annotation_index = 0;
677
4.58k
    if (scope_type == COMPILE_SCOPE_CLASS) {
678
725
        u->u_static_attributes = PySet_New(0);
679
725
        if (!u->u_static_attributes) {
680
0
            compiler_unit_free(u);
681
0
            return ERROR;
682
0
        }
683
725
    }
684
3.86k
    else {
685
3.86k
        u->u_static_attributes = NULL;
686
3.86k
    }
687
688
4.58k
    u->u_instr_sequence = (instr_sequence*)_PyInstructionSequence_New();
689
4.58k
    if (!u->u_instr_sequence) {
690
0
        compiler_unit_free(u);
691
0
        return ERROR;
692
0
    }
693
4.58k
    u->u_stashed_instr_sequence = NULL;
694
695
    /* Push the old compiler_unit on the stack. */
696
4.58k
    if (c->u) {
697
3.99k
        PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL);
698
3.99k
        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
3.99k
        Py_DECREF(capsule);
704
3.99k
        if (private == NULL) {
705
3.27k
            private = c->u->u_private;
706
3.27k
        }
707
3.99k
    }
708
709
4.58k
    u->u_private = Py_XNewRef(private);
710
711
4.58k
    c->u = u;
712
4.58k
    if (scope_type != COMPILE_SCOPE_MODULE) {
713
3.99k
        RETURN_IF_ERROR(compiler_set_qualname(c));
714
3.99k
    }
715
4.58k
    return SUCCESS;
716
4.58k
}
717
718
void
719
_PyCompile_ExitScope(compiler *c)
720
4.58k
{
721
    // Don't call PySequence_DelItem() with an exception raised
722
4.58k
    PyObject *exc = PyErr_GetRaisedException();
723
724
4.58k
    instr_sequence *nested_seq = NULL;
725
4.58k
    if (c->c_save_nested_seqs) {
726
0
        nested_seq = c->u->u_instr_sequence;
727
0
        Py_INCREF(nested_seq);
728
0
    }
729
4.58k
    compiler_unit_free(c->u);
730
    /* Restore c->u to the parent unit. */
731
4.58k
    Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1;
732
4.58k
    if (n >= 0) {
733
3.99k
        PyObject *capsule = PyList_GET_ITEM(c->c_stack, n);
734
3.99k
        c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
735
3.99k
        assert(c->u);
736
        /* we are deleting from a list so this really shouldn't fail */
737
3.99k
        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
3.99k
        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
3.99k
    }
748
588
    else {
749
588
        c->u = NULL;
750
588
    }
751
4.58k
    Py_XDECREF(nested_seq);
752
753
4.58k
    PyErr_SetRaisedException(exc);
754
4.58k
}
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
2.54k
{
765
2.54k
    fblockinfo *f;
766
2.54k
    if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
767
0
        return _PyCompile_Error(c, loc, "too many statically nested blocks");
768
0
    }
769
2.54k
    f = &c->u->u_fblock[c->u->u_nfblocks++];
770
2.54k
    f->fb_type = t;
771
2.54k
    f->fb_block = block_label;
772
2.54k
    f->fb_loc = loc;
773
2.54k
    f->fb_exit = exit;
774
2.54k
    f->fb_datum = datum;
775
2.54k
    if (t == COMPILE_FBLOCK_FINALLY_END) {
776
89
        c->c_disable_warning++;
777
89
    }
778
2.54k
    return SUCCESS;
779
2.54k
}
780
781
void
782
_PyCompile_PopFBlock(compiler *c, fblocktype t, jump_target_label block_label)
783
2.54k
{
784
2.54k
    struct compiler_unit *u = c->u;
785
2.54k
    assert(u->u_nfblocks > 0);
786
2.54k
    u->u_nfblocks--;
787
2.54k
    assert(u->u_fblock[u->u_nfblocks].fb_type == t);
788
2.54k
    assert(SAME_JUMP_TARGET_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label));
789
2.54k
    if (t == COMPILE_FBLOCK_FINALLY_END) {
790
89
        c->c_disable_warning--;
791
89
    }
792
2.54k
}
793
794
fblockinfo *
795
_PyCompile_TopFBlock(compiler *c)
796
3.03k
{
797
3.03k
    if (c->u->u_nfblocks == 0) {
798
2.39k
        return NULL;
799
2.39k
    }
800
644
    return &c->u->u_fblock[c->u->u_nfblocks - 1];
801
3.03k
}
802
803
bool
804
_PyCompile_InExceptionHandler(compiler *c)
805
783
{
806
787
    for (Py_ssize_t i = 0; i < c->u->u_nfblocks; i++) {
807
20
        fblockinfo *block = &c->u->u_fblock[i];
808
20
        switch (block->fb_type) {
809
13
            case COMPILE_FBLOCK_TRY_EXCEPT:
810
13
            case COMPILE_FBLOCK_FINALLY_TRY:
811
13
            case COMPILE_FBLOCK_FINALLY_END:
812
16
            case COMPILE_FBLOCK_EXCEPTION_HANDLER:
813
16
            case COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER:
814
16
            case COMPILE_FBLOCK_HANDLER_CLEANUP:
815
16
                return true;
816
4
            default:
817
4
                break;
818
20
        }
819
20
    }
820
767
    return false;
821
783
}
822
823
void
824
_PyCompile_DeferredAnnotations(compiler *c,
825
                               PyObject **deferred_annotations,
826
                               PyObject **conditional_annotation_indices)
827
1.14k
{
828
1.14k
    *deferred_annotations = Py_XNewRef(c->u->u_deferred_annotations);
829
1.14k
    *conditional_annotation_indices = Py_XNewRef(c->u->u_conditional_annotation_indices);
830
1.14k
}
831
832
static location
833
start_location(asdl_stmt_seq *stmts)
834
422
{
835
422
    if (asdl_seq_LEN(stmts) > 0) {
836
        /* Set current line number to the line number of first statement.
837
         * This way line number for SETUP_ANNOTATIONS will always
838
         * coincide with the line number of first "real" statement in module.
839
         * If body is empty, then lineno will be set later in the assembly stage.
840
         */
841
420
        stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
842
420
        return SRC_LOCATION_FROM_AST(st);
843
420
    }
844
2
    return (const _Py_SourceLocation){1, 1, 0, 0};
845
422
}
846
847
static int
848
compiler_codegen(compiler *c, mod_ty mod)
849
588
{
850
588
    RETURN_IF_ERROR(_PyCodegen_EnterAnonymousScope(c, mod));
851
588
    assert(c->u->u_scope_type == COMPILE_SCOPE_MODULE);
852
588
    switch (mod->kind) {
853
422
    case Module_kind: {
854
422
        asdl_stmt_seq *stmts = mod->v.Module.body;
855
422
        RETURN_IF_ERROR(_PyCodegen_Module(c, start_location(stmts), stmts, false));
856
422
        break;
857
422
    }
858
422
    case Interactive_kind: {
859
0
        c->c_interactive = 1;
860
0
        asdl_stmt_seq *stmts = mod->v.Interactive.body;
861
0
        RETURN_IF_ERROR(_PyCodegen_Module(c, start_location(stmts), stmts, true));
862
0
        break;
863
0
    }
864
166
    case Expression_kind: {
865
166
        RETURN_IF_ERROR(_PyCodegen_Expression(c, mod->v.Expression.body));
866
166
        break;
867
166
    }
868
166
    default: {
869
0
        PyErr_Format(PyExc_SystemError,
870
0
                     "module kind %d should not be possible",
871
0
                     mod->kind);
872
0
        return ERROR;
873
166
    }}
874
588
    return SUCCESS;
875
588
}
876
877
static PyCodeObject *
878
compiler_mod(compiler *c, mod_ty mod)
879
588
{
880
588
    PyCodeObject *co = NULL;
881
588
    int addNone = mod->kind != Expression_kind;
882
588
    if (compiler_codegen(c, mod) < 0) {
883
0
        goto finally;
884
0
    }
885
588
    co = _PyCompile_OptimizeAndAssemble(c, addNone);
886
588
finally:
887
588
    _PyCompile_ExitScope(c);
888
588
    return co;
889
588
}
890
891
int
892
_PyCompile_GetRefType(compiler *c, PyObject *name)
893
789
{
894
789
    if (c->u->u_scope_type == COMPILE_SCOPE_CLASS &&
895
101
        (_PyUnicode_EqualToASCIIString(name, "__class__") ||
896
29
         _PyUnicode_EqualToASCIIString(name, "__classdict__") ||
897
96
         _PyUnicode_EqualToASCIIString(name, "__conditional_annotations__"))) {
898
96
        return CELL;
899
96
    }
900
693
    PySTEntryObject *ste = c->u->u_ste;
901
693
    int scope = _PyST_GetScope(ste, name);
902
693
    if (scope == 0) {
903
0
        PyErr_Format(PyExc_SystemError,
904
0
                     "_PyST_GetScope(name=%R) failed: "
905
0
                     "unknown scope in unit %S (%R); "
906
0
                     "symbols: %R; locals: %R; "
907
0
                     "globals: %R",
908
0
                     name,
909
0
                     c->u->u_metadata.u_name, ste->ste_id,
910
0
                     ste->ste_symbols, c->u->u_metadata.u_varnames,
911
0
                     c->u->u_metadata.u_names);
912
0
        return ERROR;
913
0
    }
914
693
    return scope;
915
693
}
916
917
static int
918
dict_lookup_arg(PyObject *dict, PyObject *name)
919
1.16k
{
920
1.16k
    PyObject *v = PyDict_GetItemWithError(dict, name);
921
1.16k
    if (v == NULL) {
922
0
        return ERROR;
923
0
    }
924
1.16k
    return PyLong_AsLong(v);
925
1.16k
}
926
927
int
928
_PyCompile_LookupCellvar(compiler *c, PyObject *name)
929
431
{
930
431
    assert(c->u->u_metadata.u_cellvars);
931
431
    return dict_lookup_arg(c->u->u_metadata.u_cellvars, name);
932
431
}
933
934
int
935
_PyCompile_LookupArg(compiler *c, PyCodeObject *co, PyObject *name)
936
737
{
937
    /* Special case: If a class contains a method with a
938
     * free variable that has the same name as a method,
939
     * the name will be considered free *and* local in the
940
     * class.  It should be handled by the closure, as
941
     * well as by the normal name lookup logic.
942
     */
943
737
    int reftype = _PyCompile_GetRefType(c, name);
944
737
    if (reftype == -1) {
945
0
        return ERROR;
946
0
    }
947
737
    int arg;
948
737
    if (reftype == CELL) {
949
728
        arg = dict_lookup_arg(c->u->u_metadata.u_cellvars, name);
950
728
    }
951
9
    else {
952
9
        arg = dict_lookup_arg(c->u->u_metadata.u_freevars, name);
953
9
    }
954
737
    if (arg == -1 && !PyErr_Occurred()) {
955
0
        PyObject *freevars = _PyCode_GetFreevars(co);
956
0
        if (freevars == NULL) {
957
0
            PyErr_Clear();
958
0
        }
959
0
        PyErr_Format(PyExc_SystemError,
960
0
            "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
961
0
            "freevars of code %S: %R",
962
0
            name,
963
0
            reftype,
964
0
            c->u->u_metadata.u_name,
965
0
            co->co_name,
966
0
            freevars);
967
0
        Py_XDECREF(freevars);
968
0
        return ERROR;
969
0
    }
970
737
    return arg;
971
737
}
972
973
PyObject *
974
_PyCompile_StaticAttributesAsTuple(compiler *c)
975
725
{
976
725
    assert(c->u->u_static_attributes);
977
725
    PyObject *static_attributes_unsorted = PySequence_List(c->u->u_static_attributes);
978
725
    if (static_attributes_unsorted == NULL) {
979
0
        return NULL;
980
0
    }
981
725
    if (PyList_Sort(static_attributes_unsorted) != 0) {
982
0
        Py_DECREF(static_attributes_unsorted);
983
0
        return NULL;
984
0
    }
985
725
    PyObject *static_attributes = PySequence_Tuple(static_attributes_unsorted);
986
725
    Py_DECREF(static_attributes_unsorted);
987
725
    return static_attributes;
988
725
}
989
990
int
991
_PyCompile_ResolveNameop(compiler *c, PyObject *mangled, int scope,
992
                          _PyCompile_optype *optype, Py_ssize_t *arg)
993
48.3k
{
994
48.3k
    PyObject *dict = c->u->u_metadata.u_names;
995
48.3k
    *optype = COMPILE_OP_NAME;
996
997
48.3k
    assert(scope >= 0);
998
48.3k
    switch (scope) {
999
1.34k
    case FREE:
1000
1.34k
        dict = c->u->u_metadata.u_freevars;
1001
1.34k
        *optype = COMPILE_OP_DEREF;
1002
1.34k
        break;
1003
588
    case CELL:
1004
588
        dict = c->u->u_metadata.u_cellvars;
1005
588
        *optype = COMPILE_OP_DEREF;
1006
588
        break;
1007
34.5k
    case LOCAL:
1008
34.5k
        if (_PyST_IsFunctionLike(c->u->u_ste)) {
1009
28.2k
            *optype = COMPILE_OP_FAST;
1010
28.2k
        }
1011
6.28k
        else {
1012
6.28k
            PyObject *item;
1013
6.28k
            RETURN_IF_ERROR(PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, mangled,
1014
6.28k
                                              &item));
1015
6.28k
            if (item == Py_True) {
1016
10
                *optype = COMPILE_OP_FAST;
1017
10
            }
1018
6.28k
            Py_XDECREF(item);
1019
6.28k
        }
1020
34.5k
        break;
1021
34.5k
    case GLOBAL_IMPLICIT:
1022
7.53k
        if (_PyST_IsFunctionLike(c->u->u_ste)) {
1023
7.08k
            *optype = COMPILE_OP_GLOBAL;
1024
7.08k
        }
1025
7.53k
        break;
1026
28
    case GLOBAL_EXPLICIT:
1027
28
        *optype = COMPILE_OP_GLOBAL;
1028
28
        break;
1029
4.29k
    default:
1030
        /* scope can be 0 */
1031
4.29k
        break;
1032
48.3k
    }
1033
48.3k
    if (*optype != COMPILE_OP_FAST) {
1034
20.0k
        *arg = _PyCompile_DictAddObj(dict, mangled);
1035
20.0k
        RETURN_IF_ERROR(*arg);
1036
20.0k
    }
1037
48.3k
    return SUCCESS;
1038
48.3k
}
1039
1040
int
1041
_PyCompile_TweakInlinedComprehensionScopes(compiler *c, location loc,
1042
                                            PySTEntryObject *entry,
1043
                                            _PyCompile_InlinedComprehensionState *state)
1044
53
{
1045
53
    int in_class_block = (c->u->u_ste->ste_type == ClassBlock) && !c->u->u_in_inlined_comp;
1046
53
    c->u->u_in_inlined_comp++;
1047
1048
53
    PyObject *k, *v;
1049
53
    Py_ssize_t pos = 0;
1050
217
    while (PyDict_Next(entry->ste_symbols, &pos, &k, &v)) {
1051
164
        long symbol = PyLong_AsLong(v);
1052
164
        assert(symbol >= 0 || PyErr_Occurred());
1053
164
        RETURN_IF_ERROR(symbol);
1054
164
        long scope = SYMBOL_TO_SCOPE(symbol);
1055
1056
164
        long outsymbol = _PyST_GetSymbol(c->u->u_ste, k);
1057
164
        RETURN_IF_ERROR(outsymbol);
1058
164
        long outsc = SYMBOL_TO_SCOPE(outsymbol);
1059
1060
        // If a name has different scope inside than outside the comprehension,
1061
        // we need to temporarily handle it with the right scope while
1062
        // compiling the comprehension. If it's free in the comprehension
1063
        // scope, no special handling; it should be handled the same as the
1064
        // enclosing scope. (If it's free in outer scope and cell in inner
1065
        // scope, we can't treat it as both cell and free in the same function,
1066
        // but treating it as free throughout is fine; it's *_DEREF
1067
        // either way.)
1068
164
        if ((scope != outsc && scope != FREE && !(scope == CELL && outsc == FREE))
1069
111
                || in_class_block) {
1070
54
            if (state->temp_symbols == NULL) {
1071
53
                state->temp_symbols = PyDict_New();
1072
53
                if (state->temp_symbols == NULL) {
1073
0
                    return ERROR;
1074
0
                }
1075
53
            }
1076
            // update the symbol to the in-comprehension version and save
1077
            // the outer version; we'll restore it after running the
1078
            // comprehension
1079
54
            if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v) < 0) {
1080
0
                return ERROR;
1081
0
            }
1082
54
            PyObject *outv = PyLong_FromLong(outsymbol);
1083
54
            if (outv == NULL) {
1084
0
                return ERROR;
1085
0
            }
1086
54
            int res = PyDict_SetItem(state->temp_symbols, k, outv);
1087
54
            Py_DECREF(outv);
1088
54
            RETURN_IF_ERROR(res);
1089
54
        }
1090
        // locals handling for names bound in comprehension (DEF_LOCAL |
1091
        // DEF_NONLOCAL occurs in assignment expression to nonlocal)
1092
164
        if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) {
1093
64
            if (!_PyST_IsFunctionLike(c->u->u_ste)) {
1094
                // non-function scope: override this name to use fast locals
1095
5
                PyObject *orig;
1096
5
                if (PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, k, &orig) < 0) {
1097
0
                    return ERROR;
1098
0
                }
1099
5
                assert(orig == NULL || orig == Py_True || orig == Py_False);
1100
5
                if (orig != Py_True) {
1101
5
                    if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_True) < 0) {
1102
0
                        return ERROR;
1103
0
                    }
1104
5
                    if (state->fast_hidden == NULL) {
1105
4
                        state->fast_hidden = PySet_New(NULL);
1106
4
                        if (state->fast_hidden == NULL) {
1107
0
                            return ERROR;
1108
0
                        }
1109
4
                    }
1110
5
                    if (PySet_Add(state->fast_hidden, k) < 0) {
1111
0
                        return ERROR;
1112
0
                    }
1113
5
                }
1114
5
            }
1115
64
        }
1116
164
    }
1117
53
    return SUCCESS;
1118
53
}
1119
1120
int
1121
_PyCompile_RevertInlinedComprehensionScopes(compiler *c, location loc,
1122
                                             _PyCompile_InlinedComprehensionState *state)
1123
53
{
1124
53
    c->u->u_in_inlined_comp--;
1125
53
    if (state->temp_symbols) {
1126
53
        PyObject *k, *v;
1127
53
        Py_ssize_t pos = 0;
1128
107
        while (PyDict_Next(state->temp_symbols, &pos, &k, &v)) {
1129
54
            if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v)) {
1130
0
                return ERROR;
1131
0
            }
1132
54
        }
1133
53
        Py_CLEAR(state->temp_symbols);
1134
53
    }
1135
53
    if (state->fast_hidden) {
1136
9
        while (PySet_Size(state->fast_hidden) > 0) {
1137
5
            PyObject *k = PySet_Pop(state->fast_hidden);
1138
5
            if (k == NULL) {
1139
0
                return ERROR;
1140
0
            }
1141
            // we set to False instead of clearing, so we can track which names
1142
            // were temporarily fast-locals and should use CO_FAST_HIDDEN
1143
5
            if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_False)) {
1144
0
                Py_DECREF(k);
1145
0
                return ERROR;
1146
0
            }
1147
5
            Py_DECREF(k);
1148
5
        }
1149
4
        Py_CLEAR(state->fast_hidden);
1150
4
    }
1151
53
    return SUCCESS;
1152
53
}
1153
1154
void
1155
_PyCompile_EnterConditionalBlock(struct _PyCompiler *c)
1156
3.90k
{
1157
3.90k
    c->u->u_in_conditional_block++;
1158
3.90k
}
1159
1160
void
1161
_PyCompile_LeaveConditionalBlock(struct _PyCompiler *c)
1162
3.90k
{
1163
3.90k
    assert(c->u->u_in_conditional_block > 0);
1164
3.90k
    c->u->u_in_conditional_block--;
1165
3.90k
}
1166
1167
int
1168
_PyCompile_AddDeferredAnnotation(compiler *c, stmt_ty s,
1169
                                 PyObject **conditional_annotation_index)
1170
12
{
1171
12
    if (c->u->u_deferred_annotations == NULL) {
1172
6
        c->u->u_deferred_annotations = PyList_New(0);
1173
6
        if (c->u->u_deferred_annotations == NULL) {
1174
0
            return ERROR;
1175
0
        }
1176
6
    }
1177
12
    if (c->u->u_conditional_annotation_indices == NULL) {
1178
6
        c->u->u_conditional_annotation_indices = PyList_New(0);
1179
6
        if (c->u->u_conditional_annotation_indices == NULL) {
1180
0
            return ERROR;
1181
0
        }
1182
6
    }
1183
12
    PyObject *ptr = PyLong_FromVoidPtr((void *)s);
1184
12
    if (ptr == NULL) {
1185
0
        return ERROR;
1186
0
    }
1187
12
    if (PyList_Append(c->u->u_deferred_annotations, ptr) < 0) {
1188
0
        Py_DECREF(ptr);
1189
0
        return ERROR;
1190
0
    }
1191
12
    Py_DECREF(ptr);
1192
12
    PyObject *index;
1193
12
    if (c->u->u_scope_type == COMPILE_SCOPE_MODULE || c->u->u_in_conditional_block) {
1194
0
        index = PyLong_FromLong(c->u->u_next_conditional_annotation_index);
1195
0
        if (index == NULL) {
1196
0
            return ERROR;
1197
0
        }
1198
0
        *conditional_annotation_index = Py_NewRef(index);
1199
0
        c->u->u_next_conditional_annotation_index++;
1200
0
    }
1201
12
    else {
1202
12
        index = PyLong_FromLong(-1);
1203
12
        if (index == NULL) {
1204
0
            return ERROR;
1205
0
        }
1206
12
    }
1207
12
    int rc = PyList_Append(c->u->u_conditional_annotation_indices, index);
1208
12
    Py_DECREF(index);
1209
12
    RETURN_IF_ERROR(rc);
1210
12
    return SUCCESS;
1211
12
}
1212
1213
/* Raises a SyntaxError and returns ERROR.
1214
 * If something goes wrong, a different exception may be raised.
1215
 */
1216
int
1217
_PyCompile_Error(compiler *c, location loc, const char *format, ...)
1218
0
{
1219
0
    va_list vargs;
1220
0
    va_start(vargs, format);
1221
0
    PyObject *msg = PyUnicode_FromFormatV(format, vargs);
1222
0
    va_end(vargs);
1223
0
    if (msg == NULL) {
1224
0
        return ERROR;
1225
0
    }
1226
0
    _PyErr_RaiseSyntaxError(msg, c->c_filename, loc.lineno, loc.col_offset + 1,
1227
0
                            loc.end_lineno, loc.end_col_offset + 1);
1228
0
    Py_DECREF(msg);
1229
0
    return ERROR;
1230
0
}
1231
1232
/* Emits a SyntaxWarning and returns 0 on success.
1233
   If a SyntaxWarning raised as error, replaces it with a SyntaxError
1234
   and returns -1.
1235
*/
1236
int
1237
_PyCompile_Warn(compiler *c, location loc, const char *format, ...)
1238
0
{
1239
0
    if (c->c_disable_warning) {
1240
0
        return 0;
1241
0
    }
1242
0
    va_list vargs;
1243
0
    va_start(vargs, format);
1244
0
    PyObject *msg = PyUnicode_FromFormatV(format, vargs);
1245
0
    va_end(vargs);
1246
0
    if (msg == NULL) {
1247
0
        return ERROR;
1248
0
    }
1249
0
    int ret = _PyErr_EmitSyntaxWarning(msg, c->c_filename, loc.lineno, loc.col_offset + 1,
1250
0
                                       loc.end_lineno, loc.end_col_offset + 1,
1251
0
                                       c->c_module);
1252
0
    Py_DECREF(msg);
1253
0
    return ret;
1254
0
}
1255
1256
PyObject *
1257
_PyCompile_Mangle(compiler *c, PyObject *name)
1258
12
{
1259
12
    return _Py_Mangle(c->u->u_private, name);
1260
12
}
1261
1262
PyObject *
1263
_PyCompile_MaybeMangle(compiler *c, PyObject *name)
1264
65.7k
{
1265
65.7k
    return _Py_MaybeMangle(c->u->u_private, c->u->u_ste, name);
1266
65.7k
}
1267
1268
instr_sequence *
1269
_PyCompile_InstrSequence(compiler *c)
1270
232k
{
1271
232k
    return c->u->u_instr_sequence;
1272
232k
}
1273
1274
int
1275
_PyCompile_StartAnnotationSetup(struct _PyCompiler *c)
1276
0
{
1277
0
    instr_sequence *new_seq = (instr_sequence *)_PyInstructionSequence_New();
1278
0
    if (new_seq == NULL) {
1279
0
        return ERROR;
1280
0
    }
1281
0
    assert(c->u->u_stashed_instr_sequence == NULL);
1282
0
    c->u->u_stashed_instr_sequence = c->u->u_instr_sequence;
1283
0
    c->u->u_instr_sequence = new_seq;
1284
0
    return SUCCESS;
1285
0
}
1286
1287
int
1288
_PyCompile_EndAnnotationSetup(struct _PyCompiler *c)
1289
0
{
1290
0
    assert(c->u->u_stashed_instr_sequence != NULL);
1291
0
    instr_sequence *parent_seq = c->u->u_stashed_instr_sequence;
1292
0
    instr_sequence *anno_seq = c->u->u_instr_sequence;
1293
0
    c->u->u_stashed_instr_sequence = NULL;
1294
0
    c->u->u_instr_sequence = parent_seq;
1295
0
    if (_PyInstructionSequence_SetAnnotationsCode(parent_seq, anno_seq) == ERROR) {
1296
0
        Py_DECREF(anno_seq);
1297
0
        return ERROR;
1298
0
    }
1299
0
    return SUCCESS;
1300
0
}
1301
1302
1303
int
1304
_PyCompile_FutureFeatures(compiler *c)
1305
2.38k
{
1306
2.38k
    return c->c_future.ff_features;
1307
2.38k
}
1308
1309
struct symtable *
1310
_PyCompile_Symtable(compiler *c)
1311
7.67k
{
1312
7.67k
    return c->c_st;
1313
7.67k
}
1314
1315
PySTEntryObject *
1316
_PyCompile_SymtableEntry(compiler *c)
1317
76.9k
{
1318
76.9k
    return c->u->u_ste;
1319
76.9k
}
1320
1321
int
1322
_PyCompile_OptimizationLevel(compiler *c)
1323
87
{
1324
87
    return c->c_optimize;
1325
87
}
1326
1327
int
1328
_PyCompile_IsInteractiveTopLevel(compiler *c)
1329
3.45k
{
1330
3.45k
    assert(c->c_stack != NULL);
1331
3.45k
    assert(PyList_CheckExact(c->c_stack));
1332
3.45k
    bool is_nested_scope = PyList_GET_SIZE(c->c_stack) > 0;
1333
3.45k
    return c->c_interactive && !is_nested_scope;
1334
3.45k
}
1335
1336
int
1337
_PyCompile_ScopeType(compiler *c)
1338
824
{
1339
824
    return c->u->u_scope_type;
1340
824
}
1341
1342
int
1343
_PyCompile_IsInInlinedComp(compiler *c)
1344
1.17k
{
1345
1.17k
    return c->u->u_in_inlined_comp;
1346
1.17k
}
1347
1348
PyObject *
1349
_PyCompile_Qualname(compiler *c)
1350
725
{
1351
725
    assert(c->u->u_metadata.u_qualname);
1352
725
    return c->u->u_metadata.u_qualname;
1353
725
}
1354
1355
_PyCompile_CodeUnitMetadata *
1356
_PyCompile_Metadata(compiler *c)
1357
46.1k
{
1358
46.1k
    return &c->u->u_metadata;
1359
46.1k
}
1360
1361
// Merge *obj* with constant cache, without recursion.
1362
int
1363
_PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj)
1364
28.5k
{
1365
28.5k
    PyObject *key = const_cache_insert(const_cache, *obj, false);
1366
28.5k
    if (key == NULL) {
1367
0
        return ERROR;
1368
0
    }
1369
28.5k
    if (PyTuple_CheckExact(key)) {
1370
28.3k
        PyObject *item = PyTuple_GET_ITEM(key, 1);
1371
28.3k
        Py_SETREF(*obj, Py_NewRef(item));
1372
28.3k
        Py_DECREF(key);
1373
28.3k
    }
1374
122
    else {
1375
122
        Py_SETREF(*obj, key);
1376
122
    }
1377
28.5k
    return SUCCESS;
1378
28.5k
}
1379
1380
static PyObject *
1381
consts_dict_keys_inorder(PyObject *dict)
1382
4.58k
{
1383
4.58k
    PyObject *consts, *k, *v;
1384
4.58k
    Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
1385
1386
4.58k
    consts = PyList_New(size);   /* PyCode_Optimize() requires a list */
1387
4.58k
    if (consts == NULL)
1388
0
        return NULL;
1389
31.9k
    while (PyDict_Next(dict, &pos, &k, &v)) {
1390
27.3k
        assert(PyLong_CheckExact(v));
1391
27.3k
        i = PyLong_AsLong(v);
1392
        /* The keys of the dictionary can be tuples wrapping a constant.
1393
         * (see _PyCompile_DictAddObj and _PyCode_ConstantKey). In that case
1394
         * the object we want is always second. */
1395
27.3k
        if (PyTuple_CheckExact(k)) {
1396
2.29k
            k = PyTuple_GET_ITEM(k, 1);
1397
2.29k
        }
1398
27.3k
        assert(i < size);
1399
27.3k
        assert(i >= 0);
1400
27.3k
        PyList_SET_ITEM(consts, i, Py_NewRef(k));
1401
27.3k
    }
1402
4.58k
    return consts;
1403
4.58k
}
1404
1405
static int
1406
compute_code_flags(compiler *c)
1407
4.58k
{
1408
4.58k
    PySTEntryObject *ste = c->u->u_ste;
1409
4.58k
    int flags = 0;
1410
4.58k
    if (_PyST_IsFunctionLike(ste)) {
1411
3.27k
        flags |= CO_NEWLOCALS | CO_OPTIMIZED;
1412
3.27k
        if (ste->ste_nested)
1413
683
            flags |= CO_NESTED;
1414
3.27k
        if (ste->ste_generator && !ste->ste_coroutine)
1415
113
            flags |= CO_GENERATOR;
1416
3.27k
        if (ste->ste_generator && ste->ste_coroutine)
1417
0
            flags |= CO_ASYNC_GENERATOR;
1418
3.27k
        if (ste->ste_varargs)
1419
111
            flags |= CO_VARARGS;
1420
3.27k
        if (ste->ste_varkeywords)
1421
104
            flags |= CO_VARKEYWORDS;
1422
3.27k
        if (ste->ste_has_docstring)
1423
582
            flags |= CO_HAS_DOCSTRING;
1424
3.27k
        if (ste->ste_method)
1425
1.78k
            flags |= CO_METHOD;
1426
3.27k
    }
1427
1428
4.58k
    if (ste->ste_coroutine && !ste->ste_generator) {
1429
135
        flags |= CO_COROUTINE;
1430
135
    }
1431
1432
    /* (Only) inherit compilerflags in PyCF_MASK */
1433
4.58k
    flags |= (c->c_flags.cf_flags & PyCF_MASK);
1434
1435
4.58k
    return flags;
1436
4.58k
}
1437
1438
static PyCodeObject *
1439
optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache,
1440
                                int code_flags, PyObject *filename)
1441
4.58k
{
1442
4.58k
    cfg_builder *g = NULL;
1443
4.58k
    instr_sequence optimized_instrs;
1444
4.58k
    memset(&optimized_instrs, 0, sizeof(instr_sequence));
1445
1446
4.58k
    PyCodeObject *co = NULL;
1447
4.58k
    PyObject *consts = consts_dict_keys_inorder(u->u_metadata.u_consts);
1448
4.58k
    if (consts == NULL) {
1449
0
        goto error;
1450
0
    }
1451
4.58k
    g = _PyCfg_FromInstructionSequence(u->u_instr_sequence);
1452
4.58k
    if (g == NULL) {
1453
0
        goto error;
1454
0
    }
1455
4.58k
    int nlocals = (int)PyDict_GET_SIZE(u->u_metadata.u_varnames);
1456
4.58k
    int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames);
1457
4.58k
    assert(u->u_metadata.u_firstlineno);
1458
1459
4.58k
    if (_PyCfg_OptimizeCodeUnit(g, consts, const_cache, nlocals,
1460
4.58k
                                nparams, u->u_metadata.u_firstlineno) < 0) {
1461
0
        goto error;
1462
0
    }
1463
1464
4.58k
    int stackdepth;
1465
4.58k
    int nlocalsplus;
1466
4.58k
    if (_PyCfg_OptimizedCfgToInstructionSequence(g, &u->u_metadata,
1467
4.58k
                                                 &stackdepth, &nlocalsplus,
1468
4.58k
                                                 &optimized_instrs) < 0) {
1469
0
        goto error;
1470
0
    }
1471
1472
    /** Assembly **/
1473
4.58k
    co = _PyAssemble_MakeCodeObject(&u->u_metadata, const_cache, consts,
1474
4.58k
                                    stackdepth, &optimized_instrs, nlocalsplus,
1475
4.58k
                                    code_flags, filename);
1476
1477
4.58k
error:
1478
4.58k
    Py_XDECREF(consts);
1479
4.58k
    PyInstructionSequence_Fini(&optimized_instrs);
1480
4.58k
    _PyCfgBuilder_Free(g);
1481
4.58k
    return co;
1482
4.58k
}
1483
1484
1485
PyCodeObject *
1486
_PyCompile_OptimizeAndAssemble(compiler *c, int addNone)
1487
4.58k
{
1488
4.58k
    struct compiler_unit *u = c->u;
1489
4.58k
    PyObject *const_cache = c->c_const_cache;
1490
4.58k
    PyObject *filename = c->c_filename;
1491
1492
4.58k
    int code_flags = compute_code_flags(c);
1493
4.58k
    if (code_flags < 0) {
1494
0
        return NULL;
1495
0
    }
1496
1497
4.58k
    if (_PyCodegen_AddReturnAtEnd(c, addNone) < 0) {
1498
0
        return NULL;
1499
0
    }
1500
1501
4.58k
    return optimize_and_assemble_code_unit(u, const_cache, code_flags, filename);
1502
4.58k
}
1503
1504
PyCodeObject *
1505
_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
1506
               int optimize, PyArena *arena, PyObject *module)
1507
588
{
1508
588
    assert(!PyErr_Occurred());
1509
588
    compiler *c = new_compiler(mod, filename, pflags, optimize, arena, module);
1510
588
    if (c == NULL) {
1511
0
        return NULL;
1512
0
    }
1513
1514
588
    PyCodeObject *co = compiler_mod(c, mod);
1515
588
    compiler_free(c);
1516
588
    assert(co || PyErr_Occurred());
1517
588
    return co;
1518
588
}
1519
1520
int
1521
_PyCompile_AstPreprocess(mod_ty mod, PyObject *filename, PyCompilerFlags *cf,
1522
                         int optimize, PyArena *arena, int no_const_folding,
1523
                         PyObject *module)
1524
5.01k
{
1525
5.01k
    _PyFutureFeatures future;
1526
5.01k
    if (!_PyFuture_FromAST(mod, filename, &future)) {
1527
12
        return -1;
1528
12
    }
1529
4.99k
    int flags = future.ff_features | cf->cf_flags;
1530
4.99k
    if (optimize == -1) {
1531
4.99k
        optimize = _Py_GetConfig()->optimization_level;
1532
4.99k
    }
1533
4.99k
    if (!_PyAST_Preprocess(mod, arena, filename, optimize, flags,
1534
4.99k
                           no_const_folding, 0, module))
1535
0
    {
1536
0
        return -1;
1537
0
    }
1538
4.99k
    return 0;
1539
4.99k
}
1540
1541
// C implementation of inspect.cleandoc()
1542
//
1543
// Difference from inspect.cleandoc():
1544
// - Do not remove leading and trailing blank lines to keep lineno.
1545
PyObject *
1546
_PyCompile_CleanDoc(PyObject *doc)
1547
817
{
1548
817
    doc = PyObject_CallMethod(doc, "expandtabs", NULL);
1549
817
    if (doc == NULL) {
1550
0
        return NULL;
1551
0
    }
1552
1553
817
    Py_ssize_t doc_size;
1554
817
    const char *doc_utf8 = PyUnicode_AsUTF8AndSize(doc, &doc_size);
1555
817
    if (doc_utf8 == NULL) {
1556
0
        Py_DECREF(doc);
1557
0
        return NULL;
1558
0
    }
1559
817
    const char *p = doc_utf8;
1560
817
    const char *pend = p + doc_size;
1561
1562
    // First pass: find minimum indentation of any non-blank lines
1563
    // after first line.
1564
39.4k
    while (p < pend && *p++ != '\n') {
1565
38.6k
    }
1566
1567
817
    Py_ssize_t margin = PY_SSIZE_T_MAX;
1568
5.17k
    while (p < pend) {
1569
4.35k
        const char *s = p;
1570
26.3k
        while (*p == ' ') p++;
1571
4.35k
        if (p < pend && *p != '\n') {
1572
2.88k
            margin = Py_MIN(margin, p - s);
1573
2.88k
        }
1574
145k
        while (p < pend && *p++ != '\n') {
1575
140k
        }
1576
4.35k
    }
1577
817
    if (margin == PY_SSIZE_T_MAX) {
1578
351
        margin = 0;
1579
351
    }
1580
1581
    // Second pass: write cleandoc into buff.
1582
1583
    // copy first line without leading spaces.
1584
817
    p = doc_utf8;
1585
898
    while (*p == ' ') {
1586
81
        p++;
1587
81
    }
1588
817
    if (p == doc_utf8 && margin == 0 ) {
1589
        // doc is already clean.
1590
306
        return doc;
1591
306
    }
1592
1593
511
    char *buff = PyMem_Malloc(doc_size);
1594
511
    if (buff == NULL){
1595
0
        Py_DECREF(doc);
1596
0
        PyErr_NoMemory();
1597
0
        return NULL;
1598
0
    }
1599
1600
511
    char *w = buff;
1601
1602
25.4k
    while (p < pend) {
1603
25.4k
        int ch = *w++ = *p++;
1604
25.4k
        if (ch == '\n') {
1605
510
            break;
1606
510
        }
1607
25.4k
    }
1608
1609
    // copy subsequent lines without margin.
1610
4.64k
    while (p < pend) {
1611
23.2k
        for (Py_ssize_t i = 0; i < margin; i++, p++) {
1612
20.0k
            if (*p != ' ') {
1613
919
                assert(*p == '\n' || *p == '\0');
1614
919
                break;
1615
919
            }
1616
20.0k
        }
1617
140k
        while (p < pend) {
1618
140k
            int ch = *w++ = *p++;
1619
140k
            if (ch == '\n') {
1620
3.70k
                break;
1621
3.70k
            }
1622
140k
        }
1623
4.13k
    }
1624
1625
511
    Py_DECREF(doc);
1626
511
    PyObject *res = PyUnicode_FromStringAndSize(buff, w - buff);
1627
511
    PyMem_Free(buff);
1628
511
    return res;
1629
511
}
1630
1631
/* Access to compiler optimizations for unit tests.
1632
 *
1633
 * _PyCompile_CodeGen takes an AST, applies code-gen and
1634
 * returns the unoptimized CFG as an instruction list.
1635
 *
1636
 */
1637
PyObject *
1638
_PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
1639
                   int optimize, int compile_mode)
1640
0
{
1641
0
    PyObject *res = NULL;
1642
0
    PyObject *metadata = NULL;
1643
1644
0
    if (!PyAST_Check(ast)) {
1645
0
        PyErr_SetString(PyExc_TypeError, "expected an AST");
1646
0
        return NULL;
1647
0
    }
1648
1649
0
    PyArena *arena = _PyArena_New();
1650
0
    if (arena == NULL) {
1651
0
        return NULL;
1652
0
    }
1653
1654
0
    mod_ty mod = PyAST_obj2mod(ast, arena, compile_mode);
1655
0
    if (mod == NULL || !_PyAST_Validate(mod)) {
1656
0
        _PyArena_Free(arena);
1657
0
        return NULL;
1658
0
    }
1659
1660
0
    compiler *c = new_compiler(mod, filename, pflags, optimize, arena, NULL);
1661
0
    if (c == NULL) {
1662
0
        _PyArena_Free(arena);
1663
0
        return NULL;
1664
0
    }
1665
0
    c->c_save_nested_seqs = true;
1666
1667
0
    metadata = PyDict_New();
1668
0
    if (metadata == NULL) {
1669
0
        return NULL;
1670
0
    }
1671
1672
0
    if (compiler_codegen(c, mod) < 0) {
1673
0
        goto finally;
1674
0
    }
1675
1676
0
    _PyCompile_CodeUnitMetadata *umd = &c->u->u_metadata;
1677
1678
0
#define SET_METADATA_INT(key, value) do { \
1679
0
        PyObject *v = PyLong_FromLong((long)value); \
1680
0
        if (v == NULL) goto finally; \
1681
0
        int res = PyDict_SetItemString(metadata, key, v); \
1682
0
        Py_XDECREF(v); \
1683
0
        if (res < 0) goto finally; \
1684
0
    } while (0);
1685
1686
0
    SET_METADATA_INT("argcount", umd->u_argcount);
1687
0
    SET_METADATA_INT("posonlyargcount", umd->u_posonlyargcount);
1688
0
    SET_METADATA_INT("kwonlyargcount", umd->u_kwonlyargcount);
1689
0
#undef SET_METADATA_INT
1690
1691
0
    int addNone = mod->kind != Expression_kind;
1692
0
    if (_PyCodegen_AddReturnAtEnd(c, addNone) < 0) {
1693
0
        goto finally;
1694
0
    }
1695
1696
0
    if (_PyInstructionSequence_ApplyLabelMap(_PyCompile_InstrSequence(c)) < 0) {
1697
0
        return NULL;
1698
0
    }
1699
    /* Allocate a copy of the instruction sequence on the heap */
1700
0
    res = PyTuple_Pack(2, _PyCompile_InstrSequence(c), metadata);
1701
1702
0
finally:
1703
0
    Py_XDECREF(metadata);
1704
0
    _PyCompile_ExitScope(c);
1705
0
    compiler_free(c);
1706
0
    _PyArena_Free(arena);
1707
0
    return res;
1708
0
}
1709
1710
int _PyCfg_JumpLabelsToTargets(cfg_builder *g);
1711
1712
PyCodeObject *
1713
_PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename,
1714
                    PyObject *seq)
1715
0
{
1716
0
    if (!_PyInstructionSequence_Check(seq)) {
1717
0
        PyErr_SetString(PyExc_TypeError, "expected an instruction sequence");
1718
0
        return NULL;
1719
0
    }
1720
0
    cfg_builder *g = NULL;
1721
0
    PyCodeObject *co = NULL;
1722
0
    instr_sequence optimized_instrs;
1723
0
    memset(&optimized_instrs, 0, sizeof(instr_sequence));
1724
1725
0
    PyObject *const_cache = PyDict_New();
1726
0
    if (const_cache == NULL) {
1727
0
        return NULL;
1728
0
    }
1729
1730
0
    g = _PyCfg_FromInstructionSequence((instr_sequence*)seq);
1731
0
    if (g == NULL) {
1732
0
        goto error;
1733
0
    }
1734
1735
0
    if (_PyCfg_JumpLabelsToTargets(g) < 0) {
1736
0
        goto error;
1737
0
    }
1738
1739
0
    int code_flags = 0;
1740
0
    int stackdepth, nlocalsplus;
1741
0
    if (_PyCfg_OptimizedCfgToInstructionSequence(g, umd,
1742
0
                                                 &stackdepth, &nlocalsplus,
1743
0
                                                 &optimized_instrs) < 0) {
1744
0
        goto error;
1745
0
    }
1746
1747
0
    PyObject *consts = consts_dict_keys_inorder(umd->u_consts);
1748
0
    if (consts == NULL) {
1749
0
        goto error;
1750
0
    }
1751
0
    co = _PyAssemble_MakeCodeObject(umd, const_cache,
1752
0
                                    consts, stackdepth, &optimized_instrs,
1753
0
                                    nlocalsplus, code_flags, filename);
1754
0
    Py_DECREF(consts);
1755
1756
0
error:
1757
0
    Py_DECREF(const_cache);
1758
0
    _PyCfgBuilder_Free(g);
1759
0
    PyInstructionSequence_Fini(&optimized_instrs);
1760
0
    return co;
1761
0
}
1762
1763
/* Retained for API compatibility.
1764
 * Optimization is now done in _PyCfg_OptimizeCodeUnit */
1765
1766
PyObject *
1767
PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts),
1768
                PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj))
1769
0
{
1770
0
    return Py_NewRef(code);
1771
0
}