Coverage Report

Created: 2026-08-13 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Python/codegen.c
Line
Count
Source
1
/*
2
 * This file implements the compiler's code generation stage, which
3
 * produces a sequence of pseudo-instructions from an AST.
4
 *
5
 * The primary entry point is _PyCodegen_Module() for modules, and
6
 * _PyCodegen_Expression() for expressions.
7
 *
8
 * CAUTION: The VISIT_* macros abort the current function when they
9
 * encounter a problem. So don't invoke them when there is memory
10
 * which needs to be released. Code blocks are OK, as the compiler
11
 * structure takes care of releasing those.  Use the arena to manage
12
 * objects.
13
 */
14
15
#include "Python.h"
16
#include "opcode.h"
17
#include "pycore_ast.h"           // _PyAST_GetDocString()
18
#define NEED_OPCODE_TABLES
19
#include "pycore_opcode_utils.h"
20
#undef NEED_OPCODE_TABLES
21
#include "pycore_c_array.h"       // _Py_c_array_t
22
#include "pycore_code.h"          // COMPARISON_LESS_THAN
23
#include "pycore_compile.h"
24
#include "pycore_instruction_sequence.h" // _PyInstructionSequence_NewLabel()
25
#include "pycore_intrinsics.h"
26
#include "pycore_long.h"          // _PyLong_GetZero()
27
#include "pycore_object.h"        // _Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS
28
#include "pycore_pystate.h"       // _Py_GetConfig()
29
#include "pycore_symtable.h"      // PySTEntryObject
30
#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString
31
#include "pycore_ceval.h"         // SPECIAL___ENTER__
32
#include "pycore_template.h"      // _PyTemplate_Type
33
34
#define NEED_OPCODE_METADATA
35
#include "pycore_opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
36
#undef NEED_OPCODE_METADATA
37
38
#include <stdbool.h>
39
40
4.54k
#define COMP_GENEXP   0
41
268
#define COMP_LISTCOMP 1
42
4.66k
#define COMP_SETCOMP  2
43
2.08k
#define COMP_DICTCOMP 3
44
45
#undef SUCCESS
46
#undef ERROR
47
20.3M
#define SUCCESS 0
48
4.58k
#define ERROR -1
49
50
#define RETURN_IF_ERROR(X)  \
51
11.2M
    do {                    \
52
11.2M
        if ((X) == -1) {    \
53
3.55k
            return ERROR;   \
54
3.55k
        }                   \
55
11.2M
    } while (0)
56
57
#define RETURN_IF_ERROR_IN_SCOPE(C, CALL)   \
58
186k
    do {                                    \
59
186k
        if ((CALL) < 0) {                   \
60
73
            _PyCompile_ExitScope((C));      \
61
73
            return ERROR;                   \
62
73
        }                                   \
63
186k
    } while (0)
64
65
struct _PyCompiler;
66
typedef struct _PyCompiler compiler;
67
68
322k
#define INSTR_SEQUENCE(C) _PyCompile_InstrSequence(C)
69
72.4k
#define FUTURE_FEATURES(C) _PyCompile_FutureFeatures(C)
70
3.62k
#define SYMTABLE(C) _PyCompile_Symtable(C)
71
962k
#define SYMTABLE_ENTRY(C) _PyCompile_SymtableEntry(C)
72
2.17k
#define OPTIMIZATION_LEVEL(C) _PyCompile_OptimizationLevel(C)
73
89.8k
#define IS_INTERACTIVE_TOP_LEVEL(C) _PyCompile_IsInteractiveTopLevel(C)
74
52.9k
#define SCOPE_TYPE(C) _PyCompile_ScopeType(C)
75
#define QUALNAME(C) _PyCompile_Qualname(C)
76
156k
#define METADATA(C) _PyCompile_Metadata(C)
77
78
typedef _PyInstruction instruction;
79
typedef _PyInstructionSequence instr_sequence;
80
typedef _Py_SourceLocation location;
81
typedef _PyJumpTargetLabel jump_target_label;
82
83
typedef _PyCompile_FBlockInfo fblockinfo;
84
85
#define LOCATION(LNO, END_LNO, COL, END_COL) \
86
69.9k
    ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})
87
88
2.93M
#define LOC(x) SRC_LOCATION_FROM_AST(x)
89
90
#define NEW_JUMP_TARGET_LABEL(C, NAME) \
91
315k
    jump_target_label NAME = _PyInstructionSequence_NewLabel(INSTR_SEQUENCE(C)); \
92
315k
    if (!IS_JUMP_TARGET_LABEL(NAME)) { \
93
0
        return ERROR; \
94
0
    }
95
96
#define USE_LABEL(C, LBL) \
97
312k
    RETURN_IF_ERROR(_PyInstructionSequence_UseLabel(INSTR_SEQUENCE(C), (LBL).id))
98
99
static const int compare_masks[] = {
100
    [Py_LT] = COMPARISON_LESS_THAN,
101
    [Py_LE] = COMPARISON_LESS_THAN | COMPARISON_EQUALS,
102
    [Py_EQ] = COMPARISON_EQUALS,
103
    [Py_NE] = COMPARISON_NOT_EQUALS,
104
    [Py_GT] = COMPARISON_GREATER_THAN,
105
    [Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS,
106
};
107
108
109
int
110
12.7k
_Py_CArray_Init(_Py_c_array_t* array, int item_size, int initial_num_entries) {
111
12.7k
    memset(array, 0, sizeof(_Py_c_array_t));
112
12.7k
    array->item_size = item_size;
113
12.7k
    array->initial_num_entries = initial_num_entries;
114
12.7k
    return 0;
115
12.7k
}
116
117
void
118
_Py_CArray_Fini(_Py_c_array_t* array)
119
12.7k
{
120
12.7k
    if (array->array) {
121
2.33k
        PyMem_Free(array->array);
122
2.33k
        array->allocated_entries = 0;
123
2.33k
    }
124
12.7k
}
125
126
int
127
_Py_CArray_EnsureCapacity(_Py_c_array_t *c_array, int idx)
128
14.5M
{
129
14.5M
    void *arr = c_array->array;
130
14.5M
    int alloc = c_array->allocated_entries;
131
14.5M
    if (arr == NULL) {
132
680k
        int new_alloc = c_array->initial_num_entries;
133
680k
        if (idx >= new_alloc) {
134
29
            new_alloc = idx + c_array->initial_num_entries;
135
29
        }
136
680k
        arr = PyMem_Calloc(new_alloc, c_array->item_size);
137
680k
        if (arr == NULL) {
138
0
            PyErr_NoMemory();
139
0
            return ERROR;
140
0
        }
141
680k
        alloc = new_alloc;
142
680k
    }
143
13.8M
    else if (idx >= alloc) {
144
97.1k
        size_t oldsize = alloc * c_array->item_size;
145
97.1k
        int new_alloc = alloc << 1;
146
97.1k
        if (idx >= new_alloc) {
147
3
            new_alloc = idx + c_array->initial_num_entries;
148
3
        }
149
97.1k
        size_t newsize = new_alloc * c_array->item_size;
150
151
97.1k
        if (oldsize > (SIZE_MAX >> 1)) {
152
0
            PyErr_NoMemory();
153
0
            return ERROR;
154
0
        }
155
156
97.1k
        assert(newsize > 0);
157
97.1k
        void *tmp = PyMem_Realloc(arr, newsize);
158
97.1k
        if (tmp == NULL) {
159
0
            PyErr_NoMemory();
160
0
            return ERROR;
161
0
        }
162
97.1k
        alloc = new_alloc;
163
97.1k
        arr = tmp;
164
97.1k
        memset((char *)arr + oldsize, 0, newsize - oldsize);
165
97.1k
    }
166
167
14.5M
    c_array->array = arr;
168
14.5M
    c_array->allocated_entries = alloc;
169
14.5M
    return SUCCESS;
170
14.5M
}
171
172
173
typedef struct {
174
    // A list of strings corresponding to name captures. It is used to track:
175
    // - Repeated name assignments in the same pattern.
176
    // - Different name assignments in alternatives.
177
    // - The order of name assignments in alternatives.
178
    PyObject *stores;
179
    // If 0, any name captures against our subject will raise.
180
    int allow_irrefutable;
181
    // An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop
182
    // i items off of the stack. The end result looks like this (with each block
183
    // falling through to the next):
184
    // fail_pop[4]: POP_TOP
185
    // fail_pop[3]: POP_TOP
186
    // fail_pop[2]: POP_TOP
187
    // fail_pop[1]: POP_TOP
188
    // fail_pop[0]: NOP
189
    jump_target_label *fail_pop;
190
    // The current length of fail_pop.
191
    Py_ssize_t fail_pop_size;
192
    // The number of items on top of the stack that need to *stay* on top of the
193
    // stack. Variable captures go beneath these. All of them will be popped on
194
    // failure.
195
    Py_ssize_t on_top;
196
} pattern_context;
197
198
static int codegen_nameop(compiler *, location, identifier, expr_context_ty);
199
200
static int codegen_visit_stmt(compiler *, stmt_ty);
201
static int codegen_visit_keyword(compiler *, keyword_ty);
202
static int codegen_visit_expr(compiler *, expr_ty);
203
static int codegen_visit_unused_expr(compiler *, expr_ty);
204
static int codegen_augassign(compiler *, stmt_ty);
205
static int codegen_annassign(compiler *, stmt_ty);
206
static int codegen_subscript(compiler *, expr_ty);
207
static int codegen_slice_two_parts(compiler *, expr_ty);
208
static int codegen_slice(compiler *, expr_ty);
209
210
static int codegen_body(compiler *, location, asdl_stmt_seq *, bool);
211
static int codegen_with(compiler *, stmt_ty);
212
static int codegen_async_with(compiler *, stmt_ty);
213
static int codegen_with_inner(compiler *, stmt_ty, int);
214
static int codegen_async_with_inner(compiler *, stmt_ty, int);
215
static int codegen_async_for(compiler *, stmt_ty);
216
static int codegen_call_simple_kw_helper(compiler *c,
217
                                         location loc,
218
                                         asdl_keyword_seq *keywords,
219
                                         Py_ssize_t nkwelts);
220
static int codegen_call_helper_impl(compiler *c, location loc,
221
                                    int n, /* Args already pushed */
222
                                    asdl_expr_seq *args,
223
                                    PyObject *injected_arg,
224
                                    asdl_keyword_seq *keywords);
225
static int codegen_call_helper(compiler *c, location loc,
226
                               int n, asdl_expr_seq *args,
227
                               asdl_keyword_seq *keywords);
228
static int codegen_try_except(compiler *, stmt_ty);
229
static int codegen_try_star_except(compiler *, stmt_ty);
230
231
typedef enum {
232
    ITERABLE_IN_LOCAL = 0,
233
    ITERABLE_ON_STACK = 1,
234
    ITERATOR_ON_STACK = 2,
235
} IterStackPosition;
236
237
static int codegen_sync_comprehension_generator(
238
                                      compiler *c, location loc,
239
                                      asdl_comprehension_seq *generators, int gen_index,
240
                                      int depth,
241
                                      expr_ty elt, expr_ty val, int type,
242
                                      IterStackPosition iter_pos, bool avoid_creation);
243
244
static int codegen_async_comprehension_generator(
245
                                      compiler *c, location loc,
246
                                      asdl_comprehension_seq *generators, int gen_index,
247
                                      int depth,
248
                                      expr_ty elt, expr_ty val, int type,
249
                                      IterStackPosition iter_pos, bool avoid_creation);
250
251
static int codegen_pattern(compiler *, pattern_ty, pattern_context *);
252
static int codegen_match(compiler *, stmt_ty);
253
static int codegen_pattern_subpattern(compiler *,
254
                                      pattern_ty, pattern_context *);
255
static int codegen_make_closure(compiler *c, location loc,
256
                                PyCodeObject *co, Py_ssize_t flags);
257
258
259
/* Add an opcode with an integer argument */
260
static int
261
codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc)
262
3.78M
{
263
    /* oparg value is unsigned, but a signed C int is usually used to store
264
       it in the C code (like Python/ceval.c).
265
266
       Limit to 32-bit signed C int (rather than INT_MAX) for portability.
267
268
       The argument of a concrete bytecode instruction is limited to 8-bit.
269
       EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */
270
271
3.78M
    int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
272
3.78M
    assert(!IS_ASSEMBLER_OPCODE(opcode));
273
3.78M
    return _PyInstructionSequence_Addop(seq, opcode, oparg_, loc);
274
3.78M
}
275
276
#define ADDOP_I(C, LOC, OP, O) \
277
3.77M
    RETURN_IF_ERROR(codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
278
279
#define ADDOP_I_IN_SCOPE(C, LOC, OP, O) \
280
7.23k
    RETURN_IF_ERROR_IN_SCOPE(C, codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
281
282
static int
283
codegen_addop_noarg(instr_sequence *seq, int opcode, location loc)
284
996k
{
285
996k
    assert(!OPCODE_HAS_ARG(opcode));
286
996k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
287
996k
    return _PyInstructionSequence_Addop(seq, opcode, 0, loc);
288
996k
}
289
290
#define ADDOP(C, LOC, OP) \
291
962k
    RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
292
293
#define ADDOP_IN_SCOPE(C, LOC, OP) \
294
30.0k
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
295
296
static int
297
codegen_addop_load_const(compiler *c, location loc, PyObject *o)
298
1.27M
{
299
1.27M
    Py_ssize_t arg = _PyCompile_AddConst(c, o);
300
1.27M
    if (arg < 0) {
301
0
        return ERROR;
302
0
    }
303
1.27M
    ADDOP_I(c, loc, LOAD_CONST, arg);
304
1.27M
    return SUCCESS;
305
1.27M
}
306
307
#define ADDOP_LOAD_CONST(C, LOC, O) \
308
1.20M
    RETURN_IF_ERROR(codegen_addop_load_const((C), (LOC), (O)))
309
310
#define ADDOP_LOAD_CONST_IN_SCOPE(C, LOC, O) \
311
1
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_load_const((C), (LOC), (O)))
312
313
/* Same as ADDOP_LOAD_CONST, but steals a reference. */
314
#define ADDOP_LOAD_CONST_NEW(C, LOC, O)                                 \
315
71.9k
    do {                                                                \
316
71.9k
        PyObject *__new_const = (O);                                    \
317
71.9k
        if (__new_const == NULL) {                                      \
318
0
            return ERROR;                                               \
319
0
        }                                                               \
320
71.9k
        if (codegen_addop_load_const((C), (LOC), __new_const) < 0) {    \
321
0
            Py_DECREF(__new_const);                                     \
322
0
            return ERROR;                                               \
323
0
        }                                                               \
324
71.9k
        Py_DECREF(__new_const);                                         \
325
71.9k
    } while (0)
326
327
static int
328
codegen_addop_o(compiler *c, location loc,
329
                int opcode, PyObject *dict, PyObject *o)
330
156k
{
331
156k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, o);
332
156k
    RETURN_IF_ERROR(arg);
333
156k
    ADDOP_I(c, loc, opcode, arg);
334
156k
    return SUCCESS;
335
156k
}
336
337
#define ADDOP_N(C, LOC, OP, O, TYPE)                                    \
338
149k
    do {                                                                \
339
149k
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
340
149k
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
341
149k
                                  METADATA(C)->u_ ## TYPE, (O));        \
342
149k
        Py_DECREF((O));                                                 \
343
149k
        RETURN_IF_ERROR(ret);                                           \
344
149k
    } while (0)
345
346
#define ADDOP_N_IN_SCOPE(C, LOC, OP, O, TYPE)                           \
347
6.93k
    do {                                                                \
348
6.93k
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
349
6.93k
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
350
6.93k
                                  METADATA(C)->u_ ## TYPE, (O));        \
351
6.93k
        Py_DECREF((O));                                                 \
352
6.93k
        RETURN_IF_ERROR_IN_SCOPE((C), ret);                             \
353
6.93k
    } while (0)
354
355
54.4k
#define LOAD_METHOD -1
356
54.4k
#define LOAD_SUPER_METHOD -2
357
54.4k
#define LOAD_ZERO_SUPER_ATTR -3
358
54.4k
#define LOAD_ZERO_SUPER_METHOD -4
359
360
static int
361
codegen_addop_name_custom(compiler *c, location loc, int opcode,
362
                          PyObject *dict, PyObject *o, int shift, int low)
363
64.9k
{
364
64.9k
    PyObject *mangled = _PyCompile_MaybeMangle(c, o);
365
64.9k
    if (!mangled) {
366
0
        return ERROR;
367
0
    }
368
64.9k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, mangled);
369
64.9k
    Py_DECREF(mangled);
370
64.9k
    if (arg < 0) {
371
0
        return ERROR;
372
0
    }
373
64.9k
    ADDOP_I(c, loc, opcode, (arg << shift) | low);
374
64.9k
    return SUCCESS;
375
64.9k
}
376
377
static int
378
codegen_addop_name(compiler *c, location loc,
379
                   int opcode, PyObject *dict, PyObject *o)
380
54.4k
{
381
54.4k
    int shift = 0, low = 0;
382
54.4k
    if (opcode == LOAD_ATTR) {
383
13.2k
        shift = 1;
384
13.2k
    }
385
54.4k
    if (opcode == LOAD_METHOD) {
386
1.15k
        opcode = LOAD_ATTR;
387
1.15k
        shift = 1;
388
1.15k
        low = 1;
389
1.15k
    }
390
54.4k
    if (opcode == LOAD_SUPER_ATTR) {
391
499
        shift = 2;
392
499
        low = 2;
393
499
    }
394
54.4k
    if (opcode == LOAD_SUPER_METHOD) {
395
24
        opcode = LOAD_SUPER_ATTR;
396
24
        shift = 2;
397
24
        low = 3;
398
24
    }
399
54.4k
    if (opcode == LOAD_ZERO_SUPER_ATTR) {
400
0
        opcode = LOAD_SUPER_ATTR;
401
0
        shift = 2;
402
0
    }
403
54.4k
    if (opcode == LOAD_ZERO_SUPER_METHOD) {
404
0
        opcode = LOAD_SUPER_ATTR;
405
0
        shift = 2;
406
0
        low = 1;
407
0
    }
408
54.4k
    return codegen_addop_name_custom(c, loc, opcode, dict, o, shift, low);
409
54.4k
}
410
411
#define ADDOP_NAME(C, LOC, OP, O, TYPE) \
412
54.4k
    RETURN_IF_ERROR(codegen_addop_name((C), (LOC), (OP), METADATA(C)->u_ ## TYPE, (O)))
413
414
#define ADDOP_NAME_CUSTOM(C, LOC, OP, O, TYPE, SHIFT, LOW) \
415
10.5k
    RETURN_IF_ERROR(codegen_addop_name_custom((C), (LOC), (OP), METADATA(C)->u_ ## TYPE, (O), SHIFT, LOW))
416
417
    static int
418
codegen_addop_j(instr_sequence *seq, location loc,
419
                int opcode, jump_target_label target)
420
313k
{
421
313k
    assert(IS_JUMP_TARGET_LABEL(target));
422
313k
    assert(HAS_TARGET(opcode));
423
313k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
424
313k
    return _PyInstructionSequence_Addop(seq, opcode, target.id, loc);
425
313k
}
426
427
#define ADDOP_JUMP(C, LOC, OP, O) \
428
313k
    RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O)))
429
430
#define ADDOP_COMPARE(C, LOC, CMP) \
431
82.3k
    RETURN_IF_ERROR(codegen_addcompare((C), (LOC), (cmpop_ty)(CMP)))
432
433
#define ADDOP_BINARY(C, LOC, BINOP) \
434
793k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false))
435
436
#define ADDOP_INPLACE(C, LOC, BINOP) \
437
6.49k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true))
438
439
#define ADD_YIELD_FROM(C, LOC, await) \
440
35.9k
    RETURN_IF_ERROR(codegen_add_yield_from((C), (LOC), (await)))
441
442
#define POP_EXCEPT_AND_RERAISE(C, LOC) \
443
16.0k
    RETURN_IF_ERROR(codegen_pop_except_and_reraise((C), (LOC)))
444
445
#define ADDOP_YIELD(C, LOC) \
446
517
    RETURN_IF_ERROR(codegen_addop_yield((C), (LOC)))
447
448
/* VISIT and VISIT_SEQ takes an ASDL type as their second argument.  They use
449
   the ASDL name to synthesize the name of the C type and the visit function.
450
*/
451
452
#define VISIT(C, TYPE, V) \
453
2.53M
    RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), (V)))
454
455
#define VISIT_IN_SCOPE(C, TYPE, V) \
456
22.1k
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_visit_ ## TYPE((C), (V)))
457
458
#define VISIT_SEQ(C, TYPE, SEQ)                                             \
459
28.3k
    do {                                                                    \
460
28.3k
        asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */    \
461
85.0k
        for (int _i = 0; _i < asdl_seq_LEN(seq); _i++) {                    \
462
56.8k
            TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i);           \
463
56.8k
            RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), elt));              \
464
56.8k
        }                                                                   \
465
28.3k
    } while (0)
466
467
#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ)                                    \
468
    do {                                                                    \
469
        asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */    \
470
        for (int _i = 0; _i < asdl_seq_LEN(seq); _i++) {                    \
471
            TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i);           \
472
            if (codegen_visit_ ## TYPE((C), elt) < 0) {                     \
473
                _PyCompile_ExitScope(C);                                    \
474
                return ERROR;                                               \
475
            }                                                               \
476
        }                                                                   \
477
    } while (0)
478
479
#define VISIT_UNUSED(C, TYPE, V) \
480
83.7k
    RETURN_IF_ERROR(codegen_visit_unused_ ## TYPE((C), (V)))
481
482
static int
483
codegen_call_exit_with_nones(compiler *c, location loc)
484
13.5k
{
485
13.5k
    ADDOP_LOAD_CONST(c, loc, Py_None);
486
13.5k
    ADDOP_LOAD_CONST(c, loc, Py_None);
487
13.5k
    ADDOP_LOAD_CONST(c, loc, Py_None);
488
13.5k
    ADDOP_I(c, loc, CALL, 3);
489
13.5k
    return SUCCESS;
490
13.5k
}
491
492
static int
493
codegen_add_yield_from(compiler *c, location loc, int await)
494
35.9k
{
495
35.9k
    NEW_JUMP_TARGET_LABEL(c, send);
496
35.9k
    NEW_JUMP_TARGET_LABEL(c, fail);
497
35.9k
    NEW_JUMP_TARGET_LABEL(c, exit);
498
499
35.9k
    USE_LABEL(c, send);
500
35.9k
    ADDOP_JUMP(c, loc, SEND, exit);
501
    // Set up a virtual try/except to handle when StopIteration is raised during
502
    // a close or throw call. The only way YIELD_VALUE raises if they do!
503
35.9k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
504
35.9k
    ADDOP_I(c, loc, YIELD_VALUE, 1);
505
35.9k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
506
35.9k
    ADDOP_I(c, loc, RESUME, await ? RESUME_AFTER_AWAIT : RESUME_AFTER_YIELD_FROM);
507
35.9k
    ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
508
509
35.9k
    USE_LABEL(c, fail);
510
35.9k
    ADDOP(c, loc, CLEANUP_THROW);
511
512
35.9k
    USE_LABEL(c, exit);
513
35.9k
    ADDOP(c, loc, END_SEND);
514
35.9k
    return SUCCESS;
515
35.9k
}
516
517
static int
518
codegen_pop_except_and_reraise(compiler *c, location loc)
519
16.0k
{
520
    /* Stack contents
521
     * [exc_info, lasti, exc]            COPY        3
522
     * [exc_info, lasti, exc, exc_info]  POP_EXCEPT
523
     * [exc_info, lasti, exc]            RERAISE      1
524
     * (exception_unwind clears the stack)
525
     */
526
527
16.0k
    ADDOP_I(c, loc, COPY, 3);
528
16.0k
    ADDOP(c, loc, POP_EXCEPT);
529
16.0k
    ADDOP_I(c, loc, RERAISE, 1);
530
16.0k
    return SUCCESS;
531
16.0k
}
532
533
/* Unwind a frame block.  If preserve_tos is true, the TOS before
534
 * popping the blocks will be restored afterwards, unless another
535
 * return, break or continue is found. In which case, the TOS will
536
 * be popped.
537
 */
538
static int
539
codegen_unwind_fblock(compiler *c, location *ploc,
540
                      fblockinfo *info, int preserve_tos)
541
2.24k
{
542
2.24k
    switch (info->fb_type) {
543
0
        case COMPILE_FBLOCK_WHILE_LOOP:
544
2
        case COMPILE_FBLOCK_EXCEPTION_HANDLER:
545
2
        case COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER:
546
2
        case COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR:
547
196
        case COMPILE_FBLOCK_STOP_ITERATION:
548
196
            return SUCCESS;
549
550
0
        case COMPILE_FBLOCK_FOR_LOOP:
551
            /* Pop the iterator */
552
0
            if (preserve_tos) {
553
0
                ADDOP_I(c, *ploc, SWAP, 3);
554
0
            }
555
0
            ADDOP(c, *ploc, POP_TOP);
556
0
            ADDOP(c, *ploc, POP_TOP);
557
0
            return SUCCESS;
558
559
0
        case COMPILE_FBLOCK_ASYNC_FOR_LOOP:
560
            /* Pop the iterator */
561
0
            if (preserve_tos) {
562
0
                ADDOP_I(c, *ploc, SWAP, 2);
563
0
            }
564
0
            ADDOP(c, *ploc, POP_TOP);
565
0
            return SUCCESS;
566
567
2
        case COMPILE_FBLOCK_TRY_EXCEPT:
568
2
            ADDOP(c, *ploc, POP_BLOCK);
569
2
            return SUCCESS;
570
571
9
        case COMPILE_FBLOCK_FINALLY_TRY:
572
            /* This POP_BLOCK gets the line number of the unwinding statement */
573
9
            ADDOP(c, *ploc, POP_BLOCK);
574
9
            if (preserve_tos) {
575
0
                RETURN_IF_ERROR(
576
0
                    _PyCompile_PushFBlock(c, *ploc, COMPILE_FBLOCK_POP_VALUE,
577
0
                                          NO_LABEL, NO_LABEL, NULL));
578
0
            }
579
            /* Emit the finally block */
580
9
            VISIT_SEQ(c, stmt, info->fb_datum);
581
8
            if (preserve_tos) {
582
0
                _PyCompile_PopFBlock(c, COMPILE_FBLOCK_POP_VALUE, NO_LABEL);
583
0
            }
584
            /* The finally block should appear to execute after the
585
             * statement causing the unwinding, so make the unwinding
586
             * instruction artificial */
587
8
            *ploc = NO_LOCATION;
588
8
            return SUCCESS;
589
590
0
        case COMPILE_FBLOCK_FINALLY_END:
591
0
            if (preserve_tos) {
592
0
                ADDOP_I(c, *ploc, SWAP, 2);
593
0
            }
594
0
            ADDOP(c, *ploc, POP_TOP); /* exc_value */
595
0
            if (preserve_tos) {
596
0
                ADDOP_I(c, *ploc, SWAP, 2);
597
0
            }
598
0
            ADDOP(c, *ploc, POP_BLOCK);
599
0
            ADDOP(c, *ploc, POP_EXCEPT);
600
0
            return SUCCESS;
601
602
19
        case COMPILE_FBLOCK_WITH:
603
2.03k
        case COMPILE_FBLOCK_ASYNC_WITH:
604
2.03k
            *ploc = info->fb_loc;
605
2.03k
            ADDOP(c, *ploc, POP_BLOCK);
606
2.03k
            if (preserve_tos) {
607
57
                ADDOP_I(c, *ploc, SWAP, 3);
608
57
                ADDOP_I(c, *ploc, SWAP, 2);
609
57
            }
610
2.03k
            RETURN_IF_ERROR(codegen_call_exit_with_nones(c, *ploc));
611
2.03k
            if (info->fb_type == COMPILE_FBLOCK_ASYNC_WITH) {
612
2.01k
                ADDOP_I(c, *ploc, GET_AWAITABLE, 2);
613
2.01k
                ADDOP(c, *ploc, PUSH_NULL);
614
2.01k
                ADDOP_LOAD_CONST(c, *ploc, Py_None);
615
2.01k
                ADD_YIELD_FROM(c, *ploc, 1);
616
2.01k
            }
617
2.03k
            ADDOP(c, *ploc, POP_TOP);
618
            /* The exit block should appear to execute after the
619
             * statement causing the unwinding, so make the unwinding
620
             * instruction artificial */
621
2.03k
            *ploc = NO_LOCATION;
622
2.03k
            return SUCCESS;
623
624
4
        case COMPILE_FBLOCK_HANDLER_CLEANUP: {
625
4
            if (info->fb_datum) {
626
0
                ADDOP(c, *ploc, POP_BLOCK);
627
0
            }
628
4
            if (preserve_tos) {
629
0
                ADDOP_I(c, *ploc, SWAP, 2);
630
0
            }
631
4
            ADDOP(c, *ploc, POP_BLOCK);
632
4
            ADDOP(c, *ploc, POP_EXCEPT);
633
4
            if (info->fb_datum) {
634
0
                ADDOP_LOAD_CONST(c, *ploc, Py_None);
635
0
                RETURN_IF_ERROR(codegen_nameop(c, *ploc, info->fb_datum, Store));
636
0
                RETURN_IF_ERROR(codegen_nameop(c, *ploc, info->fb_datum, Del));
637
0
            }
638
4
            return SUCCESS;
639
4
        }
640
0
        case COMPILE_FBLOCK_POP_VALUE: {
641
0
            if (preserve_tos) {
642
0
                ADDOP_I(c, *ploc, SWAP, 2);
643
0
            }
644
0
            ADDOP(c, *ploc, POP_TOP);
645
0
            return SUCCESS;
646
0
        }
647
2.24k
    }
648
2.24k
    Py_UNREACHABLE();
649
2.24k
}
650
651
/** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */
652
static int
653
codegen_unwind_fblock_stack(compiler *c, location *ploc,
654
                            int preserve_tos, fblockinfo **loop)
655
2.57k
{
656
2.57k
    fblockinfo *top = _PyCompile_TopFBlock(c);
657
2.57k
    if (top == NULL) {
658
229
        return SUCCESS;
659
229
    }
660
2.34k
    if (top->fb_type == COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER) {
661
2
        return _PyCompile_Error(
662
2
            c, *ploc, "'break', 'continue' and 'return' cannot appear in an except* block");
663
2
    }
664
2.34k
    if (loop != NULL && (top->fb_type == COMPILE_FBLOCK_WHILE_LOOP ||
665
26
                         top->fb_type == COMPILE_FBLOCK_FOR_LOOP ||
666
105
                         top->fb_type == COMPILE_FBLOCK_ASYNC_FOR_LOOP)) {
667
105
        *loop = top;
668
105
        return SUCCESS;
669
105
    }
670
2.24k
    fblockinfo copy = *top;
671
2.24k
    _PyCompile_PopFBlock(c, top->fb_type, top->fb_block);
672
2.24k
    RETURN_IF_ERROR(codegen_unwind_fblock(c, ploc, &copy, preserve_tos));
673
2.24k
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, ploc, preserve_tos, loop));
674
2.23k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, copy.fb_loc, copy.fb_type, copy.fb_block,
675
2.23k
                          copy.fb_exit, copy.fb_datum));
676
2.23k
    return SUCCESS;
677
2.23k
}
678
679
static int
680
codegen_enter_scope(compiler *c, identifier name, int scope_type,
681
                    void *key, int lineno, PyObject *private,
682
                    _PyCompile_CodeUnitMetadata *umd)
683
53.3k
{
684
53.3k
    RETURN_IF_ERROR(
685
53.3k
        _PyCompile_EnterScope(c, name, scope_type, key, lineno, private, umd));
686
53.3k
    location loc = LOCATION(lineno, lineno, 0, 0);
687
53.3k
    if (scope_type == COMPILE_SCOPE_MODULE) {
688
10.5k
        loc.lineno = 0;
689
10.5k
    }
690
    /* Add the generator prefix instructions. */
691
692
53.3k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
693
53.3k
    if (ste->ste_coroutine || ste->ste_generator) {
694
        /* Note that RETURN_GENERATOR + POP_TOP have a net stack effect
695
         * of 0. This is because RETURN_GENERATOR pushes the generator
696
         before returning. */
697
3.14k
        location loc = LOCATION(lineno, lineno, -1, -1);
698
3.14k
        ADDOP(c, loc, RETURN_GENERATOR);
699
3.14k
        ADDOP(c, loc, POP_TOP);
700
3.14k
    }
701
702
53.3k
    ADDOP_I(c, loc, RESUME, RESUME_AT_FUNC_START);
703
53.3k
    if (scope_type == COMPILE_SCOPE_MODULE) {
704
10.5k
        ADDOP(c, loc, ANNOTATIONS_PLACEHOLDER);
705
10.5k
    }
706
53.3k
    return SUCCESS;
707
53.3k
}
708
709
static int
710
codegen_setup_annotations_scope(compiler *c, location loc,
711
                                void *key, PyObject *name)
712
12.6k
{
713
12.6k
    _PyCompile_CodeUnitMetadata umd = {
714
12.6k
        .u_posonlyargcount = 1,
715
12.6k
    };
716
12.6k
    RETURN_IF_ERROR(
717
12.6k
        codegen_enter_scope(c, name, COMPILE_SCOPE_ANNOTATIONS,
718
12.6k
                            key, loc.lineno, NULL, &umd));
719
720
    // if .format > VALUE_WITH_FAKE_GLOBALS: raise NotImplementedError
721
12.6k
    PyObject *value_with_fake_globals = PyLong_FromLong(_Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS);
722
12.6k
    if (value_with_fake_globals == NULL) {
723
0
        return ERROR;
724
0
    }
725
726
12.6k
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
727
12.6k
    _Py_DECLARE_STR(format, ".format");
728
12.6k
    ADDOP_I(c, loc, LOAD_FAST, 0);
729
12.6k
    ADDOP_LOAD_CONST_NEW(c, loc, value_with_fake_globals);
730
12.6k
    ADDOP_I(c, loc, COMPARE_OP, (Py_GT << 5) | compare_masks[Py_GT]);
731
12.6k
    NEW_JUMP_TARGET_LABEL(c, body);
732
12.6k
    ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, body);
733
12.6k
    ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR);
734
12.6k
    ADDOP_I(c, loc, RAISE_VARARGS, 1);
735
12.6k
    USE_LABEL(c, body);
736
12.6k
    return SUCCESS;
737
12.6k
}
738
739
static int
740
codegen_rename_annotations_format_param(PyCodeObject *co)
741
12.6k
{
742
    // We want the parameter to __annotate__ to be named "format" in the
743
    // signature  shown by inspect.signature(), but we need to use a
744
    // different name (.format) in the symtable; if the name
745
    // "format" appears in the annotations, it doesn't get clobbered
746
    // by this name.  This code is essentially:
747
    // co->co_localsplusnames = ("format", *co->co_localsplusnames[1:])
748
12.6k
    const Py_ssize_t size = PyObject_Size(co->co_localsplusnames);
749
12.6k
    if (size == -1) {
750
0
        return ERROR;
751
0
    }
752
12.6k
    PyObject *new_names = PyTuple_New(size);
753
12.6k
    if (new_names == NULL) {
754
0
        return ERROR;
755
0
    }
756
12.6k
    PyTuple_SET_ITEM(new_names, 0, Py_NewRef(&_Py_ID(format)));
757
19.3k
    for (int i = 1; i < size; i++) {
758
6.70k
        PyObject *item = PyTuple_GetItem(co->co_localsplusnames, i);
759
6.70k
        if (item == NULL) {
760
0
            Py_DECREF(new_names);
761
0
            return ERROR;
762
0
        }
763
6.70k
        Py_INCREF(item);
764
6.70k
        PyTuple_SET_ITEM(new_names, i, item);
765
6.70k
    }
766
12.6k
    Py_SETREF(co->co_localsplusnames, new_names);
767
12.6k
    return SUCCESS;
768
12.6k
}
769
770
static int
771
codegen_leave_annotations_scope(compiler *c, location loc)
772
9.94k
{
773
9.94k
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
774
9.94k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
775
9.94k
    if (co == NULL) {
776
0
        return ERROR;
777
0
    }
778
779
9.94k
    if (codegen_rename_annotations_format_param(co) < 0) {
780
0
        Py_DECREF(co);
781
0
        return ERROR;
782
0
    }
783
784
9.94k
    _PyCompile_ExitScope(c);
785
9.94k
    int ret = codegen_make_closure(c, loc, co, 0);
786
9.94k
    Py_DECREF(co);
787
9.94k
    RETURN_IF_ERROR(ret);
788
9.94k
    return SUCCESS;
789
9.94k
}
790
791
static int
792
codegen_deferred_annotations_body(compiler *c, location loc,
793
    PyObject *deferred_anno, PyObject *conditional_annotation_indices, int scope_type)
