Coverage Report

Created: 2025-08-26 06:26

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