Coverage Report

Created: 2026-01-17 06:16

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