794
6.50k
{
795
6.50k
    Py_ssize_t annotations_len = PyList_GET_SIZE(deferred_anno);
796
797
6.50k
    assert(PyList_CheckExact(conditional_annotation_indices));
798
6.50k
    assert(annotations_len == PyList_Size(conditional_annotation_indices));
799
800
6.50k
    ADDOP_I(c, loc, BUILD_MAP, 0); // stack now contains <annos>
801
802
22.9k
    for (Py_ssize_t i = 0; i < annotations_len; i++) {
803
16.4k
        PyObject *ptr = PyList_GET_ITEM(deferred_anno, i);
804
0
        stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr);
805
16.4k
        if (st == NULL) {
806
0
            return ERROR;
807
0
        }
808
16.4k
        PyObject *mangled = _PyCompile_Mangle(c, st->v.AnnAssign.target->v.Name.id);
809
16.4k
        if (!mangled) {
810
0
            return ERROR;
811
0
        }
812
        // NOTE: ref of mangled can be leaked on ADDOP* and VISIT macros due to early returns
813
        // fixing would require an overhaul of these macros
814
815
16.4k
        PyObject *cond_index = PyList_GET_ITEM(conditional_annotation_indices, i);
816
16.4k
        assert(PyLong_CheckExact(cond_index));
817
16.4k
        long idx = PyLong_AS_LONG(cond_index);
818
16.4k
        NEW_JUMP_TARGET_LABEL(c, not_set);
819
820
16.4k
        if (idx != -1) {
821
4.46k
            ADDOP_LOAD_CONST(c, LOC(st), cond_index);
822
4.46k
            if (scope_type == COMPILE_SCOPE_CLASS) {
823
819
                ADDOP_NAME(
824
819
                    c, LOC(st), LOAD_DEREF, &_Py_ID(__conditional_annotations__), freevars);
825
819
            }
826
3.64k
            else {
827
3.64k
                ADDOP_NAME(
828
3.64k
                    c, LOC(st), LOAD_GLOBAL, &_Py_ID(__conditional_annotations__), names);
829
3.64k
            }
830
831
4.46k
            ADDOP_I(c, LOC(st), CONTAINS_OP, 0);
832
4.46k
            ADDOP_JUMP(c, LOC(st), POP_JUMP_IF_FALSE, not_set);
833
4.46k
        }
834
835
16.4k
        VISIT(c, expr, st->v.AnnAssign.annotation);
836
16.4k
        ADDOP_I(c, LOC(st), COPY, 2);
837
16.4k
        ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
838
        // stack now contains <annos> <name> <annos> <value>
839
16.4k
        ADDOP(c, loc, STORE_SUBSCR);
840
        // stack now contains <annos>
841
842
16.4k
        USE_LABEL(c, not_set);
843
16.4k
    }
844
6.49k
    return SUCCESS;
845
6.50k
}
846
847
static int
848
codegen_process_deferred_annotations(compiler *c, location loc)
849
19.3k
{
850
19.3k
    PyObject *deferred_anno = NULL;
851
19.3k
    PyObject *conditional_annotation_indices = NULL;
852
19.3k
    _PyCompile_DeferredAnnotations(c, &deferred_anno, &conditional_annotation_indices);
853
19.3k
    if (deferred_anno == NULL) {
854
12.8k
        assert(conditional_annotation_indices == NULL);
855
12.8k
        return SUCCESS;
856
12.8k
    }
857
858
6.50k
    int scope_type = SCOPE_TYPE(c);
859
6.50k
    bool need_separate_block = scope_type == COMPILE_SCOPE_MODULE;
860
6.50k
    if (need_separate_block) {
861
608
        if (_PyCompile_StartAnnotationSetup(c) == ERROR) {
862
0
            goto error;
863
0
        }
864
608
    }
865
866
    // It's possible that ste_annotations_block is set but
867
    // u_deferred_annotations is not, because the former is still
868
    // set if there are only non-simple annotations (i.e., annotations
869
    // for attributes, subscripts, or parenthesized names). However, the
870
    // reverse should not be possible.
871
6.50k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
872
6.50k
    assert(ste->ste_annotation_block != NULL);
873
6.50k
    void *key = (void *)((uintptr_t)ste->ste_id + 1);
874
6.50k
    if (codegen_setup_annotations_scope(c, loc, key,
875
6.50k
                                        ste->ste_annotation_block->ste_name) < 0) {
876
0
        goto error;
877
0
    }
878
6.50k
    if (codegen_deferred_annotations_body(c, loc, deferred_anno,
879
6.50k
                                          conditional_annotation_indices, scope_type) < 0) {
880
9
        _PyCompile_ExitScope(c);
881
9
        goto error;
882
9
    }
883
884
6.49k
    Py_DECREF(deferred_anno);
885
6.49k
    Py_DECREF(conditional_annotation_indices);
886
887
6.49k
    RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
888
6.49k
    RETURN_IF_ERROR(codegen_nameop(
889
6.49k
        c, loc,
890
6.49k
        ste->ste_type == ClassBlock ? &_Py_ID(__annotate_func__) : &_Py_ID(__annotate__),
891
6.49k
        Store));
892
893
6.49k
    if (need_separate_block) {
894
599
        RETURN_IF_ERROR(_PyCompile_EndAnnotationSetup(c));
895
599
    }
896
897
6.49k
    return SUCCESS;
898
9
error:
899
9
    Py_XDECREF(deferred_anno);
900
9
    Py_XDECREF(conditional_annotation_indices);
901
9
    return ERROR;
902
6.49k
}
903
904
/* Compile an expression */
905
int
906
_PyCodegen_Expression(compiler *c, expr_ty e)
907
1.51k
{
908
1.51k
    VISIT(c, expr, e);
909
1.47k
    return SUCCESS;
910
1.51k
}
911
912
/* Compile a sequence of statements, checking for a docstring
913
   and for annotations. */
914
915
int
916
_PyCodegen_Module(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interactive)
917
9.05k
{
918
9.05k
    if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) {
919
2.03k
        ADDOP_I(c, loc, BUILD_SET, 0);
920
2.03k
        ADDOP_N(c, loc, STORE_NAME, &_Py_ID(__conditional_annotations__), names);
921
2.03k
    }
922
9.05k
    return codegen_body(c, loc, stmts, is_interactive);
923
9.05k
}
924
925
int
926
codegen_body(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interactive)
927
22.1k
{
928
    /* If from __future__ import annotations is active,
929
     * every annotated class and module should have __annotations__.
930
     * Else __annotate__ is created when necessary. */
931
22.1k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
932
22.1k
    if ((FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) && ste->ste_annotations_used) {
933
2.00k
        ADDOP(c, loc, SETUP_ANNOTATIONS);
934
2.00k
    }
935
22.1k
    if (!asdl_seq_LEN(stmts)) {
936
91
        return SUCCESS;
937
91
    }
938
22.0k
    Py_ssize_t first_instr = 0;
939
22.0k
    if (!is_interactive) { /* A string literal on REPL prompt is not a docstring */
940
20.2k
        if (ste->ste_has_docstring) {
941
1.31k
            PyObject *docstring = _PyAST_GetDocString(stmts);
942
1.31k
            assert(docstring);
943
1.31k
            first_instr = 1;
944
            /* set docstring */
945
1.31k
            assert(OPTIMIZATION_LEVEL(c) < 2);
946
1.31k
            PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
947
1.31k
            if (cleandoc == NULL) {
948
0
                return ERROR;
949
0
            }
950
1.31k
            stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
951
1.31k
            assert(st->kind == Expr_kind);
952
1.31k
            location loc = LOC(st->v.Expr.value);
953
1.31k
            ADDOP_LOAD_CONST(c, loc, cleandoc);
954
1.31k
            Py_DECREF(cleandoc);
955
1.31k
            RETURN_IF_ERROR(codegen_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
956
1.31k
        }
957
20.2k
    }
958
134k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(stmts); i++) {
959
113k
        VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
960
113k
    }
961
    // If there are annotations and the future import is not on, we
962
    // collect the annotations in a separate pass and generate an
963
    // __annotate__ function. See PEP 649.
964
21.5k
    if (!(FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS)) {
965
19.3k
        RETURN_IF_ERROR(codegen_process_deferred_annotations(c, loc));
966
19.3k
    }
967
21.5k
    return SUCCESS;
968
21.5k
}
969
970
int
971
_PyCodegen_EnterAnonymousScope(compiler* c, mod_ty mod)
972
10.5k
{
973
10.5k
    _Py_DECLARE_STR(anon_module, "<module>");
974
10.5k
    RETURN_IF_ERROR(
975
10.5k
        codegen_enter_scope(c, &_Py_STR(anon_module), COMPILE_SCOPE_MODULE,
976
10.5k
                            mod, 1, NULL, NULL));
977
10.5k
    return SUCCESS;
978
10.5k
}
979
980
static int
981
codegen_make_closure(compiler *c, location loc,
982
                     PyCodeObject *co, Py_ssize_t flags)
983
42.7k
{
984
42.7k
    if (co->co_nfreevars) {
985
10.9k
        int i = PyUnstable_Code_GetFirstFree(co);
986
23.2k
        for (; i < co->co_nlocalsplus; ++i) {
987
            /* Bypass com_addop_varname because it will generate
988
               LOAD_DEREF but LOAD_CLOSURE is needed.
989
            */
990
12.3k
            PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
991
0
            int arg = _PyCompile_LookupArg(c, co, name);
992
12.3k
            RETURN_IF_ERROR(arg);
993
12.3k
            ADDOP_I(c, loc, LOAD_CLOSURE, arg);
994
12.3k
        }
995
10.9k
        flags |= MAKE_FUNCTION_CLOSURE;
996
10.9k
        ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
997
10.9k
    }
998
42.7k
    ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
999
1000
42.7k
    ADDOP(c, loc, MAKE_FUNCTION);
1001
1002
42.7k
    if (flags & MAKE_FUNCTION_CLOSURE) {
1003
10.9k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_CLOSURE);
1004
10.9k
    }
1005
42.7k
    if (flags & MAKE_FUNCTION_ANNOTATIONS) {
1006
0
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATIONS);
1007
0
    }
1008
42.7k
    if (flags & MAKE_FUNCTION_ANNOTATE) {
1009
3.42k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATE);
1010
3.42k
    }
1011
42.7k
    if (flags & MAKE_FUNCTION_KWDEFAULTS) {
1012
1.44k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_KWDEFAULTS);
1013
1.44k
    }
1014
42.7k
    if (flags & MAKE_FUNCTION_DEFAULTS) {
1015
3.04k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_DEFAULTS);
1016
3.04k
    }
1017
42.7k
    return SUCCESS;
1018
42.7k
}
1019
1020
static int
1021
codegen_decorators(compiler *c, asdl_expr_seq* decos)
1022
20.4k
{
1023
20.4k
    if (!decos) {
1024
19.8k
        return SUCCESS;
1025
19.8k
    }
1026
1027
2.51k
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) {
1028
1.89k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
1029
1.89k
    }
1030
624
    return SUCCESS;
1031
624
}
1032
1033
static int
1034
codegen_apply_decorators(compiler *c, asdl_expr_seq* decos)
1035
20.4k
{
1036
20.4k
    if (!decos) {
1037
19.8k
        return SUCCESS;
1038
19.8k
    }
1039
1040
2.51k
    for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
1041
1.89k
        location loc = LOC((expr_ty)asdl_seq_GET(decos, i));
1042
1.89k
        ADDOP_I(c, loc, CALL, 0);
1043
1.89k
    }
1044
624
    return SUCCESS;
1045
624
}
1046
1047
static int
1048
codegen_kwonlydefaults(compiler *c, location loc,
1049
                       asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
1050
11.7k
{
1051
    /* Push a dict of keyword-only default values.
1052
1053
       Return -1 on error, 0 if no dict pushed, 1 if a dict is pushed.
1054
       */
1055
11.7k
    int default_count = 0;
1056
14.2k
    for (int i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
1057
2.50k
        arg_ty arg = asdl_seq_GET(kwonlyargs, i);
1058
2.50k
        expr_ty default_ = asdl_seq_GET(kw_defaults, i);
1059
2.50k
        if (default_) {
1060
1.54k
            default_count++;
1061
1.54k
            PyObject *mangled = _PyCompile_MaybeMangle(c, arg->arg);
1062
1.54k
            if (!mangled) {
1063
0
                return ERROR;
1064
0
            }
1065
1.54k
            ADDOP_LOAD_CONST_NEW(c, loc, mangled);
1066
1.54k
            VISIT(c, expr, default_);
1067
1.54k
        }
1068
2.50k
    }
1069
11.7k
    if (default_count) {
1070
1.44k
        ADDOP_I(c, loc, BUILD_MAP, default_count);
1071
1.44k
        return 1;
1072
1.44k
    }
1073
10.3k
    else {
1074
10.3k
        return 0;
1075
10.3k
    }
1076
11.7k
}
1077
1078
static int
1079
codegen_visit_annexpr(compiler *c, expr_ty annotation)
1080
5.21k
{
1081
5.21k
    location loc = LOC(annotation);
1082
5.21k
    ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation));
1083
5.21k
    return SUCCESS;
1084
5.21k
}
1085
1086
static int
1087
codegen_argannotation(compiler *c, identifier id,
1088
    expr_ty annotation, Py_ssize_t *annotations_len, location loc)
1089
6.63k
{
1090
6.63k
    if (!annotation) {
1091
2.90k
        return SUCCESS;
1092
2.90k
    }
1093
3.73k
    PyObject *mangled = _PyCompile_MaybeMangle(c, id);
1094
3.73k
    if (!mangled) {
1095
0
        return ERROR;
1096
0
    }
1097
3.73k
    ADDOP_LOAD_CONST(c, loc, mangled);
1098
3.73k
    Py_DECREF(mangled);
1099
1100
3.73k
    if (FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) {
1101
1.15k
        VISIT(c, annexpr, annotation);
1102
1.15k
    }
1103
2.57k
    else {
1104
2.57k
        if (annotation->kind == Starred_kind) {
1105
            // *args: *Ts (where Ts is a TypeVarTuple).
1106
            // Do [annotation_value] = [*Ts].
1107
            // (Note that in theory we could end up here even for an argument
1108
            // other than *args, but in practice the grammar doesn't allow it.)
1109
87
            VISIT(c, expr, annotation->v.Starred.value);
1110
87
            ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1);
1111
87
        }
1112
2.48k
        else {
1113
2.48k
            VISIT(c, expr, annotation);
1114
2.48k
        }
1115
2.57k
    }
1116
3.73k
    *annotations_len += 1;
1117
3.73k
    return SUCCESS;
1118
3.73k
}
1119
1120
static int
1121
codegen_argannotations(compiler *c, asdl_arg_seq* args,
1122
                       Py_ssize_t *annotations_len, location loc)
1123
10.3k
{
1124
10.3k
    int i;
1125
12.6k
    for (i = 0; i < asdl_seq_LEN(args); i++) {
1126
2.27k
        arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
1127
2.27k
        RETURN_IF_ERROR(
1128
2.27k
            codegen_argannotation(
1129
2.27k
                        c,
1130
2.27k
                        arg->arg,
1131
2.27k
                        arg->annotation,
1132
2.27k
                        annotations_len,
1133
2.27k
                        loc));
1134
2.27k
    }
1135
10.3k
    return SUCCESS;
1136
10.3k
}
1137
1138
static int
1139
codegen_annotations_in_scope(compiler *c, location loc,
1140
                             arguments_ty args, expr_ty returns,
1141
                             Py_ssize_t *annotations_len)
1142
3.45k
{
1143
3.45k
    RETURN_IF_ERROR(
1144
3.45k
        codegen_argannotations(c, args->posonlyargs, annotations_len, loc));
1145
1146
3.45k
    RETURN_IF_ERROR(
1147
3.45k
        codegen_argannotations(c, args->args, annotations_len, loc));
1148
1149
3.45k
    if (args->vararg && args->vararg->annotation) {
1150
256
        RETURN_IF_ERROR(
1151
256
            codegen_argannotation(c, args->vararg->arg,
1152
256
                                     args->vararg->annotation, annotations_len, loc));
1153
256
    }
1154
1155
3.45k
    RETURN_IF_ERROR(
1156
3.45k
        codegen_argannotations(c, args->kwonlyargs, annotations_len, loc));
1157
1158
3.45k
    if (args->kwarg && args->kwarg->annotation) {
1159
657
        RETURN_IF_ERROR(
1160
657
            codegen_argannotation(c, args->kwarg->arg,
1161
657
                                     args->kwarg->annotation, annotations_len, loc));
1162
657
    }
1163
1164
3.45k
    RETURN_IF_ERROR(
1165
3.45k
        codegen_argannotation(c, &_Py_ID(return), returns, annotations_len, loc));
1166
1167
3.45k
    return 0;
1168
3.45k
}
1169
1170
static int
1171
codegen_function_annotations(compiler *c, location loc,
1172
                             arguments_ty args, expr_ty returns)
1173
7.42k
{
1174
    /* Push arg annotation names and values.
1175
       The expressions are evaluated separately from the rest of the source code.
1176
1177
       Return -1 on error, or a combination of flags to add to the function.
1178
       */
1179
7.42k
    Py_ssize_t annotations_len = 0;
1180
1181
7.42k
    PySTEntryObject *ste;
1182
7.42k
    RETURN_IF_ERROR(_PySymtable_LookupOptional(SYMTABLE(c), args, &ste));
1183
7.42k
    assert(ste != NULL);
1184
1185
7.42k
    if (ste->ste_annotations_used) {
1186
3.45k
        int err = codegen_setup_annotations_scope(c, loc, (void *)args, ste->ste_name);
1187
3.45k
        Py_DECREF(ste);
1188
3.45k
        RETURN_IF_ERROR(err);
1189
3.45k
        RETURN_IF_ERROR_IN_SCOPE(
1190
3.45k
            c, codegen_annotations_in_scope(c, loc, args, returns, &annotations_len)
1191
3.45k
        );
1192
3.45k
        ADDOP_I(c, loc, BUILD_MAP, annotations_len);
1193
3.45k
        RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
1194
3.45k
        return MAKE_FUNCTION_ANNOTATE;
1195
3.45k
    }
1196
3.97k
    else {
1197
3.97k
        Py_DECREF(ste);
1198
3.97k
    }
1199
1200
3.97k
    return 0;
1201
7.42k
}
1202
1203
static int
1204
codegen_defaults(compiler *c, arguments_ty args,
1205
                        location loc)
1206
382
{
1207
382
    VISIT_SEQ(c, expr, args->defaults);
1208
381
    ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
1209
381
    return SUCCESS;
1210
381
}
1211
1212
static Py_ssize_t
1213
codegen_default_arguments(compiler *c, location loc,
1214
                          arguments_ty args)
1215
11.7k
{
1216
11.7k
    Py_ssize_t funcflags = 0;
1217
11.7k
    if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
1218
382
        RETURN_IF_ERROR(codegen_defaults(c, args, loc));
1219
381
        funcflags |= MAKE_FUNCTION_DEFAULTS;
1220
381
    }
1221
11.7k
    if (args->kwonlyargs) {
1222
11.7k
        int res = codegen_kwonlydefaults(c, loc,
1223
11.7k
                                         args->kwonlyargs,
1224
11.7k
                                         args->kw_defaults);
1225
11.7k
        RETURN_IF_ERROR(res);
1226
11.7k
        if (res > 0) {
1227
1.44k
            funcflags |= MAKE_FUNCTION_KWDEFAULTS;
1228
1.44k
        }
1229
11.7k
    }
1230
11.7k
    return funcflags;
1231
11.7k
}
1232
1233
static int
1234
codegen_wrap_in_stopiteration_handler(compiler *c)
1235
2.84k
{
1236
2.84k
    NEW_JUMP_TARGET_LABEL(c, handler);
1237
1238
    /* Insert SETUP_CLEANUP just after the initial RETURN_GENERATOR; POP_TOP */
1239
2.84k
    instr_sequence *seq = INSTR_SEQUENCE(c);
1240
2.84k
    int resume = 0;
1241
3.90k
    while (_PyInstructionSequence_GetInstruction(seq, resume).i_opcode != RETURN_GENERATOR) {
1242
1.05k
        resume++;
1243
1.05k
        assert(resume < seq->s_used);
1244
1.05k
    }
1245
2.84k
    resume++;
1246
2.84k
    assert(_PyInstructionSequence_GetInstruction(seq, resume).i_opcode == POP_TOP);
1247
2.84k
    resume++;
1248
2.84k
    assert(resume < seq->s_used);
1249
2.84k
    RETURN_IF_ERROR(
1250
2.84k
        _PyInstructionSequence_InsertInstruction(
1251
2.84k
            seq, resume,
1252
2.84k
            SETUP_CLEANUP, handler.id, NO_LOCATION));
1253
1254
2.84k
    ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1255
2.84k
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
1256
2.84k
    USE_LABEL(c, handler);
1257
2.84k
    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
1258
2.84k
    ADDOP_I(c, NO_LOCATION, RERAISE, 1);
1259
2.84k
    return SUCCESS;
1260
2.84k
}
1261
1262
static int
1263
codegen_type_param_bound_or_default(compiler *c, expr_ty e,
1264
                                    identifier name, void *key,
1265
                                    bool allow_starred)
1266
2.28k
{
1267
2.28k
    PyObject *defaults = PyTuple_Pack(1, _PyLong_GetOne());
1268
2.28k
    ADDOP_LOAD_CONST_NEW(c, LOC(e), defaults);
1269
2.28k
    RETURN_IF_ERROR(codegen_setup_annotations_scope(c, LOC(e), key, name));
1270
2.28k
    if (allow_starred && e->kind == Starred_kind) {
1271
0
        VISIT_IN_SCOPE(c, expr, e->v.Starred.value);
1272
0
        ADDOP_I_IN_SCOPE(c, LOC(e), UNPACK_SEQUENCE, (Py_ssize_t)1);
1273
0
    }
1274
2.28k
    else {
1275
2.28k
        VISIT_IN_SCOPE(c, expr, e);
1276
2.28k
    }
1277
2.28k
    ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE);
1278
2.28k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1279
2.28k
    _PyCompile_ExitScope(c);
1280
2.28k
    if (co == NULL) {
1281
0
        return ERROR;
1282
0
    }
1283
2.28k
    if (codegen_rename_annotations_format_param(co) < 0) {
1284
0
        Py_DECREF(co);
1285
0
        return ERROR;
1286
0
    }
1287
2.28k
    int ret = codegen_make_closure(c, LOC(e), co, MAKE_FUNCTION_DEFAULTS);
1288
2.28k
    Py_DECREF(co);
1289
2.28k
    RETURN_IF_ERROR(ret);
1290
2.28k
    return SUCCESS;
1291
2.28k
}
1292
1293
static int
1294
codegen_type_params(compiler *c, asdl_type_param_seq *type_params)
1295
4.97k
{
1296
4.97k
    if (!type_params) {
1297
0
        return SUCCESS;
1298
0
    }
1299
4.97k
    Py_ssize_t n = asdl_seq_LEN(type_params);
1300
4.97k
    bool seen_default = false;
1301
1302
14.1k
    for (Py_ssize_t i = 0; i < n; i++) {
1303
9.19k
        type_param_ty typeparam = asdl_seq_GET(type_params, i);
1304
9.19k
        location loc = LOC(typeparam);
1305
9.19k
        switch(typeparam->kind) {
1306
8.82k
        case TypeVar_kind:
1307
8.82k
            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVar.name);
1308
8.82k
            if (typeparam->v.TypeVar.bound) {
1309
2.22k
                expr_ty bound = typeparam->v.TypeVar.bound;
1310
2.22k
                RETURN_IF_ERROR(
1311
2.22k
                    codegen_type_param_bound_or_default(c, bound, typeparam->v.TypeVar.name,
1312
2.22k
                                                        (void *)typeparam, false));
1313
1314
2.22k
                int intrinsic = bound->kind == Tuple_kind
1315
2.22k
                    ? INTRINSIC_TYPEVAR_WITH_CONSTRAINTS
1316
2.22k
                    : INTRINSIC_TYPEVAR_WITH_BOUND;
1317
2.22k
                ADDOP_I(c, loc, CALL_INTRINSIC_2, intrinsic);
1318
2.22k
            }
1319
6.59k
            else {
1320
6.59k
                ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVAR);
1321
6.59k
            }
1322
8.82k
            if (typeparam->v.TypeVar.default_value) {
1323
22
                seen_default = true;
1324
22
                expr_ty default_ = typeparam->v.TypeVar.default_value;
1325
22
                RETURN_IF_ERROR(
1326
22
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.TypeVar.name,
1327
22
                                                        (void *)((uintptr_t)typeparam + 1), false));
1328
22
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1329
22
            }
1330
8.80k
            else if (seen_default) {
1331
14
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1332
14
                                        "follows default type parameter",
1333
14
                                        typeparam->v.TypeVar.name);
1334
14
            }
1335
8.81k
            ADDOP_I(c, loc, COPY, 1);
1336
8.81k
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.TypeVar.name, Store));
1337
8.81k
            break;
1338
8.81k
        case TypeVarTuple_kind:
1339
319
            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVarTuple.name);
1340
319
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVARTUPLE);
1341
319
            if (typeparam->v.TypeVarTuple.default_value) {
1342
29
                expr_ty default_ = typeparam->v.TypeVarTuple.default_value;
1343
29
                RETURN_IF_ERROR(
1344
29
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.TypeVarTuple.name,
1345
29
                                                        (void *)typeparam, true));
1346
29
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1347
29
                seen_default = true;
1348
29
            }
1349
290
            else if (seen_default) {
1350
1
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1351
1
                                        "follows default type parameter",
1352
1
                                        typeparam->v.TypeVarTuple.name);
1353
1
            }
1354
318
            ADDOP_I(c, loc, COPY, 1);
1355
318
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.TypeVarTuple.name, Store));
1356
318
            break;
1357
318
        case ParamSpec_kind:
1358
47
            ADDOP_LOAD_CONST(c, loc, typeparam->v.ParamSpec.name);
1359
47
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PARAMSPEC);
1360
47
            if (typeparam->v.ParamSpec.default_value) {
1361
4
                expr_ty default_ = typeparam->v.ParamSpec.default_value;
1362
4
                RETURN_IF_ERROR(
1363
4
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.ParamSpec.name,
1364
4
                                                        (void *)typeparam, false));
1365
4
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1366
4
                seen_default = true;
1367
4
            }
1368
43
            else if (seen_default) {
1369
0
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1370
0
                                        "follows default type parameter",
1371
0
                                        typeparam->v.ParamSpec.name);
1372
0
            }
1373
47
            ADDOP_I(c, loc, COPY, 1);
1374
47
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.ParamSpec.name, Store));
1375
47
            break;
1376
9.19k
        }
1377
9.19k
    }
1378
4.95k
    ADDOP_I(c, LOC(asdl_seq_GET(type_params, 0)), BUILD_TUPLE, n);
1379
4.95k
    return SUCCESS;
1380
4.95k
}
1381
1382
static int
1383
codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags,
1384
                      int firstlineno)
1385
7.42k
{
1386
7.42k
    arguments_ty args;
1387
7.42k
    identifier name;
1388
7.42k
    asdl_stmt_seq *body;
1389
7.42k
    int scope_type;
1390
1391
7.42k
    if (is_async) {
1392
2.50k
        assert(s->kind == AsyncFunctionDef_kind);
1393
1394
2.50k
        args = s->v.AsyncFunctionDef.args;
1395
2.50k
        name = s->v.AsyncFunctionDef.name;
1396
2.50k
        body = s->v.AsyncFunctionDef.body;
1397
1398
2.50k
        scope_type = COMPILE_SCOPE_ASYNC_FUNCTION;
1399
4.92k
    } else {
1400
4.92k
        assert(s->kind == FunctionDef_kind);
1401
1402
4.92k
        args = s->v.FunctionDef.args;
1403
4.92k
        name = s->v.FunctionDef.name;
1404
4.92k
        body = s->v.FunctionDef.body;
1405
1406
4.92k
        scope_type = COMPILE_SCOPE_FUNCTION;
1407
4.92k
    }
1408
1409
7.42k
    _PyCompile_CodeUnitMetadata umd = {
1410
7.42k
        .u_argcount = asdl_seq_LEN(args->args),
1411
7.42k
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
1412
7.42k
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
1413
7.42k
    };
1414
7.42k
    RETURN_IF_ERROR(
1415
7.42k
        codegen_enter_scope(c, name, scope_type, (void *)s, firstlineno, NULL, &umd));
1416
1417
7.42k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1418
7.42k
    Py_ssize_t first_instr = 0;
1419
7.42k
    if (ste->ste_has_docstring) {
1420
628
        PyObject *docstring = _PyAST_GetDocString(body);
1421
628
        assert(docstring);
1422
628
        first_instr = 1;
1423
628
        docstring = _PyCompile_CleanDoc(docstring);
1424
628
        if (docstring == NULL) {
1425
0
            _PyCompile_ExitScope(c);
1426
0
            return ERROR;
1427
0
        }
1428
628
        Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1429
628
        Py_DECREF(docstring);
1430
628
        RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
1431
628
    }
1432
1433
7.42k
    NEW_JUMP_TARGET_LABEL(c, start);
1434
7.42k
    USE_LABEL(c, start);
1435
7.42k
    bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1436
7.42k
    if (add_stopiteration_handler) {
1437
        /* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1438
2.52k
        RETURN_IF_ERROR(
1439
2.52k
            _PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1440
2.52k
                                  start, NO_LABEL, NULL));
1441
2.52k
    }
1442
1443
22.5k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1444
15.1k
        VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1445
15.1k
    }
1446
7.39k
    if (add_stopiteration_handler) {
1447
2.49k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_wrap_in_stopiteration_handler(c));
1448
2.49k
        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1449
2.49k
    }
1450
7.39k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1451
7.39k
    _PyCompile_ExitScope(c);
1452
7.39k
    if (co == NULL) {
1453
0
        return ERROR;
1454
0
    }
1455
7.39k
    int ret = codegen_make_closure(c, LOC(s), co, funcflags);
1456
7.39k
    Py_DECREF(co);
1457
7.39k
    return ret;
1458
7.39k
}
1459
1460
static int
1461
codegen_function(compiler *c, stmt_ty s, int is_async)
1462
7.42k
{
1463
7.42k
    arguments_ty args;
1464
7.42k
    expr_ty returns;
1465
7.42k
    identifier name;
1466
7.42k
    asdl_expr_seq *decos;
1467
7.42k
    asdl_type_param_seq *type_params;
1468
7.42k
    Py_ssize_t funcflags;
1469
7.42k
    int firstlineno;
1470
1471
7.42k
    if (is_async) {
1472
2.50k
        assert(s->kind == AsyncFunctionDef_kind);
1473
1474
2.50k
        args = s->v.AsyncFunctionDef.args;
1475
2.50k
        returns = s->v.AsyncFunctionDef.returns;
1476
2.50k
        decos = s->v.AsyncFunctionDef.decorator_list;
1477
2.50k
        name = s->v.AsyncFunctionDef.name;
1478
2.50k
        type_params = s->v.AsyncFunctionDef.type_params;
1479
4.92k
    } else {
1480
4.92k
        assert(s->kind == FunctionDef_kind);
1481
1482
4.92k
        args = s->v.FunctionDef.args;
1483
4.92k
        returns = s->v.FunctionDef.returns;
1484
4.92k
        decos = s->v.FunctionDef.decorator_list;
1485
4.92k
        name = s->v.FunctionDef.name;
1486
4.92k
        type_params = s->v.FunctionDef.type_params;
1487
4.92k
    }
1488
1489
7.42k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1490
1491
7.42k
    firstlineno = s->lineno;
1492
7.42k
    if (asdl_seq_LEN(decos)) {
1493
310
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1494
310
    }
1495
1496
7.42k
    location loc = LOC(s);
1497
1498
7.42k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1499
1500
7.42k
    funcflags = codegen_default_arguments(c, loc, args);
1501
7.42k
    RETURN_IF_ERROR(funcflags);
1502
1503
7.42k
    int num_typeparam_args = 0;
1504
1505
7.42k
    if (is_generic) {
1506
2.28k
        if (funcflags & MAKE_FUNCTION_DEFAULTS) {
1507
0
            num_typeparam_args += 1;
1508
0
        }
1509
2.28k
        if (funcflags & MAKE_FUNCTION_KWDEFAULTS) {
1510
0
            num_typeparam_args += 1;
1511
0
        }
1512
2.28k
        if (num_typeparam_args == 2) {
1513
0
            ADDOP_I(c, loc, SWAP, 2);
1514
0
        }
1515
2.28k
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>", name);
1516
2.28k
        if (!type_params_name) {
1517
0
            return ERROR;
1518
0
        }
1519
2.28k
        _PyCompile_CodeUnitMetadata umd = {
1520
2.28k
            .u_argcount = num_typeparam_args,
1521
2.28k
        };
1522
2.28k
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1523
2.28k
                                      (void *)type_params, firstlineno, NULL, &umd);
1524
2.28k
        Py_DECREF(type_params_name);
1525
2.28k
        RETURN_IF_ERROR(ret);
1526
2.28k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1527
2.28k
        for (int i = 0; i < num_typeparam_args; i++) {
1528
0
            ADDOP_I_IN_SCOPE(c, loc, LOAD_FAST, i);
1529
0
        }
1530
2.28k
    }
1531
1532
7.42k
    int annotations_flag = codegen_function_annotations(c, loc, args, returns);
1533
7.42k
    if (annotations_flag < 0) {
1534
0
        if (is_generic) {
1535
0
            _PyCompile_ExitScope(c);
1536
0
        }
1537
0
        return ERROR;
1538
0
    }
1539
7.42k
    funcflags |= annotations_flag;
1540
1541
7.42k
    int ret = codegen_function_body(c, s, is_async, funcflags, firstlineno);
1542
7.42k
    if (is_generic) {
1543
2.28k
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1544
2.28k
    }
1545
5.13k
    else {
1546
5.13k
        RETURN_IF_ERROR(ret);
1547
5.13k
    }
1548
1549
7.39k
    if (is_generic) {
1550
2.28k
        ADDOP_I_IN_SCOPE(c, loc, SWAP, 2);
1551
2.28k
        ADDOP_I_IN_SCOPE(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_FUNCTION_TYPE_PARAMS);
1552
1553
2.28k
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1554
2.28k
        _PyCompile_ExitScope(c);
1555
2.28k
        if (co == NULL) {
1556
0
            return ERROR;
1557
0
        }
1558
2.28k
        int ret = codegen_make_closure(c, loc, co, 0);
1559
2.28k
        Py_DECREF(co);
1560
2.28k
        RETURN_IF_ERROR(ret);
1561
2.28k
        if (num_typeparam_args > 0) {
1562
0
            ADDOP_I(c, loc, SWAP, num_typeparam_args + 1);
1563
0
            ADDOP_I(c, loc, CALL, num_typeparam_args - 1);
1564
0
        }
1565
2.28k
        else {
1566
2.28k
            ADDOP(c, loc, PUSH_NULL);
1567
2.28k
            ADDOP_I(c, loc, CALL, 0);
1568
2.28k
        }
1569
2.28k
    }
1570
1571
7.39k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1572
7.39k
    return codegen_nameop(c, loc, name, Store);
1573
7.39k
}
1574
1575
static int
1576
codegen_set_type_params_in_class(compiler *c, location loc)
1577
2.67k
{
1578
2.67k
    _Py_DECLARE_STR(type_params, ".type_params");
1579
2.67k
    RETURN_IF_ERROR(codegen_nameop(c, loc, &_Py_STR(type_params), Load));
1580
2.67k
    RETURN_IF_ERROR(codegen_nameop(c, loc, &_Py_ID(__type_params__), Store));
1581
2.67k
    return SUCCESS;
1582
2.67k
}
1583
1584
1585
static int
1586
codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
1587
13.0k
{
1588
    /* ultimately generate code for:
1589
         <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>)
1590
       where:
1591
         <func> is a zero arg function/closure created from the class body.
1592
            It mutates its locals to build the class namespace.
1593
         <name> is the class name
1594
         <bases> is the positional arguments and *varargs argument
1595
         <keywords> is the keyword arguments and **kwds argument
1596
       This borrows from codegen_call.
1597
    */
1598
1599
    /* 1. compile the class body into a code object */
1600
13.0k
    RETURN_IF_ERROR(
1601
13.0k
        codegen_enter_scope(c, s->v.ClassDef.name, COMPILE_SCOPE_CLASS,
1602
13.0k
                            (void *)s, firstlineno, s->v.ClassDef.name, NULL));
1603
1604
13.0k
    location loc = LOCATION(firstlineno, firstlineno, 0, 0);
1605
    /* load (global) __name__ ... */
1606
13.0k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__name__), Load));
1607
    /* ... and store it as __module__ */
1608
13.0k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__module__), Store));
1609
13.0k
    ADDOP_LOAD_CONST(c, loc, QUALNAME(c));
1610
13.0k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__qualname__), Store));
1611
13.0k
    ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
1612
13.0k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__firstlineno__), Store));
1613
13.0k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1614
13.0k
    if (asdl_seq_LEN(type_params) > 0) {
1615
2.67k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_set_type_params_in_class(c, loc));
1616
2.67k
    }
1617
13.0k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1618
6.06k
        ADDOP(c, loc, LOAD_LOCALS);
1619
1620
        // We can't use codegen_nameop here because we need to generate a
1621
        // STORE_DEREF in a class namespace, and codegen_nameop() won't do
1622
        // that by default.
1623
6.06k
        ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__classdict__), cellvars);
1624
6.06k
    }
1625
13.0k
    if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) {
1626
873
        ADDOP_I(c, loc, BUILD_SET, 0);
1627
873
        ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
1628
873
    }
1629
    /* compile the body proper */
