Coverage Report

Created: 2026-10-17 06:15

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