Coverage Report

Created: 2026-08-31 07:18

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