1630
13.0k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, false));
1631
13.0k
    PyObject *static_attributes = _PyCompile_StaticAttributesAsTuple(c);
1632
13.0k
    if (static_attributes == NULL) {
1633
0
        _PyCompile_ExitScope(c);
1634
0
        return ERROR;
1635
0
    }
1636
13.0k
    ADDOP_LOAD_CONST(c, NO_LOCATION, static_attributes);
1637
13.0k
    Py_CLEAR(static_attributes);
1638
13.0k
    RETURN_IF_ERROR_IN_SCOPE(
1639
13.0k
        c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__static_attributes__), Store));
1640
    /* The following code is artificial */
1641
    /* Set __classdictcell__ if necessary */
1642
13.0k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1643
        /* Store __classdictcell__ into class namespace */
1644
6.05k
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__classdict__));
1645
6.05k
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1646
6.05k
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1647
6.05k
        RETURN_IF_ERROR_IN_SCOPE(
1648
6.05k
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store));
1649
6.05k
    }
1650
    /* Return __classcell__ if it is referenced, otherwise return None */
1651
13.0k
    if (SYMTABLE_ENTRY(c)->ste_needs_class_closure) {
1652
        /* Store __classcell__ into class namespace & return it */
1653
25
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__class__));
1654
25
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1655
25
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1656
25
        ADDOP_I(c, NO_LOCATION, COPY, 1);
1657
25
        RETURN_IF_ERROR_IN_SCOPE(
1658
25
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store));
1659
25
    }
1660
13.0k
    else {
1661
        /* No methods referenced __class__, so just return None */
1662
13.0k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1663
13.0k
    }
1664
13.0k
    ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
1665
    /* create the code object */
1666
13.0k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1667
1668
    /* leave the new scope */
1669
13.0k
    _PyCompile_ExitScope(c);
1670
13.0k
    if (co == NULL) {
1671
0
        return ERROR;
1672
0
    }
1673
1674
    /* 2. load the 'build_class' function */
1675
1676
    // these instructions should be attributed to the class line,
1677
    // not a decorator line
1678
13.0k
    loc = LOC(s);
1679
13.0k
    ADDOP(c, loc, LOAD_BUILD_CLASS);
1680
13.0k
    ADDOP(c, loc, PUSH_NULL);
1681
1682
    /* 3. load a function (or closure) made from the code object */
1683
13.0k
    int ret = codegen_make_closure(c, loc, co, 0);
1684
13.0k
    Py_DECREF(co);
1685
13.0k
    RETURN_IF_ERROR(ret);
1686
1687
    /* 4. load class name */
1688
13.0k
    ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
1689
1690
13.0k
    return SUCCESS;
1691
13.0k
}
1692
1693
static int
1694
codegen_class(compiler *c, stmt_ty s)
1695
13.0k
{
1696
13.0k
    asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
1697
1698
13.0k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1699
1700
13.0k
    int firstlineno = s->lineno;
1701
13.0k
    if (asdl_seq_LEN(decos)) {
1702
314
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1703
314
    }
1704
13.0k
    location loc = LOC(s);
1705
1706
13.0k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1707
13.0k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1708
13.0k
    if (is_generic) {
1709
2.68k
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>",
1710
2.68k
                                                         s->v.ClassDef.name);
1711
2.68k
        if (!type_params_name) {
1712
0
            return ERROR;
1713
0
        }
1714
2.68k
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1715
2.68k
                                      (void *)type_params, firstlineno, s->v.ClassDef.name, NULL);
1716
2.68k
        Py_DECREF(type_params_name);
1717
2.68k
        RETURN_IF_ERROR(ret);
1718
2.68k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1719
2.67k
        _Py_DECLARE_STR(type_params, ".type_params");
1720
2.67k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(type_params), Store));
1721
2.67k
    }
1722
1723
13.0k
    int ret = codegen_class_body(c, s, firstlineno);
1724
13.0k
    if (is_generic) {
1725
2.67k
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1726
2.67k
    }
1727
10.3k
    else {
1728
10.3k
        RETURN_IF_ERROR(ret);
1729
10.3k
    }
1730
1731
    /* generate the rest of the code for the call */
1732
1733
13.0k
    if (is_generic) {
1734
2.67k
        _Py_DECLARE_STR(type_params, ".type_params");
1735
2.67k
        _Py_DECLARE_STR(generic_base, ".generic_base");
1736
2.67k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(type_params), Load));
1737
2.67k
        ADDOP_I_IN_SCOPE(c, loc, CALL_INTRINSIC_1, INTRINSIC_SUBSCRIPT_GENERIC);
1738
2.67k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(generic_base), Store));
1739
1740
2.67k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_call_helper_impl(c, loc, 2,
1741
2.67k
                                                             s->v.ClassDef.bases,
1742
2.67k
                                                             &_Py_STR(generic_base),
1743
2.67k
                                                             s->v.ClassDef.keywords));
1744
1745
2.67k
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1746
1747
2.67k
        _PyCompile_ExitScope(c);
1748
2.67k
        if (co == NULL) {
1749
0
            return ERROR;
1750
0
        }
1751
2.67k
        int ret = codegen_make_closure(c, loc, co, 0);
1752
2.67k
        Py_DECREF(co);
1753
2.67k
        RETURN_IF_ERROR(ret);
1754
2.67k
        ADDOP(c, loc, PUSH_NULL);
1755
2.67k
        ADDOP_I(c, loc, CALL, 0);
1756
10.3k
    } else {
1757
10.3k
        RETURN_IF_ERROR(codegen_call_helper(c, loc, 2,
1758
10.3k
                                            s->v.ClassDef.bases,
1759
10.3k
                                            s->v.ClassDef.keywords));
1760
10.3k
    }
1761
1762
    /* 6. apply decorators */
1763
13.0k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1764
1765
    /* 7. store into <name> */
1766
13.0k
    RETURN_IF_ERROR(codegen_nameop(c, loc, s->v.ClassDef.name, Store));
1767
13.0k
    return SUCCESS;
1768
13.0k
}
1769
1770
static int
1771
codegen_typealias_body(compiler *c, stmt_ty s)
1772
381
{
1773
381
    location loc = LOC(s);
1774
381
    PyObject *name = s->v.TypeAlias.name->v.Name.id;
1775
381
    PyObject *defaults = PyTuple_Pack(1, _PyLong_GetOne());
1776
381
    ADDOP_LOAD_CONST_NEW(c, loc, defaults);
1777
381
    RETURN_IF_ERROR(
1778
381
        codegen_setup_annotations_scope(c, LOC(s), s, name));
1779
1780
381
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
1781
381
    VISIT_IN_SCOPE(c, expr, s->v.TypeAlias.value);
1782
380
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
1783
380
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1784
380
    _PyCompile_ExitScope(c);
1785
380
    if (co == NULL) {
1786
0
        return ERROR;
1787
0
    }
1788
380
    if (codegen_rename_annotations_format_param(co) < 0) {
1789
0
        Py_DECREF(co);
1790
0
        return ERROR;
1791
0
    }
1792
380
    int ret = codegen_make_closure(c, loc, co, MAKE_FUNCTION_DEFAULTS);
1793
380
    Py_DECREF(co);
1794
380
    RETURN_IF_ERROR(ret);
1795
1796
380
    ADDOP_I(c, loc, BUILD_TUPLE, 3);
1797
380
    ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEALIAS);
1798
380
    return SUCCESS;
1799
380
}
1800
1801
static int
1802
codegen_typealias(compiler *c, stmt_ty s)
1803
381
{
1804
381
    location loc = LOC(s);
1805
381
    asdl_type_param_seq *type_params = s->v.TypeAlias.type_params;
1806
381
    int is_generic = asdl_seq_LEN(type_params) > 0;
1807
381
    PyObject *name = s->v.TypeAlias.name->v.Name.id;
1808
381
    if (is_generic) {
1809
1
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>",
1810
1
                                                         name);
1811
1
        if (!type_params_name) {
1812
0
            return ERROR;
1813
0
        }
1814
1
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1815
1
                                      (void *)type_params, loc.lineno, NULL, NULL);
1816
1
        Py_DECREF(type_params_name);
1817
1
        RETURN_IF_ERROR(ret);
1818
1
        ADDOP_LOAD_CONST_IN_SCOPE(c, loc, name);
1819
1
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1820
1
    }
1821
380
    else {
1822
380
        ADDOP_LOAD_CONST(c, loc, name);
1823
380
        ADDOP_LOAD_CONST(c, loc, Py_None);
1824
380
    }
1825
1826
381
    int ret = codegen_typealias_body(c, s);
1827
381
    if (is_generic) {
1828
1
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1829
1
    }
1830
380
    else {
1831
380
        RETURN_IF_ERROR(ret);
1832
380
    }
1833
1834
380
    if (is_generic) {
1835
1
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1836
1
        _PyCompile_ExitScope(c);
1837
1
        if (co == NULL) {
1838
0
            return ERROR;
1839
0
        }
1840
1
        int ret = codegen_make_closure(c, loc, co, 0);
1841
1
        Py_DECREF(co);
1842
1
        RETURN_IF_ERROR(ret);
1843
1
        ADDOP(c, loc, PUSH_NULL);
1844
1
        ADDOP_I(c, loc, CALL, 0);
1845
1
    }
1846
380
    RETURN_IF_ERROR(codegen_nameop(c, loc, name, Store));
1847
380
    return SUCCESS;
1848
380
}
1849
1850
static bool
1851
is_const_tuple(asdl_expr_seq *elts)
1852
295
{
1853
295
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(elts); i++) {
1854
8
        expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
1855
8
        if (e->kind != Constant_kind) {
1856
8
            return false;
1857
8
        }
1858
8
    }
1859
287
    return true;
1860
295
}
1861
1862
/* Return false if the expression is a constant value except named singletons.
1863
   Return true otherwise. */
1864
static bool
1865
check_is_arg(expr_ty e)
1866
103k
{
1867
103k
    if (e->kind == Tuple_kind) {
1868
295
        return !is_const_tuple(e->v.Tuple.elts);
1869
295
    }
1870
102k
    if (e->kind != Constant_kind) {
1871
84.4k
        return true;
1872
84.4k
    }
1873
18.5k
    PyObject *value = e->v.Constant.value;
1874
18.5k
    return (value == Py_None
1875
18.5k
         || value == Py_False
1876
18.5k
         || value == Py_True
1877
13.5k
         || value == Py_Ellipsis);
1878
102k
}
1879
1880
static PyTypeObject * infer_type(expr_ty e);
1881
1882
/* Check operands of identity checks ("is" and "is not").
1883
   Emit a warning if any operand is a constant except named singletons.
1884
 */
1885
static int
1886
codegen_check_compare(compiler *c, expr_ty e)
1887
22.0k
{
1888
22.0k
    Py_ssize_t i, n;
1889
22.0k
    bool left = check_is_arg(e->v.Compare.left);
1890
22.0k
    expr_ty left_expr = e->v.Compare.left;
1891
22.0k
    n = asdl_seq_LEN(e->v.Compare.ops);
1892
102k
    for (i = 0; i < n; i++) {
1893
81.2k
        cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
1894
81.2k
        expr_ty right_expr = (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i);
1895
81.2k
        bool right = check_is_arg(right_expr);
1896
81.2k
        if (op == Is || op == IsNot) {
1897
4.22k
            if (!right || !left) {
1898
1.14k
                const char *msg = (op == Is)
1899
1.14k
                        ? "\"is\" with '%.200s' literal. Did you mean \"==\"?"
1900
1.14k
                        : "\"is not\" with '%.200s' literal. Did you mean \"!=\"?";
1901
1.14k
                expr_ty literal = !left ? left_expr : right_expr;
1902
1.14k
                return _PyCompile_Warn(
1903
1.14k
                    c, LOC(e), msg, infer_type(literal)->tp_name
1904
1.14k
                );
1905
1.14k
            }
1906
4.22k
        }
1907
80.0k
        left = right;
1908
80.0k
        left_expr = right_expr;
1909
80.0k
    }
1910
20.8k
    return SUCCESS;
1911
22.0k
}
1912
1913
static int
1914
codegen_addcompare(compiler *c, location loc, cmpop_ty op)
1915
82.3k
{
1916
82.3k
    int cmp;
1917
82.3k
    switch (op) {
1918
3.81k
    case Eq:
1919
3.81k
        cmp = Py_EQ;
1920
3.81k
        break;
1921
122
    case NotEq:
1922
122
        cmp = Py_NE;
1923
122
        break;
1924
27.8k
    case Lt:
1925
27.8k
        cmp = Py_LT;
1926
27.8k
        break;
1927
1.57k
    case LtE:
1928
1.57k
        cmp = Py_LE;
1929
1.57k
        break;
1930
36.7k
    case Gt:
1931
36.7k
        cmp = Py_GT;
1932
36.7k
        break;
1933
5.94k
    case GtE:
1934
5.94k
        cmp = Py_GE;
1935
5.94k
        break;
1936
4.35k
    case Is:
1937
4.35k
        ADDOP_I(c, loc, IS_OP, 0);
1938
4.35k
        return SUCCESS;
1939
6
    case IsNot:
1940
6
        ADDOP_I(c, loc, IS_OP, 1);
1941
6
        return SUCCESS;
1942
1.79k
    case In:
1943
1.79k
        ADDOP_I(c, loc, CONTAINS_OP, 0);
1944
1.79k
        return SUCCESS;
1945
45
    case NotIn:
1946
45
        ADDOP_I(c, loc, CONTAINS_OP, 1);
1947
45
        return SUCCESS;
1948
0
    default:
1949
0
        Py_UNREACHABLE();
1950
82.3k
    }
1951
    // cmp goes in top three bits of the oparg, while the low four bits are used
1952
    // by quickened versions of this opcode to store the comparison mask. The
1953
    // fifth-lowest bit indicates whether the result should be converted to bool
1954
    // and is set later):
1955
76.1k
    ADDOP_I(c, loc, COMPARE_OP, (cmp << 5) | compare_masks[cmp]);
1956
76.1k
    return SUCCESS;
1957
76.1k
}
1958
1959
static int
1960
codegen_jump_if(compiler *c, location loc,
1961
                expr_ty e, jump_target_label next, int cond)
1962
9.71k
{
1963
9.71k
    switch (e->kind) {
1964
519
    case UnaryOp_kind:
1965
519
        if (e->v.UnaryOp.op == Not) {
1966
1
            return codegen_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond);
1967
1
        }
1968
        /* fallback to general implementation */
1969
518
        break;
1970
518
    case BoolOp_kind: {
1971
360
        asdl_expr_seq *s = e->v.BoolOp.values;
1972
360
        Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
1973
360
        assert(n >= 0);
1974
360
        int cond2 = e->v.BoolOp.op == Or;
1975
360
        jump_target_label next2 = next;
1976
360
        if (!cond2 != !cond) {
1977
221
            NEW_JUMP_TARGET_LABEL(c, new_next2);
1978
221
            next2 = new_next2;
1979
221
        }
1980
1.26k
        for (i = 0; i < n; ++i) {
1981
900
            RETURN_IF_ERROR(
1982
900
                codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2));
1983
900
        }
1984
360
        RETURN_IF_ERROR(
1985
360
            codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond));
1986
360
        if (!SAME_JUMP_TARGET_LABEL(next2, next)) {
1987
221
            USE_LABEL(c, next2);
1988
221
        }
1989
360
        return SUCCESS;
1990
360
    }
1991
718
    case IfExp_kind: {
1992
718
        NEW_JUMP_TARGET_LABEL(c, end);
1993
718
        NEW_JUMP_TARGET_LABEL(c, next2);
1994
718
        RETURN_IF_ERROR(
1995
718
            codegen_jump_if(c, loc, e->v.IfExp.test, next2, 0));
1996
718
        RETURN_IF_ERROR(
1997
718
            codegen_jump_if(c, loc, e->v.IfExp.body, next, cond));
1998
717
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1999
2000
717
        USE_LABEL(c, next2);
2001
717
        RETURN_IF_ERROR(
2002
717
            codegen_jump_if(c, loc, e->v.IfExp.orelse, next, cond));
2003
2004
717
        USE_LABEL(c, end);
2005
717
        return SUCCESS;
2006
717
    }
2007
1.29k
    case Compare_kind: {
2008
1.29k
        Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1;
2009
1.29k
        if (n > 0) {
2010
693
            RETURN_IF_ERROR(codegen_check_compare(c, e));
2011
693
            NEW_JUMP_TARGET_LABEL(c, cleanup);
2012
693
            VISIT(c, expr, e->v.Compare.left);
2013
3.48k
            for (Py_ssize_t i = 0; i < n; i++) {
2014
2.79k
                VISIT(c, expr,
2015
2.79k
                    (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
2016
2.79k
                ADDOP_I(c, LOC(e), SWAP, 2);
2017
2.79k
                ADDOP_I(c, LOC(e), COPY, 2);
2018
2.79k
                ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i));
2019
2.79k
                ADDOP(c, LOC(e), TO_BOOL);
2020
2.79k
                ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup);
2021
2.79k
            }
2022
691
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
2023
688
            ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n));
2024
688
            ADDOP(c, LOC(e), TO_BOOL);
2025
688
            ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2026
688
            NEW_JUMP_TARGET_LABEL(c, end);
2027
688
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2028
2029
688
            USE_LABEL(c, cleanup);
2030
688
            ADDOP(c, LOC(e), POP_TOP);
2031
688
            if (!cond) {
2032
437
                ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, next);
2033
437
            }
2034
2035
688
            USE_LABEL(c, end);
2036
688
            return SUCCESS;
2037
688
        }
2038
        /* fallback to general implementation */
2039
601
        break;
2040
1.29k
    }
2041
6.82k
    default:
2042
        /* fallback to general implementation */
2043
6.82k
        break;
2044
9.71k
    }
2045
2046
    /* general implementation */
2047
7.94k
    VISIT(c, expr, e);
2048
7.94k
    ADDOP(c, LOC(e), TO_BOOL);
2049
7.94k
    ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2050
7.94k
    return SUCCESS;
2051
7.94k
}
2052
2053
static int
2054
codegen_ifexp(compiler *c, expr_ty e)
2055
587
{
2056
587
    assert(e->kind == IfExp_kind);
2057
587
    NEW_JUMP_TARGET_LABEL(c, end);
2058
587
    NEW_JUMP_TARGET_LABEL(c, next);
2059
2060
587
    RETURN_IF_ERROR(
2061
587
        codegen_jump_if(c, LOC(e), e->v.IfExp.test, next, 0));
2062
2063
587
    VISIT(c, expr, e->v.IfExp.body);
2064
586
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2065
2066
586
    USE_LABEL(c, next);
2067
586
    VISIT(c, expr, e->v.IfExp.orelse);
2068
2069
570
    USE_LABEL(c, end);
2070
570
    return SUCCESS;
2071
570
}
2072
2073
static int
2074
codegen_lambda(compiler *c, expr_ty e)
2075
4.36k
{
2076
4.36k
    PyCodeObject *co;
2077
4.36k
    Py_ssize_t funcflags;
2078
4.36k
    arguments_ty args = e->v.Lambda.args;
2079
4.36k
    assert(e->kind == Lambda_kind);
2080
2081
4.36k
    location loc = LOC(e);
2082
4.36k
    funcflags = codegen_default_arguments(c, loc, args);
2083
4.36k
    RETURN_IF_ERROR(funcflags);
2084
2085
4.36k
    _PyCompile_CodeUnitMetadata umd = {
2086
4.36k
        .u_argcount = asdl_seq_LEN(args->args),
2087
4.36k
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
2088
4.36k
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
2089
4.36k
    };
2090
4.36k
    _Py_DECLARE_STR(anon_lambda, "<lambda>");
2091
4.36k
    RETURN_IF_ERROR(
2092
4.36k
        codegen_enter_scope(c, &_Py_STR(anon_lambda), COMPILE_SCOPE_LAMBDA,
2093
4.36k
                            (void *)e, e->lineno, NULL, &umd));
2094
2095
4.36k
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
2096
2097
4.36k
    VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
2098
4.35k
    if (SYMTABLE_ENTRY(c)->ste_generator) {
2099
0
        co = _PyCompile_OptimizeAndAssemble(c, 0);
2100
0
    }
2101
4.35k
    else {
2102
4.35k
        location loc = LOC(e->v.Lambda.body);
2103
4.35k
        ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
2104
4.35k
        co = _PyCompile_OptimizeAndAssemble(c, 1);
2105
4.35k
    }
2106
4.35k
    _PyCompile_ExitScope(c);
2107
4.35k
    if (co == NULL) {
2108
0
        return ERROR;
2109
0
    }
2110
2111
4.35k
    int ret = codegen_make_closure(c, loc, co, funcflags);
2112
4.35k
    Py_DECREF(co);
2113
4.35k
    RETURN_IF_ERROR(ret);
2114
4.35k
    return SUCCESS;
2115
4.35k
}
2116
2117
static int
2118
codegen_if(compiler *c, stmt_ty s)
2119
1.69k
{
2120
1.69k
    jump_target_label next;
2121
1.69k
    assert(s->kind == If_kind);
2122
1.69k
    NEW_JUMP_TARGET_LABEL(c, end);
2123
1.69k
    if (asdl_seq_LEN(s->v.If.orelse)) {
2124
360
        NEW_JUMP_TARGET_LABEL(c, orelse);
2125
360
        next = orelse;
2126
360
    }
2127
1.33k
    else {
2128
1.33k
        next = end;
2129
1.33k
    }
2130
1.69k
    RETURN_IF_ERROR(
2131
1.69k
        codegen_jump_if(c, LOC(s), s->v.If.test, next, 0));
2132
2133
1.69k
    VISIT_SEQ(c, stmt, s->v.If.body);
2134
1.68k
    if (asdl_seq_LEN(s->v.If.orelse)) {
2135
360
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2136
2137
360
        USE_LABEL(c, next);
2138
360
        VISIT_SEQ(c, stmt, s->v.If.orelse);
2139
360
    }
2140
2141
1.68k
    USE_LABEL(c, end);
2142
1.68k
    return SUCCESS;
2143
1.68k
}
2144
2145
static int
2146
codegen_for(compiler *c, stmt_ty s)
2147
623
{
2148
623
    location loc = LOC(s);
2149
623
    NEW_JUMP_TARGET_LABEL(c, start);
2150
623
    NEW_JUMP_TARGET_LABEL(c, body);
2151
623
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2152
623
    NEW_JUMP_TARGET_LABEL(c, end);
2153
2154
623
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FOR_LOOP, start, end, NULL));
2155
2156
623
    VISIT(c, expr, s->v.For.iter);
2157
2158
620
    loc = LOC(s->v.For.iter);
2159
620
    ADDOP_I(c, loc, GET_ITER, 0);
2160
2161
620
    USE_LABEL(c, start);
2162
620
    ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
2163
2164
    /* Add NOP to ensure correct line tracing of multiline for statements.
2165
     * It will be removed later if redundant.
2166
     */
2167
620
    ADDOP(c, LOC(s->v.For.target), NOP);
2168
2169
620
    USE_LABEL(c, body);
2170
620
    VISIT(c, expr, s->v.For.target);
2171
619
    VISIT_SEQ(c, stmt, s->v.For.body);
2172
    /* Mark jump as artificial */
2173
618
    ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
2174
2175
618
    USE_LABEL(c, cleanup);
2176
    /* It is important for instrumentation that the `END_FOR` comes first.
2177
    * Iteration over a generator will jump to the first of these instructions,
2178
    * but a non-generator will jump to the second instruction.
2179
    */
2180
618
    ADDOP(c, NO_LOCATION, END_FOR);
2181
618
    ADDOP(c, NO_LOCATION, POP_ITER);
2182
2183
618
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FOR_LOOP, start);
2184
2185
618
    VISIT_SEQ(c, stmt, s->v.For.orelse);
2186
2187
614
    USE_LABEL(c, end);
2188
614
    return SUCCESS;
2189
614
}
2190
2191
static int
2192
codegen_async_for(compiler *c, stmt_ty s)
2193
91
{
2194
91
    location loc = LOC(s);
2195
2196
91
    NEW_JUMP_TARGET_LABEL(c, start);
2197
91
    NEW_JUMP_TARGET_LABEL(c, send);
2198
91
    NEW_JUMP_TARGET_LABEL(c, except);
2199
91
    NEW_JUMP_TARGET_LABEL(c, end);
2200
2201
91
    VISIT(c, expr, s->v.AsyncFor.iter);
2202
90
    ADDOP(c, LOC(s->v.AsyncFor.iter), GET_AITER);
2203
2204
90
    USE_LABEL(c, start);
2205
90
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_FOR_LOOP, start, end, NULL));
2206
2207
    /* SETUP_FINALLY to guard the __anext__ call */
2208
90
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2209
90
    ADDOP(c, loc, GET_ANEXT);
2210
90
    ADDOP(c, loc, PUSH_NULL);
2211
90
    ADDOP_LOAD_CONST(c, loc, Py_None);
2212
90
    USE_LABEL(c, send);
2213
90
    ADD_YIELD_FROM(c, loc, 1);
2214
90
    ADDOP(c, loc, POP_BLOCK);  /* for SETUP_FINALLY */
2215
90
    ADDOP(c, loc, NOT_TAKEN);
2216
2217
    /* Success block for __anext__ */
2218
90
    VISIT(c, expr, s->v.AsyncFor.target);
2219
89
    VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
2220
    /* Mark jump as artificial */
2221
88
    ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
2222
2223
88
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_FOR_LOOP, start);
2224
2225
    /* Except block for __anext__ */
2226
88
    USE_LABEL(c, except);
2227
2228
    /* Use same line number as the iterator,
2229
     * as the END_ASYNC_FOR succeeds the `for`, not the body. */
2230
88
    loc = LOC(s->v.AsyncFor.iter);
2231
88
    ADDOP_JUMP(c, loc, END_ASYNC_FOR, send);
2232
2233
    /* `else` block */
2234
88
    VISIT_SEQ(c, stmt, s->v.AsyncFor.orelse);
2235
2236
87
    USE_LABEL(c, end);
2237
87
    return SUCCESS;
2238
87
}
2239
2240
static int
2241
codegen_while(compiler *c, stmt_ty s)
2242
2.13k
{
2243
2.13k
    NEW_JUMP_TARGET_LABEL(c, loop);
2244
2.13k
    NEW_JUMP_TARGET_LABEL(c, end);
2245
2.13k
    NEW_JUMP_TARGET_LABEL(c, anchor);
2246
2247
2.13k
    USE_LABEL(c, loop);
2248
2249
2.13k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, LOC(s), COMPILE_FBLOCK_WHILE_LOOP, loop, end, NULL));
2250
2.13k
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.While.test, anchor, 0));
2251
2252
2.13k
    VISIT_SEQ(c, stmt, s->v.While.body);
2253
2.13k
    ADDOP_JUMP(c, NO_LOCATION, JUMP, loop);
2254
2255
2.13k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_WHILE_LOOP, loop);
2256
2257
2.13k
    USE_LABEL(c, anchor);
2258
2.13k
    if (s->v.While.orelse) {
2259
166
        VISIT_SEQ(c, stmt, s->v.While.orelse);
2260
166
    }
2261
2262
2.13k
    USE_LABEL(c, end);
2263
2.13k
    return SUCCESS;
2264
2.13k
}
2265
2266
static int
2267
codegen_return(compiler *c, stmt_ty s)
2268
229
{
2269
229
    location loc = LOC(s);
2270
229
    int preserve_tos = ((s->v.Return.value != NULL) &&
2271
34
                        (s->v.Return.value->kind != Constant_kind));
2272
2273
229
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
2274
229
    if (!_PyST_IsFunctionLike(ste)) {
2275
31
        return _PyCompile_Error(c, loc, "'return' outside function");
2276
31
    }
2277
198
    if (s->v.Return.value != NULL && ste->ste_coroutine && ste->ste_generator) {
2278
0
        return _PyCompile_Error(c, loc, "'return' with value in async generator");
2279
0
    }
2280
2281
198
    if (preserve_tos) {
2282
23
        VISIT(c, expr, s->v.Return.value);
2283
175
    } else {
2284
        /* Emit instruction with line number for return value */
2285
175
        if (s->v.Return.value != NULL) {
2286
1
            loc = LOC(s->v.Return.value);
2287
1
            ADDOP(c, loc, NOP);
2288
1
        }
2289
175
    }
2290
195
    if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
2291
174
        loc = LOC(s);
2292
174
        ADDOP(c, loc, NOP);
2293
174
    }
2294
2295
195
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, preserve_tos, NULL));
2296
195
    if (s->v.Return.value == NULL) {
2297
174
        ADDOP_LOAD_CONST(c, loc, Py_None);
2298
174
    }
2299
21
    else if (!preserve_tos) {
2300
1
        ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value);
2301
1
    }
2302
195
    ADDOP(c, loc, RETURN_VALUE);
2303
2304
195
    return SUCCESS;
2305
195
}
2306
2307
static int
2308
codegen_break(compiler *c, location loc)
2309
9
{
2310
9
    fblockinfo *loop = NULL;
2311
9
    location origin_loc = loc;
2312
    /* Emit instruction with line number */
2313
9
    ADDOP(c, loc, NOP);
2314
9
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2315
9
    if (loop == NULL) {
2316
9
        return _PyCompile_Error(c, origin_loc, "'break' outside loop");
2317
9
    }
2318
0
    RETURN_IF_ERROR(codegen_unwind_fblock(c, &loc, loop, 0));
2319
0
    ADDOP_JUMP(c, loc, JUMP, loop->fb_exit);
2320
0
    return SUCCESS;
2321
0
}
2322
2323
static int
2324
codegen_continue(compiler *c, location loc)
2325
133
{
2326
133
    fblockinfo *loop = NULL;
2327
133
    location origin_loc = loc;
2328
    /* Emit instruction with line number */
2329
133
    ADDOP(c, loc, NOP);
2330
133
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2331
130
    if (loop == NULL) {
2332
25
        return _PyCompile_Error(c, origin_loc, "'continue' not properly in loop");
2333
25
    }
2334
105
    ADDOP_JUMP(c, loc, JUMP, loop->fb_block);
2335
105
    return SUCCESS;
2336
105
}
2337
2338
2339
/* Code generated for "try: <body> finally: <finalbody>" is as follows:
2340
2341
        SETUP_FINALLY           L
2342
        <code for body>
2343
        POP_BLOCK
2344
        <code for finalbody>
2345
        JUMP E
2346
    L:
2347
        <code for finalbody>
2348
    E:
2349
2350
   The special instructions use the block stack.  Each block
2351
   stack entry contains the instruction that created it (here
2352
   SETUP_FINALLY), the level of the value stack at the time the
2353
   block stack entry was created, and a label (here L).
2354
2355
   SETUP_FINALLY:
2356
    Pushes the current value stack level and the label
2357
    onto the block stack.
2358
   POP_BLOCK:
2359
    Pops en entry from the block stack.
2360
2361
   The block stack is unwound when an exception is raised:
2362
   when a SETUP_FINALLY entry is found, the raised and the caught
2363
   exceptions are pushed onto the value stack (and the exception
2364
   condition is cleared), and the interpreter jumps to the label
2365
   gotten from the block stack.
2366
*/
2367
2368
static int
2369
codegen_try_finally(compiler *c, stmt_ty s)
2370
2.06k
{
2371
2.06k
    location loc = LOC(s);
2372
2373
2.06k
    NEW_JUMP_TARGET_LABEL(c, body);
2374
2.06k
    NEW_JUMP_TARGET_LABEL(c, end);
2375
2.06k
    NEW_JUMP_TARGET_LABEL(c, exit);
2376
2.06k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2377
2378
    /* `try` block */
2379
2.06k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
2380
2381
2.06k
    USE_LABEL(c, body);
2382
2.06k
    RETURN_IF_ERROR(
2383
2.06k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_TRY, body, end,
2384
2.06k
                              s->v.Try.finalbody));
2385
2386
2.06k
    if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
2387
761
        RETURN_IF_ERROR(codegen_try_except(c, s));
2388
761
    }
2389
1.30k
    else {
2390
1.30k
        VISIT_SEQ(c, stmt, s->v.Try.body);
2391
1.30k
    }
2392
2.05k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2393
2.05k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_TRY, body);
2394
2.05k
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2395
2396
2.03k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
2397
    /* `finally` block */
2398
2399
2.03k
    USE_LABEL(c, end);
2400
2401
2.03k
    loc = NO_LOCATION;
2402
2.03k
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
2403
2.03k
    ADDOP(c, loc, PUSH_EXC_INFO);
2404
2.03k
    RETURN_IF_ERROR(
2405
2.03k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_END, end, NO_LABEL, NULL));
2406
2.03k
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2407
2.03k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_END, end);
2408
2409
2.03k
    loc = NO_LOCATION;
2410
2.03k
    ADDOP_I(c, loc, RERAISE, 0);
2411
2412
2.03k
    USE_LABEL(c, cleanup);
2413
2.03k
    POP_EXCEPT_AND_RERAISE(c, loc);
2414
2415
2.03k
    USE_LABEL(c, exit);
2416
2.03k
    return SUCCESS;
2417
2.03k
}
2418
2419
static int
2420
codegen_try_star_finally(compiler *c, stmt_ty s)
2421
112
{
2422
112
    location loc = LOC(s);
2423
2424
112
    NEW_JUMP_TARGET_LABEL(c, body);
2425
112
    NEW_JUMP_TARGET_LABEL(c, end);
2426
112
    NEW_JUMP_TARGET_LABEL(c, exit);
2427
112
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2428
    /* `try` block */
2429
112
    ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
2430
2431
112
    USE_LABEL(c, body);
2432
112
    RETURN_IF_ERROR(
2433
112
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_TRY, body, end,
2434
112
                              s->v.TryStar.finalbody));
2435
2436
112
    if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) {
2437
112
        RETURN_IF_ERROR(codegen_try_star_except(c, s));
2438
112
    }
2439
0
    else {
2440
0
        VISIT_SEQ(c, stmt, s->v.TryStar.body);
2441
0
    }
2442
111
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2443
111
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_TRY, body);
2444
111
    VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
2445
2446
107
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
2447
2448
    /* `finally` block */
2449
107
    USE_LABEL(c, end);
2450
2451
107
    loc = NO_LOCATION;
2452
107
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
2453
107
    ADDOP(c, loc, PUSH_EXC_INFO);
2454
107
    RETURN_IF_ERROR(
2455
107
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_END, end, NO_LABEL, NULL));
2456
2457
107
    VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
2458
2459
107
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_END, end);
2460
107
    loc = NO_LOCATION;
2461
107
    ADDOP_I(c, loc, RERAISE, 0);
2462
2463
107
    USE_LABEL(c, cleanup);
2464
107
    POP_EXCEPT_AND_RERAISE(c, loc);
2465
2466
107
    USE_LABEL(c, exit);
2467
107
    return SUCCESS;
2468
107
}
2469
2470
2471
/*
2472
   Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
2473
   (The contents of the value stack is shown in [], with the top
2474
   at the right; 'tb' is trace-back info, 'val' the exception's
2475
   associated value, and 'exc' the exception.)
2476
2477
   Value stack          Label   Instruction     Argument
2478
   []                           SETUP_FINALLY   L1
2479
   []                           <code for S>
2480
   []                           POP_BLOCK
2481
   []                           JUMP            L0
2482
2483
   [exc]                L1:     <evaluate E1>           )
2484
   [exc, E1]                    CHECK_EXC_MATCH         )
2485
   [exc, bool]                  POP_JUMP_IF_FALSE L2    ) only if E1
2486
   [exc]                        <assign to V1>  (or POP if no V1)
2487
   []                           <code for S1>
2488
                                JUMP            L0
2489
2490
   [exc]                L2:     <evaluate E2>
2491
   .............................etc.......................
2492
2493
   [exc]                Ln+1:   RERAISE     # re-raise exception
2494
2495
   []                   L0:     <next statement>
2496
2497
   Of course, parts are not generated if Vi or Ei is not present.
2498
*/
2499
static int
2500
codegen_try_except(compiler *c, stmt_ty s)
2501
1.20k
{
2502
1.20k
    location loc = LOC(s);
2503
1.20k
    Py_ssize_t i, n;
2504
2505
1.20k
    NEW_JUMP_TARGET_LABEL(c, body);
2506
1.20k
    NEW_JUMP_TARGET_LABEL(c, except);
2507
1.20k
    NEW_JUMP_TARGET_LABEL(c, end);
2508
1.20k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2509
2510
1.20k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2511
2512
1.20k
    USE_LABEL(c, body);
2513
1.20k
    RETURN_IF_ERROR(
2514
1.20k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_TRY_EXCEPT, body, NO_LABEL, NULL));
2515
1.20k
    VISIT_SEQ(c, stmt, s->v.Try.body);
2516
1.19k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_TRY_EXCEPT, body);
2517
1.19k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2518
1.19k
    if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
2519
81
        VISIT_SEQ(c, stmt, s->v.Try.orelse);
2520
81
    }
2521
1.19k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2522
1.19k
    n = asdl_seq_LEN(s->v.Try.handlers);
2523
2524
1.19k
    USE_LABEL(c, except);
2525
2526
1.19k
    ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
2527
1.19k
    ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
2528
2529
    /* Runtime will push a block here, so we need to account for that */
2530
1.19k
    RETURN_IF_ERROR(
2531
1.19k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_EXCEPTION_HANDLER,
2532
1.19k
                              NO_LABEL, NO_LABEL, NULL));
