Coverage Report

Created: 2026-04-12 06:54

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