Coverage Report

Created: 2026-04-20 06:11

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