2533
2534
2.59k
    for (i = 0; i < n; i++) {
2535
1.40k
        excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
2536
1.40k
            s->v.Try.handlers, i);
2537
1.40k
        location loc = LOC(handler);
2538
1.40k
        if (!handler->v.ExceptHandler.type && i < n-1) {
2539
2
            return _PyCompile_Error(c, loc, "default 'except:' must be last");
2540
2
        }
2541
1.40k
        NEW_JUMP_TARGET_LABEL(c, next_except);
2542
1.40k
        except = next_except;
2543
1.40k
        if (handler->v.ExceptHandler.type) {
2544
298
            VISIT(c, expr, handler->v.ExceptHandler.type);
2545
297
            ADDOP(c, loc, CHECK_EXC_MATCH);
2546
297
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
2547
297
        }
2548
1.40k
        if (handler->v.ExceptHandler.name) {
2549
34
            NEW_JUMP_TARGET_LABEL(c, cleanup_end);
2550
34
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2551
2552
34
            RETURN_IF_ERROR(
2553
34
                codegen_nameop(c, loc, handler->v.ExceptHandler.name, Store));
2554
2555
            /*
2556
              try:
2557
                  # body
2558
              except type as name:
2559
                  try:
2560
                      # body
2561
                  finally:
2562
                      name = None # in case body contains "del name"
2563
                      del name
2564
            */
2565
2566
            /* second try: */
2567
34
            ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
2568
2569
34
            USE_LABEL(c, cleanup_body);
2570
34
            RETURN_IF_ERROR(
2571
34
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2572
34
                                      NO_LABEL, handler->v.ExceptHandler.name));
2573
2574
            /* second # body */
2575
34
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2576
32
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2577
            /* name = None; del name; # Mark as artificial */
2578
32
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2579
32
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2580
32
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2581
32
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2582
32
            RETURN_IF_ERROR(
2583
32
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2584
32
            RETURN_IF_ERROR(
2585
32
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2586
32
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2587
2588
            /* except: */
2589
32
            USE_LABEL(c, cleanup_end);
2590
2591
            /* name = None; del name; # artificial */
2592
32
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2593
32
            RETURN_IF_ERROR(
2594
32
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2595
32
            RETURN_IF_ERROR(
2596
32
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2597
2598
32
            ADDOP_I(c, NO_LOCATION, RERAISE, 1);
2599
32
        }
2600
1.37k
        else {
2601
1.37k
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2602
2603
1.37k
            ADDOP(c, loc, POP_TOP); /* exc_value */
2604
2605
1.37k
            USE_LABEL(c, cleanup_body);
2606
1.37k
            RETURN_IF_ERROR(
2607
1.37k
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2608
1.37k
                                      NO_LABEL, NULL));
2609
2610
1.37k
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2611
1.36k
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2612
1.36k
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2613
1.36k
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2614
1.36k
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2615
1.36k
        }
2616
2617
1.39k
        USE_LABEL(c, except);
2618
1.39k
    }
2619
    /* artificial */
2620
1.18k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_EXCEPTION_HANDLER, NO_LABEL);
2621
1.18k
    ADDOP_I(c, NO_LOCATION, RERAISE, 0);
2622
2623
1.18k
    USE_LABEL(c, cleanup);
2624
1.18k
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
2625
2626
1.18k
    USE_LABEL(c, end);
2627
1.18k
    return SUCCESS;
2628
1.18k
}
2629
2630
/*
2631
   Code generated for "try: S except* E1 as V1: S1 except* E2 as V2: S2 ...":
2632
   (The contents of the value stack is shown in [], with the top
2633
   at the right; 'tb' is trace-back info, 'val' the exception instance,
2634
   and 'typ' the exception's type.)
2635
2636
   Value stack                   Label         Instruction     Argument
2637
   []                                         SETUP_FINALLY         L1
2638
   []                                         <code for S>
2639
   []                                         POP_BLOCK
2640
   []                                         JUMP                  L0
2641
2642
   [exc]                            L1:       BUILD_LIST   )  list for raised/reraised excs ("result")
2643
   [orig, res]                                COPY 2       )  make a copy of the original EG
2644
2645
   [orig, res, exc]                           <evaluate E1>
2646
   [orig, res, exc, E1]                       CHECK_EG_MATCH
2647
   [orig, res, rest/exc, match?]              COPY 1
2648
   [orig, res, rest/exc, match?, match?]      POP_JUMP_IF_NONE      C1
2649
2650
   [orig, res, rest, match]                   <assign to V1>  (or POP if no V1)
2651
2652
   [orig, res, rest]                          SETUP_FINALLY         R1
2653
   [orig, res, rest]                          <code for S1>
2654
   [orig, res, rest]                          JUMP                  L2
2655
2656
   [orig, res, rest, i, v]          R1:       LIST_APPEND   3 ) exc raised in except* body - add to res
2657
   [orig, res, rest, i]                       POP
2658
   [orig, res, rest]                          JUMP                  LE2
2659
2660
   [orig, res, rest]                L2:       NOP  ) for lineno
2661
   [orig, res, rest]                          JUMP                  LE2
2662
2663
   [orig, res, rest/exc, None]      C1:       POP
2664
2665
   [orig, res, rest]               LE2:       <evaluate E2>
2666
   .............................etc.......................
2667
2668
   [orig, res, rest]                Ln+1:     LIST_APPEND 1  ) add unhandled exc to res (could be None)
2669
2670
   [orig, res]                                CALL_INTRINSIC_2 PREP_RERAISE_STAR
2671
   [exc]                                      COPY 1
2672
   [exc, exc]                                 POP_JUMP_IF_NOT_NONE  RER
2673
   [exc]                                      POP_TOP
2674
   []                                         JUMP                  L0
2675
2676
   [exc]                            RER:      SWAP 2
2677
   [exc, prev_exc_info]                       POP_EXCEPT
2678
   [exc]                                      RERAISE               0
2679
2680
   []                               L0:       <next statement>
2681
*/
2682
static int
2683
codegen_try_star_except(compiler *c, stmt_ty s)
2684
1.18k
{
2685
1.18k
    location loc = LOC(s);
2686
2687
1.18k
    NEW_JUMP_TARGET_LABEL(c, body);
2688
1.18k
    NEW_JUMP_TARGET_LABEL(c, except);
2689
1.18k
    NEW_JUMP_TARGET_LABEL(c, orelse);
2690
1.18k
    NEW_JUMP_TARGET_LABEL(c, end);
2691
1.18k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2692
1.18k
    NEW_JUMP_TARGET_LABEL(c, reraise_star);
2693
2694
1.18k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2695
2696
1.18k
    USE_LABEL(c, body);
2697
1.18k
    RETURN_IF_ERROR(
2698
1.18k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_TRY_EXCEPT, body, NO_LABEL, NULL));
2699
1.18k
    VISIT_SEQ(c, stmt, s->v.TryStar.body);
2700
1.17k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_TRY_EXCEPT, body);
2701
1.17k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2702
1.17k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, orelse);
2703
1.17k
    Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers);
2704
2705
1.17k
    USE_LABEL(c, except);
2706
2707
1.17k
    ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
2708
1.17k
    ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
2709
2710
    /* Runtime will push a block here, so we need to account for that */
2711
1.17k
    RETURN_IF_ERROR(
2712
1.17k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER,
2713
1.17k
                              NO_LABEL, NO_LABEL, "except handler"));
2714
2715
2.66k
    for (Py_ssize_t i = 0; i < n; i++) {
2716
1.48k
        excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
2717
1.48k
            s->v.TryStar.handlers, i);
2718
1.48k
        location loc = LOC(handler);
2719
1.48k
        NEW_JUMP_TARGET_LABEL(c, next_except);
2720
1.48k
        except = next_except;
2721
1.48k
        NEW_JUMP_TARGET_LABEL(c, except_with_error);
2722
1.48k
        NEW_JUMP_TARGET_LABEL(c, no_match);
2723
1.48k
        if (i == 0) {
2724
            /* create empty list for exceptions raised/reraise in the except* blocks */
2725
            /*
2726
               [orig]       BUILD_LIST
2727
            */
2728
            /* Create a copy of the original EG */
2729
            /*
2730
               [orig, []]   COPY 2
2731
               [orig, [], exc]
2732
            */
2733
1.17k
            ADDOP_I(c, loc, BUILD_LIST, 0);
2734
1.17k
            ADDOP_I(c, loc, COPY, 2);
2735
1.17k
        }
2736
1.48k
        if (handler->v.ExceptHandler.type) {
2737
1.48k
            VISIT(c, expr, handler->v.ExceptHandler.type);
2738
1.48k
            ADDOP(c, loc, CHECK_EG_MATCH);
2739
1.48k
            ADDOP_I(c, loc, COPY, 1);
2740
1.48k
            ADDOP_JUMP(c, loc, POP_JUMP_IF_NONE, no_match);
2741
1.48k
        }
2742
2743
1.48k
        NEW_JUMP_TARGET_LABEL(c, cleanup_end);
2744
1.48k
        NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2745
2746
1.48k
        if (handler->v.ExceptHandler.name) {
2747
38
            RETURN_IF_ERROR(
2748
38
                codegen_nameop(c, loc, handler->v.ExceptHandler.name, Store));
2749
38
        }
2750
1.44k
        else {
2751
1.44k
            ADDOP(c, loc, POP_TOP);  // match
2752
1.44k
        }
2753
2754
        /*
2755
          try:
2756
              # body
2757
          except type as name:
2758
              try:
2759
                  # body
2760
              finally:
2761
                  name = None # in case body contains "del name"
2762
                  del name
2763
        */
2764
        /* second try: */
2765
1.48k
        ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
2766
2767
1.48k
        USE_LABEL(c, cleanup_body);
2768
1.48k
        RETURN_IF_ERROR(
2769
1.48k
            _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2770
1.48k
                                  NO_LABEL, handler->v.ExceptHandler.name));
2771
2772
        /* second # body */
2773
1.48k
        VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2774
1.48k
        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2775
        /* name = None; del name; # artificial */
2776
1.48k
        ADDOP(c, NO_LOCATION, POP_BLOCK);
2777
1.48k
        if (handler->v.ExceptHandler.name) {
2778
38
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2779
38
            RETURN_IF_ERROR(
2780
38
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2781
38
            RETURN_IF_ERROR(
2782
38
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2783
38
        }
2784
1.48k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except);
2785
2786
        /* except: */
2787
1.48k
        USE_LABEL(c, cleanup_end);
2788
2789
        /* name = None; del name; # artificial */
2790
1.48k
        if (handler->v.ExceptHandler.name) {
2791
38
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2792
38
            RETURN_IF_ERROR(
2793
38
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2794
38
            RETURN_IF_ERROR(
2795
38
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2796
38
        }
2797
2798
        /* add exception raised to the res list */
2799
1.48k
        ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc
2800
1.48k
        ADDOP(c, NO_LOCATION, POP_TOP); // lasti
2801
1.48k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except_with_error);
2802
2803
1.48k
        USE_LABEL(c, except);
2804
1.48k
        ADDOP(c, NO_LOCATION, NOP);  // to hold a propagated location info
2805
1.48k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except_with_error);
2806
2807
1.48k
        USE_LABEL(c, no_match);
2808
1.48k
        ADDOP(c, loc, POP_TOP);  // match (None)
2809
2810
1.48k
        USE_LABEL(c, except_with_error);
2811
2812
1.48k
        if (i == n - 1) {
2813
            /* Add exc to the list (if not None it's the unhandled part of the EG) */
2814
1.17k
            ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1);
2815
1.17k
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, reraise_star);
2816
1.17k
        }
2817
1.48k
    }
2818
    /* artificial */
2819
1.17k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER, NO_LABEL);
2820
1.17k
    NEW_JUMP_TARGET_LABEL(c, reraise);
2821
2822
1.17k
    USE_LABEL(c, reraise_star);
2823
1.17k
    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_2, INTRINSIC_PREP_RERAISE_STAR);
2824
1.17k
    ADDOP_I(c, NO_LOCATION, COPY, 1);
2825
1.17k
    ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise);
2826
2827
    /* Nothing to reraise */
2828
1.17k
    ADDOP(c, NO_LOCATION, POP_TOP);
2829
1.17k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2830
1.17k
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
2831
1.17k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2832
2833
1.17k
    USE_LABEL(c, reraise);
2834
1.17k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2835
1.17k
    ADDOP_I(c, NO_LOCATION, SWAP, 2);
2836
1.17k
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
2837
1.17k
    ADDOP_I(c, NO_LOCATION, RERAISE, 0);
2838
2839
1.17k
    USE_LABEL(c, cleanup);
2840
1.17k
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
2841
2842
1.17k
    USE_LABEL(c, orelse);
2843
1.17k
    VISIT_SEQ(c, stmt, s->v.TryStar.orelse);
2844
2845
1.17k
    USE_LABEL(c, end);
2846
1.17k
    return SUCCESS;
2847
1.17k
}
2848
2849
static int
2850
2.50k
codegen_try(compiler *c, stmt_ty s) {
2851
2.50k
    if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
2852
2.06k
        return codegen_try_finally(c, s);
2853
440
    else
2854
440
        return codegen_try_except(c, s);
2855
2.50k
}
2856
2857
static int
2858
codegen_try_star(compiler *c, stmt_ty s)
2859
1.18k
{
2860
1.18k
    if (s->v.TryStar.finalbody && asdl_seq_LEN(s->v.TryStar.finalbody)) {
2861
112
        return codegen_try_star_finally(c, s);
2862
112
    }
2863
1.06k
    else {
2864
1.06k
        return codegen_try_star_except(c, s);
2865
1.06k
    }
2866
1.18k
}
2867
2868
static int
2869
codegen_import_as(compiler *c, location loc,
2870
                  identifier name, identifier asname)
2871
177
{
2872
    /* The IMPORT_NAME opcode was already generated.  This function
2873
       merely needs to bind the result to a name.
2874
2875
       If there is a dot in name, we need to split it and emit a
2876
       IMPORT_FROM for each name.
2877
    */
2878
177
    Py_ssize_t len = PyUnicode_GET_LENGTH(name);
2879
177
    Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
2880
177
    if (dot == -2) {
2881
0
        return ERROR;
2882
0
    }
2883
177
    if (dot != -1) {
2884
        /* Consume the base module name to get the first attribute */
2885
2.44k
        while (1) {
2886
2.44k
            Py_ssize_t pos = dot + 1;
2887
2.44k
            PyObject *attr;
2888
2.44k
            dot = PyUnicode_FindChar(name, '.', pos, len, 1);
2889
2.44k
            if (dot == -2) {
2890
0
                return ERROR;
2891
0
            }
2892
2.44k
            attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
2893
2.44k
            if (!attr) {
2894
0
                return ERROR;
2895
0
            }
2896
2.44k
            ADDOP_N(c, loc, IMPORT_FROM, attr, names);
2897
2.44k
            if (dot == -1) {
2898
129
                break;
2899
129
            }
2900
2.31k
            ADDOP_I(c, loc, SWAP, 2);
2901
2.31k
            ADDOP(c, loc, POP_TOP);
2902
2.31k
        }
2903
129
        RETURN_IF_ERROR(codegen_nameop(c, loc, asname, Store));
2904
129
        ADDOP(c, loc, POP_TOP);
2905
129
        return SUCCESS;
2906
129
    }
2907
48
    return codegen_nameop(c, loc, asname, Store);
2908
177
}
2909
2910
static int
2911
codegen_validate_lazy_import(compiler *c, location loc)
2912
12
{
2913
12
    if (_PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE) {
2914
0
        return _PyCompile_Error(
2915
0
            c, loc, "lazy imports only allowed in module scope");
2916
0
    }
2917
2918
12
    return SUCCESS;
2919
12
}
2920
2921
static int
2922
codegen_import(compiler *c, stmt_ty s)
2923
2.49k
{
2924
2.49k
    location loc = LOC(s);
2925
    /* The Import node stores a module name like a.b.c as a single
2926
       string.  This is convenient for all cases except
2927
         import a.b.c as d
2928
       where we need to parse that string to extract the individual
2929
       module names.
2930
       XXX Perhaps change the representation to make this case simpler?
2931
     */
2932
2.49k
    Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
2933
2934
2.49k
    PyObject *zero = _PyLong_GetZero();  // borrowed reference
2935
10.8k
    for (i = 0; i < n; i++) {
2936
8.36k
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
2937
8.36k
        int r;
2938
2939
8.36k
        ADDOP_LOAD_CONST(c, loc, zero);
2940
8.36k
        ADDOP_LOAD_CONST(c, loc, Py_None);
2941
8.36k
        if (s->v.Import.is_lazy) {
2942
11
            RETURN_IF_ERROR(codegen_validate_lazy_import(c, loc));
2943
11
            ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 1);
2944
8.35k
        } else {
2945
8.35k
            if (_PyCompile_InExceptionHandler(c) ||
2946
8.21k
                _PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE) {
2947
                // force eager import in try/except block
2948
1.85k
                ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 2);
2949
6.49k
            } else {
2950
6.49k
                ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 0);
2951
6.49k
            }
2952
8.35k
        }
2953
2954
8.36k
        if (alias->asname) {
2955
177
            r = codegen_import_as(c, loc, alias->name, alias->asname);
2956
177
            RETURN_IF_ERROR(r);
2957
177
        }
2958
8.18k
        else {
2959
8.18k
            identifier tmp = alias->name;
2960
8.18k
            Py_ssize_t dot = PyUnicode_FindChar(
2961
8.18k
                alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
2962
8.18k
            if (dot != -1) {
2963
3.19k
                tmp = PyUnicode_Substring(alias->name, 0, dot);
2964
3.19k
                if (tmp == NULL) {
2965
0
                    return ERROR;
2966
0
                }
2967
3.19k
            }
2968
8.18k
            r = codegen_nameop(c, loc, tmp, Store);
2969
8.18k
            if (dot != -1) {
2970
3.19k
                Py_DECREF(tmp);
2971
3.19k
            }
2972
8.18k
            RETURN_IF_ERROR(r);
2973
8.18k
        }
2974
8.36k
    }
2975
2.49k
    return SUCCESS;
2976
2.49k
}
2977
2978
static int
2979
codegen_from_import(compiler *c, stmt_ty s)
2980
2.18k
{
2981
2.18k
    Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names);
2982
2983
2.18k
    ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level));
2984
2985
2.18k
    PyObject *names = PyTuple_New(n);
2986
2.18k
    if (!names) {
2987
0
        return ERROR;
2988
0
    }
2989
2990
    /* build up the names */
2991
5.95k
    for (Py_ssize_t i = 0; i < n; i++) {
2992
3.76k
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
2993
3.76k
        PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name));
2994
3.76k
    }
2995
2996
2.18k
    ADDOP_LOAD_CONST_NEW(c, LOC(s), names);
2997
2998
2.18k
    identifier from = &_Py_STR(empty);
2999
2.18k
    if (s->v.ImportFrom.module) {
3000
1.93k
        from = s->v.ImportFrom.module;
3001
1.93k
    }
3002
2.18k
    if (s->v.ImportFrom.is_lazy) {
3003
1
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, 0);
3004
1
        if (PyUnicode_READ_CHAR(alias->name, 0) == '*') {
3005
0
            return _PyCompile_Error(c, LOC(s), "cannot lazy import *");
3006
0
        }
3007
1
        RETURN_IF_ERROR(codegen_validate_lazy_import(c, LOC(s)));
3008
1
        ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 1);
3009
2.18k
    } else {
3010
2.18k
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, 0);
3011
2.18k
        if (_PyCompile_InExceptionHandler(c) ||
3012
2.17k
            _PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE ||
3013
2.03k
            PyUnicode_READ_CHAR(alias->name, 0) == '*') {
3014
            // forced non-lazy import due to try/except or import *
3015
154
            ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 2);
3016
2.03k
        } else {
3017
2.03k
            ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 0);
3018
2.03k
        }
3019
2.18k
    }
3020
3021
5.94k
    for (Py_ssize_t i = 0; i < n; i++) {
3022
3.76k
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
3023
3.76k
        identifier store_name;
3024
3025
3.76k
        if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
3026
1
            assert(n == 1);
3027
1
            ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
3028
1
            ADDOP(c, NO_LOCATION, POP_TOP);
3029
1
            return SUCCESS;
3030
1
        }
3031
3032
3.76k
        ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names);
3033
3.76k
        store_name = alias->name;
3034
3.76k
        if (alias->asname) {
3035
206
            store_name = alias->asname;
3036
206
        }
3037
3038
3.76k
        RETURN_IF_ERROR(codegen_nameop(c, LOC(s), store_name, Store));
3039
3.76k
    }
3040
    /* remove imported module */
3041
2.18k
    ADDOP(c, LOC(s), POP_TOP);
3042
2.18k
    return SUCCESS;
3043
2.18k
}
3044
3045
static int
3046
codegen_assert(compiler *c, stmt_ty s)
3047
2.17k
{
3048
    /* Always emit a warning if the test is a non-zero length tuple */
3049
2.17k
    if ((s->v.Assert.test->kind == Tuple_kind &&
3050
244
        asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
3051
2.01k
        (s->v.Assert.test->kind == Constant_kind &&
3052
2.01k
         PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
3053
0
         PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0))
3054
157
    {
3055
157
        RETURN_IF_ERROR(
3056
157
            _PyCompile_Warn(c, LOC(s), "assertion is always true, "
3057
157
                                       "perhaps remove parentheses?"));
3058
157
    }
3059
2.17k
    if (OPTIMIZATION_LEVEL(c)) {
3060
462
        return SUCCESS;
3061
462
    }
3062
1.71k
    NEW_JUMP_TARGET_LABEL(c, end);
3063
1.71k
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.Assert.test, end, 1));
3064
1.71k
    ADDOP_I(c, LOC(s), LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR);
3065
1.71k
    if (s->v.Assert.msg) {
3066
665
        VISIT(c, expr, s->v.Assert.msg);
3067
664
        ADDOP_I(c, LOC(s), CALL, 0);
3068
664
    }
3069
1.71k
    ADDOP_I(c, LOC(s->v.Assert.test), RAISE_VARARGS, 1);
3070
3071
1.71k
    USE_LABEL(c, end);
3072
1.71k
    return SUCCESS;
3073
1.71k
}
3074
3075
static int
3076
codegen_stmt_expr(compiler *c, location loc, expr_ty value)
3077
89.8k
{
3078
89.8k
    if (IS_INTERACTIVE_TOP_LEVEL(c)) {
3079
3.38k
        VISIT(c, expr, value);
3080
3.31k
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT);
3081
3.31k
        ADDOP(c, NO_LOCATION, POP_TOP);
3082
3.31k
        return SUCCESS;
3083
3.31k
    }
3084
3085
86.4k
    if (value->kind == Constant_kind) {
3086
        /* ignore constant statement */
3087
2.65k
        ADDOP(c, loc, NOP);
3088
2.65k
        return SUCCESS;
3089
2.65k
    }
3090
3091
83.7k
    VISIT_UNUSED(c, expr, value);
3092
83.6k
    ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */
3093
83.6k
    return SUCCESS;
3094
83.6k
}
3095
3096
#define CODEGEN_COND_BLOCK(FUNC, C, S) \
3097
11.0k
    do { \
3098
11.0k
        _PyCompile_EnterConditionalBlock((C)); \
3099
11.0k
        int result = FUNC((C), (S)); \
3100
11.0k
        _PyCompile_LeaveConditionalBlock((C)); \
3101
11.0k
        return result; \
3102
11.0k
    } while(0)
3103
3104
static int
3105
codegen_visit_stmt(compiler *c, stmt_ty s)
3106
172k
{
3107
3108
172k
    switch (s->kind) {
3109
4.92k
    case FunctionDef_kind:
3110
4.92k
        return codegen_function(c, s, 0);
3111
13.0k
    case ClassDef_kind:
3112
13.0k
        return codegen_class(c, s);
3113
381
    case TypeAlias_kind:
3114
381
        return codegen_typealias(c, s);
3115
229
    case Return_kind:
3116
229
        return codegen_return(c, s);
3117
1.25k
    case Delete_kind:
3118
1.25k
        VISIT_SEQ(c, expr, s->v.Delete.targets);
3119
1.25k
        break;
3120
8.45k
    case Assign_kind:
3121
8.45k
    {
3122
8.45k
        Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets);
3123
8.45k
        VISIT(c, expr, s->v.Assign.value);
3124
59.0k
        for (Py_ssize_t i = 0; i < n; i++) {
3125
50.6k
            if (i < n - 1) {
3126
42.2k
                ADDOP_I(c, LOC(s), COPY, 1);
3127
42.2k
            }
3128
50.6k
            VISIT(c, expr,
3129
50.6k
                  (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
3130
50.6k
        }
3131
8.43k
        break;
3132
8.43k
    }
3133
8.43k
    case AugAssign_kind:
3134
6.50k
        return codegen_augassign(c, s);
3135
25.0k
    case AnnAssign_kind:
3136
25.0k
        return codegen_annassign(c, s);
3137
623
    case For_kind:
3138
623
        CODEGEN_COND_BLOCK(codegen_for, c, s);
3139
0
        break;
3140
2.13k
    case While_kind:
3141
2.13k
        CODEGEN_COND_BLOCK(codegen_while, c, s);
3142
0
        break;
3143
1.69k
    case If_kind:
3144
1.69k
        CODEGEN_COND_BLOCK(codegen_if, c, s);
3145
0
        break;
3146
198
    case Match_kind:
3147
198
        CODEGEN_COND_BLOCK(codegen_match, c, s);
3148
0
        break;
3149
497
    case Raise_kind:
3150
497
    {
3151
497
        Py_ssize_t n = 0;
3152
497
        if (s->v.Raise.exc) {
3153
226
            VISIT(c, expr, s->v.Raise.exc);
3154
218
            n++;
3155
218
            if (s->v.Raise.cause) {
3156
143
                VISIT(c, expr, s->v.Raise.cause);
3157
143
                n++;
3158
143
            }
3159
218
        }
3160
489
        ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n);
3161
489
        break;
3162
489
    }
3163
2.50k
    case Try_kind:
3164
2.50k
        CODEGEN_COND_BLOCK(codegen_try, c, s);
3165
0
        break;
3166
1.18k
    case TryStar_kind:
3167
1.18k
        CODEGEN_COND_BLOCK(codegen_try_star, c, s);
3168
0
        break;
3169
2.17k
    case Assert_kind:
3170
2.17k
        return codegen_assert(c, s);
3171
2.49k
    case Import_kind:
3172
2.49k
        return codegen_import(c, s);
3173
2.18k
    case ImportFrom_kind:
3174
2.18k
        return codegen_from_import(c, s);
3175
600
    case Global_kind:
3176
600
    case Nonlocal_kind:
3177
600
        break;
3178
89.8k
    case Expr_kind:
3179
89.8k
    {
3180
89.8k
        return codegen_stmt_expr(c, LOC(s), s->v.Expr.value);
3181
600
    }
3182
1.38k
    case Pass_kind:
3183
1.38k
    {
3184
1.38k
        ADDOP(c, LOC(s), NOP);
3185
1.38k
        break;
3186
1.38k
    }
3187
1.38k
    case Break_kind:
3188
9
    {
3189
9
        return codegen_break(c, LOC(s));
3190
1.38k
    }
3191
133
    case Continue_kind:
3192
133
    {
3193
133
        return codegen_continue(c, LOC(s));
3194
1.38k
    }
3195
545
    case With_kind:
3196
545
        CODEGEN_COND_BLOCK(codegen_with, c, s);
3197
0
        break;
3198
2.50k
    case AsyncFunctionDef_kind:
3199
2.50k
        return codegen_function(c, s, 1);
3200
2.09k
    case AsyncWith_kind:
3201
2.09k
        CODEGEN_COND_BLOCK(codegen_async_with, c, s);
3202
0
        break;
3203
91
    case AsyncFor_kind:
3204
91
        CODEGEN_COND_BLOCK(codegen_async_for, c, s);
3205
0
        break;
3206
172k
    }
3207
3208
12.1k
    return SUCCESS;
3209
172k
}
3210
3211
static int
3212
unaryop(unaryop_ty op)
3213
170k
{
3214
170k
    switch (op) {
3215
11.8k
    case Invert:
3216
11.8k
        return UNARY_INVERT;
3217
158k
    case USub:
3218
158k
        return UNARY_NEGATIVE;
3219
0
    default:
3220
0
        PyErr_Format(PyExc_SystemError,
3221
0
            "unary op %d should not be possible", op);
3222
0
        return 0;
3223
170k
    }
3224
170k
}
3225
3226
static int
3227
addop_binary(compiler *c, location loc, operator_ty binop,
3228
             bool inplace)
3229
799k
{
3230
799k
    int oparg;
3231
799k
    switch (binop) {
3232
128k
        case Add:
3233
128k
            oparg = inplace ? NB_INPLACE_ADD : NB_ADD;
3234
128k
            break;
3235
145k
        case Sub:
3236
145k
            oparg = inplace ? NB_INPLACE_SUBTRACT : NB_SUBTRACT;
3237
145k
            break;
3238
164k
        case Mult:
3239
164k
            oparg = inplace ? NB_INPLACE_MULTIPLY : NB_MULTIPLY;
3240
164k
            break;
3241
1.11k
        case MatMult:
3242
1.11k
            oparg = inplace ? NB_INPLACE_MATRIX_MULTIPLY : NB_MATRIX_MULTIPLY;
3243
1.11k
            break;
3244
84.9k
        case Div:
3245
84.9k
            oparg = inplace ? NB_INPLACE_TRUE_DIVIDE : NB_TRUE_DIVIDE;
3246
84.9k
            break;
3247
51.4k
        case Mod:
3248
51.4k
            oparg = inplace ? NB_INPLACE_REMAINDER : NB_REMAINDER;
3249
51.4k
            break;
3250
122k
        case Pow:
3251
122k
            oparg = inplace ? NB_INPLACE_POWER : NB_POWER;
3252
122k
            break;
3253
12.0k
        case LShift:
3254
12.0k
            oparg = inplace ? NB_INPLACE_LSHIFT : NB_LSHIFT;
3255
12.0k
            break;
3256
16.8k
        case RShift:
3257
16.8k
            oparg = inplace ? NB_INPLACE_RSHIFT : NB_RSHIFT;
3258
16.8k
            break;
3259
10.6k
        case BitOr:
3260
10.6k
            oparg = inplace ? NB_INPLACE_OR : NB_OR;
3261
10.6k
            break;
3262
13.8k
        case BitXor:
3263
13.8k
            oparg = inplace ? NB_INPLACE_XOR : NB_XOR;
3264
13.8k
            break;
3265
19.6k
        case BitAnd:
3266
19.6k
            oparg = inplace ? NB_INPLACE_AND : NB_AND;
3267
19.6k
            break;
3268
28.1k
        case FloorDiv:
3269
28.1k
            oparg = inplace ? NB_INPLACE_FLOOR_DIVIDE : NB_FLOOR_DIVIDE;
3270
28.1k
            break;
3271
0
        default:
3272
0
            PyErr_Format(PyExc_SystemError, "%s op %d should not be possible",
3273
0
                         inplace ? "inplace" : "binary", binop);
3274
0
            return ERROR;
3275
799k
    }
3276
799k
    ADDOP_I(c, loc, BINARY_OP, oparg);
3277
799k
    return SUCCESS;
3278
799k
}
3279
3280
3281
static int
3282
517
codegen_addop_yield(compiler *c, location loc) {
3283
517
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
3284
517
    if (ste->ste_generator && ste->ste_coroutine) {
3285
149
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
3286
149
    }
3287
517
    ADDOP_I(c, loc, YIELD_VALUE, 0);
3288
517
    ADDOP_I(c, loc, RESUME, RESUME_AFTER_YIELD);
3289
517
    return SUCCESS;
3290
517
}
3291
3292
static int
3293
codegen_load_classdict_freevar(compiler *c, location loc)
3294
13.7k
{
3295
13.7k
    ADDOP_N(c, loc, LOAD_DEREF, &_Py_ID(__classdict__), freevars);
3296
13.7k
    return SUCCESS;
3297
13.7k
}
3298
3299
static int
3300
codegen_nameop(compiler *c, location loc,
3301
               identifier name, expr_context_ty ctx)
3302
526k
{
3303
526k
    assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
3304
526k
           !_PyUnicode_EqualToASCIIString(name, "True") &&
3305
526k
           !_PyUnicode_EqualToASCIIString(name, "False"));
3306
3307
526k
    PyObject *mangled = _PyCompile_MaybeMangle(c, name);
3308
526k
    if (!mangled) {
3309
0
        return ERROR;
3310
0
    }
3311
3312
526k
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), mangled);
3313
526k
    if (scope == -1) {
3314
0
        goto error;
3315
0
    }
3316
3317
526k
    _PyCompile_optype optype;
3318
526k
    Py_ssize_t arg = 0;
3319
526k
    if (_PyCompile_ResolveNameop(c, mangled, scope, &optype, &arg) < 0) {
3320
0
        Py_DECREF(mangled);
3321
0
        return ERROR;
3322
0
    }
3323
3324
    /* XXX Leave assert here, but handle __doc__ and the like better */
3325
526k
    assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
3326
3327
526k
    int op = 0;
3328
526k
    switch (optype) {
3329
9.30k
    case COMPILE_OP_DEREF:
3330
9.30k
        switch (ctx) {
3331
6.31k
        case Load:
3332
6.31k
            if (SYMTABLE_ENTRY(c)->ste_type == ClassBlock && !_PyCompile_IsInInlinedComp(c)) {
3333
2.67k
                op = LOAD_FROM_DICT_OR_DEREF;
3334
                // First load the locals
3335
2.67k
                if (codegen_addop_noarg(INSTR_SEQUENCE(c), LOAD_LOCALS, loc) < 0) {
3336
0
                    goto error;
3337
0
                }
3338
2.67k
            }
3339
3.64k
            else if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope) {
3340
169
                op = LOAD_FROM_DICT_OR_DEREF;
3341
                // First load the classdict
3342
169
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3343
0
                    goto error;
3344
0
                }
3345
169
            }
3346
3.47k
            else {
3347
3.47k
                op = LOAD_DEREF;
3348
3.47k
            }
3349
6.31k
            break;
3350
6.31k
        case Store: op = STORE_DEREF; break;
3351
0
        case Del: op = DELETE_DEREF; break;
3352
9.30k
        }
3353
9.30k
        break;
3354
131k
    case COMPILE_OP_FAST:
3355
131k
        switch (ctx) {
3356
19.0k
        case Load: op = LOAD_FAST; break;
3357
109k
        case Store: op = STORE_FAST; break;
3358
3.12k
        case Del: op = DELETE_FAST; break;
3359
131k
        }
3360
131k
        ADDOP_N(c, loc, op, mangled, varnames);
3361
131k
        return SUCCESS;
3362
93.5k
    case COMPILE_OP_GLOBAL:
3363
93.5k
        switch (ctx) {
3364
92.9k
        case Load:
3365
92.9k
            if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) {
3366
13.6k
                op = LOAD_FROM_DICT_OR_GLOBALS;
3367
                // First load the classdict
3368
13.6k
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3369
0
                    goto error;
3370
0
                }
3371
79.3k
            } else {
3372
79.3k
                op = LOAD_GLOBAL;
3373
79.3k
            }
3374
92.9k
            break;
3375
92.9k
        case Store: op = STORE_GLOBAL; break;
3376
47
        case Del:
3377
47
            ADDOP(c, loc, PUSH_NULL);
3378
47
            op = STORE_GLOBAL;
3379
47
            break;
3380
93.5k
        }
3381
93.5k
        break;
3382
291k
    case COMPILE_OP_NAME:
3383
291k
        switch (ctx) {
3384
171k
        case Load:
3385
171k
            op = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock
3386
49.9k
                    && _PyCompile_IsInInlinedComp(c))
3387
171k
                ? LOAD_GLOBAL
3388
171k
                : LOAD_NAME;
3389
171k
            break;
3390
118k
        case Store: op = STORE_NAME; break;
3391
935
        case Del:
3392
935
            ADDOP(c, loc, PUSH_NULL);
3393
935
            op = STORE_NAME;
3394
935
            break;
3395
291k
        }
3396
291k
        break;
3397
526k
    }
3398
3399
526k
    assert(op);
3400
394k
    Py_DECREF(mangled);
3401
394k
    if (op == LOAD_GLOBAL) {
3402
79.3k
        arg <<= 1;
3403
79.3k
    }
3404
394k
    ADDOP_I(c, loc, op, arg);
3405
394k
    return SUCCESS;
3406
3407
0
error:
3408
0
    Py_DECREF(mangled);
3409
0
    return ERROR;
3410
394k
}
3411
3412
static int
3413
codegen_boolop(compiler *c, expr_ty e)
3414
2.69k
{
3415
2.69k
    int jumpi;
3416
2.69k
    Py_ssize_t i, n;
3417
2.69k
    asdl_expr_seq *s;
3418
3419
2.69k
    location loc = LOC(e);
3420
2.69k
    assert(e->kind == BoolOp_kind);
3421
2.69k
    if (e->v.BoolOp.op == And)
3422
1.25k
        jumpi = JUMP_IF_FALSE;
3423
1.43k
    else
3424
1.43k
        jumpi = JUMP_IF_TRUE;
3425
2.69k
    NEW_JUMP_TARGET_LABEL(c, end);
3426
2.69k
    s = e->v.BoolOp.values;
3427
2.69k
    n = asdl_seq_LEN(s) - 1;
3428
2.69k
    assert(n >= 0);
3429
8.70k
    for (i = 0; i < n; ++i) {
3430
6.03k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
3431
6.01k
        ADDOP_JUMP(c, loc, jumpi, end);
3432
6.01k
        ADDOP(c, loc, POP_TOP);
3433
6.01k
    }
3434
2.67k
    VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
3435
3436
2.66k
    USE_LABEL(c, end);
3437
2.66k
    return SUCCESS;
3438
2.66k
}
3439
3440
static int
3441
starunpack_helper_impl(compiler *c, location loc,
3442
                       asdl_expr_seq *elts, PyObject *injected_arg, int pushed,
3443
                       int build, int add, int extend, int tuple)
3444
65.4k
{
3445
65.4k
    Py_ssize_t n = asdl_seq_LEN(elts);
3446
65.4k
    int big = n + pushed + (injected_arg ? 1 : 0) > _PY_STACK_USE_GUIDELINE;
3447
65.4k
    int seen_star = 0;
3448
245k
    for (Py_ssize_t i = 0; i < n; i++) {
3449
187k
        expr_ty elt = asdl_seq_GET(elts, i);
3450
187k
        if (elt->kind == Starred_kind) {
3451
7.37k
            seen_star = 1;
3452
7.37k
            break;
3453
7.37k
        }
3454
187k
    }
3455
65.4k
    if (!seen_star && !big) {
3456
182k
        for (Py_ssize_t i = 0; i < n; i++) {
3457
124k
            expr_ty elt = asdl_seq_GET(elts, i);
3458
124k
            VISIT(c, expr, elt);
3459
124k
        }
3460
57.7k
        if (injected_arg) {
3461
0
            RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
3462
0
            n++;
3463
0
        }
3464
57.7k
        if (tuple) {
3465
53.5k
            ADDOP_I(c, loc, BUILD_TUPLE, n+pushed);
3466
53.5k
        } else {
3467
4.10k
            ADDOP_I(c, loc, build, n+pushed);
3468
4.10k
        }
3469
57.7k
        return SUCCESS;
3470
57.7k
    }
3471
7.69k
    int sequence_built = 0;
3472
7.69k
    if (big) {
3473
365
        ADDOP_I(c, loc, build, pushed);
3474
365
        sequence_built = 1;
3475
365
    }
3476
75.8k
    for (Py_ssize_t i = 0; i < n; i++) {
3477
68.2k
        expr_ty elt = asdl_seq_GET(elts, i);
3478
68.2k
        if (elt->kind == Starred_kind) {
3479
8.33k
            if (sequence_built == 0) {
3480
7.32k
                ADDOP_I(c, loc, build, i+pushed);
3481
7.32k
                sequence_built = 1;
3482
7.32k
            }
3483
8.33k
            VISIT(c, expr, elt->v.Starred.value);
3484
8.31k
            ADDOP_I(c, loc, extend, 1);
3485
8.31k
        }
3486
59.8k
        else {
3487
59.8k
            VISIT(c, expr, elt);
3488
59.8k
            if (sequence_built) {
3489
37.7k
                ADDOP_I(c, loc, add, 1);
3490
37.7k
            }
3491
59.8k
        }
3492
68.2k
    }
3493
7.69k
    assert(sequence_built);
3494
7.66k
    if (injected_arg) {
3495
0
        RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
3496
0
        ADDOP_I(c, loc, add, 1);
3497
0
    }
3498
7.66k
    if (tuple) {
3499
2.85k
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
3500
2.85k
    }
3501
7.66k
    return SUCCESS;
3502
7.66k
}
3503
3504
static int
3505
starunpack_helper(compiler *c, location loc,
3506
                  asdl_expr_seq *elts, int pushed,
3507
                  int build, int add, int extend, int tuple)
3508
63.6k
{
3509
63.6k
    return starunpack_helper_impl(c, loc, elts, NULL, pushed,
3510
63.6k
                                  build, add, extend, tuple);
3511
63.6k
}
3512
3513
static int
3514
unpack_helper(compiler *c, location loc, asdl_expr_seq *elts)
3515
23.3k
{
3516
23.3k
    Py_ssize_t n = asdl_seq_LEN(elts);
3517
23.3k
    int seen_star = 0;
3518
100k
    for (Py_ssize_t i = 0; i < n; i++) {
3519
76.7k
        expr_ty elt = asdl_seq_GET(elts, i);
3520
76.7k
        if (elt->kind == Starred_kind && !seen_star) {
3521
413
            if ((i >= (1 << 8)) ||
3522
413
                (n-i-1 >= (INT_MAX >> 8))) {
3523
0
                return _PyCompile_Error(c, loc,
3524
0
                    "too many expressions in "
3525
0
                    "star-unpacking assignment");
3526
0
            }
3527
413
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
3528
413
            seen_star = 1;
3529
413
        }
3530
76.3k
        else if (elt->kind == Starred_kind) {
3531
5
            return _PyCompile_Error(c, loc,
3532
5
                "multiple starred expressions in assignment");
3533
5
        }
3534
76.7k
    }
3535
23.3k
    if (!seen_star) {
3536
22.9k
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
3537
22.9k
    }
3538
23.3k
    return SUCCESS;
3539
23.3k
}
3540
3541
static int
3542
assignment_helper(compiler *c, location loc, asdl_expr_seq *elts)
3543
23.3k
{
3544
23.3k
    Py_ssize_t n = asdl_seq_LEN(elts);
3545
23.3k
    RETURN_IF_ERROR(unpack_helper(c, loc, elts));
3546
100k
    for (Py_ssize_t i = 0; i < n; i++) {
3547
76.7k
        expr_ty elt = asdl_seq_GET(elts, i);
3548
76.7k
        VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
3549
76.7k
    }
3550
23.3k
    return SUCCESS;
3551
23.3k
}
3552
3553
static int
3554
codegen_list(compiler *c, expr_ty e)
3555
2.54k
{
3556
2.54k
    location loc = LOC(e);
3557
2.54k
    asdl_expr_seq *elts = e->v.List.elts;
3558
2.54k
    if (e->v.List.ctx == Store) {
3559
222
        return assignment_helper(c, loc, elts);
3560
222
    }
3561
2.32k
    else if (e->v.List.ctx == Load) {
3562
2.25k
        return starunpack_helper(c, loc, elts, 0,
3563
2.25k
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0);
3564
2.25k
    }
3565
77
    else {
3566
77
        VISIT_SEQ(c, expr, elts);
3567
77
    }
3568
77
    return SUCCESS;
3569
2.54k
}
3570
3571
static int
3572
codegen_tuple(compiler *c, expr_ty e)
3573
78.0k
{
3574
78.0k
    location loc = LOC(e);
3575
78.0k
    asdl_expr_seq *elts = e->v.Tuple.elts;
3576
78.0k
    if (e->v.Tuple.ctx == Store) {
3577
23.1k
        return assignment_helper(c, loc, elts);
3578
23.1k
    }
3579
54.8k
    else if (e->v.Tuple.ctx == Load) {
3580
54.7k
        return starunpack_helper(c, loc, elts, 0,
3581
54.7k
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1);
3582
54.7k
    }
3583
131
    else {
3584
131
        VISIT_SEQ(c, expr, elts);
3585
131
    }
3586
131
    return SUCCESS;
3587
78.0k
}
3588
3589
static int
3590
codegen_set(compiler *c, expr_ty e)
3591
6.67k
{
3592
6.67k
    location loc = LOC(e);
3593
6.67k
    return starunpack_helper(c, loc, e->v.Set.elts, 0,
3594
6.67k
                             BUILD_SET, SET_ADD, SET_UPDATE, 0);
3595
6.67k
}
3596
3597
static int
3598
codegen_subdict(compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
3599
170
{
3600
170
    Py_ssize_t i, n = end - begin;
3601
170
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
3602
170
    location loc = LOC(e);
3603
170
    if (big) {
3604
17
        ADDOP_I(c, loc, BUILD_MAP, 0);
3605
17
    }
3606
634
    for (i = begin; i < end; i++) {
3607
470
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
3608
469
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3609
464
        if (big) {
3610
288
            ADDOP_I(c, loc, MAP_ADD, 1);
3611
288
        }
3612
464
    }
3613
164
    if (!big) {
3614
147
        ADDOP_I(c, loc, BUILD_MAP, n);
3615
147
    }
3616
164
    return SUCCESS;
3617
164
}
3618
3619
static int
3620
codegen_dict(compiler *c, expr_ty e)
3621
535
{
3622
535
    location loc = LOC(e);
3623
535
    Py_ssize_t i, n, elements;
3624
535
    int have_dict;
3625
535
    int is_unpacking = 0;
3626
535
    n = asdl_seq_LEN(e->v.Dict.values);
3627
535
    have_dict = 0;
3628
535
    elements = 0;
3629
1.14k
    for (i = 0; i < n; i++) {
3630
613
        is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
3631
613
        if (is_unpacking) {
3632
143
            if (elements) {
3633
98
                RETURN_IF_ERROR(codegen_subdict(c, e, i - elements, i));
3634
96
                if (have_dict) {
3635
0
                    ADDOP_I(c, loc, DICT_UPDATE, 1);
3636
0
                }
3637
96
                have_dict = 1;
3638
96
                elements = 0;
3639
96
            }
3640
141
            if (have_dict == 0) {
3641
45
                ADDOP_I(c, loc, BUILD_MAP, 0);
3642
45
                have_dict = 1;
3643
45
            }
3644
141
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3645
138
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3646
138
        }
3647
470
        else {
3648
470
            if (elements*2 > _PY_STACK_USE_GUIDELINE) {
3649
16
                RETURN_IF_ERROR(codegen_subdict(c, e, i - elements, i + 1));
3650
16
                if (have_dict) {
3651
10
                    ADDOP_I(c, loc, DICT_UPDATE, 1);
3652
10
                }
3653
16
                have_dict = 1;
3654
16
                elements = 0;
3655
16
            }
3656
454
            else {
3657
454
                elements++;
3658
454
            }
3659
470
        }
3660
613
    }
3661
530
    if (elements) {
3662
56
        RETURN_IF_ERROR(codegen_subdict(c, e, n - elements, n));
3663
52
        if (have_dict) {
3664
5
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3665
5
        }
3666
52
        have_dict = 1;
3667
52
    }
3668
526
    if (!have_dict) {
3669
335
        ADDOP_I(c, loc, BUILD_MAP, 0);
3670
335
    }
3671
526
    return SUCCESS;
3672
526
}
3673
3674
static int
3675
codegen_compare(compiler *c, expr_ty e)
3676
21.3k
{
3677
21.3k
    location loc = LOC(e);
3678
21.3k
    Py_ssize_t i, n;
3679
3680
21.3k
    RETURN_IF_ERROR(codegen_check_compare(c, e));
3681
21.3k
    VISIT(c, expr, e->v.Compare.left);
3682
21.3k
    assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
3683
21.2k
    n = asdl_seq_LEN(e->v.Compare.ops) - 1;
3684
21.2k
    if (n == 0) {
3685
11.5k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
3686
11.5k
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0));
3687
11.5k
    }
3688
9.71k
    else {
3689
9.71k
        NEW_JUMP_TARGET_LABEL(c, cleanup);
3690
66.1k
        for (i = 0; i < n; i++) {
3691
56.4k
            VISIT(c, expr,
3692
56.4k
                (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
3693
56.4k
            ADDOP_I(c, loc, SWAP, 2);
3694
56.4k
            ADDOP_I(c, loc, COPY, 2);
3695
56.4k
            ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i));
3696
56.4k
            ADDOP_I(c, loc, COPY, 1);
3697
56.4k
            ADDOP(c, loc, TO_BOOL);
3698
56.4k
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, cleanup);
3699
56.4k
            ADDOP(c, loc, POP_TOP);
3700
56.4k
        }
3701
9.69k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
3702
9.68k
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
3703
9.68k
        NEW_JUMP_TARGET_LABEL(c, end);
3704
9.68k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
3705
3706
9.68k
        USE_LABEL(c, cleanup);
3707
9.68k
        ADDOP_I(c, loc, SWAP, 2);
3708
9.68k
        ADDOP(c, loc, POP_TOP);
3709
3710
9.68k
        USE_LABEL(c, end);
3711
9.68k
    }
3712
21.2k
    return SUCCESS;
3713
21.2k
}
3714
3715
static PyTypeObject *
3716
infer_type(expr_ty e)
3717
16.0k
{
3718
16.0k
    switch (e->kind) {
3719
2.36k
    case Tuple_kind:
3720
2.36k
        return &PyTuple_Type;
3721
551
    case List_kind:
3722
569
    case ListComp_kind:
3723
569
        return &PyList_Type;
3724
107
    case Dict_kind:
3725
757
    case DictComp_kind:
3726
757
        return &PyDict_Type;
3727
522
    case Set_kind:
3728
1.17k
    case SetComp_kind:
3729
1.17k
        return &PySet_Type;
3730
126
    case GeneratorExp_kind:
3731
126
        return &PyGen_Type;
3732
130
    case Lambda_kind:
3733
130
        return &PyFunction_Type;
3734
64
    case TemplateStr_kind:
3735
64
    case Interpolation_kind:
3736
64
        return &_PyTemplate_Type;
3737
50
    case JoinedStr_kind:
3738
50
    case FormattedValue_kind:
3739
50
        return &PyUnicode_Type;
3740
4.03k
    case Constant_kind:
3741
4.03k
        return Py_TYPE(e->v.Constant.value);
3742
6.76k
    default:
3743
6.76k
        return NULL;
3744
16.0k
    }
3745
16.0k
}
3746
3747
static int
3748
check_caller(compiler *c, expr_ty e)
3749
8.58k
{
3750
8.58k
    switch (e->kind) {
3751
1.52k
    case Constant_kind:
3752
1.57k
    case Tuple_kind:
3753
1.58k
    case List_kind:
3754
1.59k
    case ListComp_kind:
3755
1.64k
    case Dict_kind:
3756
2.28k
    case DictComp_kind:
3757
2.40k
    case Set_kind:
3758
2.96k
    case SetComp_kind:
3759
3.08k
    case GeneratorExp_kind:
3760
3.12k
    case JoinedStr_kind:
3761
3.12k
    case TemplateStr_kind:
3762
3.12k
    case FormattedValue_kind:
3763
3.12k
    case Interpolation_kind: {
3764
3.12k
        location loc = LOC(e);
3765
3.12k
        return _PyCompile_Warn(c, loc, "'%.200s' object is not callable; "
3766
3.12k
                                       "perhaps you missed a comma?",
3767
3.12k
                                       infer_type(e)->tp_name);
3768
3.12k
    }
3769
5.45k
    default:
3770
5.45k
        return SUCCESS;
3771
8.58k
    }
3772
8.58k
}
3773
3774
static int
3775
check_subscripter(compiler *c, expr_ty e)
3776
10.0k
{
3777
10.0k
    PyObject *v;
3778
3779
10.0k
    switch (e->kind) {
3780
4.37k
    case Constant_kind:
3781
4.37k
        v = e->v.Constant.value;
3782
4.37k
        if (!(v == Py_None || v == Py_Ellipsis ||
3783
4.37k
              PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) ||
3784
4.01k
              PyAnySet_Check(v)))
3785
4.01k
        {
3786
4.01k
            return SUCCESS;
3787
4.01k
        }
3788
359
        _Py_FALLTHROUGH;
3789
369
    case Set_kind:
3790
369
    case SetComp_kind:
3791
369
    case GeneratorExp_kind:
3792
426
    case TemplateStr_kind:
3793
426
    case Interpolation_kind:
3794
426
    case Lambda_kind: {
3795
426
        location loc = LOC(e);
3796
426
        return _PyCompile_Warn(c, loc, "'%.200s' object is not subscriptable; "
3797
426
                                       "perhaps you missed a comma?",
3798
426
                                       infer_type(e)->tp_name);
3799
426
    }
3800
5.60k
    default:
3801
5.60k
        return SUCCESS;
3802
10.0k
    }
3803
10.0k
}
3804
3805
static int
3806
check_index(compiler *c, expr_ty e, expr_ty s)
3807
10.0k
{
3808
10.0k
    PyObject *v;
3809
3810
10.0k
    PyTypeObject *index_type = infer_type(s);
3811
10.0k
    if (index_type == NULL
3812
3.27k
        || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
3813
7.46k
        || index_type == &PySlice_Type) {
3814
7.46k
        return SUCCESS;
3815
7.46k
    }
3816
3817
2.57k
    switch (e->kind) {
3818
385
    case Constant_kind:
3819
385
        v = e->v.Constant.value;
3820
385
        if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
3821
136
            return SUCCESS;
3822
136
        }
3823
249
        _Py_FALLTHROUGH;
3824
744
    case Tuple_kind:
3825
1.27k
    case List_kind:
3826
1.28k
    case ListComp_kind:
3827
1.29k
    case JoinedStr_kind:
3828
1.29k
    case FormattedValue_kind: {
3829
1.29k
        location loc = LOC(e);
3830
1.29k
        return _PyCompile_Warn(c, loc, "%.200s indices must be integers "
3831
1.29k
                                       "or slices, not %.200s; "
3832
1.29k
                                       "perhaps you missed a comma?",
3833
1.29k
                                       infer_type(e)->tp_name,
3834
1.29k
                                       index_type->tp_name);
3835
1.29k
    }
3836
1.14k
    default:
3837
1.14k
        return SUCCESS;
3838
2.57k
    }
3839
2.57k
}
3840
3841
static int
3842
is_import_originated(compiler *c, expr_ty e)
3843
1.54k
{
3844
    /* Check whether the global scope has an import named
3845
     e, if it is a Name object. For not traversing all the
3846
     scope stack every time this function is called, it will
3847
     only check the global scope to determine whether something
3848
     is imported or not. */
3849
3850
1.54k
    if (e->kind != Name_kind) {
3851
1.35k
        return 0;
3852
1.35k
    }
3853
3854
185
    long flags = _PyST_GetSymbol(SYMTABLE(c)->st_top, e->v.Name.id);
3855
185
    RETURN_IF_ERROR(flags);
3856
185
    return flags & DEF_IMPORT;
3857
185
}
3858
3859
static int
3860
can_optimize_super_call(compiler *c, expr_ty attr)
3861
13.7k
{
3862
13.7k
    expr_ty e = attr->v.Attribute.value;
3863
13.7k
    if (e->kind != Call_kind ||
3864
5.28k
        e->v.Call.func->kind != Name_kind ||
3865
2.27k
        !_PyUnicode_EqualToASCIIString(e->v.Call.func->v.Name.id, "super") ||
3866
795
        _PyUnicode_EqualToASCIIString(attr->v.Attribute.attr, "__class__") ||
3867
12.9k
        asdl_seq_LEN(e->v.Call.keywords) != 0) {
3868
12.9k
        return 0;
3869
12.9k
    }
3870
783
    Py_ssize_t num_args = asdl_seq_LEN(e->v.Call.args);
3871
3872
783
    PyObject *super_name = e->v.Call.func->v.Name.id;
3873
    // detect statically-visible shadowing of 'super' name
3874
783
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), super_name);
3875
783
    RETURN_IF_ERROR(scope);
3876
783
    if (scope != GLOBAL_IMPLICIT) {
3877
93
        return 0;
3878
93
    }
3879
690
    scope = _PyST_GetScope(SYMTABLE(c)->st_top, super_name);
3880
690
    RETURN_IF_ERROR(scope);
3881
690
    if (scope != 0) {
3882
102
        return 0;
3883
102
    }
3884
3885
588
    if (num_args == 2) {
3886
1.61k
        for (Py_ssize_t i = 0; i < num_args; i++) {
3887
1.08k
            expr_ty elt = asdl_seq_GET(e->v.Call.args, i);
3888
1.08k
            if (elt->kind == Starred_kind) {
3889
26
                return 0;
3890
26
            }
3891
1.08k
        }
3892
        // exactly two non-starred args; we can just load
3893
        // the provided args
3894
523
        return 1;
3895
549
    }
3896
3897
39
    if (num_args != 0) {
3898
27
        return 0;
3899
27
    }
3900
    // we need the following for zero-arg super():
3901
3902
    // enclosing function should have at least one argument
3903
12
    if (METADATA(c)->u_argcount == 0 &&
3904
2
        METADATA(c)->u_posonlyargcount == 0) {
3905
1
        return 0;
3906
1
    }
3907
    // __class__ cell should be available
3908
11
    if (_PyCompile_GetRefType(c, &_Py_ID(__class__)) == FREE) {
3909
0
        return 1;
3910
0
    }
3911
11
    return 0;
3912
11
}
3913
3914
static int
3915
523
load_args_for_super(compiler *c, expr_ty e) {
3916
523
    location loc = LOC(e);
3917
3918
    // load super() global
3919
523
    PyObject *super_name = e->v.Call.func->v.Name.id;
3920
523
    RETURN_IF_ERROR(codegen_nameop(c, LOC(e->v.Call.func), super_name, Load));
3921
3922
523
    if (asdl_seq_LEN(e->v.Call.args) == 2) {
3923
523
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0));
3924
523
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 1));
3925
523
        return SUCCESS;
3926
523
    }
3927
3928
    // load __class__ cell
3929
0
    PyObject *name = &_Py_ID(__class__);
3930
0
    assert(_PyCompile_GetRefType(c, name) == FREE);
3931
0
    RETURN_IF_ERROR(codegen_nameop(c, loc, name, Load));
3932
3933
    // load self (first argument)
3934
0
    Py_ssize_t i = 0;
3935
0
    PyObject *key, *value;
3936
0
    if (!PyDict_Next(METADATA(c)->u_varnames, &i, &key, &value)) {
3937
0
        return ERROR;
3938
0
    }
3939
0
    RETURN_IF_ERROR(codegen_nameop(c, loc, key, Load));
3940
3941
0
    return SUCCESS;
3942
0
}
3943
3944
// If an attribute access spans multiple lines, update the current start
3945
// location to point to the attribute name.
3946
static location
3947
update_start_location_to_match_attr(compiler *c, location loc,
3948
                                    expr_ty attr)
3949
19.1k
{
3950
19.1k
    assert(attr->kind == Attribute_kind);
3951
19.1k
    if (loc.lineno != attr->end_lineno) {
3952
1.66k
        loc.lineno = attr->end_lineno;
3953
1.66k
        int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
3954
1.66k
        if (len <= attr->end_col_offset) {
3955
1.66k
            loc.col_offset = attr->end_col_offset - len;
3956
1.66k
        }
3957
0
        else {
3958
            // GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
3959
0
            loc.col_offset = -1;
3960
0
            loc.end_col_offset = -1;
3961
0
        }
3962
        // Make sure the end position still follows the start position, even for
3963
        // weird ASTs:
3964
1.66k
        loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno);
3965
1.66k
        if (loc.lineno == loc.end_lineno) {
3966
1.09k
            loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset);
3967
1.09k
        }
3968
1.66k
    }
3969
19.1k
    return loc;
3970
19.1k
}
3971
3972
static int
3973
maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
3974
8.54k
{
3975
8.54k
    asdl_expr_seq *args = e->v.Call.args;
3976
8.54k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
3977
8.54k
    expr_ty func = e->v.Call.func;
3978
3979
8.54k
    if (! (func->kind == Name_kind &&
3980
3.14k
           asdl_seq_LEN(args) == 1 &&
3981
1.35k
           asdl_seq_LEN(kwds) == 0))
3982
7.44k
    {
3983
7.44k
        return 0;
3984
7.44k
    }
3985
3986
1.10k
    location loc = LOC(func);
3987
3988
1.10k
    expr_ty arg_expr = asdl_seq_GET(args, 0);
3989
3990
1.10k
    if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "frozenset")
3991
0
        && (arg_expr->kind == Set_kind || arg_expr->kind == SetComp_kind)) {
3992
0
        NEW_JUMP_TARGET_LABEL(c, skip_optimization);
3993
3994
0
        ADDOP_I(c, loc, COPY, 1);
3995
0
        ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_BUILTIN_FROZENSET);
3996
0
        ADDOP_COMPARE(c, loc, Is);
3997
0
        ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, skip_optimization);
3998
0
        ADDOP(c, loc, POP_TOP);
3999
4000
0
        VISIT(c, expr, arg_expr);
4001
0
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_BUILD_FROZENSET);
4002
4003
0
        ADDOP_JUMP(c, loc, JUMP, end);
4004
4005
0
        USE_LABEL(c, skip_optimization);
4006
0
        return 1;
4007
0
    }
4008
4009
1.10k
    if (arg_expr->kind != GeneratorExp_kind) {
4010
1.08k
        return 0;
4011
1.08k
    }
4012
4013
17
    PySTEntryObject *generator_entry = _PySymtable_Lookup(SYMTABLE(c), (void *)arg_expr);
4014
17
    if (generator_entry->ste_coroutine) {
4015
4
        Py_DECREF(generator_entry);
4016
4
        return 0;
4017
4
    }
4018
13
    Py_DECREF(generator_entry);
4019
4020
13
    int optimized = 0;
4021
13
    NEW_JUMP_TARGET_LABEL(c, skip_optimization);
4022
4023
13
    int const_oparg = -1;
4024
13
    PyObject *initial_res = NULL;
4025
13
    int continue_jump_opcode = -1;
4026
13
    if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "all")) {
4027
0
        const_oparg = CONSTANT_BUILTIN_ALL;
4028
0
        initial_res = Py_True;
4029
0
        continue_jump_opcode = POP_JUMP_IF_TRUE;
4030
0
    }
4031
13
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "any")) {
4032
0
        const_oparg = CONSTANT_BUILTIN_ANY;
4033
0
        initial_res = Py_False;
4034
0
        continue_jump_opcode = POP_JUMP_IF_FALSE;
4035
0
    }
4036
13
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "tuple")) {
4037
0
        const_oparg = CONSTANT_BUILTIN_TUPLE;
4038
0
    }
4039
13
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "list")) {
4040
0
        const_oparg = CONSTANT_BUILTIN_LIST;
4041
0
    }
4042
13
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "set")) {
4043
0
        const_oparg = CONSTANT_BUILTIN_SET;
4044
0
    }
4045
13
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "frozenset")) {
4046
0
        const_oparg = CONSTANT_BUILTIN_FROZENSET;
4047
0
    }
4048
13
    if (const_oparg != -1) {
4049
0
        ADDOP_I(c, loc, COPY, 1); // the function
4050
0
        ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, const_oparg);
4051
0
        ADDOP_COMPARE(c, loc, Is);
4052
0
        ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, skip_optimization);
4053
0
        ADDOP(c, loc, POP_TOP);
4054
4055
0
        if (const_oparg == CONSTANT_BUILTIN_TUPLE || const_oparg == CONSTANT_BUILTIN_LIST) {
4056
0
            ADDOP_I(c, loc, BUILD_LIST, 0);
4057
0
        } else if (const_oparg == CONSTANT_BUILTIN_SET || const_oparg == CONSTANT_BUILTIN_FROZENSET) {
4058
0
            ADDOP_I(c, loc, BUILD_SET, 0);
4059
0
        }
4060
0
        VISIT(c, expr, arg_expr);
4061
4062
0
        NEW_JUMP_TARGET_LABEL(c, loop);
4063
0
        NEW_JUMP_TARGET_LABEL(c, cleanup);
4064
4065
0
        ADDOP(c, loc, PUSH_NULL); // Push NULL index for loop
4066
0
        USE_LABEL(c, loop);
4067
0
        ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
4068
0
        if (const_oparg == CONSTANT_BUILTIN_TUPLE || const_oparg == CONSTANT_BUILTIN_LIST) {
4069
0
            ADDOP_I(c, loc, LIST_APPEND, 3);
4070
0
            ADDOP_JUMP(c, loc, JUMP, loop);
4071
0
        } else if (const_oparg == CONSTANT_BUILTIN_SET || const_oparg == CONSTANT_BUILTIN_FROZENSET) {
4072
0
            ADDOP_I(c, loc, SET_ADD, 3);
4073
0
            ADDOP_JUMP(c, loc, JUMP, loop);
4074
0
        }
4075
0
        else {
4076
0
            ADDOP(c, loc, TO_BOOL);
4077
0
            ADDOP_JUMP(c, loc, continue_jump_opcode, loop);
4078
0
        }
4079
4080
0
        ADDOP(c, NO_LOCATION, POP_ITER);
4081
0
        if (const_oparg != CONSTANT_BUILTIN_TUPLE &&
4082
0
            const_oparg != CONSTANT_BUILTIN_LIST &&
4083
0
            const_oparg != CONSTANT_BUILTIN_SET &&
4084
0
            const_oparg != CONSTANT_BUILTIN_FROZENSET) {
4085
0
            ADDOP_LOAD_CONST(c, loc, initial_res == Py_True ? Py_False : Py_True);
4086
0
        }
4087
0
        ADDOP_JUMP(c, loc, JUMP, end);
4088
4089
0
        USE_LABEL(c, cleanup);
4090
0
        ADDOP(c, NO_LOCATION, END_FOR);
4091
0
        ADDOP(c, NO_LOCATION, POP_ITER);
4092
0
        if (const_oparg == CONSTANT_BUILTIN_TUPLE) {
4093
0
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
4094
0
        } else if (const_oparg == CONSTANT_BUILTIN_LIST) {
4095
            // result is already a list
4096
0
        } else if (const_oparg == CONSTANT_BUILTIN_SET) {
4097
            // result is already a set
4098
0
        }
4099
0
        else if (const_oparg == CONSTANT_BUILTIN_FROZENSET) {
4100
0
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_BUILD_FROZENSET);
4101
0
        }
4102
0
        else {
4103
0
            ADDOP_LOAD_CONST(c, loc, initial_res);
4104
0
        }
4105
4106
0
        optimized = 1;
4107
0
        ADDOP_JUMP(c, loc, JUMP, end);
4108
0
    }
4109
13
    USE_LABEL(c, skip_optimization);
4110
13
    return optimized;
4111
13
}
4112
4113
// Return 1 if the method call was optimized, 0 if not, and -1 on error.
4114
static int
4115
maybe_optimize_method_call(compiler *c, expr_ty e)
4116
9.82k
{
4117
9.82k
    Py_ssize_t argsl, i, kwdsl;
4118
9.82k
    expr_ty meth = e->v.Call.func;
4119
9.82k
    asdl_expr_seq *args = e->v.Call.args;
4120
9.82k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
4121
4122
    /* Check that the call node is an attribute access */
4123
9.82k
    if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) {
4124
8.28k
        return 0;
4125
8.28k
    }
4126
4127
    /* Check that the base object is not something that is imported */
4128
1.54k
    int ret = is_import_originated(c, meth->v.Attribute.value);
4129
1.54k
    RETURN_IF_ERROR(ret);
4130
1.54k
    if (ret) {
4131
0
        return 0;
4132
0
    }
4133
4134
    /* Check that there aren't too many arguments */
4135
1.54k
    argsl = asdl_seq_LEN(args);
4136
1.54k
    kwdsl = asdl_seq_LEN(kwds);
4137
1.54k
    if (argsl + kwdsl + (kwdsl != 0) >= _PY_STACK_USE_GUIDELINE) {
4138
2
        return 0;
4139
2
    }
4140
    /* Check that there are no *varargs types of arguments. */
4141
2.58k
    for (i = 0; i < argsl; i++) {
4142
1.09k
        expr_ty elt = asdl_seq_GET(args, i);
4143
1.09k
        if (elt->kind == Starred_kind) {
4144
55
            return 0;
4145
55
        }
4146
1.09k
    }
4147
4148
1.72k
    for (i = 0; i < kwdsl; i++) {
4149
479
        keyword_ty kw = asdl_seq_GET(kwds, i);
4150
479
        if (kw->arg == NULL) {
4151
243
            return 0;
4152
243
        }
4153
479
    }
4154
4155
    /* Alright, we can optimize the code. */
4156
1.24k
    location loc = LOC(meth);
4157
4158
1.24k
    ret = can_optimize_super_call(c, meth);
4159
1.24k
    RETURN_IF_ERROR(ret);
4160
1.24k
    if (ret) {
4161
24
        RETURN_IF_ERROR(load_args_for_super(c, meth->v.Attribute.value));
4162
24
        int opcode = asdl_seq_LEN(meth->v.Attribute.value->v.Call.args) ?
4163
24
            LOAD_SUPER_METHOD : LOAD_ZERO_SUPER_METHOD;
4164
24
        ADDOP_NAME(c, loc, opcode, meth->v.Attribute.attr, names);
4165
24
        loc = update_start_location_to_match_attr(c, loc, meth);
4166
24
        ADDOP(c, loc, NOP);
4167
1.21k
    } else {
4168
1.21k
        VISIT(c, expr, meth->v.Attribute.value);
4169
1.10k
        loc = update_start_location_to_match_attr(c, loc, meth);
4170
1.10k
        ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names);
4171
1.10k
    }
4172
4173
1.13k
    VISIT_SEQ(c, expr, e->v.Call.args);
4174
4175
1.11k
    if (kwdsl) {
4176
122
        VISIT_SEQ(c, keyword, kwds);
4177
119
        RETURN_IF_ERROR(
4178
119
            codegen_call_simple_kw_helper(c, loc, kwds, kwdsl));
4179
119
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4180
119
        ADDOP_I(c, loc, CALL_KW, argsl + kwdsl);
4181
119
    }
4182
993
    else {
4183
993
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4184
993
        ADDOP_I(c, loc, CALL, argsl);
4185
993
    }
4186
1.11k
    return 1;
4187
1.11k
}
4188
4189
static int
4190
codegen_validate_keywords(compiler *c, asdl_keyword_seq *keywords)
4191
31.4k
{
4192
31.4k
    Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
4193
34.3k
    for (Py_ssize_t i = 0; i < nkeywords; i++) {
4194
2.96k
        keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
4195
2.96k
        if (key->arg == NULL) {
4196
1.71k
            continue;
4197
1.71k
        }
4198
1.56k
        for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
4199
335
            keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
4200
335
            if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
4201
22
                return _PyCompile_Error(c, LOC(other), "keyword argument repeated: %U", key->arg);
4202
22
            }
4203
335
        }
4204
1.25k
    }
4205
31.4k
    return SUCCESS;
4206
31.4k
}
4207
4208
static int
4209
codegen_call(compiler *c, expr_ty e)
4210
9.84k
{
4211
9.84k
    RETURN_IF_ERROR(codegen_validate_keywords(c, e->v.Call.keywords));
4212
9.82k
    int ret = maybe_optimize_method_call(c, e);
4213
9.82k
    if (ret < 0) {
4214
130
        return ERROR;
4215
130
    }
4216
9.69k
    if (ret == 1) {
4217
1.11k
        return SUCCESS;
4218
1.11k
    }
4219
8.58k
    NEW_JUMP_TARGET_LABEL(c, skip_normal_call);
4220
8.58k
    RETURN_IF_ERROR(check_caller(c, e->v.Call.func));
4221
8.58k
    VISIT(c, expr, e->v.Call.func);
4222
8.54k
    RETURN_IF_ERROR(maybe_optimize_function_call(c, e, skip_normal_call));
4223
8.54k
    location loc = LOC(e->v.Call.func);
4224
8.54k
    ADDOP(c, loc, PUSH_NULL);
4225
8.54k
    loc = LOC(e);
4226
8.54k
    ret = codegen_call_helper(c, loc, 0,
4227
8.54k
                              e->v.Call.args,
4228
8.54k
                              e->v.Call.keywords);
4229
8.54k
    USE_LABEL(c, skip_normal_call);
4230
8.54k
    return ret;
4231
8.54k
}
4232
4233
static int
4234
codegen_template_str(compiler *c, expr_ty e)
4235
1.09k
{
4236
1.09k
    location loc = LOC(e);
4237
1.09k
    expr_ty value;
4238
4239
1.09k
    Py_ssize_t value_count = asdl_seq_LEN(e->v.TemplateStr.values);
4240
1.09k
    int last_was_interpolation = 1;
4241
1.09k
    Py_ssize_t stringslen = 0;
4242
3.83k
    for (Py_ssize_t i = 0; i < value_count; i++) {
4243
2.74k
        value = asdl_seq_GET(e->v.TemplateStr.values, i);
4244
2.74k
        if (value->kind == Interpolation_kind) {
4245
1.60k
            if (last_was_interpolation) {
4246
947
                ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
4247
947
                stringslen++;
4248
947
            }
4249
1.60k
            last_was_interpolation = 1;
4250
1.60k
        }
4251
1.13k
        else {
4252
1.13k
            VISIT(c, expr, value);
4253
1.13k
            stringslen++;
4254
1.13k
            last_was_interpolation = 0;
4255
1.13k
        }
4256
2.74k
    }
4257
1.09k
    if (last_was_interpolation) {
4258
613
        ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
4259
613
        stringslen++;
4260
613
    }
4261
1.09k
    ADDOP_I(c, loc, BUILD_TUPLE, stringslen);
4262
4263
1.09k
    Py_ssize_t interpolationslen = 0;
4264
3.81k
    for (Py_ssize_t i = 0; i < value_count; i++) {
4265
2.73k
        value = asdl_seq_GET(e->v.TemplateStr.values, i);
4266
2.73k
        if (value->kind == Interpolation_kind) {
4267
1.60k
            VISIT(c, expr, value);
4268
1.59k
            interpolationslen++;
4269
1.59k
        }
4270
2.73k
    }
4271
1.07k
    ADDOP_I(c, loc, BUILD_TUPLE, interpolationslen);
4272
1.07k
    ADDOP(c, loc, BUILD_TEMPLATE);
4273
1.07k
    return SUCCESS;
4274
1.07k
}
4275
4276
static int
4277
codegen_joined_str(compiler *c, expr_ty e)
4278
3.51k
{
4279
3.51k
    location loc = LOC(e);
4280
3.51k
    Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
4281
3.51k
    if (value_count > _PY_STACK_USE_GUIDELINE) {
4282
44
        _Py_DECLARE_STR(empty, "");
4283
44
        ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4284
44
        ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names);
4285
44
        ADDOP_I(c, loc, BUILD_LIST, 0);
4286
3.13k
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
4287
3.09k
            VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
4288
3.09k
            ADDOP_I(c, loc, LIST_APPEND, 1);
4289
3.09k
        }
4290
37
        ADDOP_I(c, loc, CALL, 1);
4291
37
    }
4292
3.46k
    else {
4293
3.46k
        VISIT_SEQ(c, expr, e->v.JoinedStr.values);
4294
3.40k
        if (value_count > 1) {
4295
1.66k
            ADDOP_I(c, loc, BUILD_STRING, value_count);
4296
1.66k
        }
4297
1.73k
        else if (value_count == 0) {
4298
354
            _Py_DECLARE_STR(empty, "");
4299
354
            ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4300
354
        }
4301
3.40k
    }
4302
3.43k
    return SUCCESS;
4303
3.51k
}
4304
4305
static int
4306
codegen_interpolation(compiler *c, expr_ty e)
4307
1.60k
{
4308
1.60k
    location loc = LOC(e);
4309
4310
1.60k
    VISIT(c, expr, e->v.Interpolation.value);
4311
1.59k
    ADDOP_LOAD_CONST(c, loc, e->v.Interpolation.str);
4312
4313
1.59k
    int oparg = 2;
4314
1.59k
    if (e->v.Interpolation.format_spec) {
4315
493
        oparg++;
4316
493
        VISIT(c, expr, e->v.Interpolation.format_spec);
4317
493
    }
4318
4319
1.59k
    int conversion = e->v.Interpolation.conversion;
4320
1.59k
    if (conversion != -1) {
4321
520
        switch (conversion) {
4322
69
        case 's': oparg |= FVC_STR << 2;   break;
4323
139
        case 'r': oparg |= FVC_REPR << 2;  break;
4324
312
        case 'a': oparg |= FVC_ASCII << 2; break;
4325
0
        default:
4326
0
            PyErr_Format(PyExc_SystemError,
4327
0
                     "Unrecognized conversion character %d", conversion);
4328
0
            return ERROR;
4329
520
        }
4330
520
    }
4331
4332
1.59k
    ADDOP_I(c, loc, BUILD_INTERPOLATION, oparg);
4333
1.59k
    return SUCCESS;
4334
1.59k
}
4335
4336
/* Used to implement f-strings. Format a single value. */
4337
static int
4338
codegen_formatted_value(compiler *c, expr_ty e)
4339
3.80k
{
4340
3.80k
    int conversion = e->v.FormattedValue.conversion;
4341
3.80k
    int oparg;
4342
4343
    /* The expression to be formatted. */
4344
3.80k
    VISIT(c, expr, e->v.FormattedValue.value);
4345
4346
3.74k
    location loc = LOC(e);
4347
3.74k
    if (conversion != -1) {
4348
2.11k
        switch (conversion) {
4349
410
        case 's': oparg = FVC_STR;   break;
4350
776
        case 'r': oparg = FVC_REPR;  break;
4351
931
        case 'a': oparg = FVC_ASCII; break;
4352
0
        default:
4353
0
            PyErr_Format(PyExc_SystemError,
4354
0
                     "Unrecognized conversion character %d", conversion);
4355
0
            return ERROR;
4356
2.11k
        }
4357
2.11k
        ADDOP_I(c, loc, CONVERT_VALUE, oparg);
4358
2.11k
    }
4359
3.74k
    if (e->v.FormattedValue.format_spec) {
4360
        /* Evaluate the format spec, and update our opcode arg. */
4361
1.62k
        VISIT(c, expr, e->v.FormattedValue.format_spec);
4362
1.61k
        ADDOP(c, loc, FORMAT_WITH_SPEC);
4363
2.11k
    } else {
4364
2.11k
        ADDOP(c, loc, FORMAT_SIMPLE);
4365
2.11k
    }
4366
3.73k
    return SUCCESS;
4367
3.74k
}
4368
4369
static int
4370
codegen_subkwargs(compiler *c, location loc,
4371
                  asdl_keyword_seq *keywords,
4372
                  Py_ssize_t begin, Py_ssize_t end)
4373
28
{
4374
28
    Py_ssize_t i, n = end - begin;
4375
28
    keyword_ty kw;
4376
28
    assert(n > 0);
4377
28
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
4378
28
    if (big) {
4379
0
        ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0);
4380
0
    }
4381
62
    for (i = begin; i < end; i++) {
4382
37
        kw = asdl_seq_GET(keywords, i);
4383
37
        ADDOP_LOAD_CONST(c, loc, kw->arg);
4384
37
        VISIT(c, expr, kw->value);
4385
34
        if (big) {
4386
0
            ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
4387
0
        }
4388
34
    }
4389
25
    if (!big) {
4390
25
        ADDOP_I(c, loc, BUILD_MAP, n);
4391
25
    }
4392
25
    return SUCCESS;
4393
25
}
4394
4395
/* Used by codegen_call_helper and maybe_optimize_method_call to emit
4396
 * a tuple of keyword names before CALL.
4397
 */
4398
static int
4399
codegen_call_simple_kw_helper(compiler *c, location loc,
4400
                              asdl_keyword_seq *keywords, Py_ssize_t nkwelts)
4401
553
{
4402
553
    PyObject *names;
4403
553
    names = PyTuple_New(nkwelts);
4404
553
    if (names == NULL) {
4405
0
        return ERROR;
4406
0
    }
4407
1.24k
    for (Py_ssize_t i = 0; i < nkwelts; i++) {
4408
687
        keyword_ty kw = asdl_seq_GET(keywords, i);
4409
687
        PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
4410
687
    }
4411
553
    ADDOP_LOAD_CONST_NEW(c, loc, names);
4412
553
    return SUCCESS;
4413
553
}
4414
4415
/* shared code between codegen_call and codegen_class */
4416
static int
4417
codegen_call_helper_impl(compiler *c, location loc,
4418
                         int n, /* Args already pushed */
4419
                         asdl_expr_seq *args,
4420
                         PyObject *injected_arg,
4421
                         asdl_keyword_seq *keywords)
4422
21.5k
{
4423
21.5k
    Py_ssize_t i, nseen, nelts, nkwelts;
4424
4425
21.5k
    RETURN_IF_ERROR(codegen_validate_keywords(c, keywords));
4426
4427
21.5k
    nelts = asdl_seq_LEN(args);
4428
21.5k
    nkwelts = asdl_seq_LEN(keywords);
4429
4430
21.5k
    if (nelts + nkwelts*2 > _PY_STACK_USE_GUIDELINE) {
4431
2
         goto ex_call;
4432
2
    }
4433
30.0k
    for (i = 0; i < nelts; i++) {
4434
10.4k
        expr_ty elt = asdl_seq_GET(args, i);
4435
10.4k
        if (elt->kind == Starred_kind) {
4436
2.01k
            goto ex_call;
4437
2.01k
        }
4438
10.4k
    }
4439
20.0k
    for (i = 0; i < nkwelts; i++) {
4440
989
        keyword_ty kw = asdl_seq_GET(keywords, i);
4441
989
        if (kw->arg == NULL) {
4442
512
            goto ex_call;
4443
512
        }
4444
989
    }
4445
4446
    /* No * or ** args, so can use faster calling sequence */
4447
26.9k
    for (i = 0; i < nelts; i++) {
4448
7.90k
        expr_ty elt = asdl_seq_GET(args, i);
4449
7.90k
        assert(elt->kind != Starred_kind);
4450
7.90k
        VISIT(c, expr, elt);
4451
7.90k
    }
4452
19.0k
    if (injected_arg) {
4453
2.67k
        RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
4454
2.67k
        nelts++;
4455
2.67k
    }
4456
19.0k
    if (nkwelts) {
4457
447
        VISIT_SEQ(c, keyword, keywords);
4458
434
        RETURN_IF_ERROR(
4459
434
            codegen_call_simple_kw_helper(c, loc, keywords, nkwelts));
4460
434
        ADDOP_I(c, loc, CALL_KW, n + nelts + nkwelts);
4461
434
    }
4462
18.5k
    else {
4463
18.5k
        ADDOP_I(c, loc, CALL, n + nelts);
4464
18.5k
    }
4465
18.9k
    return SUCCESS;
4466
4467
2.52k
ex_call:
4468
4469
    /* Do positional arguments. */
4470
2.52k
    if (n == 0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
4471
744
        VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
4472
744
    }
4473
1.78k
    else {
4474
1.78k
        RETURN_IF_ERROR(starunpack_helper_impl(c, loc, args, injected_arg, n,
4475
1.78k
                                               BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1));
4476
1.78k
    }
4477
    /* Then keyword arguments */
4478
2.50k
    if (nkwelts) {
4479
        /* Has a new dict been pushed */
4480
526
        int have_dict = 0;
4481
4482
526
        nseen = 0;  /* the number of keyword arguments on the stack following */
4483
1.40k
        for (i = 0; i < nkwelts; i++) {
4484
881
            keyword_ty kw = asdl_seq_GET(keywords, i);
4485
881
            if (kw->arg == NULL) {
4486
                /* A keyword argument unpacking. */
4487
844
                if (nseen) {
4488
12
                    RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, i - nseen, i));
4489
10
                    if (have_dict) {
4490
3
                        ADDOP_I(c, loc, DICT_MERGE, 1);
4491
3
                    }
4492
10
                    have_dict = 1;
4493
10
                    nseen = 0;
4494
10
                }
4495
842
                if (!have_dict) {
4496
505
                    ADDOP_I(c, loc, BUILD_MAP, 0);
4497
505
                    have_dict = 1;
4498
505
                }
4499
842
                VISIT(c, expr, kw->value);
4500
839
                ADDOP_I(c, loc, DICT_MERGE, 1);
4501
839
            }
4502
37
            else {
4503
37
                nseen++;
4504
37
            }
4505
881
        }
4506
521
        if (nseen) {
4507
            /* Pack up any trailing keyword arguments. */
4508
16
            RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts));
4509
15
            if (have_dict) {
4510
4
                ADDOP_I(c, loc, DICT_MERGE, 1);
4511
4
            }
4512
15
            have_dict = 1;
4513
15
        }
4514
521
        assert(have_dict);
4515
520
    }
4516
2.49k
    if (nkwelts == 0) {
4517
1.97k
        ADDOP(c, loc, PUSH_NULL);
4518
1.97k
    }
4519
2.49k
    ADDOP(c, loc, CALL_FUNCTION_EX);
4520
2.49k
    return SUCCESS;
4521
2.49k
}
4522
4523
static int
4524
codegen_call_helper(compiler *c, location loc,
4525
                    int n, /* Args already pushed */
4526
                    asdl_expr_seq *args,
4527
                    asdl_keyword_seq *keywords)
4528
18.9k
{
4529
18.9k
    return codegen_call_helper_impl(c, loc, n, args, NULL, keywords);
4530
18.9k
}
4531
4532
/* List and set comprehensions work by being inlined at the location where
4533
  they are defined. The isolation of iteration variables is provided by
4534
  pushing/popping clashing locals on the stack. Generator expressions work
4535
  by creating a nested function to perform the actual iteration.
4536
  This means that the iteration variables don't leak into the current scope.
4537
  See https://peps.python.org/pep-0709/ for additional information.
4538
  The defined function is called immediately following its definition, with the
4539
  result of that call being the result of the expression.
4540
  The LC/SC version returns the populated container, while the GE version is
4541
  flagged in symtable.c as a generator, so it returns the generator object
4542
  when the function is called.
4543
4544
  Possible cleanups:
4545
    - iterate over the generator sequence instead of using recursion
4546
*/
4547
4548
4549
static int
4550
codegen_comprehension_generator(compiler *c, location loc,
4551
                                asdl_comprehension_seq *generators, int gen_index,
4552
                                int depth,
4553
                                expr_ty elt, expr_ty val, int type,
4554
                                IterStackPosition iter_pos, bool avoid_creation)
4555
3.03k
{
4556
3.03k
    comprehension_ty gen;
4557
3.03k
    gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
4558
3.03k
    if (gen->is_async) {
4559
1.12k
        return codegen_async_comprehension_generator(
4560
1.12k
            c, loc, generators, gen_index, depth, elt, val, type,
4561
1.12k
            iter_pos, avoid_creation);
4562
1.90k
    } else {
4563
1.90k
        return codegen_sync_comprehension_generator(
4564
1.90k
            c, loc, generators, gen_index, depth, elt, val, type,
4565
1.90k
            iter_pos, avoid_creation);
4566
1.90k
    }
4567
3.03k
}
4568
4569
static int
4570
codegen_unpack_starred(compiler *c, location loc, expr_ty value, bool yield)
4571
2
{
4572
2
    NEW_JUMP_TARGET_LABEL(c, unpack_start);
4573
2
    NEW_JUMP_TARGET_LABEL(c, unpack_end);
4574
2
    VISIT(c, expr, value);
4575
2
    ADDOP_I(c, loc, GET_ITER, 0);
4576
2
    USE_LABEL(c, unpack_start);
4577
2
    ADDOP_JUMP(c, loc, FOR_ITER, unpack_end);
4578
2
    if (yield) {
4579
0
        ADDOP_YIELD(c, loc);
4580
0
    }
4581
2
    ADDOP(c, loc, POP_TOP);
4582
2
    ADDOP_JUMP(c, NO_LOCATION, JUMP, unpack_start);
4583
2
    USE_LABEL(c, unpack_end);
4584
2
    ADDOP(c, NO_LOCATION, END_FOR);
4585
2
    ADDOP(c, NO_LOCATION, POP_ITER);
4586
2
    return SUCCESS;
4587
2
}
4588
4589
static int
4590
codegen_sync_comprehension_generator(compiler *c, location loc,
4591
                                     asdl_comprehension_seq *generators,
4592
                                     int gen_index, int depth,
4593
                                     expr_ty elt, expr_ty val, int type,
4594
                                     IterStackPosition iter_pos, bool avoid_creation)
4595
1.90k
{
4596
    /* generate code for the iterator, then each of the ifs,
4597
       and then write to the element */
4598
4599
1.90k
    NEW_JUMP_TARGET_LABEL(c, start);
4600
1.90k
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4601
1.90k
    NEW_JUMP_TARGET_LABEL(c, anchor);
4602
4603
1.90k
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4604
1.90k
                                                          gen_index);
4605
4606
1.90k
    if (iter_pos == ITERABLE_IN_LOCAL) {
4607
104
        if (gen_index == 0) {
4608
0
            assert(METADATA(c)->u_argcount == 1);
4609
0
            ADDOP_I(c, loc, LOAD_FAST, 0);
4610
0
        }
4611
104
        else {
4612
            /* Sub-iter - calculate on the fly */
4613
            /* Fast path for the temporary variable assignment idiom:
4614
                for y in [f(x)]
4615
            */
4616
104
            asdl_expr_seq *elts;
4617
104
            switch (gen->iter->kind) {
4618
2
                case List_kind:
4619
2
                    elts = gen->iter->v.List.elts;
4620
2
                    break;
4621
0
                case Tuple_kind:
4622
0
                    elts = gen->iter->v.Tuple.elts;
4623
0
                    break;
4624
102
                default:
4625
102
                    elts = NULL;
4626
104
            }
4627
104
            if (asdl_seq_LEN(elts) == 1) {
4628
2
                expr_ty elt = asdl_seq_GET(elts, 0);
4629
2
                if (elt->kind != Starred_kind) {
4630
2
                    VISIT(c, expr, elt);
4631
2
                    start = NO_LABEL;
4632
2
                }
4633
2
            }
4634
104
            if (IS_JUMP_TARGET_LABEL(start)) {
4635
102
                VISIT(c, expr, gen->iter);
4636
102
            }
4637
104
        }
4638
104
    }
4639
4640
1.90k
    if (IS_JUMP_TARGET_LABEL(start)) {
4641
1.90k
        if (iter_pos != ITERATOR_ON_STACK) {
4642
1.53k
            ADDOP_I(c, LOC(gen->iter), GET_ITER, 0);
4643
1.53k
            depth += 1;
4644
1.53k
        }
4645
1.90k
        USE_LABEL(c, start);
4646
1.90k
        depth += 1;
4647
1.90k
        ADDOP_JUMP(c, LOC(gen->iter), FOR_ITER, anchor);
4648
1.90k
    }
4649
1.90k
    VISIT(c, expr, gen->target);
4650
4651
    /* XXX this needs to be cleaned up...a lot! */
4652
1.87k
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4653
2.04k
    for (Py_ssize_t i = 0; i < n; i++) {
4654
171
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4655
171
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4656
171
    }
4657
4658
1.87k
    if (++gen_index < asdl_seq_LEN(generators)) {
4659
223
        RETURN_IF_ERROR(
4660
223
            codegen_comprehension_generator(c, loc,
4661
223
                                            generators, gen_index, depth,
4662
223
                                            elt, val, type, ITERABLE_IN_LOCAL, avoid_creation));
4663
223
    }
4664
4665
1.86k
    location elt_loc = LOC(elt);
4666
4667
    /* only append after the last for generator */
4668
1.86k
    if (gen_index >= asdl_seq_LEN(generators)) {
4669
        /* comprehension specific code */
4670
1.64k
        switch (type) {
4671
349
        case COMP_GENEXP:
4672
349
            assert(!avoid_creation);
4673
349
            if (elt->kind == Starred_kind) {
4674
0
                RETURN_IF_ERROR(codegen_unpack_starred(c, elt_loc, elt->v.Starred.value, /*yield=*/true));
4675
0
            }
4676
349
            else {
4677
349
                VISIT(c, expr, elt);
4678
349
                ADDOP_YIELD(c, elt_loc);
4679
349
                ADDOP(c, elt_loc, POP_TOP);
4680
349
            }
4681
349
            break;
4682
349
        case COMP_LISTCOMP:
4683
87
            if (avoid_creation) {
4684
2
                if (elt->kind == Starred_kind) {
4685
2
                    RETURN_IF_ERROR(codegen_unpack_starred(c, elt_loc, elt->v.Starred.value, /*yield=*/false));
4686
2
                } else {
4687
0
                    VISIT(c, expr, elt);
4688
0
                    ADDOP(c, elt_loc, POP_TOP);
4689
0
                }
4690
2
                break;
4691
2
            }
4692
85
            if (elt->kind == Starred_kind) {
4693
5
                VISIT(c, expr, elt->v.Starred.value);
4694
5
                ADDOP_I(c, elt_loc, LIST_EXTEND, depth + 1);
4695
5
            }
4696
80
            else {
4697
80
                VISIT(c, expr, elt);
4698
80
                ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4699
80
            }
4700
85
            break;
4701
1.03k
        case COMP_SETCOMP:
4702
1.03k
            if (elt->kind == Starred_kind) {
4703
33
                VISIT(c, expr, elt->v.Starred.value);
4704
33
                ADDOP_I(c, elt_loc, SET_UPDATE, depth + 1);
4705
33
            }
4706
1.00k
            else {
4707
1.00k
                VISIT(c, expr, elt);
4708
1.00k
                ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4709
1.00k
            }
4710
1.03k
            break;
4711
1.03k
        case COMP_DICTCOMP:
4712
179
            if (val == NULL) {
4713
                /* unpacking (**) case */
4714
28
                VISIT(c, expr, elt);
4715
28
                ADDOP_I(c, elt_loc, DICT_UPDATE, depth+1);
4716
28
            }
4717
151
            else {
4718
                /* With '{k: v}', k is evaluated before v, so we do
4719
                the same. */
4720
151
                VISIT(c, expr, elt);
4721
151
                VISIT(c, expr, val);
4722
151
                elt_loc = LOCATION(elt->lineno,
4723
151
                                   val->end_lineno,
4724
151
                                   elt->col_offset,
4725
151
                                   val->end_col_offset);
4726
151
                ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4727
151
            }
4728
179
            break;
4729
179
        default:
4730
0
            return ERROR;
4731
1.64k
        }
4732
1.64k
    }
4733
4734
1.86k
    USE_LABEL(c, if_cleanup);
4735
1.86k
    if (IS_JUMP_TARGET_LABEL(start)) {
4736
1.86k
        ADDOP_JUMP(c, elt_loc, JUMP, start);
4737
4738
1.86k
        USE_LABEL(c, anchor);
4739
        /* It is important for instrumentation that the `END_FOR` comes first.
4740
        * Iteration over a generator will jump to the first of these instructions,
4741
        * but a non-generator will jump to a later instruction.
4742
        */
4743
1.86k
        ADDOP(c, NO_LOCATION, END_FOR);
4744
1.86k
        ADDOP(c, NO_LOCATION, POP_ITER);
4745
1.86k
    }
4746
4747
1.86k
    return SUCCESS;
4748
1.86k
}
4749
4750
static int
4751
codegen_async_comprehension_generator(compiler *c, location loc,
4752
                                      asdl_comprehension_seq *generators,
4753
                                      int gen_index, int depth,
4754
                                      expr_ty elt, expr_ty val, int type,
4755
                                      IterStackPosition iter_pos, bool avoid_creation)
4756
1.12k
{
4757
1.12k
    NEW_JUMP_TARGET_LABEL(c, start);
4758
1.12k
    NEW_JUMP_TARGET_LABEL(c, send);
4759
1.12k
    NEW_JUMP_TARGET_LABEL(c, except);
4760
1.12k
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4761
4762
1.12k
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4763
1.12k
                                                          gen_index);
4764
4765
1.12k
    if (iter_pos == ITERABLE_IN_LOCAL) {
4766
206
        if (gen_index == 0) {
4767
0
            assert(METADATA(c)->u_argcount == 1);
4768
0
            ADDOP_I(c, loc, LOAD_FAST, 0);
4769
0
        }
4770
206
        else {
4771
            /* Sub-iter - calculate on the fly */
4772
206
            VISIT(c, expr, gen->iter);
4773
206
        }
4774
206
    }
4775
1.12k
    if (iter_pos != ITERATOR_ON_STACK) {
4776
1.11k
        ADDOP(c, LOC(gen->iter), GET_AITER);
4777
1.11k
    }
4778
4779
1.12k
    USE_LABEL(c, start);
4780
    /* Runtime will push a block here, so we need to account for that */
4781
1.12k
    RETURN_IF_ERROR(
4782
1.12k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR,
4783
1.12k
                              start, NO_LABEL, NULL));
4784
4785
1.12k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
4786
1.12k
    ADDOP(c, loc, GET_ANEXT);
4787
1.12k
    ADDOP(c, loc, PUSH_NULL);
4788
1.12k
    ADDOP_LOAD_CONST(c, loc, Py_None);
4789
1.12k
    USE_LABEL(c, send);
4790
1.12k
    ADD_YIELD_FROM(c, loc, 1);
4791
1.12k
    ADDOP(c, loc, POP_BLOCK);
4792
1.12k
    VISIT(c, expr, gen->target);
4793
4794
1.12k
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4795
1.12k
    for (Py_ssize_t i = 0; i < n; i++) {
4796
1
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4797
1
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4798
1
    }
4799
4800
1.12k
    depth++;
4801
1.12k
    if (++gen_index < asdl_seq_LEN(generators)) {
4802
87
        RETURN_IF_ERROR(
4803
87
            codegen_comprehension_generator(c, loc,
4804
87
                                            generators, gen_index, depth,
4805
87
                                            elt, val, type, 0, avoid_creation));
4806
87
    }
4807
4808
1.12k
    location elt_loc = LOC(elt);
4809
    /* only append after the last for generator */
4810
1.12k
    if (gen_index >= asdl_seq_LEN(generators)) {
4811
        /* comprehension specific code */
4812
1.03k
        switch (type) {
4813
3
        case COMP_GENEXP:
4814
3
            assert(!avoid_creation);
4815
3
            if (elt->kind == Starred_kind) {
4816
0
                NEW_JUMP_TARGET_LABEL(c, unpack_start);
4817
0
                NEW_JUMP_TARGET_LABEL(c, unpack_end);
4818
0
                VISIT(c, expr, elt->v.Starred.value);
4819
0
                ADDOP_I(c, elt_loc, GET_ITER, 0);
4820
0
                USE_LABEL(c, unpack_start);
4821
0
                ADDOP_JUMP(c, elt_loc, FOR_ITER, unpack_end);
4822
0
                ADDOP_YIELD(c, elt_loc);
4823
0
                ADDOP(c, elt_loc, POP_TOP);
4824
0
                ADDOP_JUMP(c, NO_LOCATION, JUMP, unpack_start);
4825
0
                USE_LABEL(c, unpack_end);
4826
0
                ADDOP(c, NO_LOCATION, END_FOR);
4827
0
                ADDOP(c, NO_LOCATION, POP_ITER);
4828
0
            }
4829
3
            else {
4830
3
                VISIT(c, expr, elt);
4831
3
                ADDOP_YIELD(c, elt_loc);
4832
3
                ADDOP(c, elt_loc, POP_TOP);
4833
3
            }
4834
3
            break;
4835
3
        case COMP_LISTCOMP:
4836
1
            if (avoid_creation) {
4837
0
                if (elt->kind == Starred_kind) {
4838
0
                    RETURN_IF_ERROR(codegen_unpack_starred(c, elt_loc, elt->v.Starred.value, /*yield=*/false));
4839
0
                } else {
4840
0
                    VISIT(c, expr, elt);
4841
0
                    ADDOP(c, elt_loc, POP_TOP);
4842
0
                }
4843
0
                break;
4844
0
            }
4845
4846
1
            if (elt->kind == Starred_kind) {
4847
0
                VISIT(c, expr, elt->v.Starred.value);
4848
0
                ADDOP_I(c, elt_loc, LIST_EXTEND, depth + 1);
4849
0
            }
4850
1
            else {
4851
1
                VISIT(c, expr, elt);
4852
1
                ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4853
1
            }
4854
1
            break;
4855
514
        case COMP_SETCOMP:
4856
514
            assert(!avoid_creation);
4857
514
            if (elt->kind == Starred_kind) {
4858
54
                VISIT(c, expr, elt->v.Starred.value);
4859
54
                ADDOP_I(c, elt_loc, SET_UPDATE, depth + 1);
4860
54
            }
4861
460
            else {
4862
460
                VISIT(c, expr, elt);
4863
460
                ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4864
460
            }
4865
514
            break;
4866
516
        case COMP_DICTCOMP:
4867
516
            assert(!avoid_creation);
4868
516
            if (val == NULL) {
4869
                /* unpacking (**) case */
4870
352
                VISIT(c, expr, elt);
4871
352
                ADDOP_I(c, elt_loc, DICT_UPDATE, depth+1);
4872
352
            }
4873
164
            else {
4874
                /* With '{k: v}', k is evaluated before v, so we do
4875
                the same. */
4876
164
                VISIT(c, expr, elt);
4877
164
                VISIT(c, expr, val);
4878
164
                elt_loc = LOCATION(elt->lineno,
4879
164
                                   val->end_lineno,
4880
164
                                   elt->col_offset,
4881
164
                                   val->end_col_offset);
4882
164
                ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4883
164
            }
4884
516
            break;
4885
516
        default:
4886
0
            return ERROR;
4887
1.03k
        }
4888
1.03k
    }
4889
4890
1.12k
    USE_LABEL(c, if_cleanup);
4891
1.12k
    ADDOP_JUMP(c, elt_loc, JUMP, start);
4892
4893
1.12k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR, start);
4894
4895
1.12k
    USE_LABEL(c, except);
4896
4897
1.12k
    ADDOP_JUMP(c, loc, END_ASYNC_FOR, send);
4898
4899
1.12k
    return SUCCESS;
4900
1.12k
}
4901
4902
static int
4903
codegen_push_inlined_comprehension_locals(compiler *c, location loc,
4904
                                          PySTEntryObject *comp,
4905
                                          _PyCompile_InlinedComprehensionState *state)
4906
2.34k
{
4907
2.34k
    int in_class_block = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock) &&
4908
21
                          !_PyCompile_IsInInlinedComp(c);
4909
2.34k
    PySTEntryObject *outer = SYMTABLE_ENTRY(c);
4910
    // iterate over names bound in the comprehension and ensure we isolate
4911
    // them from the outer scope as needed
4912
2.34k
    PyObject *k, *v;
4913
2.34k
    Py_ssize_t pos = 0;
4914
14.8k
    while (PyDict_Next(comp->ste_symbols, &pos, &k, &v)) {
4915
12.4k
        long symbol = PyLong_AsLong(v);
4916
12.4k
        assert(symbol >= 0 || PyErr_Occurred());
4917
12.4k
        RETURN_IF_ERROR(symbol);
4918
12.4k
        long scope = SYMBOL_TO_SCOPE(symbol);
4919
4920
12.4k
        long outsymbol = _PyST_GetSymbol(outer, k);
4921
12.4k
        RETURN_IF_ERROR(outsymbol);
4922
12.4k
        long outsc = SYMBOL_TO_SCOPE(outsymbol);
4923
4924
12.4k
        if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) {
4925
            // local names bound in comprehension must be isolated from
4926
            // outer scope; push existing value (which may be NULL if
4927
            // not defined) on stack
4928
6.60k
            if (state->pushed_locals == NULL) {
4929
2.27k
                state->pushed_locals = PyList_New(0);
4930
2.27k
                if (state->pushed_locals == NULL) {
4931
0
                    return ERROR;
4932
0
                }
4933
2.27k
            }
4934
            // in the case of a cell, this will actually push the cell
4935
            // itself to the stack, then we'll create a new one for the
4936
            // comprehension and restore the original one after
4937
6.60k
            ADDOP_NAME(c, loc, LOAD_FAST_AND_CLEAR, k, varnames);
4938
6.60k
            if (scope == CELL) {
4939
0
                if (outsc == FREE) {
4940
0
                    ADDOP_NAME(c, loc, MAKE_CELL, k, freevars);
4941
0
                } else {
4942
0
                    ADDOP_NAME(c, loc, MAKE_CELL, k, cellvars);
4943
0
                }
4944
0
            }
4945
6.60k
            if (PyList_Append(state->pushed_locals, k) < 0) {
4946
0
                return ERROR;
4947
0
            }
4948
6.60k
        }
4949
12.4k
    }
4950
2.34k
    if (state->pushed_locals) {
4951
        // Outermost iterable expression was already evaluated and is on the
4952
        // stack, we need to swap it back to TOS. This also rotates the order of
4953
        // `pushed_locals` on the stack, but this will be reversed when we swap
4954
        // out the comprehension result in pop_inlined_comprehension_state
4955
2.27k
        ADDOP_I(c, loc, SWAP, PyList_GET_SIZE(state->pushed_locals) + 1);
4956
4957
        // Add our own cleanup handler to restore comprehension locals in case
4958
        // of exception, so they have the correct values inside an exception
4959
        // handler or finally block.
4960
2.27k
        NEW_JUMP_TARGET_LABEL(c, cleanup);
4961
2.27k
        state->cleanup = cleanup;
4962
4963
        // no need to push an fblock for this "virtual" try/finally; there can't
4964
        // be return/continue/break inside a comprehension
4965
2.27k
        ADDOP_JUMP(c, loc, SETUP_FINALLY, cleanup);
4966
2.27k
    }
4967
2.34k
    return SUCCESS;
4968
2.34k
}
4969
4970
static int
4971
push_inlined_comprehension_state(compiler *c, location loc,
4972
                                 PySTEntryObject *comp,
4973
                                 _PyCompile_InlinedComprehensionState *state)
4974
2.34k
{
4975
2.34k
    RETURN_IF_ERROR(
4976
2.34k
        _PyCompile_TweakInlinedComprehensionScopes(c, loc, comp, state));
4977
2.34k
    RETURN_IF_ERROR(
4978
2.34k
        codegen_push_inlined_comprehension_locals(c, loc, comp, state));
4979
2.34k
    return SUCCESS;
4980
2.34k
}
4981
4982
static int
4983
restore_inlined_comprehension_locals(compiler *c, location loc,
4984
                                     _PyCompile_InlinedComprehensionState *state)
4985
4.52k
{
4986
4.52k
    PyObject *k;
4987
    // pop names we pushed to stack earlier
4988
4.52k
    Py_ssize_t npops = PyList_GET_SIZE(state->pushed_locals);
4989
    // Preserve the comprehension result (or exception) as TOS. This
4990
    // reverses the SWAP we did in push_inlined_comprehension_state
4991
    // to get the outermost iterable to TOS, so we can still just iterate
4992
    // pushed_locals in simple reverse order
4993
4.52k
    ADDOP_I(c, loc, SWAP, npops + 1);
4994
17.6k
    for (Py_ssize_t i = npops - 1; i >= 0; --i) {
4995
13.1k
        k = PyList_GetItem(state->pushed_locals, i);
4996
13.1k
        if (k == NULL) {
4997
0
            return ERROR;
4998
0
        }
4999
13.1k
        ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames);
5000
13.1k
    }
5001
4.52k
    return SUCCESS;
5002
4.52k
}
5003
5004
static int
5005
codegen_pop_inlined_comprehension_locals(compiler *c, location loc,
5006
                                         _PyCompile_InlinedComprehensionState *state)
5007
2.33k
{
5008
2.33k
    if (state->pushed_locals) {
5009
2.26k
        ADDOP(c, NO_LOCATION, POP_BLOCK);
5010
5011
2.26k
        NEW_JUMP_TARGET_LABEL(c, end);
5012
2.26k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
5013
5014
        // cleanup from an exception inside the comprehension
5015
2.26k
        USE_LABEL(c, state->cleanup);
5016
        // discard incomplete comprehension result (beneath exc on stack)
5017
2.26k
        ADDOP_I(c, NO_LOCATION, SWAP, 2);
5018
2.26k
        ADDOP(c, NO_LOCATION, POP_TOP);
5019
2.26k
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
5020
2.26k
        ADDOP_I(c, NO_LOCATION, RERAISE, 0);
5021
5022
2.26k
        USE_LABEL(c, end);
5023
2.26k
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
5024
2.26k
        Py_CLEAR(state->pushed_locals);
5025
2.26k
    }
5026
2.33k
    return SUCCESS;
5027
2.33k
}
5028
5029
static int
5030
pop_inlined_comprehension_state(compiler *c, location loc,
5031
                                _PyCompile_InlinedComprehensionState *state)
5032
2.33k
{
5033
2.33k
    RETURN_IF_ERROR(codegen_pop_inlined_comprehension_locals(c, loc, state));
5034
2.33k
    RETURN_IF_ERROR(_PyCompile_RevertInlinedComprehensionScopes(c, loc, state));
5035
2.33k
    return SUCCESS;
5036
2.33k
}
5037
5038
static int
5039
codegen_comprehension(compiler *c, expr_ty e, int type,
5040
                      identifier name, asdl_comprehension_seq *generators, expr_ty elt,
5041
                      expr_ty val, bool avoid_creation)
5042
2.72k
{
5043
2.72k
    PyCodeObject *co = NULL;
5044
2.72k
    _PyCompile_InlinedComprehensionState inline_state = {NULL, NULL, NULL, NO_LABEL};
5045
2.72k
    comprehension_ty outermost;
5046
2.72k
    PySTEntryObject *entry = _PySymtable_Lookup(SYMTABLE(c), (void *)e);
5047
2.72k
    if (entry == NULL) {
5048
0
        goto error;
5049
0
    }
5050
2.72k
    int is_inlined = entry->ste_comp_inlined;
5051
2.72k
    int is_async_comprehension = entry->ste_coroutine;
5052
5053
2.72k
    location loc = LOC(e);
5054
5055
2.72k
    outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
5056
2.72k
    IterStackPosition iter_state;
5057
2.72k
    if (is_inlined) {
5058
2.34k
        VISIT(c, expr, outermost->iter);
5059
2.34k
        if (push_inlined_comprehension_state(c, loc, entry, &inline_state)) {
5060
0
            goto error;
5061
0
        }
5062
2.34k
        iter_state = ITERABLE_ON_STACK;
5063
2.34k
    }
5064
379
    else {
5065
        /* Receive outermost iter as an implicit argument */
5066
379
        _PyCompile_CodeUnitMetadata umd = {
5067
379
            .u_argcount = 1,
5068
379
        };
5069
379
        if (codegen_enter_scope(c, name, COMPILE_SCOPE_COMPREHENSION,
5070
379
                                (void *)e, e->lineno, NULL, &umd) < 0) {
5071
0
            goto error;
5072
0
        }
5073
379
        if (type == COMP_GENEXP) {
5074
            /* Insert GET_ITER before RETURN_GENERATOR.
5075
               https://docs.python.org/3/reference/expressions.html#generator-expressions */
5076
379
            RETURN_IF_ERROR(
5077
379
                _PyInstructionSequence_InsertInstruction(
5078
379
                    INSTR_SEQUENCE(c), 0,
5079
379
                    RESUME, RESUME_AT_GEN_EXPR_START, NO_LOCATION));
5080
379
            RETURN_IF_ERROR(
5081
379
                _PyInstructionSequence_InsertInstruction(
5082
379
                    INSTR_SEQUENCE(c), 1,
5083
379
                    LOAD_FAST, 0, LOC(outermost->iter)));
5084
379
            RETURN_IF_ERROR(
5085
379
                _PyInstructionSequence_InsertInstruction(
5086
379
                    INSTR_SEQUENCE(c), 2,
5087
379
                    outermost->is_async ? GET_AITER : GET_ITER,
5088
379
                    0, LOC(outermost->iter)));
5089
379
            iter_state = ITERATOR_ON_STACK;
5090
379
        }
5091
0
        else {
5092
0
            iter_state = ITERABLE_IN_LOCAL;
5093
0
        }
5094
379
    }
5095
2.72k
    Py_CLEAR(entry);
5096
5097
2.72k
    if (type != COMP_GENEXP) {
5098
2.34k
        int op;
5099
2.34k
        switch (type) {
5100
89
        case COMP_LISTCOMP:
5101
89
            op = BUILD_LIST;
5102
89
            break;
5103
1.56k
        case COMP_SETCOMP:
5104
1.56k
            op = BUILD_SET;
5105
1.56k
            break;
5106
697
        case COMP_DICTCOMP:
5107
697
            op = BUILD_MAP;
5108
697
            break;
5109
0
        default:
5110
0
            PyErr_Format(PyExc_SystemError,
5111
0
                         "unknown comprehension type %d", type);
5112
0
            goto error_in_scope;
5113
2.34k
        }
5114
5115
2.34k
        if (!avoid_creation) {
5116
2.34k
            ADDOP_I(c, loc, op, 0);
5117
2.34k
            if (is_inlined) {
5118
2.34k
                ADDOP_I(c, loc, SWAP, 2);
5119
2.34k
            }
5120
2.34k
        } else {
5121
2
            ADDOP_I(c, loc, COPY, 1);
5122
2
        }
5123
2.34k
    }
5124
2.72k
    if (codegen_comprehension_generator(c, loc, generators, 0, 0,
5125
2.72k
                                        elt, val, type, iter_state, avoid_creation) < 0) {
5126
42
        goto error_in_scope;
5127
42
    }
5128
5129
2.68k
    if (is_inlined) {
5130
2.33k
        if (pop_inlined_comprehension_state(c, loc, &inline_state)) {
5131
0
            goto error;
5132
0
        }
5133
2.33k
        return SUCCESS;
5134
2.33k
    }
5135
5136
352
    if (type != COMP_GENEXP) {
5137
0
        ADDOP(c, LOC(e), RETURN_VALUE);
5138
0
    }
5139
352
    if (type == COMP_GENEXP) {
5140
352
        if (codegen_wrap_in_stopiteration_handler(c) < 0) {
5141
0
            goto error_in_scope;
5142
0
        }
5143
352
    }
5144
5145
352
    co = _PyCompile_OptimizeAndAssemble(c, 1);
5146
352
    _PyCompile_ExitScope(c);
5147
352
    if (co == NULL) {
5148
0
        goto error;
5149
0
    }
5150
5151
352
    loc = LOC(e);
5152
352
    if (codegen_make_closure(c, loc, co, 0) < 0) {
5153
0
        goto error;
5154
0
    }
5155
352
    Py_CLEAR(co);
5156
5157
352
    VISIT(c, expr, outermost->iter);
5158
345
    ADDOP_I(c, loc, CALL, 0);
5159
5160
345
    if (is_async_comprehension && type != COMP_GENEXP) {
5161
0
        ADDOP_I(c, loc, GET_AWAITABLE, 0);
5162
0
        ADDOP(c, loc, PUSH_NULL);
5163
0
        ADDOP_LOAD_CONST(c, loc, Py_None);
5164
0
        ADD_YIELD_FROM(c, loc, 1);
5165
0
    }
5166
5167
345
    assert(!avoid_creation);
5168
5169
345
    return SUCCESS;
5170
42
error_in_scope:
5171
42
    if (!is_inlined) {
5172
27
        _PyCompile_ExitScope(c);
5173
27
    }
5174
42
error:
5175
42
    Py_XDECREF(co);
5176
42
    Py_XDECREF(entry);
5177
42
    Py_XDECREF(inline_state.pushed_locals);
5178
42
    Py_XDECREF(inline_state.temp_symbols);
5179
42
    Py_XDECREF(inline_state.fast_hidden);
5180
42
    return ERROR;
5181
42
}
5182
5183
static int
5184
codegen_genexp(compiler *c, expr_ty e)
5185
379
{
5186
379
    assert(e->kind == GeneratorExp_kind);
5187
379
    _Py_DECLARE_STR(anon_genexpr, "<genexpr>");
5188
379
    return codegen_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
5189
379
                                 e->v.GeneratorExp.generators,
5190
379
                                 e->v.GeneratorExp.elt, NULL, false);
5191
379
}
5192
5193
static int
5194
codegen_listcomp(compiler *c, expr_ty e, bool avoid_creation)
5195
91
{
5196
91
    assert(e->kind == ListComp_kind);
5197
91
    _Py_DECLARE_STR(anon_listcomp, "<listcomp>");
5198
91
    return codegen_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
5199
91
                                 e->v.ListComp.generators,
5200
91
                                 e->v.ListComp.elt, NULL, avoid_creation);
5201
91
}
5202
5203
static int
5204
codegen_setcomp(compiler *c, expr_ty e)
5205
1.56k
{
5206
1.56k
    assert(e->kind == SetComp_kind);
5207
1.56k
    _Py_DECLARE_STR(anon_setcomp, "<setcomp>");
5208
1.56k
    return codegen_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp),
5209
1.56k
                                 e->v.SetComp.generators,
5210
1.56k
                                 e->v.SetComp.elt, NULL, /*avoid_creation=*/false);
5211
1.56k
}
5212
5213
5214
static int
5215
codegen_dictcomp(compiler *c, expr_ty e)
5216
697
{
5217
697
    assert(e->kind == DictComp_kind);
5218
697
    _Py_DECLARE_STR(anon_dictcomp, "<dictcomp>");
5219
697
    return codegen_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
5220
697
                                 e->v.DictComp.generators,
5221
697
                                 e->v.DictComp.key, e->v.DictComp.value, /*avoid_creation=*/false);
5222
697
}
5223
5224
5225
static int
5226
codegen_visit_keyword(compiler *c, keyword_ty k)
5227
703
{
5228
703
    VISIT(c, expr, k->value);
5229
687
    return SUCCESS;
5230
703
}
5231
5232
5233
static int
5234
11.5k
codegen_with_except_finish(compiler *c, jump_target_label cleanup) {
5235
11.5k
    NEW_JUMP_TARGET_LABEL(c, suppress);
5236
11.5k
    ADDOP(c, NO_LOCATION, TO_BOOL);
5237
11.5k
    ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress);
5238
11.5k
    ADDOP_I(c, NO_LOCATION, RERAISE, 2);
5239
5240
11.5k
    USE_LABEL(c, suppress);
5241
11.5k
    ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */
5242
11.5k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
5243
11.5k
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
5244
11.5k
    ADDOP(c, NO_LOCATION, POP_TOP);
5245
11.5k
    ADDOP(c, NO_LOCATION, POP_TOP);
5246
11.5k
    ADDOP(c, NO_LOCATION, POP_TOP);
5247
11.5k
    NEW_JUMP_TARGET_LABEL(c, exit);
5248
11.5k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
5249
5250
11.5k
    USE_LABEL(c, cleanup);
5251
11.5k
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
5252
5253
11.5k
    USE_LABEL(c, exit);
5254
11.5k
    return SUCCESS;
5255
11.5k
}
5256
5257
/*
5258
   Implements the async with statement.
5259
5260
   The semantics outlined in that PEP are as follows:
5261
5262
   async with EXPR as VAR:
5263
       BLOCK
5264
5265
   It is implemented roughly as:
5266
5267
   context = EXPR
5268
   exit = context.__aexit__  # not calling it
5269
   value = await context.__aenter__()
5270
   try:
5271
       VAR = value  # if VAR present in the syntax
5272
       BLOCK
5273
   finally:
5274
       if an exception was raised:
5275
           exc = copy of (exception, instance, traceback)
5276
       else:
5277
           exc = (None, None, None)
5278
       if not (await exit(*exc)):
5279
           raise
5280
 */
5281
static int
5282
codegen_async_with_inner(compiler *c, stmt_ty s, int pos)
5283
10.8k
{
5284
10.8k
    location loc = LOC(s);
5285
10.8k
    withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
5286
5287
10.8k
    assert(s->kind == AsyncWith_kind);
5288
5289
10.8k
    NEW_JUMP_TARGET_LABEL(c, block);
5290
10.8k
    NEW_JUMP_TARGET_LABEL(c, final);
5291
10.8k
    NEW_JUMP_TARGET_LABEL(c, exit);
5292
10.8k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
5293
5294
    /* Evaluate EXPR */
5295
10.8k
    VISIT(c, expr, item->context_expr);
5296
10.8k
    loc = LOC(item->context_expr);
5297
10.8k
    ADDOP_I(c, loc, COPY, 1);
5298
10.8k
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AEXIT__);
5299
10.8k
    ADDOP_I(c, loc, SWAP, 2);
5300
10.8k
    ADDOP_I(c, loc, SWAP, 3);
5301
10.8k
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AENTER__);
5302
10.8k
    ADDOP_I(c, loc, CALL, 0);
5303
10.8k
    ADDOP_I(c, loc, GET_AWAITABLE, 1);
5304
10.8k
    ADDOP(c, loc, PUSH_NULL);
5305
10.8k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5306
10.8k
    ADD_YIELD_FROM(c, loc, 1);
5307
5308
10.8k
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5309
5310
    /* SETUP_WITH pushes a finally block. */
5311
10.8k
    USE_LABEL(c, block);
5312
10.8k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_WITH, block, final, s));
5313
5314
10.8k
    if (item->optional_vars) {
5315
941
        VISIT(c, expr, item->optional_vars);
5316
941
    }
5317
9.95k
    else {
5318
        /* Discard result from context.__aenter__() */
5319
9.95k
        ADDOP(c, loc, POP_TOP);
5320
9.95k
    }
5321
5322
10.8k
    pos++;
5323
10.8k
    if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) {
5324
        /* BLOCK code */
5325
2.08k
        VISIT_SEQ(c, stmt, s->v.AsyncWith.body);
5326
2.08k
    }
5327
8.80k
    else {
5328
8.80k
        RETURN_IF_ERROR(codegen_async_with_inner(c, s, pos));
5329
8.80k
    }
5330
5331
10.7k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_WITH, block);
5332
5333
10.7k
    ADDOP(c, loc, POP_BLOCK);
5334
    /* End of body; start the cleanup */
5335
5336
    /* For successful outcome:
5337
     * call __exit__(None, None, None)
5338
     */
5339
10.7k
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5340
10.7k
    ADDOP_I(c, loc, GET_AWAITABLE, 2);
5341
10.7k
    ADDOP(c, loc, PUSH_NULL);
5342
10.7k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5343
10.7k
    ADD_YIELD_FROM(c, loc, 1);
5344
5345
10.7k
    ADDOP(c, loc, POP_TOP);
5346
5347
10.7k
    ADDOP_JUMP(c, loc, JUMP, exit);
5348
5349
    /* For exceptional outcome: */
5350
10.7k
    USE_LABEL(c, final);
5351
5352
10.7k
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5353
10.7k
    ADDOP(c, loc, PUSH_EXC_INFO);
5354
10.7k
    ADDOP(c, loc, WITH_EXCEPT_START);
5355
10.7k
    ADDOP_I(c, loc, GET_AWAITABLE, 2);
5356
10.7k
    ADDOP(c, loc, PUSH_NULL);
5357
10.7k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5358
10.7k
    ADD_YIELD_FROM(c, loc, 1);
5359
10.7k
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5360
5361
10.7k
    USE_LABEL(c, exit);
5362
10.7k
    return SUCCESS;
5363
10.7k
}
5364
5365
static int
5366
codegen_async_with(compiler *c, stmt_ty s)
5367
2.09k
{
5368
2.09k
    return codegen_async_with_inner(c, s, 0);
5369
2.09k
}
5370
5371
5372
/*
5373
   Implements the with statement from PEP 343.
5374
   with EXPR as VAR:
5375
       BLOCK
5376
   is implemented as:
5377
        <code for EXPR>
5378
        SETUP_WITH  E
5379
        <code to store to VAR> or POP_TOP
5380
        <code for BLOCK>
5381
        LOAD_CONST (None, None, None)
5382
        CALL_FUNCTION_EX 0
5383
        JUMP  EXIT
5384
    E:  WITH_EXCEPT_START (calls EXPR.__exit__)
5385
        POP_JUMP_IF_TRUE T:
5386
        RERAISE
5387
    T:  POP_TOP (remove exception from stack)
5388
        POP_EXCEPT
5389
        POP_TOP
5390
    EXIT:
5391
 */
5392
5393
static int
5394
codegen_with_inner(compiler *c, stmt_ty s, int pos)
5395
836
{
5396
836
    withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
5397
5398
836
    assert(s->kind == With_kind);
5399
5400
836
    NEW_JUMP_TARGET_LABEL(c, block);
5401
836
    NEW_JUMP_TARGET_LABEL(c, final);
5402
836
    NEW_JUMP_TARGET_LABEL(c, exit);
5403
836
    NEW_JUMP_TARGET_LABEL(c, cleanup);
5404
5405
    /* Evaluate EXPR */
5406
836
    VISIT(c, expr, item->context_expr);
5407
    /* Will push bound __exit__ */
5408
835
    location loc = LOC(item->context_expr);
5409
835
    ADDOP_I(c, loc, COPY, 1);
5410
835
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___EXIT__);
5411
835
    ADDOP_I(c, loc, SWAP, 2);
5412
835
    ADDOP_I(c, loc, SWAP, 3);
5413
835
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___ENTER__);
5414
835
    ADDOP_I(c, loc, CALL, 0);
5415
835
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5416
5417
    /* SETUP_WITH pushes a finally block. */
5418
835
    USE_LABEL(c, block);
5419
835
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_WITH, block, final, s));
5420
5421
834
    if (item->optional_vars) {
5422
50
        VISIT(c, expr, item->optional_vars);
5423
50
    }
5424
784
    else {
5425
    /* Discard result from context.__enter__() */
5426
784
        ADDOP(c, loc, POP_TOP);
5427
784
    }
5428
5429
834
    pos++;
5430
834
    if (pos == asdl_seq_LEN(s->v.With.items)) {
5431
        /* BLOCK code */
5432
543
        VISIT_SEQ(c, stmt, s->v.With.body);
5433
543
    }
5434
291
    else {
5435
291
        RETURN_IF_ERROR(codegen_with_inner(c, s, pos));
5436
291
    }
5437
5438
776
    ADDOP(c, NO_LOCATION, POP_BLOCK);
5439
776
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_WITH, block);
5440
5441
    /* End of body; start the cleanup. */
5442
5443
    /* For successful outcome:
5444
     * call __exit__(None, None, None)
5445
     */
5446
776
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5447
776
    ADDOP(c, loc, POP_TOP);
5448
776
    ADDOP_JUMP(c, loc, JUMP, exit);
5449
5450
    /* For exceptional outcome: */
5451
776
    USE_LABEL(c, final);
5452
5453
776
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5454
776
    ADDOP(c, loc, PUSH_EXC_INFO);
5455
776
    ADDOP(c, loc, WITH_EXCEPT_START);
5456
776
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5457
5458
776
    USE_LABEL(c, exit);
5459
776
    return SUCCESS;
5460
776
}
5461
5462
static int
5463
codegen_with(compiler *c, stmt_ty s)
5464
545
{
5465
545
    return codegen_with_inner(c, s, 0);
5466
545
}
5467
5468
static int
5469
codegen_visit_expr_impl(compiler *c, expr_ty e, bool result_is_unused)
5470
2.51M
{
5471
2.51M
    if (Py_EnterRecursiveCall(" during compilation")) {
5472
0
        return ERROR;
5473
0
    }
5474
2.51M
    location loc = LOC(e);
5475
2.51M
    switch (e->kind) {
5476
936
    case NamedExpr_kind:
5477
936
        VISIT(c, expr, e->v.NamedExpr.value);
5478
933
        ADDOP_I(c, loc, COPY, 1);
5479
933
        VISIT(c, expr, e->v.NamedExpr.target);
5480
933
        break;
5481
2.69k
    case BoolOp_kind:
5482
2.69k
        return codegen_boolop(c, e);
5483
793k
    case BinOp_kind:
5484
793k
        VISIT(c, expr, e->v.BinOp.left);
5485
792k
        VISIT(c, expr, e->v.BinOp.right);
5486
792k
        ADDOP_BINARY(c, loc, e->v.BinOp.op);
5487
792k
        break;
5488
792k
    case UnaryOp_kind:
5489
229k
        VISIT(c, expr, e->v.UnaryOp.operand);
5490
229k
        if (e->v.UnaryOp.op == UAdd) {
5491
57.4k
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE);
5492
57.4k
        }
5493
171k
        else if (e->v.UnaryOp.op == Not) {
5494
1.35k
            ADDOP(c, loc, TO_BOOL);
5495
1.35k
            ADDOP(c, loc, UNARY_NOT);
5496
1.35k
        }
5497
170k
        else {
5498
170k
            ADDOP(c, loc, unaryop(e->v.UnaryOp.op));
5499
170k
        }
5500
229k
        break;
5501
229k
    case Lambda_kind:
5502
4.36k
        return codegen_lambda(c, e);
5503
587
    case IfExp_kind:
5504
587
        return codegen_ifexp(c, e);
5505
535
    case Dict_kind:
5506
535
        return codegen_dict(c, e);
5507
6.67k
    case Set_kind:
5508
6.67k
        return codegen_set(c, e);
5509
379
    case GeneratorExp_kind:
5510
379
        return codegen_genexp(c, e);
5511
91
    case ListComp_kind:
5512
91
        return codegen_listcomp(c, e, result_is_unused);
5513
1.56k
    case SetComp_kind:
5514
1.56k
        return codegen_setcomp(c, e);
5515
697
    case DictComp_kind:
5516
697
        return codegen_dictcomp(c, e);
5517
274
    case Yield_kind:
5518
274
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5519
109
            return _PyCompile_Error(c, loc, "'yield' outside function");
5520
109
        }
5521
165
        if (e->v.Yield.value) {
5522
59
            VISIT(c, expr, e->v.Yield.value);
5523
59
        }
5524
106
        else {
5525
106
            ADDOP_LOAD_CONST(c, loc, Py_None);
5526
106
        }
5527
165
        ADDOP_YIELD(c, loc);
5528
165
        break;
5529
165
    case YieldFrom_kind:
5530
18
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5531
6
            return _PyCompile_Error(c, loc, "'yield from' outside function");
5532
6
        }
5533
12
        if (SCOPE_TYPE(c) == COMPILE_SCOPE_ASYNC_FUNCTION) {
5534
6
            return _PyCompile_Error(c, loc, "'yield from' inside async function");
5535
6
        }
5536
6
        VISIT(c, expr, e->v.YieldFrom.value);
5537
6
        ADDOP_I(c, loc, GET_ITER, GET_ITER_YIELD_FROM);
5538
6
        ADDOP_LOAD_CONST(c, loc, Py_None);
5539
6
        ADD_YIELD_FROM(c, loc, 0);
5540
6
        break;
5541
308
    case Await_kind:
5542
308
        VISIT(c, expr, e->v.Await.value);
5543
301
        ADDOP_I(c, loc, GET_AWAITABLE, 0);
5544
301
        ADDOP(c, loc, PUSH_NULL);
5545
301
        ADDOP_LOAD_CONST(c, loc, Py_None);
5546
301
        ADD_YIELD_FROM(c, loc, 1);
5547
301
        break;
5548
21.3k
    case Compare_kind:
5549
21.3k
        return codegen_compare(c, e);
5550
9.84k
    case Call_kind:
5551
9.84k
        return codegen_call(c, e);
5552
942k
    case Constant_kind:
5553
942k
        ADDOP_LOAD_CONST(c, loc, e->v.Constant.value);
5554
942k
        break;
5555
942k
    case JoinedStr_kind:
5556
3.51k
        return codegen_joined_str(c, e);
5557
1.09k
    case TemplateStr_kind:
5558
1.09k
        return codegen_template_str(c, e);
5559
3.80k
    case FormattedValue_kind:
5560
3.80k
        return codegen_formatted_value(c, e);
5561
1.60k
    case Interpolation_kind:
5562
1.60k
        return codegen_interpolation(c, e);
5563
    /* The following exprs can be assignment targets. */
5564
13.9k
    case Attribute_kind:
5565
13.9k
        if (e->v.Attribute.ctx == Load) {
5566
12.4k
            int ret = can_optimize_super_call(c, e);
5567
12.4k
            RETURN_IF_ERROR(ret);
5568
12.4k
            if (ret) {
5569
499
                RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
5570
499
                int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
5571
499
                    LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
5572
499
                ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
5573
499
                loc = update_start_location_to_match_attr(c, loc, e);
5574
499
                ADDOP(c, loc, NOP);
5575
499
                return SUCCESS;
5576
499
            }
5577
12.4k
        }
5578
13.4k
        RETURN_IF_ERROR(_PyCompile_MaybeAddStaticAttributeToClass(c, e));
5579
13.4k
        loc = LOC(e);
5580
13.4k
        loc = update_start_location_to_match_attr(c, loc, e);
5581
13.4k
        switch (e->v.Attribute.ctx) {
5582
11.9k
        case Load:
5583
11.9k
            VISIT(c, expr, e->v.Attribute.value);
5584
11.7k
            ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5585
11.7k
            break;
5586
11.7k
        case Store:
5587
863
            VISIT(c, expr, e->v.Attribute.value);
5588
860
            ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5589
860
            break;
5590
860
        case Del:
5591
585
            ADDOP(c, loc, PUSH_NULL);
5592
585
            VISIT(c, expr, e->v.Attribute.value);
5593
584
            ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5594
584
            break;
5595
13.4k
        }
5596
13.2k
        break;
5597
13.2k
    case Subscript_kind:
5598
10.2k
        return codegen_subscript(c, e);
5599
175
    case Starred_kind:
5600
175
        switch (e->v.Starred.ctx) {
5601
43
        case Store:
5602
            /* In all legitimate cases, the Starred node was already replaced
5603
             * by codegen_list/codegen_tuple. XXX: is that okay? */
5604
43
            return _PyCompile_Error(c, loc,
5605
43
                "starred assignment target must be in a list or tuple");
5606
132
        default:
5607
132
            return _PyCompile_Error(c, loc,
5608
132
                "can't use starred expression here");
5609
175
        }
5610
0
        break;
5611
9.97k
    case Slice_kind:
5612
9.97k
        RETURN_IF_ERROR(codegen_slice(c, e));
5613
9.96k
        break;
5614
376k
    case Name_kind:
5615
376k
        return codegen_nameop(c, loc, e->v.Name.id, e->v.Name.ctx);
5616
    /* child nodes of List and Tuple will have expr_context set */
5617
2.54k
    case List_kind:
5618
2.54k
        return codegen_list(c, e);
5619
78.0k
    case Tuple_kind:
5620
78.0k
        return codegen_tuple(c, e);
5621
2.51M
    }
5622
1.98M
    return SUCCESS;
5623
2.51M
}
5624
5625
static int
5626
codegen_visit_expr(compiler *c, expr_ty e)
5627
2.43M
{
5628
2.43M
    return codegen_visit_expr_impl(c, e, false);
5629
2.43M
}
5630
5631
static int
5632
codegen_visit_unused_expr(compiler *c, expr_ty e)
5633
83.7k
{
5634
83.7k
    return codegen_visit_expr_impl(c, e, true);
5635
83.7k
}
5636
5637
static bool
5638
is_constant_slice(expr_ty s)
5639
20.8k
{
5640
20.8k
    return s->kind == Slice_kind &&
5641
15.2k
        (s->v.Slice.lower == NULL ||
5642
10.7k
         s->v.Slice.lower->kind == Constant_kind) &&
5643
10.1k
        (s->v.Slice.upper == NULL ||
5644
3.21k
         s->v.Slice.upper->kind == Constant_kind) &&
5645
9.74k
        (s->v.Slice.step == NULL ||
5646
3.86k
         s->v.Slice.step->kind == Constant_kind);
5647
20.8k
}
5648
5649
static bool
5650
should_apply_two_element_slice_optimization(expr_ty s)
5651
10.8k
{
5652
10.8k
    return !is_constant_slice(s) &&
5653
6.59k
           s->kind == Slice_kind &&
5654
973
           s->v.Slice.step == NULL;
5655
10.8k
}
5656
5657
static int
5658
codegen_augassign(compiler *c, stmt_ty s)
5659
6.50k
{
5660
6.50k
    assert(s->kind == AugAssign_kind);
5661
6.50k
    expr_ty e = s->v.AugAssign.target;
5662
5663
6.50k
    location loc = LOC(e);
5664
5665
6.50k
    switch (e->kind) {
5666
1.50k
    case Attribute_kind:
5667
1.50k
        VISIT(c, expr, e->v.Attribute.value);
5668
1.50k
        ADDOP_I(c, loc, COPY, 1);
5669
1.50k
        loc = update_start_location_to_match_attr(c, loc, e);
5670
1.50k
        ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5671
1.50k
        break;
5672
1.50k
    case Subscript_kind:
5673
353
        VISIT(c, expr, e->v.Subscript.value);
5674
353
        if (should_apply_two_element_slice_optimization(e->v.Subscript.slice)) {
5675
216
            RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5676
215
            ADDOP_I(c, loc, COPY, 3);
5677
215
            ADDOP_I(c, loc, COPY, 3);
5678
215
            ADDOP_I(c, loc, COPY, 3);
5679
215
            ADDOP(c, loc, BINARY_SLICE);
5680
215
        }
5681
137
        else {
5682
137
            VISIT(c, expr, e->v.Subscript.slice);
5683
136
            ADDOP_I(c, loc, COPY, 2);
5684
136
            ADDOP_I(c, loc, COPY, 2);
5685
136
            ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5686
136
        }
5687
351
        break;
5688
4.64k
    case Name_kind:
5689
4.64k
        RETURN_IF_ERROR(codegen_nameop(c, loc, e->v.Name.id, Load));
5690
4.64k
        break;
5691
4.64k
    default:
5692
0
        PyErr_Format(PyExc_SystemError,
5693
0
            "invalid node type (%d) for augmented assignment",
5694
0
            e->kind);
5695
0
        return ERROR;
5696
6.50k
    }
5697
5698
6.50k
    loc = LOC(s);
5699
5700
6.50k
    VISIT(c, expr, s->v.AugAssign.value);
5701
6.49k
    ADDOP_INPLACE(c, loc, s->v.AugAssign.op);
5702
5703
6.49k
    loc = LOC(e);
5704
5705
6.49k
    switch (e->kind) {
5706
1.50k
    case Attribute_kind:
5707
1.50k
        loc = update_start_location_to_match_attr(c, loc, e);
5708
1.50k
        ADDOP_I(c, loc, SWAP, 2);
5709
1.50k
        ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5710
1.50k
        break;
5711
1.50k
    case Subscript_kind:
5712
351
        if (should_apply_two_element_slice_optimization(e->v.Subscript.slice)) {
5713
215
            ADDOP_I(c, loc, SWAP, 4);
5714
215
            ADDOP_I(c, loc, SWAP, 3);
5715
215
            ADDOP_I(c, loc, SWAP, 2);
5716
215
            ADDOP(c, loc, STORE_SLICE);
5717
215
        }
5718
136
        else {
5719
136
            ADDOP_I(c, loc, SWAP, 3);
5720
136
            ADDOP_I(c, loc, SWAP, 2);
5721
136
            ADDOP(c, loc, STORE_SUBSCR);
5722
136
        }
5723
351
        break;
5724
4.63k
    case Name_kind:
5725
4.63k
        return codegen_nameop(c, loc, e->v.Name.id, Store);
5726
0
    default:
5727
0
        Py_UNREACHABLE();
5728
6.49k
    }
5729
1.85k
    return SUCCESS;
5730
6.49k
}
5731
5732
static int
5733
codegen_check_ann_expr(compiler *c, expr_ty e)
5734
4.89k
{
5735
4.89k
    VISIT(c, expr, e);
5736
4.88k
    ADDOP(c, LOC(e), POP_TOP);
5737
4.88k
    return SUCCESS;
5738
4.88k
}
5739
5740
static int
5741
codegen_check_ann_subscr(compiler *c, expr_ty e)
5742
3.85k
{
5743
    /* We check that everything in a subscript is defined at runtime. */
5744
3.85k
    switch (e->kind) {
5745
2.13k
    case Slice_kind:
5746
2.13k
        if (e->v.Slice.lower && codegen_check_ann_expr(c, e->v.Slice.lower) < 0) {
5747
1
            return ERROR;
5748
1
        }
5749
2.13k
        if (e->v.Slice.upper && codegen_check_ann_expr(c, e->v.Slice.upper) < 0) {
5750
2
            return ERROR;
5751
2
        }
5752
2.13k
        if (e->v.Slice.step && codegen_check_ann_expr(c, e->v.Slice.step) < 0) {
5753
1
            return ERROR;
5754
1
        }
5755
2.13k
        return SUCCESS;
5756
377
    case Tuple_kind: {
5757
        /* extended slice */
5758
377
        asdl_expr_seq *elts = e->v.Tuple.elts;
5759
377
        Py_ssize_t i, n = asdl_seq_LEN(elts);
5760
3.82k
        for (i = 0; i < n; i++) {
5761
3.45k
            RETURN_IF_ERROR(codegen_check_ann_subscr(c, asdl_seq_GET(elts, i)));
5762
3.45k
        }
5763
369
        return SUCCESS;
5764
377
    }
5765
1.34k
    default:
5766
1.34k
        return codegen_check_ann_expr(c, e);
5767
3.85k
    }
5768
3.85k
}
5769
5770
static int
5771
codegen_annassign(compiler *c, stmt_ty s)
5772
25.0k
{
5773
25.0k
    location loc = LOC(s);
5774
25.0k
    expr_ty targ = s->v.AnnAssign.target;
5775
25.0k
    bool future_annotations = FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS;
5776
25.0k
    PyObject *mangled;
5777
5778
25.0k
    assert(s->kind == AnnAssign_kind);
5779
5780
    /* We perform the actual assignment first. */
5781
25.0k
    if (s->v.AnnAssign.value) {
5782
433
        VISIT(c, expr, s->v.AnnAssign.value);
5783
422
        VISIT(c, expr, targ);
5784
422
    }
5785
25.0k
    switch (targ->kind) {
5786
23.9k
    case Name_kind:
5787
        /* If we have a simple name in a module or class, store annotation. */
5788
23.9k
        if (s->v.AnnAssign.simple &&
5789
23.8k
            (SCOPE_TYPE(c) == COMPILE_SCOPE_MODULE ||
5790
20.5k
             SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS)) {
5791
20.5k
            if (future_annotations) {
5792
4.05k
                VISIT(c, annexpr, s->v.AnnAssign.annotation);
5793
4.05k
                ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
5794
4.05k
                mangled = _PyCompile_MaybeMangle(c, targ->v.Name.id);
5795
4.05k
                ADDOP_LOAD_CONST_NEW(c, loc, mangled);
5796
4.05k
                ADDOP(c, loc, STORE_SUBSCR);
5797
4.05k
            }
5798
16.5k
            else {
5799
16.5k
                PyObject *conditional_annotation_index = NULL;
5800
16.5k
                RETURN_IF_ERROR(_PyCompile_AddDeferredAnnotation(
5801
16.5k
                    c, s, &conditional_annotation_index));
5802
16.5k
                if (conditional_annotation_index != NULL) {
5803
4.49k
                    if (SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS) {
5804
820
                        ADDOP_NAME(c, loc, LOAD_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
5805
820
                    }
5806
3.67k
                    else {
5807
3.67k
                        ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__conditional_annotations__), names);
5808
3.67k
                    }
5809
4.49k
                    ADDOP_LOAD_CONST_NEW(c, loc, conditional_annotation_index);
5810
                    // gh-154902: change SET_ADD to new INTRINSIC_ADD_CONDITIONAL_ANNOTATION intrinsic
5811
4.49k
                    ADDOP_I(c, loc, CALL_INTRINSIC_2,
5812
4.49k
                            INTRINSIC_ADD_CONDITIONAL_ANNOTATION);
5813
4.49k
                    ADDOP(c, loc, POP_TOP);
5814
4.49k
                }
5815
16.5k
            }
5816
20.5k
        }
5817
23.9k
        break;
5818
23.9k
    case Attribute_kind:
5819
665
        if (!s->v.AnnAssign.value &&
5820
596
            codegen_check_ann_expr(c, targ->v.Attribute.value) < 0) {
5821
3
            return ERROR;
5822
3
        }
5823
662
        break;
5824
662
    case Subscript_kind:
5825
430
        if (!s->v.AnnAssign.value &&
5826
407
            (codegen_check_ann_expr(c, targ->v.Subscript.value) < 0 ||
5827
405
             codegen_check_ann_subscr(c, targ->v.Subscript.slice) < 0)) {
5828
12
                return ERROR;
5829
12
        }
5830
418
        break;
5831
418
    default:
5832
0
        PyErr_Format(PyExc_SystemError,
5833
0
                     "invalid node type (%d) for annotated assignment",
5834
0
                     targ->kind);
5835
0
        return ERROR;
5836
25.0k
    }
5837
25.0k
    return SUCCESS;
5838
25.0k
}
5839
5840
static int
5841
codegen_subscript(compiler *c, expr_ty e)
5842
10.2k
{
5843
10.2k
    location loc = LOC(e);
5844
10.2k
    expr_context_ty ctx = e->v.Subscript.ctx;
5845
5846
10.2k
    if (ctx == Load) {
5847
10.0k
        RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value));
5848
10.0k
        RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice));
5849
10.0k
    }
5850
5851
10.2k
    VISIT(c, expr, e->v.Subscript.value);
5852
10.1k
    if (should_apply_two_element_slice_optimization(e->v.Subscript.slice) &&
5853
419
        ctx != Del
5854
10.1k
    ) {
5855
416
        RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5856
409
        if (ctx == Load) {
5857
362
            ADDOP(c, loc, BINARY_SLICE);
5858
362
        }
5859
47
        else {
5860
47
            assert(ctx == Store);
5861
47
            ADDOP(c, loc, STORE_SLICE);
5862
47
        }
5863
409
    }
5864
9.77k
    else {
5865
9.77k
        VISIT(c, expr, e->v.Subscript.slice);
5866
9.75k
        switch (ctx) {
5867
9.63k
            case Load:
5868
9.63k
                ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5869
9.63k
                break;
5870
9.63k
            case Store:
5871
73
                ADDOP(c, loc, STORE_SUBSCR);
5872
73
                break;
5873
73
            case Del:
5874
49
                ADDOP(c, loc, DELETE_SUBSCR);
5875
49
                break;
5876
9.75k
        }
5877
9.75k
    }
5878
10.1k
    return SUCCESS;
5879
10.1k
}
5880
5881
static int
5882
codegen_slice_two_parts(compiler *c, expr_ty s)
5883
5.61k
{
5884
5.61k
    if (s->v.Slice.lower) {
5885
4.93k
        VISIT(c, expr, s->v.Slice.lower);
5886
4.93k
    }
5887
674
    else {
5888
674
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5889
674
    }
5890
5891
5.60k
    if (s->v.Slice.upper) {
5892
2.26k
        VISIT(c, expr, s->v.Slice.upper);
5893
2.26k
    }
5894
3.33k
    else {
5895
3.33k
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5896
3.33k
    }
5897
5898
5.59k
    return 0;
5899
5.60k
}
5900
5901
static int
5902
codegen_slice(compiler *c, expr_ty s)
5903
9.97k
{
5904
9.97k
    int n = 2;
5905
9.97k
    assert(s->kind == Slice_kind);
5906
5907
9.97k
    if (is_constant_slice(s)) {
5908
4.99k
        PyObject *start = NULL;
5909
4.99k
        if (s->v.Slice.lower) {
5910
2.82k
            start = s->v.Slice.lower->v.Constant.value;
5911
2.82k
        }
5912
4.99k
        PyObject *stop = NULL;
5913
4.99k
        if (s->v.Slice.upper) {
5914
1.50k
            stop = s->v.Slice.upper->v.Constant.value;
5915
1.50k
        }
5916
4.99k
        PyObject *step = NULL;
5917
4.99k
        if (s->v.Slice.step) {
5918
1.67k
            step = s->v.Slice.step->v.Constant.value;
5919
1.67k
        }
5920
4.99k
        PyObject *slice = PySlice_New(start, stop, step);
5921
4.99k
        if (slice == NULL) {
5922
0
            return ERROR;
5923
0
        }
5924
4.99k
        ADDOP_LOAD_CONST_NEW(c, LOC(s), slice);
5925
4.99k
        return SUCCESS;
5926
4.99k
    }
5927
5928
4.98k
    RETURN_IF_ERROR(codegen_slice_two_parts(c, s));
5929
5930
4.97k
    if (s->v.Slice.step) {
5931
1.70k
        n++;
5932
1.70k
        VISIT(c, expr, s->v.Slice.step);
5933
1.70k
    }
5934
5935
4.97k
    ADDOP_I(c, LOC(s), BUILD_SLICE, n);
5936
4.97k
    return SUCCESS;
5937
4.97k
}
5938
5939
5940
// PEP 634: Structural Pattern Matching
5941
5942
// To keep things simple, all codegen_pattern_* routines follow the convention
5943
// of consuming TOS (the subject for the given pattern) and calling
5944
// jump_to_fail_pop on failure (no match).
5945
5946
// When calling into these routines, it's important that pc->on_top be kept
5947
// updated to reflect the current number of items that we are using on the top
5948
// of the stack: they will be popped on failure, and any name captures will be
5949
// stored *underneath* them on success. This lets us defer all names stores
5950
// until the *entire* pattern matches.
5951
5952
#define WILDCARD_CHECK(N) \
5953
6.68k
    ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name)
5954
5955
#define WILDCARD_STAR_CHECK(N) \
5956
246
    ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
5957
5958
// Limit permitted subexpressions, even if the parser & AST validator let them through
5959
#define MATCH_VALUE_EXPR(N) \
5960
249
    ((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
5961
5962
// Allocate or resize pc->fail_pop to allow for n items to be popped on failure.
5963
static int
5964
ensure_fail_pop(compiler *c, pattern_context *pc, Py_ssize_t n)
5965
2.22k
{
5966
2.22k
    Py_ssize_t size = n + 1;
5967
2.22k
    if (size <= pc->fail_pop_size) {
5968
1.04k
        return SUCCESS;
5969
1.04k
    }
5970
1.17k
    Py_ssize_t needed = sizeof(jump_target_label) * size;
5971
1.17k
    jump_target_label *resized = PyMem_Realloc(pc->fail_pop, needed);
5972
1.17k
    if (resized == NULL) {
5973
0
        PyErr_NoMemory();
5974
0
        return ERROR;
5975
0
    }
5976
1.17k
    pc->fail_pop = resized;
5977
4.27k
    while (pc->fail_pop_size < size) {
5978
3.09k
        NEW_JUMP_TARGET_LABEL(c, new_block);
5979
3.09k
        pc->fail_pop[pc->fail_pop_size++] = new_block;
5980
3.09k
    }
5981
1.17k
    return SUCCESS;
5982
1.17k
}
5983
5984
// Use op to jump to the correct fail_pop block.
5985
static int
5986
jump_to_fail_pop(compiler *c, location loc,
5987
                 pattern_context *pc, int op)
5988
2.22k
{
5989
    // Pop any items on the top of the stack, plus any objects we were going to
5990
    // capture on success:
5991
2.22k
    Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
5992
2.22k
    RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops));
5993
2.22k
    ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
5994
2.22k
    return SUCCESS;
5995
2.22k
}
5996
5997
// Build all of the fail_pop blocks and reset fail_pop.
5998
static int
5999
emit_and_reset_fail_pop(compiler *c, location loc,
6000
                        pattern_context *pc)
6001
889
{
6002
889
    if (!pc->fail_pop_size) {
6003
17
        assert(pc->fail_pop == NULL);
6004
17
        return SUCCESS;
6005
17
    }
6006
1.93k
    while (--pc->fail_pop_size) {
6007
1.05k
        USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
6008
1.05k
        if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, loc) < 0) {
6009
0
            pc->fail_pop_size = 0;
6010
0
            PyMem_Free(pc->fail_pop);
6011
0
            pc->fail_pop = NULL;
6012
0
            return ERROR;
6013
0
        }
6014
1.05k
    }
6015
872
    USE_LABEL(c, pc->fail_pop[0]);
6016
872
    PyMem_Free(pc->fail_pop);
6017
872
    pc->fail_pop = NULL;
6018
872
    return SUCCESS;
6019
872
}
6020
6021
static int
6022
codegen_error_duplicate_store(compiler *c, location loc, identifier n)
6023
24
{
6024
24
    return _PyCompile_Error(c, loc,
6025
24
        "multiple assignments to name %R in pattern", n);
6026
24
}
6027
6028
// Duplicate the effect of 3.10's ROT_* instructions using SWAPs.
6029
static int
6030
codegen_pattern_helper_rotate(compiler *c, location loc, Py_ssize_t count)
6031
1.95k
{
6032
11.2k
    while (1 < count) {
6033
9.25k
        ADDOP_I(c, loc, SWAP, count--);
6034
9.25k
    }
6035
1.95k
    return SUCCESS;
6036
1.95k
}
6037
6038
static int
6039
codegen_pattern_helper_store_name(compiler *c, location loc,
6040
                                  identifier n, pattern_context *pc)
6041
2.45k
{
6042
2.45k
    if (n == NULL) {
6043
480
        ADDOP(c, loc, POP_TOP);
6044
480
        return SUCCESS;
6045
480
    }
6046
    // Can't assign to the same name twice:
6047
1.97k
    int duplicate = PySequence_Contains(pc->stores, n);
6048
1.97k
    RETURN_IF_ERROR(duplicate);
6049
1.97k
    if (duplicate) {
6050
24
        return codegen_error_duplicate_store(c, loc, n);
6051
24
    }
6052
    // Rotate this object underneath any items we need to preserve:
6053
1.95k
    Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
6054
1.95k
    RETURN_IF_ERROR(codegen_pattern_helper_rotate(c, loc, rotations));
6055
1.95k
    RETURN_IF_ERROR(PyList_Append(pc->stores, n));
6056
1.95k
    return SUCCESS;
6057
1.95k
}
6058
6059
6060
static int
6061
codegen_pattern_unpack_helper(compiler *c, location loc,
6062
                              asdl_pattern_seq *elts)
6063
643
{
6064
643
    Py_ssize_t n = asdl_seq_LEN(elts);
6065
643
    int seen_star = 0;
6066
3.52k
    for (Py_ssize_t i = 0; i < n; i++) {
6067
2.88k
        pattern_ty elt = asdl_seq_GET(elts, i);
6068
2.88k
        if (elt->kind == MatchStar_kind && !seen_star) {
6069
26
            if ((i >= (1 << 8)) ||
6070
26
                (n-i-1 >= (INT_MAX >> 8))) {
6071
0
                return _PyCompile_Error(c, loc,
6072
0
                    "too many expressions in "
6073
0
                    "star-unpacking sequence pattern");
6074
0
            }
6075
26
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
6076
26
            seen_star = 1;
6077
26
        }
6078
2.85k
        else if (elt->kind == MatchStar_kind) {
6079
0
            return _PyCompile_Error(c, loc,
6080
0
                "multiple starred expressions in sequence pattern");
6081
0
        }
6082
2.88k
    }
6083
643
    if (!seen_star) {
6084
617
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
6085
617
    }
6086
643
    return SUCCESS;
6087
643
}
6088
6089
static int
6090
pattern_helper_sequence_unpack(compiler *c, location loc,
6091
                               asdl_pattern_seq *patterns, Py_ssize_t star,
6092
                               pattern_context *pc)
6093
643
{
6094
643
    RETURN_IF_ERROR(codegen_pattern_unpack_helper(c, loc, patterns));
6095
643
    Py_ssize_t size = asdl_seq_LEN(patterns);
6096
    // We've now got a bunch of new subjects on the stack. They need to remain
6097
    // there after each subpattern match:
6098
643
    pc->on_top += size;
6099
2.70k
    for (Py_ssize_t i = 0; i < size; i++) {
6100
        // One less item to keep track of each time we loop through:
6101
2.12k
        pc->on_top--;
6102
2.12k
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6103
2.12k
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6104
2.12k
    }
6105
579
    return SUCCESS;
6106
643
}
6107
6108
// Like pattern_helper_sequence_unpack, but uses BINARY_OP/NB_SUBSCR instead of
6109
// UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a
6110
// starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc.
6111
static int
6112
pattern_helper_sequence_subscr(compiler *c, location loc,
6113
                               asdl_pattern_seq *patterns, Py_ssize_t star,
6114
                               pattern_context *pc)
6115
216
{
6116
    // We need to keep the subject around for extracting elements:
6117
216
    pc->on_top++;
6118
216
    Py_ssize_t size = asdl_seq_LEN(patterns);
6119
929
    for (Py_ssize_t i = 0; i < size; i++) {
6120
729
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6121
729
        if (WILDCARD_CHECK(pattern)) {
6122
0
            continue;
6123
0
        }
6124
729
        if (i == star) {
6125
214
            assert(WILDCARD_STAR_CHECK(pattern));
6126
214
            continue;
6127
214
        }
6128
515
        ADDOP_I(c, loc, COPY, 1);
6129
515
        if (i < star) {
6130
8
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i));
6131
8
        }
6132
507
        else {
6133
            // The subject may not support negative indexing! Compute a
6134
            // nonnegative index:
6135
507
            ADDOP(c, loc, GET_LEN);
6136
507
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i));
6137
507
            ADDOP_BINARY(c, loc, Sub);
6138
507
        }
6139
515
        ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
6140
515
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6141
515
    }
6142
    // Pop the subject, we're done with it:
6143
200
    pc->on_top--;
6144
200
    ADDOP(c, loc, POP_TOP);
6145
200
    return SUCCESS;
6146
200
}
6147
6148
// Like codegen_pattern, but turn off checks for irrefutability.
6149
static int
6150
codegen_pattern_subpattern(compiler *c,
6151
                            pattern_ty p, pattern_context *pc)
6152
2.83k
{
6153
2.83k
    int allow_irrefutable = pc->allow_irrefutable;
6154
2.83k
    pc->allow_irrefutable = 1;
6155
2.83k
    RETURN_IF_ERROR(codegen_pattern(c, p, pc));
6156
2.73k
    pc->allow_irrefutable = allow_irrefutable;
6157
2.73k
    return SUCCESS;
6158
2.83k
}
6159
6160
static int
6161
codegen_pattern_as(compiler *c, pattern_ty p, pattern_context *pc)
6162
2.48k
{
6163
2.48k
    assert(p->kind == MatchAs_kind);
6164
2.48k
    if (p->v.MatchAs.pattern == NULL) {
6165
        // An irrefutable match:
6166
2.45k
        if (!pc->allow_irrefutable) {
6167
36
            if (p->v.MatchAs.name) {
6168
33
                const char *e = "name capture %R makes remaining patterns unreachable";
6169
33
                return _PyCompile_Error(c, LOC(p), e, p->v.MatchAs.name);
6170
33
            }
6171
3
            const char *e = "wildcard makes remaining patterns unreachable";
6172
3
            return _PyCompile_Error(c, LOC(p), e);
6173
36
        }
6174
2.41k
        return codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc);
6175
2.45k
    }
6176
    // Need to make a copy for (possibly) storing later:
6177
32
    pc->on_top++;
6178
32
    ADDOP_I(c, LOC(p), COPY, 1);
6179
32
    RETURN_IF_ERROR(codegen_pattern(c, p->v.MatchAs.pattern, pc));
6180
    // Success! Store it:
6181
29
    pc->on_top--;
6182
29
    RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc));
6183
25
    return SUCCESS;
6184
29
}
6185
6186
static int
6187
codegen_pattern_star(compiler *c, pattern_ty p, pattern_context *pc)
6188
16
{
6189
16
    assert(p->kind == MatchStar_kind);
6190
16
    RETURN_IF_ERROR(
6191
16
        codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc));
6192
15
    return SUCCESS;
6193
16
}
6194
6195
static int
6196
validate_kwd_attrs(compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns)
6197
23
{
6198
    // Any errors will point to the pattern rather than the arg name as the
6199
    // parser is only supplying identifiers rather than Name or keyword nodes
6200
23
    Py_ssize_t nattrs = asdl_seq_LEN(attrs);
6201
60
    for (Py_ssize_t i = 0; i < nattrs; i++) {
6202
45
        identifier attr = ((identifier)asdl_seq_GET(attrs, i));
6203
136
        for (Py_ssize_t j = i + 1; j < nattrs; j++) {
6204
99
            identifier other = ((identifier)asdl_seq_GET(attrs, j));
6205
99
            if (!PyUnicode_Compare(attr, other)) {
6206
8
                location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j));
6207
8
                return _PyCompile_Error(c, loc, "attribute name repeated "
6208
8
                                                "in class pattern: %U", attr);
6209
8
            }
6210
99
        }
6211
45
    }
6212
15
    return SUCCESS;
6213
23
}
6214
6215
static int
6216
codegen_pattern_class(compiler *c, pattern_ty p, pattern_context *pc)
6217
102
{
6218
102
    assert(p->kind == MatchClass_kind);
6219
102
    asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
6220
102
    asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs;
6221
102
    asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns;
6222
102
    Py_ssize_t nargs = asdl_seq_LEN(patterns);
6223
102
    Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs);
6224
102
    Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns);
6225
102
    if (nattrs != nkwd_patterns) {
6226
        // AST validator shouldn't let this happen, but if it does,
6227
        // just fail, don't crash out of the interpreter
6228
0
        const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern";
6229
0
        return _PyCompile_Error(c, LOC(p), e, nattrs, nkwd_patterns);
6230
0
    }
6231
102
    if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) {
6232
0
        const char *e = "too many sub-patterns in class pattern %R";
6233
0
        return _PyCompile_Error(c, LOC(p), e, p->v.MatchClass.cls);
6234
0
    }
6235
102
    if (nattrs) {
6236
23
        RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
6237
23
    }
6238
94
    VISIT(c, expr, p->v.MatchClass.cls);
6239
94
    PyObject *attr_names = PyTuple_New(nattrs);
6240
94
    if (attr_names == NULL) {
6241
0
        return ERROR;
6242
0
    }
6243
94
    Py_ssize_t i;
6244
123
    for (i = 0; i < nattrs; i++) {
6245
29
        PyObject *name = asdl_seq_GET(kwd_attrs, i);
6246
29
        PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name));
6247
29
    }
6248
94
    ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names);
6249
94
    ADDOP_I(c, LOC(p), MATCH_CLASS, nargs);
6250
94
    ADDOP_I(c, LOC(p), COPY, 1);
6251
94
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
6252
94
    ADDOP_I(c, LOC(p), IS_OP, 1);
6253
    // TOS is now a tuple of (nargs + nattrs) attributes (or None):
6254
94
    pc->on_top++;
6255
94
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6256
94
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs);
6257
94
    pc->on_top += nargs + nattrs - 1;
6258
256
    for (i = 0; i < nargs + nattrs; i++) {
6259
183
        pc->on_top--;
6260
183
        pattern_ty pattern;
6261
183
        if (i < nargs) {
6262
            // Positional:
6263
162
            pattern = asdl_seq_GET(patterns, i);
6264
162
        }
6265
21
        else {
6266
            // Keyword:
6267
21
            pattern = asdl_seq_GET(kwd_patterns, i - nargs);
6268
21
        }
6269
183
        if (WILDCARD_CHECK(pattern)) {
6270
3
            ADDOP(c, LOC(p), POP_TOP);
6271
3
            continue;
6272
3
        }
6273
180
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6274
180
    }
6275
    // Success! Pop the tuple of attributes:
6276
73
    return SUCCESS;
6277
94
}
6278
6279
static int
6280
codegen_pattern_mapping_key(compiler *c, PyObject *seen, pattern_ty p, Py_ssize_t i)
6281
27
{
6282
27
    asdl_expr_seq *keys = p->v.MatchMapping.keys;
6283
27
    asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
6284
27
    expr_ty key = asdl_seq_GET(keys, i);
6285
27
    if (key == NULL) {
6286
0
        const char *e = "can't use NULL keys in MatchMapping "
6287
0
                        "(set 'rest' parameter instead)";
6288
0
        location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
6289
0
        return _PyCompile_Error(c, loc, e);
6290
0
    }
6291
6292
27
    if (key->kind == Constant_kind) {
6293
27
        int in_seen = PySet_Contains(seen, key->v.Constant.value);
6294
27
        RETURN_IF_ERROR(in_seen);
6295
27
        if (in_seen) {
6296
2
            const char *e = "mapping pattern checks duplicate key (%R)";
6297
2
            return _PyCompile_Error(c, LOC(p), e, key->v.Constant.value);
6298
2
        }
6299
25
        RETURN_IF_ERROR(PySet_Add(seen, key->v.Constant.value));
6300
25
    }
6301
0
    else if (key->kind != Attribute_kind) {
6302
0
        const char *e = "mapping pattern keys may only match literals and attribute lookups";
6303
0
        return _PyCompile_Error(c, LOC(p), e);
6304
0
    }
6305
25
    VISIT(c, expr, key);
6306
25
    return SUCCESS;
6307
25
}
6308
6309
static int
6310
codegen_pattern_mapping(compiler *c, pattern_ty p,
6311
                        pattern_context *pc)
6312
15
{
6313
15
    assert(p->kind == MatchMapping_kind);
6314
15
    asdl_expr_seq *keys = p->v.MatchMapping.keys;
6315
15
    asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
6316
15
    Py_ssize_t size = asdl_seq_LEN(keys);
6317
15
    Py_ssize_t npatterns = asdl_seq_LEN(patterns);
6318
15
    if (size != npatterns) {
6319
        // AST validator shouldn't let this happen, but if it does,
6320
        // just fail, don't crash out of the interpreter
6321
0
        const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern";
6322
0
        return _PyCompile_Error(c, LOC(p), e, size, npatterns);
6323
0
    }
6324
    // We have a double-star target if "rest" is set
6325
15
    PyObject *star_target = p->v.MatchMapping.rest;
6326
    // We need to keep the subject on top during the mapping and length checks:
6327
15
    pc->on_top++;
6328
15
    ADDOP(c, LOC(p), MATCH_MAPPING);
6329
15
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6330
15
    if (!size && !star_target) {
6331
        // If the pattern is just "{}", we're done! Pop the subject:
6332
6
        pc->on_top--;
6333
6
        ADDOP(c, LOC(p), POP_TOP);
6334
6
        return SUCCESS;
6335
6
    }
6336
9
    if (size) {
6337
        // If the pattern has any keys in it, perform a length check:
6338
9
        ADDOP(c, LOC(p), GET_LEN);
6339
9
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6340
9
        ADDOP_COMPARE(c, LOC(p), GtE);
6341
9
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6342
9
    }
6343
9
    if (INT_MAX < size - 1) {
6344
0
        return _PyCompile_Error(c, LOC(p), "too many sub-patterns in mapping pattern");
6345
0
    }
6346
    // Collect all of the keys into a tuple for MATCH_KEYS and
6347
    // **rest. They can either be dotted names or literals:
6348
6349
    // Maintaining a set of Constant_kind kind keys allows us to raise a
6350
    // SyntaxError in the case of duplicates.
6351
9
    PyObject *seen = PySet_New(NULL);
6352
9
    if (seen == NULL) {
6353
0
        return ERROR;
6354
0
    }
6355
34
    for (Py_ssize_t i = 0; i < size; i++) {
6356
27
        if (codegen_pattern_mapping_key(c, seen, p, i) < 0) {
6357
2
            Py_DECREF(seen);
6358
2
            return ERROR;
6359
2
        }
6360
27
    }
6361
7
    Py_DECREF(seen);
6362
6363
    // all keys have been checked; there are no duplicates
6364
6365
7
    ADDOP_I(c, LOC(p), BUILD_TUPLE, size);
6366
7
    ADDOP(c, LOC(p), MATCH_KEYS);
6367
    // There's now a tuple of keys and a tuple of values on top of the subject:
6368
7
    pc->on_top += 2;
6369
7
    ADDOP_I(c, LOC(p), COPY, 1);
6370
7
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
6371
7
    ADDOP_I(c, LOC(p), IS_OP, 1);
6372
7
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6373
    // So far so good. Use that tuple of values on the stack to match
6374
    // sub-patterns against:
6375
7
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);
6376
7
    pc->on_top += size - 1;
6377
25
    for (Py_ssize_t i = 0; i < size; i++) {
6378
18
        pc->on_top--;
6379
18
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6380
18
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6381
18
    }
6382
    // If we get this far, it's a match! Whatever happens next should consume
6383
    // the tuple of keys and the subject:
6384
7
    pc->on_top -= 2;
6385
7
    if (star_target) {
6386
        // If we have a starred name, bind a dict of remaining items to it (this may
6387
        // seem a bit inefficient, but keys is rarely big enough to actually impact
6388
        // runtime):
6389
        // rest = dict(TOS1)
6390
        // for key in TOS:
6391
        //     del rest[key]
6392
0
        ADDOP_I(c, LOC(p), BUILD_MAP, 0);           // [subject, keys, empty]
6393
0
        ADDOP_I(c, LOC(p), SWAP, 3);                // [empty, keys, subject]
6394
0
        ADDOP_I(c, LOC(p), DICT_UPDATE, 2);         // [copy, keys]
6395
0
        ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);  // [copy, keys...]
6396
0
        while (size) {
6397
0
            ADDOP_I(c, LOC(p), COPY, 1 + size--);   // [copy, keys..., copy]
6398
0
            ADDOP_I(c, LOC(p), SWAP, 2);            // [copy, keys..., copy, key]
6399
0
            ADDOP(c, LOC(p), DELETE_SUBSCR);        // [copy, keys...]
6400
0
        }
6401
0
        RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), star_target, pc));
6402
0
    }
6403
7
    else {
6404
7
        ADDOP(c, LOC(p), POP_TOP);  // Tuple of keys.
6405
7
        ADDOP(c, LOC(p), POP_TOP);  // Subject.
6406
7
    }
6407
7
    return SUCCESS;
6408
7
}
6409
6410
static int
6411
codegen_pattern_or(compiler *c, pattern_ty p, pattern_context *pc)
6412
83
{
6413
83
    assert(p->kind == MatchOr_kind);
6414
83
    NEW_JUMP_TARGET_LABEL(c, end);
6415
83
    Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns);
6416
83
    assert(size > 1);
6417
    // We're going to be messing with pc. Keep the original info handy:
6418
83
    pattern_context old_pc = *pc;
6419
83
    Py_INCREF(pc->stores);
6420
    // control is the list of names bound by the first alternative. It is used
6421
    // for checking different name bindings in alternatives, and for correcting
6422
    // the order in which extracted elements are placed on the stack.
6423
83
    PyObject *control = NULL;
6424
    // NOTE: We can't use returning macros anymore! goto error on error.
6425
172
    for (Py_ssize_t i = 0; i < size; i++) {
6426
139
        pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i);
6427
139
        PyObject *pc_stores = PyList_New(0);
6428
139
        if (pc_stores == NULL) {
6429
0
            goto error;
6430
0
        }
6431
139
        Py_SETREF(pc->stores, pc_stores);
6432
        // An irrefutable sub-pattern must be last, if it is allowed at all:
6433
139
        pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable;
6434
139
        pc->fail_pop = NULL;
6435
139
        pc->fail_pop_size = 0;
6436
139
        pc->on_top = 0;
6437
139
        if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 ||
6438
139
            codegen_pattern(c, alt, pc) < 0) {
6439
37
            goto error;
6440
37
        }
6441
        // Success!
6442
102
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6443
102
        if (!i) {
6444
            // This is the first alternative, so save its stores as a "control"
6445
            // for the others (they can't bind a different set of names, and
6446
            // might need to be reordered):
6447
51
            assert(control == NULL);
6448
51
            control = Py_NewRef(pc->stores);
6449
51
        }
6450
51
        else if (nstores != PyList_GET_SIZE(control)) {
6451
8
            goto diff;
6452
8
        }
6453
43
        else if (nstores) {
6454
            // There were captures. Check to see if we differ from control:
6455
6
            Py_ssize_t icontrol = nstores;
6456
8
            while (icontrol--) {
6457
7
                PyObject *name = PyList_GET_ITEM(control, icontrol);
6458
0
                Py_ssize_t istores = PySequence_Index(pc->stores, name);
6459
7
                if (istores < 0) {
6460
5
                    PyErr_Clear();
6461
5
                    goto diff;
6462
5
                }
6463
2
                if (icontrol != istores) {
6464
                    // Reorder the names on the stack to match the order of the
6465
                    // names in control. There's probably a better way of doing
6466
                    // this; the current solution is potentially very
6467
                    // inefficient when each alternative subpattern binds lots
6468
                    // of names in different orders. It's fine for reasonable
6469
                    // cases, though, and the peephole optimizer will ensure
6470
                    // that the final code is as efficient as possible.
6471
0
                    assert(istores < icontrol);
6472
0
                    Py_ssize_t rotations = istores + 1;
6473
                    // Perform the same rotation on pc->stores:
6474
0
                    PyObject *rotated = PyList_GetSlice(pc->stores, 0,
6475
0
                                                        rotations);
6476
0
                    if (rotated == NULL ||
6477
0
                        PyList_SetSlice(pc->stores, 0, rotations, NULL) ||
6478
0
                        PyList_SetSlice(pc->stores, icontrol - istores,
6479
0
                                        icontrol - istores, rotated))
6480
0
                    {
6481
0
                        Py_XDECREF(rotated);
6482
0
                        goto error;
6483
0
                    }
6484
0
                    Py_DECREF(rotated);
6485
                    // That just did:
6486
                    // rotated = pc_stores[:rotations]
6487
                    // del pc_stores[:rotations]
6488
                    // pc_stores[icontrol-istores:icontrol-istores] = rotated
6489
                    // Do the same thing to the stack, using several
6490
                    // rotations:
6491
0
                    while (rotations--) {
6492
0
                        if (codegen_pattern_helper_rotate(c, LOC(alt), icontrol + 1) < 0) {
6493
0
                            goto error;
6494
0
                        }
6495
0
                    }
6496
0
                }
6497
2
            }
6498
6
        }
6499
102
        assert(control);
6500
89
        if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 ||
6501
89
            emit_and_reset_fail_pop(c, LOC(alt), pc) < 0)
6502
0
        {
6503
0
            goto error;
6504
0
        }
6505
89
    }
6506
33
    Py_DECREF(pc->stores);
6507
33
    *pc = old_pc;
6508
33
    Py_INCREF(pc->stores);
6509
    // Need to NULL this for the PyMem_Free call in the error block.
6510
33
    old_pc.fail_pop = NULL;
6511
    // No match. Pop the remaining copy of the subject and fail:
6512
33
    if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 ||
6513
33
        jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) {
6514
0
        goto error;
6515
0
    }
6516
6517
33
    USE_LABEL(c, end);
6518
33
    Py_ssize_t nstores = PyList_GET_SIZE(control);
6519
    // There's a bunch of stuff on the stack between where the new stores
6520
    // are and where they need to be:
6521
    // - The other stores.
6522
    // - A copy of the subject.
6523
    // - Anything else that may be on top of the stack.
6524
    // - Any previous stores we've already stashed away on the stack.
6525
33
    Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
6526
35
    for (Py_ssize_t i = 0; i < nstores; i++) {
6527
        // Rotate this capture to its proper place on the stack:
6528
2
        if (codegen_pattern_helper_rotate(c, LOC(p), nrots) < 0) {
6529
0
            goto error;
6530
0
        }
6531
        // Update the list of previous stores with this new name, checking for
6532
        // duplicates:
6533
2
        PyObject *name = PyList_GET_ITEM(control, i);
6534
0
        int dupe = PySequence_Contains(pc->stores, name);
6535
2
        if (dupe < 0) {
6536
0
            goto error;
6537
0
        }
6538
2
        if (dupe) {
6539
0
            codegen_error_duplicate_store(c, LOC(p), name);
6540
0
            goto error;
6541
0
        }
6542
2
        if (PyList_Append(pc->stores, name)) {
6543
0
            goto error;
6544
0
        }
6545
2
    }
6546
33
    Py_DECREF(old_pc.stores);
6547
33
    Py_DECREF(control);
6548
    // NOTE: Returning macros are safe again.
6549
    // Pop the copy of the subject:
6550
33
    ADDOP(c, LOC(p), POP_TOP);
6551
33
    return SUCCESS;
6552
13
diff:
6553
13
    _PyCompile_Error(c, LOC(p), "alternative patterns bind different names");
6554
50
error:
6555
50
    PyMem_Free(old_pc.fail_pop);
6556
50
    Py_DECREF(old_pc.stores);
6557
50
    Py_XDECREF(control);
6558
50
    return ERROR;
6559
13
}
6560
6561
6562
static int
6563
codegen_pattern_sequence(compiler *c, pattern_ty p,
6564
                         pattern_context *pc)
6565
877
{
6566
877
    assert(p->kind == MatchSequence_kind);
6567
877
    asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
6568
877
    Py_ssize_t size = asdl_seq_LEN(patterns);
6569
877
    Py_ssize_t star = -1;
6570
877
    int only_wildcard = 1;
6571
877
    int star_wildcard = 0;
6572
    // Find a starred name, if it exists. There may be at most one:
6573
6.49k
    for (Py_ssize_t i = 0; i < size; i++) {
6574
5.62k
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6575
5.62k
        if (pattern->kind == MatchStar_kind) {
6576
250
            if (star >= 0) {
6577
4
                const char *e = "multiple starred names in sequence pattern";
6578
4
                return _PyCompile_Error(c, LOC(p), e);
6579
4
            }
6580
246
            star_wildcard = WILDCARD_STAR_CHECK(pattern);
6581
246
            only_wildcard &= star_wildcard;
6582
246
            star = i;
6583
246
            continue;
6584
250
        }
6585
5.37k
        only_wildcard &= WILDCARD_CHECK(pattern);
6586
5.37k
    }
6587
    // We need to keep the subject on top during the sequence and length checks:
6588
873
    pc->on_top++;
6589
873
    ADDOP(c, LOC(p), MATCH_SEQUENCE);
6590
873
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6591
873
    if (star < 0) {
6592
        // No star: len(subject) == size
6593
631
        ADDOP(c, LOC(p), GET_LEN);
6594
631
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6595
631
        ADDOP_COMPARE(c, LOC(p), Eq);
6596
631
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6597
631
    }
6598
242
    else if (size > 1) {
6599
        // Star: len(subject) >= size - 1
6600
241
        ADDOP(c, LOC(p), GET_LEN);
6601
241
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1));
6602
241
        ADDOP_COMPARE(c, LOC(p), GtE);
6603
241
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6604
241
    }
6605
    // Whatever comes next should consume the subject:
6606
873
    pc->on_top--;
6607
873
    if (only_wildcard) {
6608
        // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
6609
14
        ADDOP(c, LOC(p), POP_TOP);
6610
14
    }
6611
859
    else if (star_wildcard) {
6612
216
        RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc));
6613
216
    }
6614
643
    else {
6615
643
        RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc));
6616
643
    }
6617
793
    return SUCCESS;
6618
873
}
6619
6620
static int
6621
codegen_pattern_value(compiler *c, pattern_ty p, pattern_context *pc)
6622
249
{
6623
249
    assert(p->kind == MatchValue_kind);
6624
249
    expr_ty value = p->v.MatchValue.value;
6625
249
    if (!MATCH_VALUE_EXPR(value)) {
6626
1
        const char *e = "patterns may only match literals and attribute lookups";
6627
1
        return _PyCompile_Error(c, LOC(p), e);
6628
1
    }
6629
248
    VISIT(c, expr, value);
6630
248
    ADDOP_COMPARE(c, LOC(p), Eq);
6631
248
    ADDOP(c, LOC(p), TO_BOOL);
6632
248
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6633
248
    return SUCCESS;
6634
248
}
6635
6636
static int
6637
codegen_pattern_singleton(compiler *c, pattern_ty p, pattern_context *pc)
6638
73
{
6639
73
    assert(p->kind == MatchSingleton_kind);
6640
73
    ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value);
6641
73
    ADDOP_COMPARE(c, LOC(p), Is);
6642
73
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6643
73
    return SUCCESS;
6644
73
}
6645
6646
static int
6647
codegen_pattern(compiler *c, pattern_ty p, pattern_context *pc)
6648
3.89k
{
6649
3.89k
    switch (p->kind) {
6650
249
        case MatchValue_kind:
6651
249
            return codegen_pattern_value(c, p, pc);
6652
73
        case MatchSingleton_kind:
6653
73
            return codegen_pattern_singleton(c, p, pc);
6654
877
        case MatchSequence_kind:
6655
877
            return codegen_pattern_sequence(c, p, pc);
6656
15
        case MatchMapping_kind:
6657
15
            return codegen_pattern_mapping(c, p, pc);
6658
102
        case MatchClass_kind:
6659
102
            return codegen_pattern_class(c, p, pc);
6660
16
        case MatchStar_kind:
6661
16
            return codegen_pattern_star(c, p, pc);
6662
2.48k
        case MatchAs_kind:
6663
2.48k
            return codegen_pattern_as(c, p, pc);
6664
83
        case MatchOr_kind:
6665
83
            return codegen_pattern_or(c, p, pc);
6666
3.89k
    }
6667
    // AST validator shouldn't let this happen, but if it does,
6668
    // just fail, don't crash out of the interpreter
6669
0
    const char *e = "invalid match pattern node in AST (kind=%d)";
6670
0
    return _PyCompile_Error(c, LOC(p), e, p->kind);
6671
3.89k
}
6672
6673
static int
6674
codegen_match_inner(compiler *c, stmt_ty s, pattern_context *pc)
6675
198
{
6676
198
    VISIT(c, expr, s->v.Match.subject);
6677
198
    NEW_JUMP_TARGET_LABEL(c, end);
6678
198
    Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases);
6679
198
    assert(cases > 0);
6680
198
    match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6681
198
    int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases;
6682
998
    for (Py_ssize_t i = 0; i < cases - has_default; i++) {
6683
892
        m = asdl_seq_GET(s->v.Match.cases, i);
6684
        // Only copy the subject if we're *not* on the last case:
6685
892
        if (i != cases - has_default - 1) {
6686
703
            ADDOP_I(c, LOC(m->pattern), COPY, 1);
6687
703
        }
6688
892
        pc->stores = PyList_New(0);
6689
892
        if (pc->stores == NULL) {
6690
0
            return ERROR;
6691
0
        }
6692
        // Irrefutable cases must be either guarded, last, or both:
6693
892
        pc->allow_irrefutable = m->guard != NULL || i == cases - 1;
6694
892
        pc->fail_pop = NULL;
6695
892
        pc->fail_pop_size = 0;
6696
892
        pc->on_top = 0;
6697
        // NOTE: Can't use returning macros here (they'll leak pc->stores)!
6698
892
        if (codegen_pattern(c, m->pattern, pc) < 0) {
6699
88
            Py_DECREF(pc->stores);
6700
88
            return ERROR;
6701
88
        }
6702
892
        assert(!pc->on_top);
6703
        // It's a match! Store all of the captured names (they're on the stack).
6704
804
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6705
2.49k
        for (Py_ssize_t n = 0; n < nstores; n++) {
6706
1.69k
            PyObject *name = PyList_GET_ITEM(pc->stores, n);
6707
1.69k
            if (codegen_nameop(c, LOC(m->pattern), name, Store) < 0) {
6708
0
                Py_DECREF(pc->stores);
6709
0
                return ERROR;
6710
0
            }
6711
1.69k
        }
6712
804
        Py_DECREF(pc->stores);
6713
        // NOTE: Returning macros are safe again.
6714
804
        if (m->guard) {
6715
1
            RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0));
6716
1
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0));
6717
1
        }
6718
        // Success! Pop the subject off, we're done with it:
6719
804
        if (i != cases - has_default - 1) {
6720
            /* Use the next location to give better locations for branch events */
6721
695
            ADDOP(c, NEXT_LOCATION, POP_TOP);
6722
695
        }
6723
804
        VISIT_SEQ(c, stmt, m->body);
6724
800
        ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
6725
        // If the pattern fails to match, we want the line number of the
6726
        // cleanup to be associated with the failed pattern, not the last line
6727
        // of the body
6728
800
        RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc));
6729
800
    }
6730
106
    if (has_default) {
6731
        // A trailing "case _" is common, and lets us save a bit of redundant
6732
        // pushing and popping in the loop above:
6733
1
        m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6734
1
        if (cases == 1) {
6735
            // No matches. Done with the subject:
6736
0
            ADDOP(c, LOC(m->pattern), POP_TOP);
6737
0
        }
6738
1
        else {
6739
            // Show line coverage for default case (it doesn't create bytecode)
6740
1
            ADDOP(c, LOC(m->pattern), NOP);
6741
1
        }
6742
1
        if (m->guard) {
6743
0
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, end, 0));
6744
0
        }
6745
1
        VISIT_SEQ(c, stmt, m->body);
6746
1
    }
6747
105
    USE_LABEL(c, end);
6748
105
    return SUCCESS;
6749
105
}
6750
6751
static int
6752
codegen_match(compiler *c, stmt_ty s)
6753
198
{
6754
198
    pattern_context pc;
6755
198
    pc.fail_pop = NULL;
6756
198
    int result = codegen_match_inner(c, s, &pc);
6757
198
    PyMem_Free(pc.fail_pop);
6758
198
    return result;
6759
198
}
6760
6761
#undef WILDCARD_CHECK
6762
#undef WILDCARD_STAR_CHECK
6763
6764
6765
int
6766
_PyCodegen_AddReturnAtEnd(compiler *c, int addNone)
6767
52.7k
{
6768
    /* Make sure every instruction stream that falls off the end returns None.
6769
     * This also ensures that no jump target offsets are out of bounds.
6770
     */
6771
52.7k
    if (addNone) {
6772
45.9k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
6773
45.9k
    }
6774
52.7k
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
6775
52.7k
    return SUCCESS;
6776
52.7k
}