Coverage Report

Created: 2025-07-04 06:49

/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.16k
#define COMP_GENEXP   0
40
492
#define COMP_LISTCOMP 1
41
9
#define COMP_SETCOMP  2
42
54
#define COMP_DICTCOMP 3
43
44
#undef SUCCESS
45
#undef ERROR
46
1.47M
#define SUCCESS 0
47
0
#define ERROR -1
48
49
#define RETURN_IF_ERROR(X)  \
50
986k
    do {                    \
51
986k
        if ((X) == -1) {    \
52
0
            return ERROR;   \
53
0
        }                   \
54
986k
    } while (0)
55
56
#define RETURN_IF_ERROR_IN_SCOPE(C, CALL)   \
57
22.7k
    do {                                    \
58
22.7k
        if ((CALL) < 0) {                   \
59
0
            _PyCompile_ExitScope((C));      \
60
0
            return ERROR;                   \
61
0
        }                                   \
62
22.7k
    } while (0)
63
64
struct _PyCompiler;
65
typedef struct _PyCompiler compiler;
66
67
35.2k
#define INSTR_SEQUENCE(C) _PyCompile_InstrSequence(C)
68
2.58k
#define FUTURE_FEATURES(C) _PyCompile_FutureFeatures(C)
69
6.72k
#define SYMTABLE(C) _PyCompile_Symtable(C)
70
122k
#define SYMTABLE_ENTRY(C) _PyCompile_SymtableEntry(C)
71
108
#define OPTIMIZATION_LEVEL(C) _PyCompile_OptimizationLevel(C)
72
3.68k
#define IS_INTERACTIVE_TOP_LEVEL(C) _PyCompile_IsInteractiveTopLevel(C)
73
30
#define SCOPE_TYPE(C) _PyCompile_ScopeType(C)
74
#define QUALNAME(C) _PyCompile_Qualname(C)
75
51.4k
#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
6.82k
    ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})
86
87
246k
#define LOC(x) SRC_LOCATION_FROM_AST(x)
88
89
#define NEW_JUMP_TARGET_LABEL(C, NAME) \
90
35.2k
    jump_target_label NAME = _PyInstructionSequence_NewLabel(INSTR_SEQUENCE(C)); \
91
35.2k
    if (!IS_JUMP_TARGET_LABEL(NAME)) { \
92
0
        return ERROR; \
93
0
    }
94
95
#define USE_LABEL(C, LBL) \
96
35.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.88k
_Py_CArray_Init(_Py_c_array_t* array, int item_size, int initial_num_entries) {
110
7.88k
    memset(array, 0, sizeof(_Py_c_array_t));
111
7.88k
    array->item_size = item_size;
112
7.88k
    array->initial_num_entries = initial_num_entries;
113
7.88k
    return 0;
114
7.88k
}
115
116
void
117
_Py_CArray_Fini(_Py_c_array_t* array)
118
7.88k
{
119
7.88k
    if (array->array) {
120
756
        PyMem_Free(array->array);
121
756
        array->allocated_entries = 0;
122
756
    }
123
7.88k
}
124
125
int
126
_Py_CArray_EnsureCapacity(_Py_c_array_t *c_array, int idx)
127
1.01M
{
128
1.01M
    void *arr = c_array->array;
129
1.01M
    int alloc = c_array->allocated_entries;
130
1.01M
    if (arr == NULL) {
131
61.3k
        int new_alloc = c_array->initial_num_entries;
132
61.3k
        if (idx >= new_alloc) {
133
0
            new_alloc = idx + c_array->initial_num_entries;
134
0
        }
135
61.3k
        arr = PyMem_Calloc(new_alloc, c_array->item_size);
136
61.3k
        if (arr == NULL) {
137
0
            PyErr_NoMemory();
138
0
            return ERROR;
139
0
        }
140
61.3k
        alloc = new_alloc;
141
61.3k
    }
142
957k
    else if (idx >= alloc) {
143
9.29k
        size_t oldsize = alloc * c_array->item_size;
144
9.29k
        int new_alloc = alloc << 1;
145
9.29k
        if (idx >= new_alloc) {
146
0
            new_alloc = idx + c_array->initial_num_entries;
147
0
        }
148
9.29k
        size_t newsize = new_alloc * c_array->item_size;
149
150
9.29k
        if (oldsize > (SIZE_MAX >> 1)) {
151
0
            PyErr_NoMemory();
152
0
            return ERROR;
153
0
        }
154
155
9.29k
        assert(newsize > 0);
156
9.29k
        void *tmp = PyMem_Realloc(arr, newsize);
157
9.29k
        if (tmp == NULL) {
158
0
            PyErr_NoMemory();
159
0
            return ERROR;
160
0
        }
161
9.29k
        alloc = new_alloc;
162
9.29k
        arr = tmp;
163
9.29k
        memset((char *)arr + oldsize, 0, newsize - oldsize);
164
9.29k
    }
165
166
1.01M
    c_array->array = arr;
167
1.01M
    c_array->allocated_entries = alloc;
168
1.01M
    return SUCCESS;
169
1.01M
}
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
234k
{
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
234k
    int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
264
234k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
265
234k
    return _PyInstructionSequence_Addop(seq, opcode, oparg_, loc);
266
234k
}
267
268
#define ADDOP_I(C, LOC, OP, O) \
269
234k
    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
60.8k
{
277
60.8k
    assert(!OPCODE_HAS_ARG(opcode));
278
60.8k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
279
60.8k
    return _PyInstructionSequence_Addop(seq, opcode, 0, loc);
280
60.8k
}
281
282
#define ADDOP(C, LOC, OP) \
283
59.6k
    RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
284
285
#define ADDOP_IN_SCOPE(C, LOC, OP) \
286
1.15k
    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
62.3k
{
291
62.3k
    Py_ssize_t arg = _PyCompile_AddConst(c, o);
292
62.3k
    if (arg < 0) {
293
0
        return ERROR;
294
0
    }
295
62.3k
    ADDOP_I(c, loc, LOAD_CONST, arg);
296
62.3k
    return SUCCESS;
297
62.3k
}
298
299
#define ADDOP_LOAD_CONST(C, LOC, O) \
300
59.5k
    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
2.82k
    do {                                                                \
308
2.82k
        PyObject *__new_const = (O);                                    \
309
2.82k
        if (__new_const == NULL) {                                      \
310
0
            return ERROR;                                               \
311
0
        }                                                               \
312
2.82k
        if (codegen_addop_load_const((C), (LOC), __new_const) < 0) {    \
313
0
            Py_DECREF(__new_const);                                     \
314
0
            return ERROR;                                               \
315
0
        }                                                               \
316
2.82k
        Py_DECREF(__new_const);                                         \
317
2.82k
    } while (0)
318
319
static int
320
codegen_addop_o(compiler *c, location loc,
321
                int opcode, PyObject *dict, PyObject *o)
322
51.1k
{
323
51.1k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, o);
324
51.1k
    RETURN_IF_ERROR(arg);
325
51.1k
    ADDOP_I(c, loc, opcode, arg);
326
51.1k
    return SUCCESS;
327
51.1k
}
328
329
#define ADDOP_N(C, LOC, OP, O, TYPE)                                    \
330
50.5k
    do {                                                                \
331
50.5k
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
332
50.5k
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
333
50.5k
                                  METADATA(C)->u_ ## TYPE, (O));        \
334
50.5k
        Py_DECREF((O));                                                 \
335
50.5k
        RETURN_IF_ERROR(ret);                                           \
336
50.5k
    } while (0)
337
338
#define ADDOP_N_IN_SCOPE(C, LOC, OP, O, TYPE)                           \
339
595
    do {                                                                \
340
595
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
341
595
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
342
595
                                  METADATA(C)->u_ ## TYPE, (O));        \
343
595
        Py_DECREF((O));                                                 \
344
595
        RETURN_IF_ERROR_IN_SCOPE((C), ret);                             \
345
595
    } while (0)
346
347
20.3k
#define LOAD_METHOD -1
348
20.3k
#define LOAD_SUPER_METHOD -2
349
20.3k
#define LOAD_ZERO_SUPER_ATTR -3
350
20.4k
#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
20.3k
{
356
20.3k
    PyObject *mangled = _PyCompile_MaybeMangle(c, o);
357
20.3k
    if (!mangled) {
358
0
        return ERROR;
359
0
    }
360
20.3k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, mangled);
361
20.3k
    Py_DECREF(mangled);
362
20.3k
    if (arg < 0) {
363
0
        return ERROR;
364
0
    }
365
20.3k
    if (opcode == LOAD_ATTR) {
366
9.95k
        arg <<= 1;
367
9.95k
    }
368
20.3k
    if (opcode == LOAD_METHOD) {
369
6.58k
        opcode = LOAD_ATTR;
370
6.58k
        arg <<= 1;
371
6.58k
        arg |= 1;
372
6.58k
    }
373
20.3k
    if (opcode == LOAD_SUPER_ATTR) {
374
16
        arg <<= 2;
375
16
        arg |= 2;
376
16
    }
377
20.3k
    if (opcode == LOAD_SUPER_METHOD) {
378
10
        opcode = LOAD_SUPER_ATTR;
379
10
        arg <<= 2;
380
10
        arg |= 3;
381
10
    }
382
20.3k
    if (opcode == LOAD_ZERO_SUPER_ATTR) {
383
45
        opcode = LOAD_SUPER_ATTR;
384
45
        arg <<= 2;
385
45
    }
386
20.3k
    if (opcode == LOAD_ZERO_SUPER_METHOD) {
387
107
        opcode = LOAD_SUPER_ATTR;
388
107
        arg <<= 2;
389
107
        arg |= 1;
390
107
    }
391
20.3k
    ADDOP_I(c, loc, opcode, arg);
392
20.3k
    return SUCCESS;
393
20.3k
}
394
395
#define ADDOP_NAME(C, LOC, OP, O, TYPE) \
396
20.3k
    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
19.1k
{
402
19.1k
    assert(IS_JUMP_TARGET_LABEL(target));
403
19.1k
    assert(HAS_TARGET(opcode));
404
19.1k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
405
19.1k
    return _PyInstructionSequence_Addop(seq, opcode, target.id, loc);
406
19.1k
}
407
408
#define ADDOP_JUMP(C, LOC, OP, O) \
409
19.1k
    RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O)))
410
411
#define ADDOP_COMPARE(C, LOC, CMP) \
412
5.25k
    RETURN_IF_ERROR(codegen_addcompare((C), (LOC), (cmpop_ty)(CMP)))
413
414
#define ADDOP_BINARY(C, LOC, BINOP) \
415
3.19k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false))
416
417
#define ADDOP_INPLACE(C, LOC, BINOP) \
418
577
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true))
419
420
#define ADD_YIELD_FROM(C, LOC, await) \
421
47
    RETURN_IF_ERROR(codegen_add_yield_from((C), (LOC), (await)))
422
423
#define POP_EXCEPT_AND_RERAISE(C, LOC) \
424
834
    RETURN_IF_ERROR(codegen_pop_except_and_reraise((C), (LOC)))
425
426
#define ADDOP_YIELD(C, LOC) \
427
379
    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
156k
    RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), (V)))
435
436
#define VISIT_IN_SCOPE(C, TYPE, V) \
437
11.9k
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_visit_ ## TYPE((C), (V)))
438
439
#define VISIT_SEQ(C, TYPE, SEQ)                                             \
440
21.1k
    do {                                                                    \
441
21.1k
        asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */    \
442
50.6k
        for (int _i = 0; _i < asdl_seq_LEN(seq); _i++) {                    \
443
29.4k
            TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i);           \
444
29.4k
            RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), elt));              \
445
29.4k
        }                                                                   \
446
21.1k
    } 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
120
{
463
120
    ADDOP_LOAD_CONST(c, loc, Py_None);
464
120
    ADDOP_LOAD_CONST(c, loc, Py_None);
465
120
    ADDOP_LOAD_CONST(c, loc, Py_None);
466
120
    ADDOP_I(c, loc, CALL, 3);
467
120
    return SUCCESS;
468
120
}
469
470
static int
471
codegen_add_yield_from(compiler *c, location loc, int await)
472
47
{
473
47
    NEW_JUMP_TARGET_LABEL(c, send);
474
47
    NEW_JUMP_TARGET_LABEL(c, fail);
475
47
    NEW_JUMP_TARGET_LABEL(c, exit);
476
477
47
    USE_LABEL(c, send);
478
47
    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
47
    ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
482
47
    ADDOP_I(c, loc, YIELD_VALUE, 1);
483
47
    ADDOP(c, NO_LOCATION, POP_BLOCK);
484
47
    ADDOP_I(c, loc, RESUME, await ? RESUME_AFTER_AWAIT : RESUME_AFTER_YIELD_FROM);
485
47
    ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
486
487
47
    USE_LABEL(c, fail);
488
47
    ADDOP(c, loc, CLEANUP_THROW);
489
490
47
    USE_LABEL(c, exit);
491
47
    ADDOP(c, loc, END_SEND);
492
47
    return SUCCESS;
493
47
}
494
495
static int
496
codegen_pop_except_and_reraise(compiler *c, location loc)
497
834
{
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
834
    ADDOP_I(c, loc, COPY, 3);
506
834
    ADDOP(c, loc, POP_EXCEPT);
507
834
    ADDOP_I(c, loc, RERAISE, 1);
508
834
    return SUCCESS;
509
834
}
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.02k
{
520
1.02k
    switch (info->fb_type) {
521
201
        case COMPILE_FBLOCK_WHILE_LOOP:
522
362
        case COMPILE_FBLOCK_EXCEPTION_HANDLER:
523
362
        case COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER:
524
362
        case COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR:
525
404
        case COMPILE_FBLOCK_STOP_ITERATION:
526
404
            return SUCCESS;
527
528
227
        case COMPILE_FBLOCK_FOR_LOOP:
529
            /* Pop the iterator */
530
227
            if (preserve_tos) {
531
76
                ADDOP_I(c, *ploc, SWAP, 3);
532
76
            }
533
227
            ADDOP(c, *ploc, POP_TOP);
534
227
            ADDOP(c, *ploc, POP_TOP);
535
227
            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
204
        case COMPILE_FBLOCK_TRY_EXCEPT:
546
204
            ADDOP(c, *ploc, POP_BLOCK);
547
204
            return SUCCESS;
548
549
10
        case COMPILE_FBLOCK_FINALLY_TRY:
550
            /* This POP_BLOCK gets the line number of the unwinding statement */
551
10
            ADDOP(c, *ploc, POP_BLOCK);
552
10
            if (preserve_tos) {
553
10
                RETURN_IF_ERROR(
554
10
                    _PyCompile_PushFBlock(c, *ploc, COMPILE_FBLOCK_POP_VALUE,
555
10
                                          NO_LABEL, NO_LABEL, NULL));
556
10
            }
557
            /* Emit the finally block */
558
10
            VISIT_SEQ(c, stmt, info->fb_datum);
559
10
            if (preserve_tos) {
560
10
                _PyCompile_PopFBlock(c, COMPILE_FBLOCK_POP_VALUE, NO_LABEL);
561
10
            }
562
            /* The finally block should appear to execute after the
563
             * statement causing the unwinding, so make the unwinding
564
             * instruction artificial */
565
10
            *ploc = NO_LOCATION;
566
10
            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
21
        case COMPILE_FBLOCK_WITH:
581
22
        case COMPILE_FBLOCK_ASYNC_WITH:
582
22
            *ploc = info->fb_loc;
583
22
            ADDOP(c, *ploc, POP_BLOCK);
584
22
            if (preserve_tos) {
585
17
                ADDOP_I(c, *ploc, SWAP, 3);
586
17
                ADDOP_I(c, *ploc, SWAP, 2);
587
17
            }
588
22
            RETURN_IF_ERROR(codegen_call_exit_with_nones(c, *ploc));
589
22
            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
22
            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
22
            *ploc = NO_LOCATION;
599
22
            return SUCCESS;
600
601
161
        case COMPILE_FBLOCK_HANDLER_CLEANUP: {
602
161
            if (info->fb_datum) {
603
20
                ADDOP(c, *ploc, POP_BLOCK);
604
20
            }
605
161
            if (preserve_tos) {
606
59
                ADDOP_I(c, *ploc, SWAP, 2);
607
59
            }
608
161
            ADDOP(c, *ploc, POP_BLOCK);
609
161
            ADDOP(c, *ploc, POP_EXCEPT);
610
161
            if (info->fb_datum) {
611
20
                ADDOP_LOAD_CONST(c, *ploc, Py_None);
612
20
                RETURN_IF_ERROR(codegen_nameop(c, *ploc, info->fb_datum, Store));
613
20
                RETURN_IF_ERROR(codegen_nameop(c, *ploc, info->fb_datum, Del));
614
20
            }
615
161
            return SUCCESS;
616
161
        }
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.02k
    }
625
1.02k
    Py_UNREACHABLE();
626
1.02k
}
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
5.76k
{
633
5.76k
    fblockinfo *top = _PyCompile_TopFBlock(c);
634
5.76k
    if (top == NULL) {
635
4.53k
        return SUCCESS;
636
4.53k
    }
637
1.23k
    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.23k
    if (loop != NULL && (top->fb_type == COMPILE_FBLOCK_WHILE_LOOP ||
642
499
                         top->fb_type == COMPILE_FBLOCK_FOR_LOOP ||
643
499
                         top->fb_type == COMPILE_FBLOCK_ASYNC_FOR_LOOP)) {
644
445
        *loop = top;
645
445
        return SUCCESS;
646
445
    }
647
791
    fblockinfo copy = *top;
648
791
    _PyCompile_PopFBlock(c, top->fb_type, top->fb_block);
649
791
    RETURN_IF_ERROR(codegen_unwind_fblock(c, ploc, &copy, preserve_tos));
650
791
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, ploc, preserve_tos, loop));
651
791
    _PyCompile_PushFBlock(c, copy.fb_loc, copy.fb_type, copy.fb_block,
652
791
                          copy.fb_exit, copy.fb_datum);
653
791
    return SUCCESS;
654
791
}
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
5.78k
{
661
5.78k
    RETURN_IF_ERROR(
662
5.78k
        _PyCompile_EnterScope(c, name, scope_type, key, lineno, private, umd));
663
5.78k
    location loc = LOCATION(lineno, lineno, 0, 0);
664
5.78k
    if (scope_type == COMPILE_SCOPE_MODULE) {
665
307
        loc.lineno = 0;
666
307
    }
667
5.78k
    ADDOP_I(c, loc, RESUME, RESUME_AT_FUNC_START);
668
5.78k
    if (scope_type == COMPILE_SCOPE_MODULE) {
669
307
        ADDOP(c, loc, ANNOTATIONS_PLACEHOLDER);
670
307
    }
671
5.78k
    return SUCCESS;
672
5.78k
}
673
674
static int
675
codegen_setup_annotations_scope(compiler *c, location loc,
676
                                void *key, PyObject *name)
677
6
{
678
6
    _PyCompile_CodeUnitMetadata umd = {
679
6
        .u_posonlyargcount = 1,
680
6
    };
681
6
    RETURN_IF_ERROR(
682
6
        codegen_enter_scope(c, name, COMPILE_SCOPE_ANNOTATIONS,
683
6
                            key, loc.lineno, NULL, &umd));
684
685
    // if .format > VALUE_WITH_FAKE_GLOBALS: raise NotImplementedError
686
6
    PyObject *value_with_fake_globals = PyLong_FromLong(_Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS);
687
6
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
688
6
    _Py_DECLARE_STR(format, ".format");
689
6
    ADDOP_I(c, loc, LOAD_FAST, 0);
690
6
    ADDOP_LOAD_CONST(c, loc, value_with_fake_globals);
691
6
    ADDOP_I(c, loc, COMPARE_OP, (Py_GT << 5) | compare_masks[Py_GT]);
692
6
    NEW_JUMP_TARGET_LABEL(c, body);
693
6
    ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, body);
694
6
    ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR);
695
6
    ADDOP_I(c, loc, RAISE_VARARGS, 1);
696
6
    USE_LABEL(c, body);
697
6
    return SUCCESS;
698
6
}
699
700
static int
701
codegen_leave_annotations_scope(compiler *c, location loc)
702
6
{
703
6
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
704
6
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
705
6
    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
6
    const Py_ssize_t size = PyObject_Size(co->co_localsplusnames);
716
6
    if (size == -1) {
717
0
        Py_DECREF(co);
718
0
        return ERROR;
719
0
    }
720
6
    PyObject *new_names = PyTuple_New(size);
721
6
    if (new_names == NULL) {
722
0
        Py_DECREF(co);
723
0
        return ERROR;
724
0
    }
725
6
    PyTuple_SET_ITEM(new_names, 0, Py_NewRef(&_Py_ID(format)));
726
7
    for (int i = 1; i < size; i++) {
727
1
        PyObject *item = PyTuple_GetItem(co->co_localsplusnames, i);
728
1
        if (item == NULL) {
729
0
            Py_DECREF(co);
730
0
            Py_DECREF(new_names);
731
0
            return ERROR;
732
0
        }
733
1
        Py_INCREF(item);
734
1
        PyTuple_SET_ITEM(new_names, i, item);
735
1
    }
736
6
    Py_SETREF(co->co_localsplusnames, new_names);
737
738
6
    _PyCompile_ExitScope(c);
739
6
    int ret = codegen_make_closure(c, loc, co, 0);
740
6
    Py_DECREF(co);
741
6
    RETURN_IF_ERROR(ret);
742
6
    return SUCCESS;
743
6
}
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
0
{
749
0
    Py_ssize_t annotations_len = PyList_GET_SIZE(deferred_anno);
750
751
0
    assert(PyList_CheckExact(conditional_annotation_indices));
752
0
    assert(annotations_len == PyList_Size(conditional_annotation_indices));
753
754
0
    ADDOP_I(c, loc, BUILD_MAP, 0); // stack now contains <annos>
755
756
0
    for (Py_ssize_t i = 0; i < annotations_len; i++) {
757
0
        PyObject *ptr = PyList_GET_ITEM(deferred_anno, i);
758
0
        stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr);
759
0
        if (st == NULL) {
760
0
            return ERROR;
761
0
        }
762
0
        PyObject *mangled = _PyCompile_Mangle(c, st->v.AnnAssign.target->v.Name.id);
763
0
        if (!mangled) {
764
0
            return ERROR;
765
0
        }
766
0
        PyObject *cond_index = PyList_GET_ITEM(conditional_annotation_indices, i);
767
0
        assert(PyLong_CheckExact(cond_index));
768
0
        long idx = PyLong_AS_LONG(cond_index);
769
0
        NEW_JUMP_TARGET_LABEL(c, not_set);
770
771
0
        if (idx != -1) {
772
0
            ADDOP_LOAD_CONST(c, LOC(st), cond_index);
773
0
            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
0
            else {
778
0
                ADDOP_NAME(
779
0
                    c, LOC(st), LOAD_GLOBAL, &_Py_ID(__conditional_annotations__), names);
780
0
            }
781
782
0
            ADDOP_I(c, LOC(st), CONTAINS_OP, 0);
783
0
            ADDOP_JUMP(c, LOC(st), POP_JUMP_IF_FALSE, not_set);
784
0
        }
785
786
0
        VISIT(c, expr, st->v.AnnAssign.annotation);
787
0
        ADDOP_I(c, LOC(st), COPY, 2);
788
0
        ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
789
        // stack now contains <annos> <name> <annos> <value>
790
0
        ADDOP(c, loc, STORE_SUBSCR);
791
        // stack now contains <annos>
792
793
0
        USE_LABEL(c, not_set);
794
0
    }
795
0
    return SUCCESS;
796
0
}
797
798
static int
799
codegen_process_deferred_annotations(compiler *c, location loc)
800
1.28k
{
801
1.28k
    PyObject *deferred_anno = NULL;
802
1.28k
    PyObject *conditional_annotation_indices = NULL;
803
1.28k
    _PyCompile_DeferredAnnotations(c, &deferred_anno, &conditional_annotation_indices);
804
1.28k
    if (deferred_anno == NULL) {
805
1.28k
        assert(conditional_annotation_indices == NULL);
806
1.28k
        return SUCCESS;
807
1.28k
    }
808
809
0
    int scope_type = SCOPE_TYPE(c);
810
0
    bool need_separate_block = scope_type == COMPILE_SCOPE_MODULE;
811
0
    if (need_separate_block) {
812
0
        if (_PyCompile_StartAnnotationSetup(c) == ERROR) {
813
0
            goto error;
814
0
        }
815
0
    }
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
0
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
823
0
    assert(ste->ste_annotation_block != NULL);
824
0
    void *key = (void *)((uintptr_t)ste->ste_id + 1);
825
0
    if (codegen_setup_annotations_scope(c, loc, key,
826
0
                                        ste->ste_annotation_block->ste_name) < 0) {
827
0
        goto error;
828
0
    }
829
0
    if (codegen_deferred_annotations_body(c, loc, deferred_anno,
830
0
                                          conditional_annotation_indices, scope_type) < 0) {
831
0
        _PyCompile_ExitScope(c);
832
0
        goto error;
833
0
    }
834
835
0
    Py_DECREF(deferred_anno);
836
0
    Py_DECREF(conditional_annotation_indices);
837
838
0
    RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
839
0
    RETURN_IF_ERROR(codegen_nameop(
840
0
        c, loc,
841
0
        ste->ste_type == ClassBlock ? &_Py_ID(__annotate_func__) : &_Py_ID(__annotate__),
842
0
        Store));
843
844
0
    if (need_separate_block) {
845
0
        RETURN_IF_ERROR(_PyCompile_EndAnnotationSetup(c));
846
0
    }
847
848
0
    return SUCCESS;
849
0
error:
850
0
    Py_XDECREF(deferred_anno);
851
0
    Py_XDECREF(conditional_annotation_indices);
852
0
    return ERROR;
853
0
}
854
855
/* Compile an expression */
856
int
857
_PyCodegen_Expression(compiler *c, expr_ty e)
858
43
{
859
43
    VISIT(c, expr, e);
860
43
    return SUCCESS;
861
43
}
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
264
{
869
264
    if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) {
870
0
        ADDOP_I(c, loc, BUILD_SET, 0);
871
0
        ADDOP_N(c, loc, STORE_NAME, &_Py_ID(__conditional_annotations__), names);
872
0
    }
873
264
    return codegen_body(c, loc, stmts, is_interactive);
874
264
}
875
876
int
877
codegen_body(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interactive)
878
1.28k
{
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.28k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
883
1.28k
    if ((FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) && ste->ste_annotations_used) {
884
0
        ADDOP(c, loc, SETUP_ANNOTATIONS);
885
0
    }
886
1.28k
    if (!asdl_seq_LEN(stmts)) {
887
3
        return SUCCESS;
888
3
    }
889
1.28k
    Py_ssize_t first_instr = 0;
890
1.28k
    if (!is_interactive) { /* A string literal on REPL prompt is not a docstring */
891
1.28k
        if (ste->ste_has_docstring) {
892
434
            PyObject *docstring = _PyAST_GetDocString(stmts);
893
434
            assert(docstring);
894
434
            first_instr = 1;
895
            /* set docstring */
896
434
            assert(OPTIMIZATION_LEVEL(c) < 2);
897
434
            PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
898
434
            if (cleandoc == NULL) {
899
0
                return ERROR;
900
0
            }
901
434
            stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
902
434
            assert(st->kind == Expr_kind);
903
434
            location loc = LOC(st->v.Expr.value);
904
434
            ADDOP_LOAD_CONST(c, loc, cleandoc);
905
434
            Py_DECREF(cleandoc);
906
434
            RETURN_IF_ERROR(codegen_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
907
434
        }
908
1.28k
    }
909
9.22k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(stmts); i++) {
910
7.93k
        VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
911
7.93k
    }
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.28k
    if (!(FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS)) {
916
1.28k
        RETURN_IF_ERROR(codegen_process_deferred_annotations(c, loc));
917
1.28k
    }
918
1.28k
    return SUCCESS;
919
1.28k
}
920
921
int
922
_PyCodegen_EnterAnonymousScope(compiler* c, mod_ty mod)
923
307
{
924
307
    _Py_DECLARE_STR(anon_module, "<module>");
925
307
    RETURN_IF_ERROR(
926
307
        codegen_enter_scope(c, &_Py_STR(anon_module), COMPILE_SCOPE_MODULE,
927
307
                            mod, 1, NULL, NULL));
928
307
    return SUCCESS;
929
307
}
930
931
static int
932
codegen_make_closure(compiler *c, location loc,
933
                     PyCodeObject *co, Py_ssize_t flags)
934
5.47k
{
935
5.47k
    if (co->co_nfreevars) {
936
447
        int i = PyUnstable_Code_GetFirstFree(co);
937
1.23k
        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
783
            PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
942
783
            int arg = _PyCompile_LookupArg(c, co, name);
943
783
            RETURN_IF_ERROR(arg);
944
783
            ADDOP_I(c, loc, LOAD_CLOSURE, arg);
945
783
        }
946
447
        flags |= MAKE_FUNCTION_CLOSURE;
947
447
        ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
948
447
    }
949
5.47k
    ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
950
951
5.47k
    ADDOP(c, loc, MAKE_FUNCTION);
952
953
5.47k
    if (flags & MAKE_FUNCTION_CLOSURE) {
954
447
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_CLOSURE);
955
447
    }
956
5.47k
    if (flags & MAKE_FUNCTION_ANNOTATIONS) {
957
0
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATIONS);
958
0
    }
959
5.47k
    if (flags & MAKE_FUNCTION_ANNOTATE) {
960
6
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATE);
961
6
    }
962
5.47k
    if (flags & MAKE_FUNCTION_KWDEFAULTS) {
963
100
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_KWDEFAULTS);
964
100
    }
965
5.47k
    if (flags & MAKE_FUNCTION_DEFAULTS) {
966
932
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_DEFAULTS);
967
932
    }
968
5.47k
    return SUCCESS;
969
5.47k
}
970
971
static int
972
codegen_decorators(compiler *c, asdl_expr_seq* decos)
973
5.15k
{
974
5.15k
    if (!decos) {
975
4.55k
        return SUCCESS;
976
4.55k
    }
977
978
1.22k
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) {
979
621
        VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
980
621
    }
981
602
    return SUCCESS;
982
602
}
983
984
static int
985
codegen_apply_decorators(compiler *c, asdl_expr_seq* decos)
986
5.15k
{
987
5.15k
    if (!decos) {
988
4.55k
        return SUCCESS;
989
4.55k
    }
990
991
1.22k
    for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
992
621
        location loc = LOC((expr_ty)asdl_seq_GET(decos, i));
993
621
        ADDOP_I(c, loc, CALL, 0);
994
621
    }
995
602
    return SUCCESS;
996
602
}
997
998
static int
999
codegen_kwonlydefaults(compiler *c, location loc,
1000
                       asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
1001
4.25k
{
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.25k
    int default_count = 0;
1007
4.50k
    for (int i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
1008
257
        arg_ty arg = asdl_seq_GET(kwonlyargs, i);
1009
257
        expr_ty default_ = asdl_seq_GET(kw_defaults, i);
1010
257
        if (default_) {
1011
250
            default_count++;
1012
250
            PyObject *mangled = _PyCompile_MaybeMangle(c, arg->arg);
1013
250
            if (!mangled) {
1014
0
                return ERROR;
1015
0
            }
1016
250
            ADDOP_LOAD_CONST_NEW(c, loc, mangled);
1017
250
            VISIT(c, expr, default_);
1018
250
        }
1019
257
    }
1020
4.25k
    if (default_count) {
1021
100
        ADDOP_I(c, loc, BUILD_MAP, default_count);
1022
100
        return 1;
1023
100
    }
1024
4.15k
    else {
1025
4.15k
        return 0;
1026
4.15k
    }
1027
4.25k
}
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
15
{
1041
15
    if (!annotation) {
1042
2
        return SUCCESS;
1043
2
    }
1044
13
    PyObject *mangled = _PyCompile_MaybeMangle(c, id);
1045
13
    if (!mangled) {
1046
0
        return ERROR;
1047
0
    }
1048
13
    ADDOP_LOAD_CONST(c, loc, mangled);
1049
13
    Py_DECREF(mangled);
1050
1051
13
    if (FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) {
1052
0
        VISIT(c, annexpr, annotation);
1053
0
    }
1054
13
    else {
1055
13
        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
13
        else {
1064
13
            VISIT(c, expr, annotation);
1065
13
        }
1066
13
    }
1067
13
    *annotations_len += 1;
1068
13
    return SUCCESS;
1069
13
}
1070
1071
static int
1072
codegen_argannotations(compiler *c, asdl_arg_seq* args,
1073
                       Py_ssize_t *annotations_len, location loc)
1074
18
{
1075
18
    int i;
1076
27
    for (i = 0; i < asdl_seq_LEN(args); i++) {
1077
9
        arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
1078
9
        RETURN_IF_ERROR(
1079
9
            codegen_argannotation(
1080
9
                        c,
1081
9
                        arg->arg,
1082
9
                        arg->annotation,
1083
9
                        annotations_len,
1084
9
                        loc));
1085
9
    }
1086
18
    return SUCCESS;
1087
18
}
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
6
{
1094
6
    RETURN_IF_ERROR(
1095
6
        codegen_argannotations(c, args->args, annotations_len, loc));
1096
1097
6
    RETURN_IF_ERROR(
1098
6
        codegen_argannotations(c, args->posonlyargs, annotations_len, loc));
1099
1100
6
    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
6
    RETURN_IF_ERROR(
1107
6
        codegen_argannotations(c, args->kwonlyargs, annotations_len, loc));
1108
1109
6
    if (args->kwarg && args->kwarg->annotation) {
1110
0
        RETURN_IF_ERROR(
1111
0
            codegen_argannotation(c, args->kwarg->arg,
1112
0
                                     args->kwarg->annotation, annotations_len, loc));
1113
0
    }
1114
1115
6
    RETURN_IF_ERROR(
1116
6
        codegen_argannotation(c, &_Py_ID(return), returns, annotations_len, loc));
1117
1118
6
    return 0;
1119
6
}
1120
1121
static int
1122
codegen_function_annotations(compiler *c, location loc,
1123
                             arguments_ty args, expr_ty returns)
1124
4.13k
{
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.13k
    Py_ssize_t annotations_len = 0;
1131
1132
4.13k
    PySTEntryObject *ste;
1133
4.13k
    RETURN_IF_ERROR(_PySymtable_LookupOptional(SYMTABLE(c), args, &ste));
1134
4.13k
    assert(ste != NULL);
1135
1136
4.13k
    if (ste->ste_annotations_used) {
1137
6
        int err = codegen_setup_annotations_scope(c, loc, (void *)args, ste->ste_name);
1138
6
        Py_DECREF(ste);
1139
6
        RETURN_IF_ERROR(err);
1140
6
        RETURN_IF_ERROR_IN_SCOPE(
1141
6
            c, codegen_annotations_in_scope(c, loc, args, returns, &annotations_len)
1142
6
        );
1143
6
        ADDOP_I(c, loc, BUILD_MAP, annotations_len);
1144
6
        RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
1145
6
        return MAKE_FUNCTION_ANNOTATE;
1146
6
    }
1147
4.12k
    else {
1148
4.12k
        Py_DECREF(ste);
1149
4.12k
    }
1150
1151
4.12k
    return 0;
1152
4.13k
}
1153
1154
static int
1155
codegen_defaults(compiler *c, arguments_ty args,
1156
                        location loc)
1157
932
{
1158
932
    VISIT_SEQ(c, expr, args->defaults);
1159
932
    ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
1160
932
    return SUCCESS;
1161
932
}
1162
1163
static Py_ssize_t
1164
codegen_default_arguments(compiler *c, location loc,
1165
                          arguments_ty args)
1166
4.25k
{
1167
4.25k
    Py_ssize_t funcflags = 0;
1168
4.25k
    if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
1169
932
        RETURN_IF_ERROR(codegen_defaults(c, args, loc));
1170
932
        funcflags |= MAKE_FUNCTION_DEFAULTS;
1171
932
    }
1172
4.25k
    if (args->kwonlyargs) {
1173
4.25k
        int res = codegen_kwonlydefaults(c, loc,
1174
4.25k
                                         args->kwonlyargs,
1175
4.25k
                                         args->kw_defaults);
1176
4.25k
        RETURN_IF_ERROR(res);
1177
4.25k
        if (res > 0) {
1178
100
            funcflags |= MAKE_FUNCTION_KWDEFAULTS;
1179
100
        }
1180
4.25k
    }
1181
4.25k
    return funcflags;
1182
4.25k
}
1183
1184
static int
1185
codegen_wrap_in_stopiteration_handler(compiler *c)
1186
307
{
1187
307
    NEW_JUMP_TARGET_LABEL(c, handler);
1188
1189
    /* Insert SETUP_CLEANUP at start */
1190
307
    RETURN_IF_ERROR(
1191
307
        _PyInstructionSequence_InsertInstruction(
1192
307
            INSTR_SEQUENCE(c), 0,
1193
307
            SETUP_CLEANUP, handler.id, NO_LOCATION));
1194
1195
307
    ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1196
307
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
1197
307
    USE_LABEL(c, handler);
1198
307
    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
1199
307
    ADDOP_I(c, NO_LOCATION, RERAISE, 1);
1200
307
    return SUCCESS;
1201
307
}
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.13k
{
1323
4.13k
    arguments_ty args;
1324
4.13k
    identifier name;
1325
4.13k
    asdl_stmt_seq *body;
1326
4.13k
    int scope_type;
1327
1328
4.13k
    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.11k
    } else {
1337
4.11k
        assert(s->kind == FunctionDef_kind);
1338
1339
4.11k
        args = s->v.FunctionDef.args;
1340
4.11k
        name = s->v.FunctionDef.name;
1341
4.11k
        body = s->v.FunctionDef.body;
1342
1343
4.11k
        scope_type = COMPILE_SCOPE_FUNCTION;
1344
4.11k
    }
1345
1346
4.13k
    _PyCompile_CodeUnitMetadata umd = {
1347
4.13k
        .u_argcount = asdl_seq_LEN(args->args),
1348
4.13k
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
1349
4.13k
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
1350
4.13k
    };
1351
4.13k
    RETURN_IF_ERROR(
1352
4.13k
        codegen_enter_scope(c, name, scope_type, (void *)s, firstlineno, NULL, &umd));
1353
1354
4.13k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1355
4.13k
    Py_ssize_t first_instr = 0;
1356
4.13k
    if (ste->ste_has_docstring) {
1357
1.44k
        PyObject *docstring = _PyAST_GetDocString(body);
1358
1.44k
        assert(docstring);
1359
1.44k
        first_instr = 1;
1360
1.44k
        docstring = _PyCompile_CleanDoc(docstring);
1361
1.44k
        if (docstring == NULL) {
1362
0
            _PyCompile_ExitScope(c);
1363
0
            return ERROR;
1364
0
        }
1365
1.44k
        Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1366
1.44k
        Py_DECREF(docstring);
1367
1.44k
        RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
1368
1.44k
    }
1369
1370
4.13k
    NEW_JUMP_TARGET_LABEL(c, start);
1371
4.13k
    USE_LABEL(c, start);
1372
4.13k
    bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1373
4.13k
    if (add_stopiteration_handler) {
1374
        /* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1375
111
        RETURN_IF_ERROR(
1376
111
            _PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1377
111
                                  start, NO_LABEL, NULL));
1378
111
    }
1379
1380
15.9k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1381
11.8k
        VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1382
11.8k
    }
1383
4.13k
    if (add_stopiteration_handler) {
1384
111
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_wrap_in_stopiteration_handler(c));
1385
111
        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1386
111
    }
1387
4.13k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1388
4.13k
    _PyCompile_ExitScope(c);
1389
4.13k
    if (co == NULL) {
1390
0
        Py_XDECREF(co);
1391
0
        return ERROR;
1392
0
    }
1393
4.13k
    int ret = codegen_make_closure(c, LOC(s), co, funcflags);
1394
4.13k
    Py_DECREF(co);
1395
4.13k
    return ret;
1396
4.13k
}
1397
1398
static int
1399
codegen_function(compiler *c, stmt_ty s, int is_async)
1400
4.13k
{
1401
4.13k
    arguments_ty args;
1402
4.13k
    expr_ty returns;
1403
4.13k
    identifier name;
1404
4.13k
    asdl_expr_seq *decos;
1405
4.13k
    asdl_type_param_seq *type_params;
1406
4.13k
    Py_ssize_t funcflags;
1407
4.13k
    int firstlineno;
1408
1409
4.13k
    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.11k
    } else {
1418
4.11k
        assert(s->kind == FunctionDef_kind);
1419
1420
4.11k
        args = s->v.FunctionDef.args;
1421
4.11k
        returns = s->v.FunctionDef.returns;
1422
4.11k
        decos = s->v.FunctionDef.decorator_list;
1423
4.11k
        name = s->v.FunctionDef.name;
1424
4.11k
        type_params = s->v.FunctionDef.type_params;
1425
4.11k
    }
1426
1427
4.13k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1428
1429
4.13k
    firstlineno = s->lineno;
1430
4.13k
    if (asdl_seq_LEN(decos)) {
1431
579
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1432
579
    }
1433
1434
4.13k
    location loc = LOC(s);
1435
1436
4.13k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1437
1438
4.13k
    funcflags = codegen_default_arguments(c, loc, args);
1439
4.13k
    RETURN_IF_ERROR(funcflags);
1440
1441
4.13k
    int num_typeparam_args = 0;
1442
1443
4.13k
    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.13k
    int annotations_flag = codegen_function_annotations(c, loc, args, returns);
1471
4.13k
    if (annotations_flag < 0) {
1472
0
        if (is_generic) {
1473
0
            _PyCompile_ExitScope(c);
1474
0
        }
1475
0
        return ERROR;
1476
0
    }
1477
4.13k
    funcflags |= annotations_flag;
1478
1479
4.13k
    int ret = codegen_function_body(c, s, is_async, funcflags, firstlineno);
1480
4.13k
    if (is_generic) {
1481
0
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1482
0
    }
1483
4.13k
    else {
1484
4.13k
        RETURN_IF_ERROR(ret);
1485
4.13k
    }
1486
1487
4.13k
    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.13k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1510
4.13k
    return codegen_nameop(c, loc, name, Store);
1511
4.13k
}
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.02k
{
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.02k
    RETURN_IF_ERROR(
1539
1.02k
        codegen_enter_scope(c, s->v.ClassDef.name, COMPILE_SCOPE_CLASS,
1540
1.02k
                            (void *)s, firstlineno, s->v.ClassDef.name, NULL));
1541
1542
1.02k
    location loc = LOCATION(firstlineno, firstlineno, 0, 0);
1543
    /* load (global) __name__ ... */
1544
1.02k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__name__), Load));
1545
    /* ... and store it as __module__ */
1546
1.02k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__module__), Store));
1547
1.02k
    ADDOP_LOAD_CONST(c, loc, QUALNAME(c));
1548
1.02k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__qualname__), Store));
1549
1.02k
    ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
1550
1.02k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__firstlineno__), Store));
1551
1.02k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1552
1.02k
    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.02k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1556
595
        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
595
        ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__classdict__), cellvars);
1562
595
    }
1563
1.02k
    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.02k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, false));
1569
1.02k
    PyObject *static_attributes = _PyCompile_StaticAttributesAsTuple(c);
1570
1.02k
    if (static_attributes == NULL) {
1571
0
        _PyCompile_ExitScope(c);
1572
0
        return ERROR;
1573
0
    }
1574
1.02k
    ADDOP_LOAD_CONST(c, NO_LOCATION, static_attributes);
1575
1.02k
    Py_CLEAR(static_attributes);
1576
1.02k
    RETURN_IF_ERROR_IN_SCOPE(
1577
1.02k
        c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__static_attributes__), Store));
1578
    /* The following code is artificial */
1579
    /* Set __classdictcell__ if necessary */
1580
1.02k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1581
        /* Store __classdictcell__ into class namespace */
1582
595
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__classdict__));
1583
595
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1584
595
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1585
595
        RETURN_IF_ERROR_IN_SCOPE(
1586
595
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store));
1587
595
    }
1588
    /* Return __classcell__ if it is referenced, otherwise return None */
1589
1.02k
    if (SYMTABLE_ENTRY(c)->ste_needs_class_closure) {
1590
        /* Store __classcell__ into class namespace & return it */
1591
66
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__class__));
1592
66
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1593
66
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1594
66
        ADDOP_I(c, NO_LOCATION, COPY, 1);
1595
66
        RETURN_IF_ERROR_IN_SCOPE(
1596
66
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store));
1597
66
    }
1598
958
    else {
1599
        /* No methods referenced __class__, so just return None */
1600
958
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1601
958
    }
1602
1.02k
    ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
1603
    /* create the code object */
1604
1.02k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1605
1606
    /* leave the new scope */
1607
1.02k
    _PyCompile_ExitScope(c);
1608
1.02k
    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.02k
    loc = LOC(s);
1617
1.02k
    ADDOP(c, loc, LOAD_BUILD_CLASS);
1618
1.02k
    ADDOP(c, loc, PUSH_NULL);
1619
1620
    /* 3. load a function (or closure) made from the code object */
1621
1.02k
    int ret = codegen_make_closure(c, loc, co, 0);
1622
1.02k
    Py_DECREF(co);
1623
1.02k
    RETURN_IF_ERROR(ret);
1624
1625
    /* 4. load class name */
1626
1.02k
    ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
1627
1628
1.02k
    return SUCCESS;
1629
1.02k
}
1630
1631
static int
1632
codegen_class(compiler *c, stmt_ty s)
1633
1.02k
{
1634
1.02k
    asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
1635
1636
1.02k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1637
1638
1.02k
    int firstlineno = s->lineno;
1639
1.02k
    if (asdl_seq_LEN(decos)) {
1640
23
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1641
23
    }
1642
1.02k
    location loc = LOC(s);
1643
1644
1.02k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1645
1.02k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1646
1.02k
    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.02k
    int ret = codegen_class_body(c, s, firstlineno);
1662
1.02k
    if (is_generic) {
1663
0
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1664
0
    }
1665
1.02k
    else {
1666
1.02k
        RETURN_IF_ERROR(ret);
1667
1.02k
    }
1668
1669
    /* generate the rest of the code for the call */
1670
1671
1.02k
    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.02k
    } else {
1695
1.02k
        RETURN_IF_ERROR(codegen_call_helper(c, loc, 2,
1696
1.02k
                                            s->v.ClassDef.bases,
1697
1.02k
                                            s->v.ClassDef.keywords));
1698
1.02k
    }
1699
1700
    /* 6. apply decorators */
1701
1.02k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1702
1703
    /* 7. store into <name> */
1704
1.02k
    RETURN_IF_ERROR(codegen_nameop(c, loc, s->v.ClassDef.name, Store));
1705
1.02k
    return SUCCESS;
1706
1.02k
}
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
124
{
1787
358
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(elts); i++) {
1788
277
        expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
1789
277
        if (e->kind != Constant_kind) {
1790
43
            return false;
1791
43
        }
1792
277
    }
1793
81
    return true;
1794
124
}
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
10.3k
{
1801
10.3k
    if (e->kind == Tuple_kind) {
1802
124
        return !is_const_tuple(e->v.Tuple.elts);
1803
124
    }
1804
10.2k
    if (e->kind != Constant_kind) {
1805
7.28k
        return true;
1806
7.28k
    }
1807
2.91k
    PyObject *value = e->v.Constant.value;
1808
2.91k
    return (value == Py_None
1809
2.91k
         || value == Py_False
1810
2.91k
         || value == Py_True
1811
2.91k
         || value == Py_Ellipsis);
1812
10.2k
}
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
5.13k
{
1822
5.13k
    Py_ssize_t i, n;
1823
5.13k
    bool left = check_is_arg(e->v.Compare.left);
1824
5.13k
    expr_ty left_expr = e->v.Compare.left;
1825
5.13k
    n = asdl_seq_LEN(e->v.Compare.ops);
1826
10.3k
    for (i = 0; i < n; i++) {
1827
5.19k
        cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
1828
5.19k
        expr_ty right_expr = (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i);
1829
5.19k
        bool right = check_is_arg(right_expr);
1830
5.19k
        if (op == Is || op == IsNot) {
1831
1.67k
            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
1.67k
        }
1841
5.19k
        left = right;
1842
5.19k
        left_expr = right_expr;
1843
5.19k
    }
1844
5.13k
    return SUCCESS;
1845
5.13k
}
1846
1847
static int
1848
codegen_addcompare(compiler *c, location loc, cmpop_ty op)
1849
5.25k
{
1850
5.25k
    int cmp;
1851
5.25k
    switch (op) {
1852
1.27k
    case Eq:
1853
1.27k
        cmp = Py_EQ;
1854
1.27k
        break;
1855
422
    case NotEq:
1856
422
        cmp = Py_NE;
1857
422
        break;
1858
309
    case Lt:
1859
309
        cmp = Py_LT;
1860
309
        break;
1861
166
    case LtE:
1862
166
        cmp = Py_LE;
1863
166
        break;
1864
271
    case Gt:
1865
271
        cmp = Py_GT;
1866
271
        break;
1867
98
    case GtE:
1868
98
        cmp = Py_GE;
1869
98
        break;
1870
1.10k
    case Is:
1871
1.10k
        ADDOP_I(c, loc, IS_OP, 0);
1872
1.10k
        return SUCCESS;
1873
629
    case IsNot:
1874
629
        ADDOP_I(c, loc, IS_OP, 1);
1875
629
        return SUCCESS;
1876
696
    case In:
1877
696
        ADDOP_I(c, loc, CONTAINS_OP, 0);
1878
696
        return SUCCESS;
1879
282
    case NotIn:
1880
282
        ADDOP_I(c, loc, CONTAINS_OP, 1);
1881
282
        return SUCCESS;
1882
0
    default:
1883
0
        Py_UNREACHABLE();
1884
5.25k
    }
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.53k
    ADDOP_I(c, loc, COMPARE_OP, (cmp << 5) | compare_masks[cmp]);
1890
2.53k
    return SUCCESS;
1891
2.53k
}
1892
1893
static int
1894
codegen_jump_if(compiler *c, location loc,
1895
                expr_ty e, jump_target_label next, int cond)
1896
10.2k
{
1897
10.2k
    switch (e->kind) {
1898
1.07k
    case UnaryOp_kind:
1899
1.07k
        if (e->v.UnaryOp.op == Not) {
1900
1.07k
            return codegen_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond);
1901
1.07k
        }
1902
        /* fallback to general implementation */
1903
0
        break;
1904
986
    case BoolOp_kind: {
1905
986
        asdl_expr_seq *s = e->v.BoolOp.values;
1906
986
        Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
1907
986
        assert(n >= 0);
1908
986
        int cond2 = e->v.BoolOp.op == Or;
1909
986
        jump_target_label next2 = next;
1910
986
        if (!cond2 != !cond) {
1911
314
            NEW_JUMP_TARGET_LABEL(c, new_next2);
1912
314
            next2 = new_next2;
1913
314
        }
1914
2.14k
        for (i = 0; i < n; ++i) {
1915
1.15k
            RETURN_IF_ERROR(
1916
1.15k
                codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2));
1917
1.15k
        }
1918
986
        RETURN_IF_ERROR(
1919
986
            codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond));
1920
986
        if (!SAME_JUMP_TARGET_LABEL(next2, next)) {
1921
314
            USE_LABEL(c, next2);
1922
314
        }
1923
986
        return SUCCESS;
1924
986
    }
1925
0
    case IfExp_kind: {
1926
0
        NEW_JUMP_TARGET_LABEL(c, end);
1927
0
        NEW_JUMP_TARGET_LABEL(c, next2);
1928
0
        RETURN_IF_ERROR(
1929
0
            codegen_jump_if(c, loc, e->v.IfExp.test, next2, 0));
1930
0
        RETURN_IF_ERROR(
1931
0
            codegen_jump_if(c, loc, e->v.IfExp.body, next, cond));
1932
0
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1933
1934
0
        USE_LABEL(c, next2);
1935
0
        RETURN_IF_ERROR(
1936
0
            codegen_jump_if(c, loc, e->v.IfExp.orelse, next, cond));
1937
1938
0
        USE_LABEL(c, end);
1939
0
        return SUCCESS;
1940
0
    }
1941
4.67k
    case Compare_kind: {
1942
4.67k
        Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1;
1943
4.67k
        if (n > 0) {
1944
44
            RETURN_IF_ERROR(codegen_check_compare(c, e));
1945
44
            NEW_JUMP_TARGET_LABEL(c, cleanup);
1946
44
            VISIT(c, expr, e->v.Compare.left);
1947
88
            for (Py_ssize_t i = 0; i < n; i++) {
1948
44
                VISIT(c, expr,
1949
44
                    (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
1950
44
                ADDOP_I(c, LOC(e), SWAP, 2);
1951
44
                ADDOP_I(c, LOC(e), COPY, 2);
1952
44
                ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i));
1953
44
                ADDOP(c, LOC(e), TO_BOOL);
1954
44
                ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup);
1955
44
            }
1956
44
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
1957
44
            ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n));
1958
44
            ADDOP(c, LOC(e), TO_BOOL);
1959
44
            ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
1960
44
            NEW_JUMP_TARGET_LABEL(c, end);
1961
44
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1962
1963
44
            USE_LABEL(c, cleanup);
1964
44
            ADDOP(c, LOC(e), POP_TOP);
1965
44
            if (!cond) {
1966
21
                ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, next);
1967
21
            }
1968
1969
44
            USE_LABEL(c, end);
1970
44
            return SUCCESS;
1971
44
        }
1972
        /* fallback to general implementation */
1973
4.62k
        break;
1974
4.67k
    }
1975
4.62k
    default:
1976
        /* fallback to general implementation */
1977
3.52k
        break;
1978
10.2k
    }
1979
1980
    /* general implementation */
1981
8.15k
    VISIT(c, expr, e);
1982
8.15k
    ADDOP(c, LOC(e), TO_BOOL);
1983
8.15k
    ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
1984
8.15k
    return SUCCESS;
1985
8.15k
}
1986
1987
static int
1988
codegen_ifexp(compiler *c, expr_ty e)
1989
148
{
1990
148
    assert(e->kind == IfExp_kind);
1991
148
    NEW_JUMP_TARGET_LABEL(c, end);
1992
148
    NEW_JUMP_TARGET_LABEL(c, next);
1993
1994
148
    RETURN_IF_ERROR(
1995
148
        codegen_jump_if(c, LOC(e), e->v.IfExp.test, next, 0));
1996
1997
148
    VISIT(c, expr, e->v.IfExp.body);
1998
148
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1999
2000
148
    USE_LABEL(c, next);
2001
148
    VISIT(c, expr, e->v.IfExp.orelse);
2002
2003
148
    USE_LABEL(c, end);
2004
148
    return SUCCESS;
2005
148
}
2006
2007
static int
2008
codegen_lambda(compiler *c, expr_ty e)
2009
121
{
2010
121
    PyCodeObject *co;
2011
121
    Py_ssize_t funcflags;
2012
121
    arguments_ty args = e->v.Lambda.args;
2013
121
    assert(e->kind == Lambda_kind);
2014
2015
121
    location loc = LOC(e);
2016
121
    funcflags = codegen_default_arguments(c, loc, args);
2017
121
    RETURN_IF_ERROR(funcflags);
2018
2019
121
    _PyCompile_CodeUnitMetadata umd = {
2020
121
        .u_argcount = asdl_seq_LEN(args->args),
2021
121
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
2022
121
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
2023
121
    };
2024
121
    _Py_DECLARE_STR(anon_lambda, "<lambda>");
2025
121
    RETURN_IF_ERROR(
2026
121
        codegen_enter_scope(c, &_Py_STR(anon_lambda), COMPILE_SCOPE_LAMBDA,
2027
121
                            (void *)e, e->lineno, NULL, &umd));
2028
2029
121
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
2030
2031
121
    VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
2032
121
    if (SYMTABLE_ENTRY(c)->ste_generator) {
2033
0
        co = _PyCompile_OptimizeAndAssemble(c, 0);
2034
0
    }
2035
121
    else {
2036
121
        location loc = LOC(e->v.Lambda.body);
2037
121
        ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
2038
121
        co = _PyCompile_OptimizeAndAssemble(c, 1);
2039
121
    }
2040
121
    _PyCompile_ExitScope(c);
2041
121
    if (co == NULL) {
2042
0
        return ERROR;
2043
0
    }
2044
2045
121
    int ret = codegen_make_closure(c, loc, co, funcflags);
2046
121
    Py_DECREF(co);
2047
121
    RETURN_IF_ERROR(ret);
2048
121
    return SUCCESS;
2049
121
}
2050
2051
static int
2052
codegen_if(compiler *c, stmt_ty s)
2053
6.46k
{
2054
6.46k
    jump_target_label next;
2055
6.46k
    assert(s->kind == If_kind);
2056
6.46k
    NEW_JUMP_TARGET_LABEL(c, end);
2057
6.46k
    if (asdl_seq_LEN(s->v.If.orelse)) {
2058
1.96k
        NEW_JUMP_TARGET_LABEL(c, orelse);
2059
1.96k
        next = orelse;
2060
1.96k
    }
2061
4.50k
    else {
2062
4.50k
        next = end;
2063
4.50k
    }
2064
6.46k
    RETURN_IF_ERROR(
2065
6.46k
        codegen_jump_if(c, LOC(s), s->v.If.test, next, 0));
2066
2067
6.46k
    VISIT_SEQ(c, stmt, s->v.If.body);
2068
6.46k
    if (asdl_seq_LEN(s->v.If.orelse)) {
2069
1.96k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2070
2071
1.96k
        USE_LABEL(c, next);
2072
1.96k
        VISIT_SEQ(c, stmt, s->v.If.orelse);
2073
1.96k
    }
2074
2075
6.46k
    USE_LABEL(c, end);
2076
6.46k
    return SUCCESS;
2077
6.46k
}
2078
2079
static int
2080
codegen_for(compiler *c, stmt_ty s)
2081
848
{
2082
848
    location loc = LOC(s);
2083
848
    NEW_JUMP_TARGET_LABEL(c, start);
2084
848
    NEW_JUMP_TARGET_LABEL(c, body);
2085
848
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2086
848
    NEW_JUMP_TARGET_LABEL(c, end);
2087
2088
848
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FOR_LOOP, start, end, NULL));
2089
2090
848
    VISIT(c, expr, s->v.For.iter);
2091
2092
848
    loc = LOC(s->v.For.iter);
2093
848
    ADDOP(c, loc, GET_ITER);
2094
2095
848
    USE_LABEL(c, start);
2096
848
    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
848
    ADDOP(c, LOC(s->v.For.target), NOP);
2102
2103
848
    USE_LABEL(c, body);
2104
848
    VISIT(c, expr, s->v.For.target);
2105
848
    VISIT_SEQ(c, stmt, s->v.For.body);
2106
    /* Mark jump as artificial */
2107
848
    ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
2108
2109
848
    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
848
    ADDOP(c, NO_LOCATION, END_FOR);
2115
848
    ADDOP(c, NO_LOCATION, POP_ITER);
2116
2117
848
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FOR_LOOP, start);
2118
2119
848
    VISIT_SEQ(c, stmt, s->v.For.orelse);
2120
2121
848
    USE_LABEL(c, end);
2122
848
    return SUCCESS;
2123
848
}
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
260
{
2176
260
    NEW_JUMP_TARGET_LABEL(c, loop);
2177
260
    NEW_JUMP_TARGET_LABEL(c, end);
2178
260
    NEW_JUMP_TARGET_LABEL(c, anchor);
2179
2180
260
    USE_LABEL(c, loop);
2181
2182
260
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, LOC(s), COMPILE_FBLOCK_WHILE_LOOP, loop, end, NULL));
2183
260
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.While.test, anchor, 0));
2184
2185
260
    VISIT_SEQ(c, stmt, s->v.While.body);
2186
260
    ADDOP_JUMP(c, NO_LOCATION, JUMP, loop);
2187
2188
260
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_WHILE_LOOP, loop);
2189
2190
260
    USE_LABEL(c, anchor);
2191
260
    if (s->v.While.orelse) {
2192
3
        VISIT_SEQ(c, stmt, s->v.While.orelse);
2193
3
    }
2194
2195
260
    USE_LABEL(c, end);
2196
260
    return SUCCESS;
2197
260
}
2198
2199
static int
2200
codegen_return(compiler *c, stmt_ty s)
2201
4.53k
{
2202
4.53k
    location loc = LOC(s);
2203
4.53k
    int preserve_tos = ((s->v.Return.value != NULL) &&
2204
4.53k
                        (s->v.Return.value->kind != Constant_kind));
2205
2206
4.53k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
2207
4.53k
    if (!_PyST_IsFunctionLike(ste)) {
2208
0
        return _PyCompile_Error(c, loc, "'return' outside function");
2209
0
    }
2210
4.53k
    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
4.53k
    if (preserve_tos) {
2215
4.00k
        VISIT(c, expr, s->v.Return.value);
2216
4.00k
    } else {
2217
        /* Emit instruction with line number for return value */
2218
525
        if (s->v.Return.value != NULL) {
2219
390
            loc = LOC(s->v.Return.value);
2220
390
            ADDOP(c, loc, NOP);
2221
390
        }
2222
525
    }
2223
4.53k
    if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
2224
155
        loc = LOC(s);
2225
155
        ADDOP(c, loc, NOP);
2226
155
    }
2227
2228
4.53k
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, preserve_tos, NULL));
2229
4.53k
    if (s->v.Return.value == NULL) {
2230
135
        ADDOP_LOAD_CONST(c, loc, Py_None);
2231
135
    }
2232
4.39k
    else if (!preserve_tos) {
2233
390
        ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value);
2234
390
    }
2235
4.53k
    ADDOP(c, loc, RETURN_VALUE);
2236
2237
4.53k
    return SUCCESS;
2238
4.53k
}
2239
2240
static int
2241
codegen_break(compiler *c, location loc)
2242
237
{
2243
237
    fblockinfo *loop = NULL;
2244
237
    location origin_loc = loc;
2245
    /* Emit instruction with line number */
2246
237
    ADDOP(c, loc, NOP);
2247
237
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2248
237
    if (loop == NULL) {
2249
0
        return _PyCompile_Error(c, origin_loc, "'break' outside loop");
2250
0
    }
2251
237
    RETURN_IF_ERROR(codegen_unwind_fblock(c, &loc, loop, 0));
2252
237
    ADDOP_JUMP(c, loc, JUMP, loop->fb_exit);
2253
237
    return SUCCESS;
2254
237
}
2255
2256
static int
2257
codegen_continue(compiler *c, location loc)
2258
208
{
2259
208
    fblockinfo *loop = NULL;
2260
208
    location origin_loc = loc;
2261
    /* Emit instruction with line number */
2262
208
    ADDOP(c, loc, NOP);
2263
208
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2264
208
    if (loop == NULL) {
2265
0
        return _PyCompile_Error(c, origin_loc, "'continue' not properly in loop");
2266
0
    }
2267
208
    ADDOP_JUMP(c, loc, JUMP, loop->fb_block);
2268
208
    return SUCCESS;
2269
208
}
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
49
{
2304
49
    location loc = LOC(s);
2305
2306
49
    NEW_JUMP_TARGET_LABEL(c, body);
2307
49
    NEW_JUMP_TARGET_LABEL(c, end);
2308
49
    NEW_JUMP_TARGET_LABEL(c, exit);
2309
49
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2310
2311
    /* `try` block */
2312
49
    ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
2313
2314
49
    USE_LABEL(c, body);
2315
49
    RETURN_IF_ERROR(
2316
49
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_TRY, body, end,
2317
49
                              s->v.Try.finalbody));
2318
2319
49
    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
49
    else {
2323
49
        VISIT_SEQ(c, stmt, s->v.Try.body);
2324
49
    }
2325
49
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2326
49
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_TRY, body);
2327
49
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2328
2329
49
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
2330
    /* `finally` block */
2331
2332
49
    USE_LABEL(c, end);
2333
2334
49
    loc = NO_LOCATION;
2335
49
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
2336
49
    ADDOP(c, loc, PUSH_EXC_INFO);
2337
49
    RETURN_IF_ERROR(
2338
49
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_END, end, NO_LABEL, NULL));
2339
49
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2340
49
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_END, end);
2341
2342
49
    loc = NO_LOCATION;
2343
49
    ADDOP_I(c, loc, RERAISE, 0);
2344
2345
49
    USE_LABEL(c, cleanup);
2346
49
    POP_EXCEPT_AND_RERAISE(c, loc);
2347
2348
49
    USE_LABEL(c, exit);
2349
49
    return SUCCESS;
2350
49
}
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
687
{
2435
687
    location loc = LOC(s);
2436
687
    Py_ssize_t i, n;
2437
2438
687
    NEW_JUMP_TARGET_LABEL(c, body);
2439
687
    NEW_JUMP_TARGET_LABEL(c, except);
2440
687
    NEW_JUMP_TARGET_LABEL(c, end);
2441
687
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2442
2443
687
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2444
2445
687
    USE_LABEL(c, body);
2446
687
    RETURN_IF_ERROR(
2447
687
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_TRY_EXCEPT, body, NO_LABEL, NULL));
2448
687
    VISIT_SEQ(c, stmt, s->v.Try.body);
2449
687
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_TRY_EXCEPT, body);
2450
687
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2451
687
    if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
2452
61
        VISIT_SEQ(c, stmt, s->v.Try.orelse);
2453
61
    }
2454
687
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2455
687
    n = asdl_seq_LEN(s->v.Try.handlers);
2456
2457
687
    USE_LABEL(c, except);
2458
2459
687
    ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
2460
687
    ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
2461
2462
    /* Runtime will push a block here, so we need to account for that */
2463
687
    RETURN_IF_ERROR(
2464
687
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_EXCEPTION_HANDLER,
2465
687
                              NO_LABEL, NO_LABEL, NULL));
2466
2467
1.40k
    for (i = 0; i < n; i++) {
2468
720
        excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
2469
720
            s->v.Try.handlers, i);
2470
720
        location loc = LOC(handler);
2471
720
        if (!handler->v.ExceptHandler.type && i < n-1) {
2472
0
            return _PyCompile_Error(c, loc, "default 'except:' must be last");
2473
0
        }
2474
720
        NEW_JUMP_TARGET_LABEL(c, next_except);
2475
720
        except = next_except;
2476
720
        if (handler->v.ExceptHandler.type) {
2477
699
            VISIT(c, expr, handler->v.ExceptHandler.type);
2478
699
            ADDOP(c, loc, CHECK_EXC_MATCH);
2479
699
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
2480
699
        }
2481
720
        if (handler->v.ExceptHandler.name) {
2482
116
            NEW_JUMP_TARGET_LABEL(c, cleanup_end);
2483
116
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2484
2485
116
            RETURN_IF_ERROR(
2486
116
                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
116
            ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
2501
2502
116
            USE_LABEL(c, cleanup_body);
2503
116
            RETURN_IF_ERROR(
2504
116
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2505
116
                                      NO_LABEL, handler->v.ExceptHandler.name));
2506
2507
            /* second # body */
2508
116
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2509
116
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2510
            /* name = None; del name; # Mark as artificial */
2511
116
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2512
116
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2513
116
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2514
116
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2515
116
            RETURN_IF_ERROR(
2516
116
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2517
116
            RETURN_IF_ERROR(
2518
116
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2519
116
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2520
2521
            /* except: */
2522
116
            USE_LABEL(c, cleanup_end);
2523
2524
            /* name = None; del name; # artificial */
2525
116
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2526
116
            RETURN_IF_ERROR(
2527
116
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2528
116
            RETURN_IF_ERROR(
2529
116
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2530
2531
116
            ADDOP_I(c, NO_LOCATION, RERAISE, 1);
2532
116
        }
2533
604
        else {
2534
604
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2535
2536
604
            ADDOP(c, loc, POP_TOP); /* exc_value */
2537
2538
604
            USE_LABEL(c, cleanup_body);
2539
604
            RETURN_IF_ERROR(
2540
604
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2541
604
                                      NO_LABEL, NULL));
2542
2543
604
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2544
604
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2545
604
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2546
604
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2547
604
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2548
604
        }
2549
2550
720
        USE_LABEL(c, except);
2551
720
    }
2552
    /* artificial */
2553
687
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_EXCEPTION_HANDLER, NO_LABEL);
2554
687
    ADDOP_I(c, NO_LOCATION, RERAISE, 0);
2555
2556
687
    USE_LABEL(c, cleanup);
2557
687
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
2558
2559
687
    USE_LABEL(c, end);
2560
687
    return SUCCESS;
2561
687
}
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
736
codegen_try(compiler *c, stmt_ty s) {
2784
736
    if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
2785
49
        return codegen_try_finally(c, s);
2786
687
    else
2787
687
        return codegen_try_except(c, s);
2788
736
}
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
42
{
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
42
    Py_ssize_t len = PyUnicode_GET_LENGTH(name);
2812
42
    Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
2813
42
    if (dot == -2) {
2814
0
        return ERROR;
2815
0
    }
2816
42
    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
42
    return codegen_nameop(c, loc, asname, Store);
2841
42
}
2842
2843
static int
2844
codegen_import(compiler *c, stmt_ty s)
2845
489
{
2846
489
    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
489
    Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
2855
2856
489
    PyObject *zero = _PyLong_GetZero();  // borrowed reference
2857
1.01k
    for (i = 0; i < n; i++) {
2858
522
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
2859
522
        int r;
2860
2861
522
        ADDOP_LOAD_CONST(c, loc, zero);
2862
522
        ADDOP_LOAD_CONST(c, loc, Py_None);
2863
522
        ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names);
2864
2865
522
        if (alias->asname) {
2866
42
            r = codegen_import_as(c, loc, alias->name, alias->asname);
2867
42
            RETURN_IF_ERROR(r);
2868
42
        }
2869
480
        else {
2870
480
            identifier tmp = alias->name;
2871
480
            Py_ssize_t dot = PyUnicode_FindChar(
2872
480
                alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
2873
480
            if (dot != -1) {
2874
25
                tmp = PyUnicode_Substring(alias->name, 0, dot);
2875
25
                if (tmp == NULL) {
2876
0
                    return ERROR;
2877
0
                }
2878
25
            }
2879
480
            r = codegen_nameop(c, loc, tmp, Store);
2880
480
            if (dot != -1) {
2881
25
                Py_DECREF(tmp);
2882
25
            }
2883
480
            RETURN_IF_ERROR(r);
2884
480
        }
2885
522
    }
2886
489
    return SUCCESS;
2887
489
}
2888
2889
static int
2890
codegen_from_import(compiler *c, stmt_ty s)
2891
296
{
2892
296
    Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names);
2893
2894
296
    ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level));
2895
2896
296
    PyObject *names = PyTuple_New(n);
2897
296
    if (!names) {
2898
0
        return ERROR;
2899
0
    }
2900
2901
    /* build up the names */
2902
833
    for (Py_ssize_t i = 0; i < n; i++) {
2903
537
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
2904
537
        PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name));
2905
537
    }
2906
2907
296
    ADDOP_LOAD_CONST_NEW(c, LOC(s), names);
2908
2909
296
    if (s->v.ImportFrom.module) {
2910
290
        ADDOP_NAME(c, LOC(s), IMPORT_NAME, s->v.ImportFrom.module, names);
2911
290
    }
2912
6
    else {
2913
6
        _Py_DECLARE_STR(empty, "");
2914
6
        ADDOP_NAME(c, LOC(s), IMPORT_NAME, &_Py_STR(empty), names);
2915
6
    }
2916
816
    for (Py_ssize_t i = 0; i < n; i++) {
2917
537
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
2918
537
        identifier store_name;
2919
2920
537
        if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
2921
17
            assert(n == 1);
2922
17
            ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
2923
17
            ADDOP(c, NO_LOCATION, POP_TOP);
2924
17
            return SUCCESS;
2925
17
        }
2926
2927
520
        ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names);
2928
520
        store_name = alias->name;
2929
520
        if (alias->asname) {
2930
71
            store_name = alias->asname;
2931
71
        }
2932
2933
520
        RETURN_IF_ERROR(codegen_nameop(c, LOC(s), store_name, Store));
2934
520
    }
2935
    /* remove imported module */
2936
279
    ADDOP(c, LOC(s), POP_TOP);
2937
279
    return SUCCESS;
2938
279
}
2939
2940
static int
2941
codegen_assert(compiler *c, stmt_ty s)
2942
108
{
2943
    /* Always emit a warning if the test is a non-zero length tuple */
2944
108
    if ((s->v.Assert.test->kind == Tuple_kind &&
2945
108
        asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
2946
108
        (s->v.Assert.test->kind == Constant_kind &&
2947
108
         PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
2948
108
         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
108
    if (OPTIMIZATION_LEVEL(c)) {
2955
0
        return SUCCESS;
2956
0
    }
2957
108
    NEW_JUMP_TARGET_LABEL(c, end);
2958
108
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.Assert.test, end, 1));
2959
108
    ADDOP_I(c, LOC(s), LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR);
2960
108
    if (s->v.Assert.msg) {
2961
26
        VISIT(c, expr, s->v.Assert.msg);
2962
26
        ADDOP_I(c, LOC(s), CALL, 0);
2963
26
    }
2964
108
    ADDOP_I(c, LOC(s->v.Assert.test), RAISE_VARARGS, 1);
2965
2966
108
    USE_LABEL(c, end);
2967
108
    return SUCCESS;
2968
108
}
2969
2970
static int
2971
codegen_stmt_expr(compiler *c, location loc, expr_ty value)
2972
3.68k
{
2973
3.68k
    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
3.68k
    if (value->kind == Constant_kind) {
2981
        /* ignore constant statement */
2982
2
        ADDOP(c, loc, NOP);
2983
2
        return SUCCESS;
2984
2
    }
2985
2986
3.68k
    VISIT(c, expr, value);
2987
3.68k
    ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */
2988
3.68k
    return SUCCESS;
2989
3.68k
}
2990
2991
#define CODEGEN_COND_BLOCK(FUNC, C, S) \
2992
8.40k
    do { \
2993
8.40k
        _PyCompile_EnterConditionalBlock((C)); \
2994
8.40k
        int result = FUNC((C), (S)); \
2995
8.40k
        _PyCompile_LeaveConditionalBlock((C)); \
2996
8.40k
        return result; \
2997
8.40k
    } while(0)
2998
2999
static int
3000
codegen_visit_stmt(compiler *c, stmt_ty s)
3001
37.2k
{
3002
3003
37.2k
    switch (s->kind) {
3004
4.11k
    case FunctionDef_kind:
3005
4.11k
        return codegen_function(c, s, 0);
3006
1.02k
    case ClassDef_kind:
3007
1.02k
        return codegen_class(c, s);
3008
0
    case TypeAlias_kind:
3009
0
        return codegen_typealias(c, s);
3010
4.53k
    case Return_kind:
3011
4.53k
        return codegen_return(c, s);
3012
101
    case Delete_kind:
3013
101
        VISIT_SEQ(c, expr, s->v.Delete.targets);
3014
101
        break;
3015
11.4k
    case Assign_kind:
3016
11.4k
    {
3017
11.4k
        Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets);
3018
11.4k
        VISIT(c, expr, s->v.Assign.value);
3019
23.1k
        for (Py_ssize_t i = 0; i < n; i++) {
3020
11.6k
            if (i < n - 1) {
3021
155
                ADDOP_I(c, LOC(s), COPY, 1);
3022
155
            }
3023
11.6k
            VISIT(c, expr,
3024
11.6k
                  (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
3025
11.6k
        }
3026
11.4k
        break;
3027
11.4k
    }
3028
11.4k
    case AugAssign_kind:
3029
577
        return codegen_augassign(c, s);
3030
0
    case AnnAssign_kind:
3031
0
        return codegen_annassign(c, s);
3032
848
    case For_kind:
3033
848
        CODEGEN_COND_BLOCK(codegen_for, c, s);
3034
0
        break;
3035
260
    case While_kind:
3036
260
        CODEGEN_COND_BLOCK(codegen_while, c, s);
3037
0
        break;
3038
6.46k
    case If_kind:
3039
6.46k
        CODEGEN_COND_BLOCK(codegen_if, c, s);
3040
0
        break;
3041
0
    case Match_kind:
3042
0
        CODEGEN_COND_BLOCK(codegen_match, c, s);
3043
0
        break;
3044
1.46k
    case Raise_kind:
3045
1.46k
    {
3046
1.46k
        Py_ssize_t n = 0;
3047
1.46k
        if (s->v.Raise.exc) {
3048
1.40k
            VISIT(c, expr, s->v.Raise.exc);
3049
1.40k
            n++;
3050
1.40k
            if (s->v.Raise.cause) {
3051
108
                VISIT(c, expr, s->v.Raise.cause);
3052
108
                n++;
3053
108
            }
3054
1.40k
        }
3055
1.46k
        ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n);
3056
1.46k
        break;
3057
1.46k
    }
3058
1.46k
    case Try_kind:
3059
736
        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
108
    case Assert_kind:
3065
108
        return codegen_assert(c, s);
3066
489
    case Import_kind:
3067
489
        return codegen_import(c, s);
3068
296
    case ImportFrom_kind:
3069
296
        return codegen_from_import(c, s);
3070
33
    case Global_kind:
3071
62
    case Nonlocal_kind:
3072
62
        break;
3073
3.68k
    case Expr_kind:
3074
3.68k
    {
3075
3.68k
        return codegen_stmt_expr(c, LOC(s), s->v.Expr.value);
3076
33
    }
3077
391
    case Pass_kind:
3078
391
    {
3079
391
        ADDOP(c, LOC(s), NOP);
3080
391
        break;
3081
391
    }
3082
391
    case Break_kind:
3083
237
    {
3084
237
        return codegen_break(c, LOC(s));
3085
391
    }
3086
208
    case Continue_kind:
3087
208
    {
3088
208
        return codegen_continue(c, LOC(s));
3089
391
    }
3090
93
    case With_kind:
3091
93
        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
37.2k
    }
3102
3103
13.5k
    return SUCCESS;
3104
37.2k
}
3105
3106
static int
3107
unaryop(unaryop_ty op)
3108
552
{
3109
552
    switch (op) {
3110
39
    case Invert:
3111
39
        return UNARY_INVERT;
3112
513
    case USub:
3113
513
        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
552
    }
3119
552
}
3120
3121
static int
3122
addop_binary(compiler *c, location loc, operator_ty binop,
3123
             bool inplace)
3124
3.76k
{
3125
3.76k
    int oparg;
3126
3.76k
    switch (binop) {
3127
1.81k
        case Add:
3128
1.81k
            oparg = inplace ? NB_INPLACE_ADD : NB_ADD;
3129
1.81k
            break;
3130
554
        case Sub:
3131
554
            oparg = inplace ? NB_INPLACE_SUBTRACT : NB_SUBTRACT;
3132
554
            break;
3133
217
        case Mult:
3134
217
            oparg = inplace ? NB_INPLACE_MULTIPLY : NB_MULTIPLY;
3135
217
            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
504
        case Mod:
3143
504
            oparg = inplace ? NB_INPLACE_REMAINDER : NB_REMAINDER;
3144
504
            break;
3145
43
        case Pow:
3146
43
            oparg = inplace ? NB_INPLACE_POWER : NB_POWER;
3147
43
            break;
3148
37
        case LShift:
3149
37
            oparg = inplace ? NB_INPLACE_LSHIFT : NB_LSHIFT;
3150
37
            break;
3151
45
        case RShift:
3152
45
            oparg = inplace ? NB_INPLACE_RSHIFT : NB_RSHIFT;
3153
45
            break;
3154
148
        case BitOr:
3155
148
            oparg = inplace ? NB_INPLACE_OR : NB_OR;
3156
148
            break;
3157
28
        case BitXor:
3158
28
            oparg = inplace ? NB_INPLACE_XOR : NB_XOR;
3159
28
            break;
3160
263
        case BitAnd:
3161
263
            oparg = inplace ? NB_INPLACE_AND : NB_AND;
3162
263
            break;
3163
74
        case FloorDiv:
3164
74
            oparg = inplace ? NB_INPLACE_FLOOR_DIVIDE : NB_FLOOR_DIVIDE;
3165
74
            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
3.76k
    }
3171
3.76k
    ADDOP_I(c, loc, BINARY_OP, oparg);
3172
3.76k
    return SUCCESS;
3173
3.76k
}
3174
3175
3176
static int
3177
379
codegen_addop_yield(compiler *c, location loc) {
3178
379
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
3179
379
    if (ste->ste_generator && ste->ste_coroutine) {
3180
1
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
3181
1
    }
3182
379
    ADDOP_I(c, loc, YIELD_VALUE, 0);
3183
379
    ADDOP_I(c, loc, RESUME, RESUME_AFTER_YIELD);
3184
379
    return SUCCESS;
3185
379
}
3186
3187
static int
3188
codegen_load_classdict_freevar(compiler *c, location loc)
3189
4
{
3190
4
    ADDOP_N(c, loc, LOAD_DEREF, &_Py_ID(__classdict__), freevars);
3191
4
    return SUCCESS;
3192
4
}
3193
3194
static int
3195
codegen_nameop(compiler *c, location loc,
3196
               identifier name, expr_context_ty ctx)
3197
84.5k
{
3198
84.5k
    assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
3199
84.5k
           !_PyUnicode_EqualToASCIIString(name, "True") &&
3200
84.5k
           !_PyUnicode_EqualToASCIIString(name, "False"));
3201
3202
84.5k
    PyObject *mangled = _PyCompile_MaybeMangle(c, name);
3203
84.5k
    if (!mangled) {
3204
0
        return ERROR;
3205
0
    }
3206
3207
84.5k
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), mangled);
3208
84.5k
    RETURN_IF_ERROR(scope);
3209
84.5k
    _PyCompile_optype optype;
3210
84.5k
    Py_ssize_t arg = 0;
3211
84.5k
    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
84.5k
    assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
3218
3219
84.5k
    int op = 0;
3220
84.5k
    switch (optype) {
3221
1.99k
    case COMPILE_OP_DEREF:
3222
1.99k
        switch (ctx) {
3223
1.69k
        case Load:
3224
1.69k
            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.69k
            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.69k
            else {
3239
1.69k
                op = LOAD_DEREF;
3240
1.69k
            }
3241
1.69k
            break;
3242
1.69k
        case Store: op = STORE_DEREF; break;
3243
0
        case Del: op = DELETE_DEREF; break;
3244
1.99k
        }
3245
1.99k
        break;
3246
50.5k
    case COMPILE_OP_FAST:
3247
50.5k
        switch (ctx) {
3248
39.3k
        case Load: op = LOAD_FAST; break;
3249
10.8k
        case Store: op = STORE_FAST; break;
3250
252
        case Del: op = DELETE_FAST; break;
3251
50.5k
        }
3252
50.5k
        ADDOP_N(c, loc, op, mangled, varnames);
3253
50.5k
        return SUCCESS;
3254
13.3k
    case COMPILE_OP_GLOBAL:
3255
13.3k
        switch (ctx) {
3256
13.3k
        case Load:
3257
13.3k
            if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) {
3258
4
                op = LOAD_FROM_DICT_OR_GLOBALS;
3259
                // First load the classdict
3260
4
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3261
0
                    goto error;
3262
0
                }
3263
13.3k
            } else {
3264
13.3k
                op = LOAD_GLOBAL;
3265
13.3k
            }
3266
13.3k
            break;
3267
13.3k
        case Store: op = STORE_GLOBAL; break;
3268
0
        case Del: op = DELETE_GLOBAL; break;
3269
13.3k
        }
3270
13.3k
        break;
3271
18.6k
    case COMPILE_OP_NAME:
3272
18.6k
        switch (ctx) {
3273
5.49k
        case Load:
3274
5.49k
            op = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock
3275
5.49k
                    && _PyCompile_IsInInlinedComp(c))
3276
5.49k
                ? LOAD_GLOBAL
3277
5.49k
                : LOAD_NAME;
3278
5.49k
            break;
3279
13.1k
        case Store: op = STORE_NAME; break;
3280
35
        case Del: op = DELETE_NAME; break;
3281
18.6k
        }
3282
18.6k
        break;
3283
84.5k
    }
3284
3285
34.0k
    assert(op);
3286
34.0k
    Py_DECREF(mangled);
3287
34.0k
    if (op == LOAD_GLOBAL) {
3288
13.3k
        arg <<= 1;
3289
13.3k
    }
3290
34.0k
    ADDOP_I(c, loc, op, arg);
3291
34.0k
    return SUCCESS;
3292
3293
0
error:
3294
0
    Py_DECREF(mangled);
3295
0
    return ERROR;
3296
34.0k
}
3297
3298
static int
3299
codegen_boolop(compiler *c, expr_ty e)
3300
369
{
3301
369
    int jumpi;
3302
369
    Py_ssize_t i, n;
3303
369
    asdl_expr_seq *s;
3304
3305
369
    location loc = LOC(e);
3306
369
    assert(e->kind == BoolOp_kind);
3307
369
    if (e->v.BoolOp.op == And)
3308
156
        jumpi = JUMP_IF_FALSE;
3309
213
    else
3310
213
        jumpi = JUMP_IF_TRUE;
3311
369
    NEW_JUMP_TARGET_LABEL(c, end);
3312
369
    s = e->v.BoolOp.values;
3313
369
    n = asdl_seq_LEN(s) - 1;
3314
369
    assert(n >= 0);
3315
767
    for (i = 0; i < n; ++i) {
3316
398
        VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
3317
398
        ADDOP_JUMP(c, loc, jumpi, end);
3318
398
        ADDOP(c, loc, POP_TOP);
3319
398
    }
3320
369
    VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
3321
3322
369
    USE_LABEL(c, end);
3323
369
    return SUCCESS;
3324
369
}
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
2.82k
{
3331
2.82k
    Py_ssize_t n = asdl_seq_LEN(elts);
3332
2.82k
    int big = n + pushed + (injected_arg ? 1 : 0) > _PY_STACK_USE_GUIDELINE;
3333
2.82k
    int seen_star = 0;
3334
9.36k
    for (Py_ssize_t i = 0; i < n; i++) {
3335
6.61k
        expr_ty elt = asdl_seq_GET(elts, i);
3336
6.61k
        if (elt->kind == Starred_kind) {
3337
67
            seen_star = 1;
3338
67
            break;
3339
67
        }
3340
6.61k
    }
3341
2.82k
    if (!seen_star && !big) {
3342
8.81k
        for (Py_ssize_t i = 0; i < n; i++) {
3343
6.06k
            expr_ty elt = asdl_seq_GET(elts, i);
3344
6.06k
            VISIT(c, expr, elt);
3345
6.06k
        }
3346
2.74k
        if (injected_arg) {
3347
0
            RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
3348
0
            n++;
3349
0
        }
3350
2.74k
        if (tuple) {
3351
1.92k
            ADDOP_I(c, loc, BUILD_TUPLE, n+pushed);
3352
1.92k
        } else {
3353
816
            ADDOP_I(c, loc, build, n+pushed);
3354
816
        }
3355
2.74k
        return SUCCESS;
3356
2.74k
    }
3357
75
    int sequence_built = 0;
3358
75
    if (big) {
3359
8
        ADDOP_I(c, loc, build, pushed);
3360
8
        sequence_built = 1;
3361
8
    }
3362
628
    for (Py_ssize_t i = 0; i < n; i++) {
3363
553
        expr_ty elt = asdl_seq_GET(elts, i);
3364
553
        if (elt->kind == Starred_kind) {
3365
74
            if (sequence_built == 0) {
3366
67
                ADDOP_I(c, loc, build, i+pushed);
3367
67
                sequence_built = 1;
3368
67
            }
3369
74
            VISIT(c, expr, elt->v.Starred.value);
3370
74
            ADDOP_I(c, loc, extend, 1);
3371
74
        }
3372
479
        else {
3373
479
            VISIT(c, expr, elt);
3374
479
            if (sequence_built) {
3375
408
                ADDOP_I(c, loc, add, 1);
3376
408
            }
3377
479
        }
3378
553
    }
3379
75
    assert(sequence_built);
3380
75
    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
75
    if (tuple) {
3385
69
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
3386
69
    }
3387
75
    return SUCCESS;
3388
75
}
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
2.72k
{
3395
2.72k
    return starunpack_helper_impl(c, loc, elts, NULL, pushed,
3396
2.72k
                                  build, add, extend, tuple);
3397
2.72k
}
3398
3399
static int
3400
unpack_helper(compiler *c, location loc, asdl_expr_seq *elts)
3401
1.00k
{
3402
1.00k
    Py_ssize_t n = asdl_seq_LEN(elts);
3403
1.00k
    int seen_star = 0;
3404
3.39k
    for (Py_ssize_t i = 0; i < n; i++) {
3405
2.38k
        expr_ty elt = asdl_seq_GET(elts, i);
3406
2.38k
        if (elt->kind == Starred_kind && !seen_star) {
3407
14
            if ((i >= (1 << 8)) ||
3408
14
                (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
14
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
3414
14
            seen_star = 1;
3415
14
        }
3416
2.36k
        else if (elt->kind == Starred_kind) {
3417
0
            return _PyCompile_Error(c, loc,
3418
0
                "multiple starred expressions in assignment");
3419
0
        }
3420
2.38k
    }
3421
1.00k
    if (!seen_star) {
3422
995
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
3423
995
    }
3424
1.00k
    return SUCCESS;
3425
1.00k
}
3426
3427
static int
3428
assignment_helper(compiler *c, location loc, asdl_expr_seq *elts)
3429
1.00k
{
3430
1.00k
    Py_ssize_t n = asdl_seq_LEN(elts);
3431
1.00k
    RETURN_IF_ERROR(unpack_helper(c, loc, elts));
3432
3.39k
    for (Py_ssize_t i = 0; i < n; i++) {
3433
2.38k
        expr_ty elt = asdl_seq_GET(elts, i);
3434
2.38k
        VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
3435
2.38k
    }
3436
1.00k
    return SUCCESS;
3437
1.00k
}
3438
3439
static int
3440
codegen_list(compiler *c, expr_ty e)
3441
766
{
3442
766
    location loc = LOC(e);
3443
766
    asdl_expr_seq *elts = e->v.List.elts;
3444
766
    if (e->v.List.ctx == Store) {
3445
5
        return assignment_helper(c, loc, elts);
3446
5
    }
3447
761
    else if (e->v.List.ctx == Load) {
3448
761
        return starunpack_helper(c, loc, elts, 0,
3449
761
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0);
3450
761
    }
3451
0
    else {
3452
0
        VISIT_SEQ(c, expr, elts);
3453
0
    }
3454
0
    return SUCCESS;
3455
766
}
3456
3457
static int
3458
codegen_tuple(compiler *c, expr_ty e)
3459
2.90k
{
3460
2.90k
    location loc = LOC(e);
3461
2.90k
    asdl_expr_seq *elts = e->v.Tuple.elts;
3462
2.90k
    if (e->v.Tuple.ctx == Store) {
3463
1.00k
        return assignment_helper(c, loc, elts);
3464
1.00k
    }
3465
1.90k
    else if (e->v.Tuple.ctx == Load) {
3466
1.90k
        return starunpack_helper(c, loc, elts, 0,
3467
1.90k
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1);
3468
1.90k
    }
3469
0
    else {
3470
0
        VISIT_SEQ(c, expr, elts);
3471
0
    }
3472
0
    return SUCCESS;
3473
2.90k
}
3474
3475
static int
3476
codegen_set(compiler *c, expr_ty e)
3477
61
{
3478
61
    location loc = LOC(e);
3479
61
    return starunpack_helper(c, loc, e->v.Set.elts, 0,
3480
61
                             BUILD_SET, SET_ADD, SET_UPDATE, 0);
3481
61
}
3482
3483
static int
3484
codegen_subdict(compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
3485
728
{
3486
728
    Py_ssize_t i, n = end - begin;
3487
728
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
3488
728
    location loc = LOC(e);
3489
728
    if (big) {
3490
616
        ADDOP_I(c, loc, BUILD_MAP, 0);
3491
616
    }
3492
11.7k
    for (i = begin; i < end; i++) {
3493
11.0k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
3494
11.0k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3495
11.0k
        if (big) {
3496
10.4k
            ADDOP_I(c, loc, MAP_ADD, 1);
3497
10.4k
        }
3498
11.0k
    }
3499
728
    if (!big) {
3500
112
        ADDOP_I(c, loc, BUILD_MAP, n);
3501
112
    }
3502
728
    return SUCCESS;
3503
728
}
3504
3505
static int
3506
codegen_dict(compiler *c, expr_ty e)
3507
279
{
3508
279
    location loc = LOC(e);
3509
279
    Py_ssize_t i, n, elements;
3510
279
    int have_dict;
3511
279
    int is_unpacking = 0;
3512
279
    n = asdl_seq_LEN(e->v.Dict.values);
3513
279
    have_dict = 0;
3514
279
    elements = 0;
3515
11.3k
    for (i = 0; i < n; i++) {
3516
11.0k
        is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
3517
11.0k
        if (is_unpacking) {
3518
20
            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
20
            if (have_dict == 0) {
3527
10
                ADDOP_I(c, loc, BUILD_MAP, 0);
3528
10
                have_dict = 1;
3529
10
            }
3530
20
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3531
20
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3532
20
        }
3533
11.0k
        else {
3534
11.0k
            if (elements*2 > _PY_STACK_USE_GUIDELINE) {
3535
614
                RETURN_IF_ERROR(codegen_subdict(c, e, i - elements, i + 1));
3536
614
                if (have_dict) {
3537
564
                    ADDOP_I(c, loc, DICT_UPDATE, 1);
3538
564
                }
3539
614
                have_dict = 1;
3540
614
                elements = 0;
3541
614
            }
3542
10.4k
            else {
3543
10.4k
                elements++;
3544
10.4k
            }
3545
11.0k
        }
3546
11.0k
    }
3547
279
    if (elements) {
3548
114
        RETURN_IF_ERROR(codegen_subdict(c, e, n - elements, n));
3549
114
        if (have_dict) {
3550
49
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3551
49
        }
3552
114
        have_dict = 1;
3553
114
    }
3554
279
    if (!have_dict) {
3555
154
        ADDOP_I(c, loc, BUILD_MAP, 0);
3556
154
    }
3557
279
    return SUCCESS;
3558
279
}
3559
3560
static int
3561
codegen_compare(compiler *c, expr_ty e)
3562
5.08k
{
3563
5.08k
    location loc = LOC(e);
3564
5.08k
    Py_ssize_t i, n;
3565
3566
5.08k
    RETURN_IF_ERROR(codegen_check_compare(c, e));
3567
5.08k
    VISIT(c, expr, e->v.Compare.left);
3568
5.08k
    assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
3569
5.08k
    n = asdl_seq_LEN(e->v.Compare.ops) - 1;
3570
5.08k
    if (n == 0) {
3571
5.06k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
3572
5.06k
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0));
3573
5.06k
    }
3574
19
    else {
3575
19
        NEW_JUMP_TARGET_LABEL(c, cleanup);
3576
38
        for (i = 0; i < n; i++) {
3577
19
            VISIT(c, expr,
3578
19
                (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
3579
19
            ADDOP_I(c, loc, SWAP, 2);
3580
19
            ADDOP_I(c, loc, COPY, 2);
3581
19
            ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i));
3582
19
            ADDOP_I(c, loc, COPY, 1);
3583
19
            ADDOP(c, loc, TO_BOOL);
3584
19
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, cleanup);
3585
19
            ADDOP(c, loc, POP_TOP);
3586
19
        }
3587
19
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
3588
19
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
3589
19
        NEW_JUMP_TARGET_LABEL(c, end);
3590
19
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
3591
3592
19
        USE_LABEL(c, cleanup);
3593
19
        ADDOP_I(c, loc, SWAP, 2);
3594
19
        ADDOP(c, loc, POP_TOP);
3595
3596
19
        USE_LABEL(c, end);
3597
19
    }
3598
5.08k
    return SUCCESS;
3599
5.08k
}
3600
3601
static PyTypeObject *
3602
infer_type(expr_ty e)
3603
2.61k
{
3604
2.61k
    switch (e->kind) {
3605
1
    case Tuple_kind:
3606
1
        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.14k
    case Constant_kind:
3626
1.14k
        return Py_TYPE(e->v.Constant.value);
3627
1.46k
    default:
3628
1.46k
        return NULL;
3629
2.61k
    }
3630
2.61k
}
3631
3632
static int
3633
check_caller(compiler *c, expr_ty e)
3634
9.97k
{
3635
9.97k
    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
9.97k
    default:
3655
9.97k
        return SUCCESS;
3656
9.97k
    }
3657
9.97k
}
3658
3659
static int
3660
check_subscripter(compiler *c, expr_ty e)
3661
2.61k
{
3662
2.61k
    PyObject *v;
3663
3664
2.61k
    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
2.59k
    default:
3684
2.59k
        return SUCCESS;
3685
2.61k
    }
3686
2.61k
}
3687
3688
static int
3689
check_index(compiler *c, expr_ty e, expr_ty s)
3690
2.61k
{
3691
2.61k
    PyObject *v;
3692
3693
2.61k
    PyTypeObject *index_type = infer_type(s);
3694
2.61k
    if (index_type == NULL
3695
2.61k
        || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
3696
2.61k
        || index_type == &PySlice_Type) {
3697
2.55k
        return SUCCESS;
3698
2.55k
    }
3699
3700
57
    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
57
    default:
3722
57
        return SUCCESS;
3723
57
    }
3724
57
}
3725
3726
static int
3727
is_import_originated(compiler *c, expr_ty e)
3728
8.09k
{
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
8.09k
    if (e->kind != Name_kind) {
3736
1.93k
        return 0;
3737
1.93k
    }
3738
3739
6.16k
    long flags = _PyST_GetSymbol(SYMTABLE(c)->st_top, e->v.Name.id);
3740
6.16k
    RETURN_IF_ERROR(flags);
3741
6.16k
    return flags & DEF_IMPORT;
3742
6.16k
}
3743
3744
static int
3745
can_optimize_super_call(compiler *c, expr_ty attr)
3746
16.6k
{
3747
16.6k
    expr_ty e = attr->v.Attribute.value;
3748
16.6k
    if (e->kind != Call_kind ||
3749
16.6k
        e->v.Call.func->kind != Name_kind ||
3750
16.6k
        !_PyUnicode_EqualToASCIIString(e->v.Call.func->v.Name.id, "super") ||
3751
16.6k
        _PyUnicode_EqualToASCIIString(attr->v.Attribute.attr, "__class__") ||
3752
16.6k
        asdl_seq_LEN(e->v.Call.keywords) != 0) {
3753
16.4k
        return 0;
3754
16.4k
    }
3755
178
    Py_ssize_t num_args = asdl_seq_LEN(e->v.Call.args);
3756
3757
178
    PyObject *super_name = e->v.Call.func->v.Name.id;
3758
    // detect statically-visible shadowing of 'super' name
3759
178
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), super_name);
3760
178
    RETURN_IF_ERROR(scope);
3761
178
    if (scope != GLOBAL_IMPLICIT) {
3762
0
        return 0;
3763
0
    }
3764
178
    scope = _PyST_GetScope(SYMTABLE(c)->st_top, super_name);
3765
178
    RETURN_IF_ERROR(scope);
3766
178
    if (scope != 0) {
3767
0
        return 0;
3768
0
    }
3769
3770
178
    if (num_args == 2) {
3771
78
        for (Py_ssize_t i = 0; i < num_args; i++) {
3772
52
            expr_ty elt = asdl_seq_GET(e->v.Call.args, i);
3773
52
            if (elt->kind == Starred_kind) {
3774
0
                return 0;
3775
0
            }
3776
52
        }
3777
        // exactly two non-starred args; we can just load
3778
        // the provided args
3779
26
        return 1;
3780
26
    }
3781
3782
152
    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
152
    if (METADATA(c)->u_argcount == 0 &&
3789
152
        METADATA(c)->u_posonlyargcount == 0) {
3790
0
        return 0;
3791
0
    }
3792
    // __class__ cell should be available
3793
152
    if (_PyCompile_GetRefType(c, &_Py_ID(__class__)) == FREE) {
3794
152
        return 1;
3795
152
    }
3796
0
    return 0;
3797
152
}
3798
3799
static int
3800
178
load_args_for_super(compiler *c, expr_ty e) {
3801
178
    location loc = LOC(e);
3802
3803
    // load super() global
3804
178
    PyObject *super_name = e->v.Call.func->v.Name.id;
3805
178
    RETURN_IF_ERROR(codegen_nameop(c, LOC(e->v.Call.func), super_name, Load));
3806
3807
178
    if (asdl_seq_LEN(e->v.Call.args) == 2) {
3808
26
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0));
3809
26
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 1));
3810
26
        return SUCCESS;
3811
26
    }
3812
3813
    // load __class__ cell
3814
152
    PyObject *name = &_Py_ID(__class__);
3815
152
    assert(_PyCompile_GetRefType(c, name) == FREE);
3816
152
    RETURN_IF_ERROR(codegen_nameop(c, loc, name, Load));
3817
3818
    // load self (first argument)
3819
152
    Py_ssize_t i = 0;
3820
152
    PyObject *key, *value;
3821
152
    if (!PyDict_Next(METADATA(c)->u_varnames, &i, &key, &value)) {
3822
0
        return ERROR;
3823
0
    }
3824
152
    RETURN_IF_ERROR(codegen_nameop(c, loc, key, Load));
3825
3826
152
    return SUCCESS;
3827
152
}
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
25.0k
{
3835
25.0k
    assert(attr->kind == Attribute_kind);
3836
25.0k
    if (loc.lineno != attr->end_lineno) {
3837
104
        loc.lineno = attr->end_lineno;
3838
104
        int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
3839
104
        if (len <= attr->end_col_offset) {
3840
104
            loc.col_offset = attr->end_col_offset - len;
3841
104
        }
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
104
        loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno);
3850
104
        if (loc.lineno == loc.end_lineno) {
3851
102
            loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset);
3852
102
        }
3853
104
    }
3854
25.0k
    return loc;
3855
25.0k
}
3856
3857
static int
3858
maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
3859
9.97k
{
3860
9.97k
    asdl_expr_seq *args = e->v.Call.args;
3861
9.97k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
3862
9.97k
    expr_ty func = e->v.Call.func;
3863
3864
9.97k
    if (! (func->kind == Name_kind &&
3865
9.97k
           asdl_seq_LEN(args) == 1 &&
3866
9.97k
           asdl_seq_LEN(kwds) == 0 &&
3867
9.97k
           asdl_seq_GET(args, 0)->kind == GeneratorExp_kind))
3868
9.90k
    {
3869
9.90k
        return 0;
3870
9.90k
    }
3871
3872
74
    location loc = LOC(func);
3873
3874
74
    int optimized = 0;
3875
74
    NEW_JUMP_TARGET_LABEL(c, skip_optimization);
3876
3877
74
    int const_oparg = -1;
3878
74
    PyObject *initial_res = NULL;
3879
74
    int continue_jump_opcode = -1;
3880
74
    if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "all")) {
3881
16
        const_oparg = CONSTANT_BUILTIN_ALL;
3882
16
        initial_res = Py_True;
3883
16
        continue_jump_opcode = POP_JUMP_IF_TRUE;
3884
16
    }
3885
58
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "any")) {
3886
28
        const_oparg = CONSTANT_BUILTIN_ANY;
3887
28
        initial_res = Py_False;
3888
28
        continue_jump_opcode = POP_JUMP_IF_FALSE;
3889
28
    }
3890
30
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "tuple")) {
3891
15
        const_oparg = CONSTANT_BUILTIN_TUPLE;
3892
15
    }
3893
74
    if (const_oparg != -1) {
3894
59
        ADDOP_I(c, loc, COPY, 1); // the function
3895
59
        ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, const_oparg);
3896
59
        ADDOP_COMPARE(c, loc, Is);
3897
59
        ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, skip_optimization);
3898
59
        ADDOP(c, loc, POP_TOP);
3899
3900
59
        if (const_oparg == CONSTANT_BUILTIN_TUPLE) {
3901
15
            ADDOP_I(c, loc, BUILD_LIST, 0);
3902
15
        }
3903
59
        expr_ty generator_exp = asdl_seq_GET(args, 0);
3904
59
        VISIT(c, expr, generator_exp);
3905
3906
59
        NEW_JUMP_TARGET_LABEL(c, loop);
3907
59
        NEW_JUMP_TARGET_LABEL(c, cleanup);
3908
3909
59
        ADDOP(c, loc, PUSH_NULL); // Push NULL index for loop
3910
59
        USE_LABEL(c, loop);
3911
59
        ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
3912
59
        if (const_oparg == CONSTANT_BUILTIN_TUPLE) {
3913
15
            ADDOP_I(c, loc, LIST_APPEND, 3);
3914
15
            ADDOP_JUMP(c, loc, JUMP, loop);
3915
15
        }
3916
44
        else {
3917
44
            ADDOP(c, loc, TO_BOOL);
3918
44
            ADDOP_JUMP(c, loc, continue_jump_opcode, loop);
3919
44
        }
3920
3921
59
        ADDOP(c, NO_LOCATION, POP_ITER);
3922
59
        if (const_oparg != CONSTANT_BUILTIN_TUPLE) {
3923
44
            ADDOP_LOAD_CONST(c, loc, initial_res == Py_True ? Py_False : Py_True);
3924
44
        }
3925
59
        ADDOP_JUMP(c, loc, JUMP, end);
3926
3927
59
        USE_LABEL(c, cleanup);
3928
59
        ADDOP(c, NO_LOCATION, END_FOR);
3929
59
        ADDOP(c, NO_LOCATION, POP_ITER);
3930
59
        if (const_oparg == CONSTANT_BUILTIN_TUPLE) {
3931
15
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
3932
15
        }
3933
44
        else {
3934
44
            ADDOP_LOAD_CONST(c, loc, initial_res);
3935
44
        }
3936
3937
59
        optimized = 1;
3938
59
        ADDOP_JUMP(c, loc, JUMP, end);
3939
59
    }
3940
74
    USE_LABEL(c, skip_optimization);
3941
74
    return optimized;
3942
74
}
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
16.6k
{
3948
16.6k
    Py_ssize_t argsl, i, kwdsl;
3949
16.6k
    expr_ty meth = e->v.Call.func;
3950
16.6k
    asdl_expr_seq *args = e->v.Call.args;
3951
16.6k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
3952
3953
    /* Check that the call node is an attribute access */
3954
16.6k
    if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) {
3955
8.58k
        return 0;
3956
8.58k
    }
3957
3958
    /* Check that the base object is not something that is imported */
3959
8.09k
    int ret = is_import_originated(c, meth->v.Attribute.value);
3960
8.09k
    RETURN_IF_ERROR(ret);
3961
8.09k
    if (ret) {
3962
1.29k
        return 0;
3963
1.29k
    }
3964
3965
    /* Check that there aren't too many arguments */
3966
6.80k
    argsl = asdl_seq_LEN(args);
3967
6.80k
    kwdsl = asdl_seq_LEN(kwds);
3968
6.80k
    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
13.6k
    for (i = 0; i < argsl; i++) {
3973
6.90k
        expr_ty elt = asdl_seq_GET(args, i);
3974
6.90k
        if (elt->kind == Starred_kind) {
3975
81
            return 0;
3976
81
        }
3977
6.90k
    }
3978
3979
7.06k
    for (i = 0; i < kwdsl; i++) {
3980
360
        keyword_ty kw = asdl_seq_GET(kwds, i);
3981
360
        if (kw->arg == NULL) {
3982
21
            return 0;
3983
21
        }
3984
360
    }
3985
3986
    /* Alright, we can optimize the code. */
3987
6.70k
    location loc = LOC(meth);
3988
3989
6.70k
    ret = can_optimize_super_call(c, meth);
3990
6.70k
    RETURN_IF_ERROR(ret);
3991
6.70k
    if (ret) {
3992
117
        RETURN_IF_ERROR(load_args_for_super(c, meth->v.Attribute.value));
3993
117
        int opcode = asdl_seq_LEN(meth->v.Attribute.value->v.Call.args) ?
3994
107
            LOAD_SUPER_METHOD : LOAD_ZERO_SUPER_METHOD;
3995
117
        ADDOP_NAME(c, loc, opcode, meth->v.Attribute.attr, names);
3996
117
        loc = update_start_location_to_match_attr(c, loc, meth);
3997
117
        ADDOP(c, loc, NOP);
3998
6.58k
    } else {
3999
6.58k
        VISIT(c, expr, meth->v.Attribute.value);
4000
6.58k
        loc = update_start_location_to_match_attr(c, loc, meth);
4001
6.58k
        ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names);
4002
6.58k
    }
4003
4004
6.70k
    VISIT_SEQ(c, expr, e->v.Call.args);
4005
4006
6.70k
    if (kwdsl) {
4007
229
        VISIT_SEQ(c, keyword, kwds);
4008
229
        RETURN_IF_ERROR(
4009
229
            codegen_call_simple_kw_helper(c, loc, kwds, kwdsl));
4010
229
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4011
229
        ADDOP_I(c, loc, CALL_KW, argsl + kwdsl);
4012
229
    }
4013
6.47k
    else {
4014
6.47k
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4015
6.47k
        ADDOP_I(c, loc, CALL, argsl);
4016
6.47k
    }
4017
6.70k
    return 1;
4018
6.70k
}
4019
4020
static int
4021
codegen_validate_keywords(compiler *c, asdl_keyword_seq *keywords)
4022
27.6k
{
4023
27.6k
    Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
4024
30.7k
    for (Py_ssize_t i = 0; i < nkeywords; i++) {
4025
3.07k
        keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
4026
3.07k
        if (key->arg == NULL) {
4027
224
            continue;
4028
224
        }
4029
8.52k
        for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
4030
5.67k
            keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
4031
5.67k
            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
5.67k
        }
4035
2.84k
    }
4036
27.6k
    return SUCCESS;
4037
27.6k
}
4038
4039
static int
4040
codegen_call(compiler *c, expr_ty e)
4041
16.6k
{
4042
16.6k
    RETURN_IF_ERROR(codegen_validate_keywords(c, e->v.Call.keywords));
4043
16.6k
    int ret = maybe_optimize_method_call(c, e);
4044
16.6k
    if (ret < 0) {
4045
0
        return ERROR;
4046
0
    }
4047
16.6k
    if (ret == 1) {
4048
6.70k
        return SUCCESS;
4049
6.70k
    }
4050
9.97k
    NEW_JUMP_TARGET_LABEL(c, skip_normal_call);
4051
9.97k
    RETURN_IF_ERROR(check_caller(c, e->v.Call.func));
4052
9.97k
    VISIT(c, expr, e->v.Call.func);
4053
9.97k
    RETURN_IF_ERROR(maybe_optimize_function_call(c, e, skip_normal_call));
4054
9.97k
    location loc = LOC(e->v.Call.func);
4055
9.97k
    ADDOP(c, loc, PUSH_NULL);
4056
9.97k
    loc = LOC(e);
4057
9.97k
    ret = codegen_call_helper(c, loc, 0,
4058
9.97k
                              e->v.Call.args,
4059
9.97k
                              e->v.Call.keywords);
4060
9.97k
    USE_LABEL(c, skip_normal_call);
4061
9.97k
    return ret;
4062
9.97k
}
4063
4064
static int
4065
codegen_template_str(compiler *c, expr_ty e)
4066
0
{
4067
0
    location loc = LOC(e);
4068
0
    expr_ty value;
4069
4070
0
    Py_ssize_t value_count = asdl_seq_LEN(e->v.TemplateStr.values);
4071
0
    int last_was_interpolation = 1;
4072
0
    Py_ssize_t stringslen = 0;
4073
0
    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
            Py_ssize_t j;
4085
0
            for (j = i + 1; j < value_count; j++) {
4086
0
                value = asdl_seq_GET(e->v.TemplateStr.values, j);
4087
0
                if (value->kind == Interpolation_kind) {
4088
0
                    break;
4089
0
                }
4090
0
                VISIT(c, expr, value);
4091
0
                ADDOP_INPLACE(c, loc, Add);
4092
0
            }
4093
0
            i = j - 1;
4094
0
            stringslen++;
4095
0
            last_was_interpolation = 0;
4096
0
        }
4097
0
    }
4098
0
    if (last_was_interpolation) {
4099
0
        ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
4100
0
        stringslen++;
4101
0
    }
4102
0
    ADDOP_I(c, loc, BUILD_TUPLE, stringslen);
4103
4104
0
    Py_ssize_t interpolationslen = 0;
4105
0
    for (Py_ssize_t i = 0; i < value_count; i++) {
4106
0
        value = asdl_seq_GET(e->v.TemplateStr.values, i);
4107
0
        if (value->kind == Interpolation_kind) {
4108
0
            VISIT(c, expr, value);
4109
0
            interpolationslen++;
4110
0
        }
4111
0
    }
4112
0
    ADDOP_I(c, loc, BUILD_TUPLE, interpolationslen);
4113
0
    ADDOP(c, loc, BUILD_TEMPLATE);
4114
0
    return SUCCESS;
4115
0
}
4116
4117
static int
4118
codegen_joined_str(compiler *c, expr_ty e)
4119
651
{
4120
651
    location loc = LOC(e);
4121
651
    Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
4122
651
    if (value_count > _PY_STACK_USE_GUIDELINE) {
4123
0
        _Py_DECLARE_STR(empty, "");
4124
0
        ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4125
0
        ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names);
4126
0
        ADDOP_I(c, loc, BUILD_LIST, 0);
4127
0
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
4128
0
            VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
4129
0
            ADDOP_I(c, loc, LIST_APPEND, 1);
4130
0
        }
4131
0
        ADDOP_I(c, loc, CALL, 1);
4132
0
    }
4133
651
    else {
4134
651
        VISIT_SEQ(c, expr, e->v.JoinedStr.values);
4135
651
        if (value_count > 1) {
4136
639
            ADDOP_I(c, loc, BUILD_STRING, value_count);
4137
639
        }
4138
12
        else if (value_count == 0) {
4139
0
            _Py_DECLARE_STR(empty, "");
4140
0
            ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4141
0
        }
4142
651
    }
4143
651
    return SUCCESS;
4144
651
}
4145
4146
static int
4147
codegen_interpolation(compiler *c, expr_ty e)
4148
0
{
4149
0
    location loc = LOC(e);
4150
4151
0
    VISIT(c, expr, e->v.Interpolation.value);
4152
0
    ADDOP_LOAD_CONST(c, loc, e->v.Interpolation.str);
4153
4154
0
    int oparg = 2;
4155
0
    if (e->v.Interpolation.format_spec) {
4156
0
        oparg++;
4157
0
        VISIT(c, expr, e->v.Interpolation.format_spec);
4158
0
    }
4159
4160
0
    int conversion = e->v.Interpolation.conversion;
4161
0
    if (conversion != -1) {
4162
0
        switch (conversion) {
4163
0
        case 's': oparg |= FVC_STR << 2;   break;
4164
0
        case 'r': oparg |= FVC_REPR << 2;  break;
4165
0
        case 'a': oparg |= FVC_ASCII << 2; break;
4166
0
        default:
4167
0
            PyErr_Format(PyExc_SystemError,
4168
0
                     "Unrecognized conversion character %d", conversion);
4169
0
            return ERROR;
4170
0
        }
4171
0
    }
4172
4173
0
    ADDOP_I(c, loc, BUILD_INTERPOLATION, oparg);
4174
0
    return SUCCESS;
4175
0
}
4176
4177
/* Used to implement f-strings. Format a single value. */
4178
static int
4179
codegen_formatted_value(compiler *c, expr_ty e)
4180
1.13k
{
4181
1.13k
    int conversion = e->v.FormattedValue.conversion;
4182
1.13k
    int oparg;
4183
4184
    /* The expression to be formatted. */
4185
1.13k
    VISIT(c, expr, e->v.FormattedValue.value);
4186
4187
1.13k
    location loc = LOC(e);
4188
1.13k
    if (conversion != -1) {
4189
901
        switch (conversion) {
4190
495
        case 's': oparg = FVC_STR;   break;
4191
406
        case 'r': oparg = FVC_REPR;  break;
4192
0
        case 'a': oparg = FVC_ASCII; break;
4193
0
        default:
4194
0
            PyErr_Format(PyExc_SystemError,
4195
0
                     "Unrecognized conversion character %d", conversion);
4196
0
            return ERROR;
4197
901
        }
4198
901
        ADDOP_I(c, loc, CONVERT_VALUE, oparg);
4199
901
    }
4200
1.13k
    if (e->v.FormattedValue.format_spec) {
4201
        /* Evaluate the format spec, and update our opcode arg. */
4202
11
        VISIT(c, expr, e->v.FormattedValue.format_spec);
4203
11
        ADDOP(c, loc, FORMAT_WITH_SPEC);
4204
1.11k
    } else {
4205
1.11k
        ADDOP(c, loc, FORMAT_SIMPLE);
4206
1.11k
    }
4207
1.13k
    return SUCCESS;
4208
1.13k
}
4209
4210
static int
4211
codegen_subkwargs(compiler *c, location loc,
4212
                  asdl_keyword_seq *keywords,
4213
                  Py_ssize_t begin, Py_ssize_t end)
4214
10
{
4215
10
    Py_ssize_t i, n = end - begin;
4216
10
    keyword_ty kw;
4217
10
    assert(n > 0);
4218
10
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
4219
10
    if (big) {
4220
0
        ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0);
4221
0
    }
4222
39
    for (i = begin; i < end; i++) {
4223
29
        kw = asdl_seq_GET(keywords, i);
4224
29
        ADDOP_LOAD_CONST(c, loc, kw->arg);
4225
29
        VISIT(c, expr, kw->value);
4226
29
        if (big) {
4227
0
            ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
4228
0
        }
4229
29
    }
4230
10
    if (!big) {
4231
10
        ADDOP_I(c, loc, BUILD_MAP, n);
4232
10
    }
4233
10
    return SUCCESS;
4234
10
}
4235
4236
/* Used by codegen_call_helper and maybe_optimize_method_call to emit
4237
 * a tuple of keyword names before CALL.
4238
 */
4239
static int
4240
codegen_call_simple_kw_helper(compiler *c, location loc,
4241
                              asdl_keyword_seq *keywords, Py_ssize_t nkwelts)
4242
651
{
4243
651
    PyObject *names;
4244
651
    names = PyTuple_New(nkwelts);
4245
651
    if (names == NULL) {
4246
0
        return ERROR;
4247
0
    }
4248
2.22k
    for (Py_ssize_t i = 0; i < nkwelts; i++) {
4249
1.56k
        keyword_ty kw = asdl_seq_GET(keywords, i);
4250
1.56k
        PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
4251
1.56k
    }
4252
651
    ADDOP_LOAD_CONST_NEW(c, loc, names);
4253
651
    return SUCCESS;
4254
651
}
4255
4256
/* shared code between codegen_call and codegen_class */
4257
static int
4258
codegen_call_helper_impl(compiler *c, location loc,
4259
                         int n, /* Args already pushed */
4260
                         asdl_expr_seq *args,
4261
                         PyObject *injected_arg,
4262
                         asdl_keyword_seq *keywords)
4263
11.0k
{
4264
11.0k
    Py_ssize_t i, nseen, nelts, nkwelts;
4265
4266
11.0k
    RETURN_IF_ERROR(codegen_validate_keywords(c, keywords));
4267
4268
11.0k
    nelts = asdl_seq_LEN(args);
4269
11.0k
    nkwelts = asdl_seq_LEN(keywords);
4270
4271
11.0k
    if (nelts + nkwelts*2 > _PY_STACK_USE_GUIDELINE) {
4272
2
         goto ex_call;
4273
2
    }
4274
25.6k
    for (i = 0; i < nelts; i++) {
4275
14.7k
        expr_ty elt = asdl_seq_GET(args, i);
4276
14.7k
        if (elt->kind == Starred_kind) {
4277
176
            goto ex_call;
4278
176
        }
4279
14.7k
    }
4280
12.0k
    for (i = 0; i < nkwelts; i++) {
4281
1.28k
        keyword_ty kw = asdl_seq_GET(keywords, i);
4282
1.28k
        if (kw->arg == NULL) {
4283
33
            goto ex_call;
4284
33
        }
4285
1.28k
    }
4286
4287
    /* No * or ** args, so can use faster calling sequence */
4288
25.2k
    for (i = 0; i < nelts; i++) {
4289
14.5k
        expr_ty elt = asdl_seq_GET(args, i);
4290
14.5k
        assert(elt->kind != Starred_kind);
4291
14.5k
        VISIT(c, expr, elt);
4292
14.5k
    }
4293
10.7k
    if (injected_arg) {
4294
0
        RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
4295
0
        nelts++;
4296
0
    }
4297
10.7k
    if (nkwelts) {
4298
422
        VISIT_SEQ(c, keyword, keywords);
4299
422
        RETURN_IF_ERROR(
4300
422
            codegen_call_simple_kw_helper(c, loc, keywords, nkwelts));
4301
422
        ADDOP_I(c, loc, CALL_KW, n + nelts + nkwelts);
4302
422
    }
4303
10.3k
    else {
4304
10.3k
        ADDOP_I(c, loc, CALL, n + nelts);
4305
10.3k
    }
4306
10.7k
    return SUCCESS;
4307
4308
211
ex_call:
4309
4310
    /* Do positional arguments. */
4311
211
    if (n == 0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
4312
114
        VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
4313
114
    }
4314
97
    else {
4315
97
        RETURN_IF_ERROR(starunpack_helper_impl(c, loc, args, injected_arg, n,
4316
97
                                               BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1));
4317
97
    }
4318
    /* Then keyword arguments */
4319
211
    if (nkwelts) {
4320
        /* Has a new dict been pushed */
4321
115
        int have_dict = 0;
4322
4323
115
        nseen = 0;  /* the number of keyword arguments on the stack following */
4324
256
        for (i = 0; i < nkwelts; i++) {
4325
141
            keyword_ty kw = asdl_seq_GET(keywords, i);
4326
141
            if (kw->arg == NULL) {
4327
                /* A keyword argument unpacking. */
4328
112
                if (nseen) {
4329
6
                    RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, i - nseen, i));
4330
6
                    if (have_dict) {
4331
0
                        ADDOP_I(c, loc, DICT_MERGE, 1);
4332
0
                    }
4333
6
                    have_dict = 1;
4334
6
                    nseen = 0;
4335
6
                }
4336
112
                if (!have_dict) {
4337
105
                    ADDOP_I(c, loc, BUILD_MAP, 0);
4338
105
                    have_dict = 1;
4339
105
                }
4340
112
                VISIT(c, expr, kw->value);
4341
112
                ADDOP_I(c, loc, DICT_MERGE, 1);
4342
112
            }
4343
29
            else {
4344
29
                nseen++;
4345
29
            }
4346
141
        }
4347
115
        if (nseen) {
4348
            /* Pack up any trailing keyword arguments. */
4349
4
            RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts));
4350
4
            if (have_dict) {
4351
0
                ADDOP_I(c, loc, DICT_MERGE, 1);
4352
0
            }
4353
4
            have_dict = 1;
4354
4
        }
4355
115
        assert(have_dict);
4356
115
    }
4357
211
    if (nkwelts == 0) {
4358
96
        ADDOP(c, loc, PUSH_NULL);
4359
96
    }
4360
211
    ADDOP(c, loc, CALL_FUNCTION_EX);
4361
211
    return SUCCESS;
4362
211
}
4363
4364
static int
4365
codegen_call_helper(compiler *c, location loc,
4366
                    int n, /* Args already pushed */
4367
                    asdl_expr_seq *args,
4368
                    asdl_keyword_seq *keywords)
4369
11.0k
{
4370
11.0k
    return codegen_call_helper_impl(c, loc, n, args, NULL, keywords);
4371
11.0k
}
4372
4373
/* List and set comprehensions work by being inlined at the location where
4374
  they are defined. The isolation of iteration variables is provided by
4375
  pushing/popping clashing locals on the stack. Generator expressions work
4376
  by creating a nested function to perform the actual iteration.
4377
  This means that the iteration variables don't leak into the current scope.
4378
  See https://peps.python.org/pep-0709/ for additional information.
4379
  The defined function is called immediately following its definition, with the
4380
  result of that call being the result of the expression.
4381
  The LC/SC version returns the populated container, while the GE version is
4382
  flagged in symtable.c as a generator, so it returns the generator object
4383
  when the function is called.
4384
4385
  Possible cleanups:
4386
    - iterate over the generator sequence instead of using recursion
4387
*/
4388
4389
4390
static int
4391
codegen_comprehension_generator(compiler *c, location loc,
4392
                                asdl_comprehension_seq *generators, int gen_index,
4393
                                int depth,
4394
                                expr_ty elt, expr_ty val, int type,
4395
                                int iter_on_stack)
4396
399
{
4397
399
    comprehension_ty gen;
4398
399
    gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
4399
399
    if (gen->is_async) {
4400
0
        return codegen_async_comprehension_generator(
4401
0
            c, loc, generators, gen_index, depth, elt, val, type,
4402
0
            iter_on_stack);
4403
399
    } else {
4404
399
        return codegen_sync_comprehension_generator(
4405
399
            c, loc, generators, gen_index, depth, elt, val, type,
4406
399
            iter_on_stack);
4407
399
    }
4408
399
}
4409
4410
static int
4411
codegen_sync_comprehension_generator(compiler *c, location loc,
4412
                                     asdl_comprehension_seq *generators,
4413
                                     int gen_index, int depth,
4414
                                     expr_ty elt, expr_ty val, int type,
4415
                                     int iter_on_stack)
4416
399
{
4417
    /* generate code for the iterator, then each of the ifs,
4418
       and then write to the element */
4419
4420
399
    NEW_JUMP_TARGET_LABEL(c, start);
4421
399
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4422
399
    NEW_JUMP_TARGET_LABEL(c, anchor);
4423
4424
399
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4425
399
                                                          gen_index);
4426
4427
399
    if (!iter_on_stack) {
4428
214
        if (gen_index == 0) {
4429
196
            assert(METADATA(c)->u_argcount == 1);
4430
196
            ADDOP_I(c, loc, LOAD_FAST, 0);
4431
196
        }
4432
18
        else {
4433
            /* Sub-iter - calculate on the fly */
4434
            /* Fast path for the temporary variable assignment idiom:
4435
                for y in [f(x)]
4436
            */
4437
18
            asdl_expr_seq *elts;
4438
18
            switch (gen->iter->kind) {
4439
0
                case List_kind:
4440
0
                    elts = gen->iter->v.List.elts;
4441
0
                    break;
4442
0
                case Tuple_kind:
4443
0
                    elts = gen->iter->v.Tuple.elts;
4444
0
                    break;
4445
18
                default:
4446
18
                    elts = NULL;
4447
18
            }
4448
18
            if (asdl_seq_LEN(elts) == 1) {
4449
0
                expr_ty elt = asdl_seq_GET(elts, 0);
4450
0
                if (elt->kind != Starred_kind) {
4451
0
                    VISIT(c, expr, elt);
4452
0
                    start = NO_LABEL;
4453
0
                }
4454
0
            }
4455
18
            if (IS_JUMP_TARGET_LABEL(start)) {
4456
18
                VISIT(c, expr, gen->iter);
4457
18
            }
4458
18
        }
4459
214
    }
4460
4461
399
    if (IS_JUMP_TARGET_LABEL(start)) {
4462
399
        depth += 2;
4463
399
        ADDOP(c, LOC(gen->iter), GET_ITER);
4464
399
        USE_LABEL(c, start);
4465
399
        ADDOP_JUMP(c, LOC(gen->iter), FOR_ITER, anchor);
4466
399
    }
4467
399
    VISIT(c, expr, gen->target);
4468
4469
    /* XXX this needs to be cleaned up...a lot! */
4470
399
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4471
457
    for (Py_ssize_t i = 0; i < n; i++) {
4472
58
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4473
58
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4474
58
    }
4475
4476
399
    if (++gen_index < asdl_seq_LEN(generators)) {
4477
18
        RETURN_IF_ERROR(
4478
18
            codegen_comprehension_generator(c, loc,
4479
18
                                            generators, gen_index, depth,
4480
18
                                            elt, val, type, 0));
4481
18
    }
4482
4483
399
    location elt_loc = LOC(elt);
4484
4485
    /* only append after the last for generator */
4486
399
    if (gen_index >= asdl_seq_LEN(generators)) {
4487
        /* comprehension specific code */
4488
381
        switch (type) {
4489
196
        case COMP_GENEXP:
4490
196
            VISIT(c, expr, elt);
4491
196
            ADDOP_YIELD(c, elt_loc);
4492
196
            ADDOP(c, elt_loc, POP_TOP);
4493
196
            break;
4494
196
        case COMP_LISTCOMP:
4495
164
            VISIT(c, expr, elt);
4496
164
            ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4497
164
            break;
4498
164
        case COMP_SETCOMP:
4499
3
            VISIT(c, expr, elt);
4500
3
            ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4501
3
            break;
4502
18
        case COMP_DICTCOMP:
4503
            /* With '{k: v}', k is evaluated before v, so we do
4504
               the same. */
4505
18
            VISIT(c, expr, elt);
4506
18
            VISIT(c, expr, val);
4507
18
            elt_loc = LOCATION(elt->lineno,
4508
18
                               val->end_lineno,
4509
18
                               elt->col_offset,
4510
18
                               val->end_col_offset);
4511
18
            ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4512
18
            break;
4513
18
        default:
4514
0
            return ERROR;
4515
381
        }
4516
381
    }
4517
4518
399
    USE_LABEL(c, if_cleanup);
4519
399
    if (IS_JUMP_TARGET_LABEL(start)) {
4520
399
        ADDOP_JUMP(c, elt_loc, JUMP, start);
4521
4522
399
        USE_LABEL(c, anchor);
4523
        /* It is important for instrumentation that the `END_FOR` comes first.
4524
        * Iteration over a generator will jump to the first of these instructions,
4525
        * but a non-generator will jump to a later instruction.
4526
        */
4527
399
        ADDOP(c, NO_LOCATION, END_FOR);
4528
399
        ADDOP(c, NO_LOCATION, POP_ITER);
4529
399
    }
4530
4531
399
    return SUCCESS;
4532
399
}
4533
4534
static int
4535
codegen_async_comprehension_generator(compiler *c, location loc,
4536
                                      asdl_comprehension_seq *generators,
4537
                                      int gen_index, int depth,
4538
                                      expr_ty elt, expr_ty val, int type,
4539
                                      int iter_on_stack)
4540
0
{
4541
0
    NEW_JUMP_TARGET_LABEL(c, start);
4542
0
    NEW_JUMP_TARGET_LABEL(c, send);
4543
0
    NEW_JUMP_TARGET_LABEL(c, except);
4544
0
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4545
4546
0
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4547
0
                                                          gen_index);
4548
4549
0
    if (!iter_on_stack) {
4550
0
        if (gen_index == 0) {
4551
0
            assert(METADATA(c)->u_argcount == 1);
4552
0
            ADDOP_I(c, loc, LOAD_FAST, 0);
4553
0
        }
4554
0
        else {
4555
            /* Sub-iter - calculate on the fly */
4556
0
            VISIT(c, expr, gen->iter);
4557
0
        }
4558
0
    }
4559
0
    ADDOP(c, LOC(gen->iter), GET_AITER);
4560
4561
0
    USE_LABEL(c, start);
4562
    /* Runtime will push a block here, so we need to account for that */
4563
0
    RETURN_IF_ERROR(
4564
0
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR,
4565
0
                              start, NO_LABEL, NULL));
4566
4567
0
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
4568
0
    ADDOP(c, loc, GET_ANEXT);
4569
0
    ADDOP_LOAD_CONST(c, loc, Py_None);
4570
0
    USE_LABEL(c, send);
4571
0
    ADD_YIELD_FROM(c, loc, 1);
4572
0
    ADDOP(c, loc, POP_BLOCK);
4573
0
    VISIT(c, expr, gen->target);
4574
4575
0
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4576
0
    for (Py_ssize_t i = 0; i < n; i++) {
4577
0
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4578
0
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4579
0
    }
4580
4581
0
    depth++;
4582
0
    if (++gen_index < asdl_seq_LEN(generators)) {
4583
0
        RETURN_IF_ERROR(
4584
0
            codegen_comprehension_generator(c, loc,
4585
0
                                            generators, gen_index, depth,
4586
0
                                            elt, val, type, 0));
4587
0
    }
4588
4589
0
    location elt_loc = LOC(elt);
4590
    /* only append after the last for generator */
4591
0
    if (gen_index >= asdl_seq_LEN(generators)) {
4592
        /* comprehension specific code */
4593
0
        switch (type) {
4594
0
        case COMP_GENEXP:
4595
0
            VISIT(c, expr, elt);
4596
0
            ADDOP_YIELD(c, elt_loc);
4597
0
            ADDOP(c, elt_loc, POP_TOP);
4598
0
            break;
4599
0
        case COMP_LISTCOMP:
4600
0
            VISIT(c, expr, elt);
4601
0
            ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4602
0
            break;
4603
0
        case COMP_SETCOMP:
4604
0
            VISIT(c, expr, elt);
4605
0
            ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4606
0
            break;
4607
0
        case COMP_DICTCOMP:
4608
            /* With '{k: v}', k is evaluated before v, so we do
4609
               the same. */
4610
0
            VISIT(c, expr, elt);
4611
0
            VISIT(c, expr, val);
4612
0
            elt_loc = LOCATION(elt->lineno,
4613
0
                               val->end_lineno,
4614
0
                               elt->col_offset,
4615
0
                               val->end_col_offset);
4616
0
            ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4617
0
            break;
4618
0
        default:
4619
0
            return ERROR;
4620
0
        }
4621
0
    }
4622
4623
0
    USE_LABEL(c, if_cleanup);
4624
0
    ADDOP_JUMP(c, elt_loc, JUMP, start);
4625
4626
0
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR, start);
4627
4628
0
    USE_LABEL(c, except);
4629
4630
0
    ADDOP_JUMP(c, loc, END_ASYNC_FOR, send);
4631
4632
0
    return SUCCESS;
4633
0
}
4634
4635
static int
4636
codegen_push_inlined_comprehension_locals(compiler *c, location loc,
4637
                                          PySTEntryObject *comp,
4638
                                          _PyCompile_InlinedComprehensionState *state)
4639
185
{
4640
185
    int in_class_block = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock) &&
4641
185
                          !_PyCompile_IsInInlinedComp(c);
4642
185
    PySTEntryObject *outer = SYMTABLE_ENTRY(c);
4643
    // iterate over names bound in the comprehension and ensure we isolate
4644
    // them from the outer scope as needed
4645
185
    PyObject *k, *v;
4646
185
    Py_ssize_t pos = 0;
4647
786
    while (PyDict_Next(comp->ste_symbols, &pos, &k, &v)) {
4648
601
        long symbol = PyLong_AsLong(v);
4649
601
        assert(symbol >= 0 || PyErr_Occurred());
4650
601
        RETURN_IF_ERROR(symbol);
4651
601
        long scope = SYMBOL_TO_SCOPE(symbol);
4652
4653
601
        long outsymbol = _PyST_GetSymbol(outer, k);
4654
601
        RETURN_IF_ERROR(outsymbol);
4655
601
        long outsc = SYMBOL_TO_SCOPE(outsymbol);
4656
4657
601
        if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) {
4658
            // local names bound in comprehension must be isolated from
4659
            // outer scope; push existing value (which may be NULL if
4660
            // not defined) on stack
4661
240
            if (state->pushed_locals == NULL) {
4662
185
                state->pushed_locals = PyList_New(0);
4663
185
                if (state->pushed_locals == NULL) {
4664
0
                    return ERROR;
4665
0
                }
4666
185
            }
4667
            // in the case of a cell, this will actually push the cell
4668
            // itself to the stack, then we'll create a new one for the
4669
            // comprehension and restore the original one after
4670
240
            ADDOP_NAME(c, loc, LOAD_FAST_AND_CLEAR, k, varnames);
4671
240
            if (scope == CELL) {
4672
0
                if (outsc == FREE) {
4673
0
                    ADDOP_NAME(c, loc, MAKE_CELL, k, freevars);
4674
0
                } else {
4675
0
                    ADDOP_NAME(c, loc, MAKE_CELL, k, cellvars);
4676
0
                }
4677
0
            }
4678
240
            if (PyList_Append(state->pushed_locals, k) < 0) {
4679
0
                return ERROR;
4680
0
            }
4681
240
        }
4682
601
    }
4683
185
    if (state->pushed_locals) {
4684
        // Outermost iterable expression was already evaluated and is on the
4685
        // stack, we need to swap it back to TOS. This also rotates the order of
4686
        // `pushed_locals` on the stack, but this will be reversed when we swap
4687
        // out the comprehension result in pop_inlined_comprehension_state
4688
185
        ADDOP_I(c, loc, SWAP, PyList_GET_SIZE(state->pushed_locals) + 1);
4689
4690
        // Add our own cleanup handler to restore comprehension locals in case
4691
        // of exception, so they have the correct values inside an exception
4692
        // handler or finally block.
4693
185
        NEW_JUMP_TARGET_LABEL(c, cleanup);
4694
185
        state->cleanup = cleanup;
4695
4696
        // no need to push an fblock for this "virtual" try/finally; there can't
4697
        // be return/continue/break inside a comprehension
4698
185
        ADDOP_JUMP(c, loc, SETUP_FINALLY, cleanup);
4699
185
    }
4700
185
    return SUCCESS;
4701
185
}
4702
4703
static int
4704
push_inlined_comprehension_state(compiler *c, location loc,
4705
                                 PySTEntryObject *comp,
4706
                                 _PyCompile_InlinedComprehensionState *state)
4707
185
{
4708
185
    RETURN_IF_ERROR(
4709
185
        _PyCompile_TweakInlinedComprehensionScopes(c, loc, comp, state));
4710
185
    RETURN_IF_ERROR(
4711
185
        codegen_push_inlined_comprehension_locals(c, loc, comp, state));
4712
185
    return SUCCESS;
4713
185
}
4714
4715
static int
4716
restore_inlined_comprehension_locals(compiler *c, location loc,
4717
                                     _PyCompile_InlinedComprehensionState *state)
4718
370
{
4719
370
    PyObject *k;
4720
    // pop names we pushed to stack earlier
4721
370
    Py_ssize_t npops = PyList_GET_SIZE(state->pushed_locals);
4722
    // Preserve the comprehension result (or exception) as TOS. This
4723
    // reverses the SWAP we did in push_inlined_comprehension_state
4724
    // to get the outermost iterable to TOS, so we can still just iterate
4725
    // pushed_locals in simple reverse order
4726
370
    ADDOP_I(c, loc, SWAP, npops + 1);
4727
850
    for (Py_ssize_t i = npops - 1; i >= 0; --i) {
4728
480
        k = PyList_GetItem(state->pushed_locals, i);
4729
480
        if (k == NULL) {
4730
0
            return ERROR;
4731
0
        }
4732
480
        ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames);
4733
480
    }
4734
370
    return SUCCESS;
4735
370
}
4736
4737
static int
4738
codegen_pop_inlined_comprehension_locals(compiler *c, location loc,
4739
                                         _PyCompile_InlinedComprehensionState *state)
4740
185
{
4741
185
    if (state->pushed_locals) {
4742
185
        ADDOP(c, NO_LOCATION, POP_BLOCK);
4743
4744
185
        NEW_JUMP_TARGET_LABEL(c, end);
4745
185
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
4746
4747
        // cleanup from an exception inside the comprehension
4748
185
        USE_LABEL(c, state->cleanup);
4749
        // discard incomplete comprehension result (beneath exc on stack)
4750
185
        ADDOP_I(c, NO_LOCATION, SWAP, 2);
4751
185
        ADDOP(c, NO_LOCATION, POP_TOP);
4752
185
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
4753
185
        ADDOP_I(c, NO_LOCATION, RERAISE, 0);
4754
4755
185
        USE_LABEL(c, end);
4756
185
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
4757
185
        Py_CLEAR(state->pushed_locals);
4758
185
    }
4759
185
    return SUCCESS;
4760
185
}
4761
4762
static int
4763
pop_inlined_comprehension_state(compiler *c, location loc,
4764
                                _PyCompile_InlinedComprehensionState *state)
4765
185
{
4766
185
    RETURN_IF_ERROR(codegen_pop_inlined_comprehension_locals(c, loc, state));
4767
185
    RETURN_IF_ERROR(_PyCompile_RevertInlinedComprehensionScopes(c, loc, state));
4768
185
    return SUCCESS;
4769
185
}
4770
4771
static int
4772
codegen_comprehension(compiler *c, expr_ty e, int type,
4773
                      identifier name, asdl_comprehension_seq *generators, expr_ty elt,
4774
                      expr_ty val)
4775
381
{
4776
381
    PyCodeObject *co = NULL;
4777
381
    _PyCompile_InlinedComprehensionState inline_state = {NULL, NULL, NULL, NO_LABEL};
4778
381
    comprehension_ty outermost;
4779
381
    PySTEntryObject *entry = _PySymtable_Lookup(SYMTABLE(c), (void *)e);
4780
381
    if (entry == NULL) {
4781
0
        goto error;
4782
0
    }
4783
381
    int is_inlined = entry->ste_comp_inlined;
4784
381
    int is_async_comprehension = entry->ste_coroutine;
4785
4786
381
    location loc = LOC(e);
4787
4788
381
    outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
4789
381
    if (is_inlined) {
4790
185
        VISIT(c, expr, outermost->iter);
4791
185
        if (push_inlined_comprehension_state(c, loc, entry, &inline_state)) {
4792
0
            goto error;
4793
0
        }
4794
185
    }
4795
196
    else {
4796
        /* Receive outermost iter as an implicit argument */
4797
196
        _PyCompile_CodeUnitMetadata umd = {
4798
196
            .u_argcount = 1,
4799
196
        };
4800
196
        if (codegen_enter_scope(c, name, COMPILE_SCOPE_COMPREHENSION,
4801
196
                                (void *)e, e->lineno, NULL, &umd) < 0) {
4802
0
            goto error;
4803
0
        }
4804
196
    }
4805
381
    Py_CLEAR(entry);
4806
4807
381
    if (type != COMP_GENEXP) {
4808
185
        int op;
4809
185
        switch (type) {
4810
164
        case COMP_LISTCOMP:
4811
164
            op = BUILD_LIST;
4812
164
            break;
4813
3
        case COMP_SETCOMP:
4814
3
            op = BUILD_SET;
4815
3
            break;
4816
18
        case COMP_DICTCOMP:
4817
18
            op = BUILD_MAP;
4818
18
            break;
4819
0
        default:
4820
0
            PyErr_Format(PyExc_SystemError,
4821
0
                         "unknown comprehension type %d", type);
4822
0
            goto error_in_scope;
4823
185
        }
4824
4825
185
        ADDOP_I(c, loc, op, 0);
4826
185
        if (is_inlined) {
4827
185
            ADDOP_I(c, loc, SWAP, 2);
4828
185
        }
4829
185
    }
4830
4831
381
    if (codegen_comprehension_generator(c, loc, generators, 0, 0,
4832
381
                                        elt, val, type, is_inlined) < 0) {
4833
0
        goto error_in_scope;
4834
0
    }
4835
4836
381
    if (is_inlined) {
4837
185
        if (pop_inlined_comprehension_state(c, loc, &inline_state)) {
4838
0
            goto error;
4839
0
        }
4840
185
        return SUCCESS;
4841
185
    }
4842
4843
196
    if (type != COMP_GENEXP) {
4844
0
        ADDOP(c, LOC(e), RETURN_VALUE);
4845
0
    }
4846
196
    if (type == COMP_GENEXP) {
4847
196
        if (codegen_wrap_in_stopiteration_handler(c) < 0) {
4848
0
            goto error_in_scope;
4849
0
        }
4850
196
    }
4851
4852
196
    co = _PyCompile_OptimizeAndAssemble(c, 1);
4853
196
    _PyCompile_ExitScope(c);
4854
196
    if (co == NULL) {
4855
0
        goto error;
4856
0
    }
4857
4858
196
    loc = LOC(e);
4859
196
    if (codegen_make_closure(c, loc, co, 0) < 0) {
4860
0
        goto error;
4861
0
    }
4862
196
    Py_CLEAR(co);
4863
4864
196
    VISIT(c, expr, outermost->iter);
4865
196
    ADDOP_I(c, loc, CALL, 0);
4866
4867
196
    if (is_async_comprehension && type != COMP_GENEXP) {
4868
0
        ADDOP_I(c, loc, GET_AWAITABLE, 0);
4869
0
        ADDOP_LOAD_CONST(c, loc, Py_None);
4870
0
        ADD_YIELD_FROM(c, loc, 1);
4871
0
    }
4872
4873
196
    return SUCCESS;
4874
0
error_in_scope:
4875
0
    if (!is_inlined) {
4876
0
        _PyCompile_ExitScope(c);
4877
0
    }
4878
0
error:
4879
0
    Py_XDECREF(co);
4880
0
    Py_XDECREF(entry);
4881
0
    Py_XDECREF(inline_state.pushed_locals);
4882
0
    Py_XDECREF(inline_state.temp_symbols);
4883
0
    Py_XDECREF(inline_state.fast_hidden);
4884
0
    return ERROR;
4885
0
}
4886
4887
static int
4888
codegen_genexp(compiler *c, expr_ty e)
4889
196
{
4890
196
    assert(e->kind == GeneratorExp_kind);
4891
196
    _Py_DECLARE_STR(anon_genexpr, "<genexpr>");
4892
196
    return codegen_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
4893
196
                                 e->v.GeneratorExp.generators,
4894
196
                                 e->v.GeneratorExp.elt, NULL);
4895
196
}
4896
4897
static int
4898
codegen_listcomp(compiler *c, expr_ty e)
4899
164
{
4900
164
    assert(e->kind == ListComp_kind);
4901
164
    _Py_DECLARE_STR(anon_listcomp, "<listcomp>");
4902
164
    return codegen_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
4903
164
                                 e->v.ListComp.generators,
4904
164
                                 e->v.ListComp.elt, NULL);
4905
164
}
4906
4907
static int
4908
codegen_setcomp(compiler *c, expr_ty e)
4909
3
{
4910
3
    assert(e->kind == SetComp_kind);
4911
3
    _Py_DECLARE_STR(anon_setcomp, "<setcomp>");
4912
3
    return codegen_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp),
4913
3
                                 e->v.SetComp.generators,
4914
3
                                 e->v.SetComp.elt, NULL);
4915
3
}
4916
4917
4918
static int
4919
codegen_dictcomp(compiler *c, expr_ty e)
4920
18
{
4921
18
    assert(e->kind == DictComp_kind);
4922
18
    _Py_DECLARE_STR(anon_dictcomp, "<dictcomp>");
4923
18
    return codegen_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
4924
18
                                 e->v.DictComp.generators,
4925
18
                                 e->v.DictComp.key, e->v.DictComp.value);
4926
18
}
4927
4928
4929
static int
4930
codegen_visit_keyword(compiler *c, keyword_ty k)
4931
1.56k
{
4932
1.56k
    VISIT(c, expr, k->value);
4933
1.56k
    return SUCCESS;
4934
1.56k
}
4935
4936
4937
static int
4938
98
codegen_with_except_finish(compiler *c, jump_target_label cleanup) {
4939
98
    NEW_JUMP_TARGET_LABEL(c, suppress);
4940
98
    ADDOP(c, NO_LOCATION, TO_BOOL);
4941
98
    ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress);
4942
98
    ADDOP_I(c, NO_LOCATION, RERAISE, 2);
4943
4944
98
    USE_LABEL(c, suppress);
4945
98
    ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */
4946
98
    ADDOP(c, NO_LOCATION, POP_BLOCK);
4947
98
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
4948
98
    ADDOP(c, NO_LOCATION, POP_TOP);
4949
98
    ADDOP(c, NO_LOCATION, POP_TOP);
4950
98
    ADDOP(c, NO_LOCATION, POP_TOP);
4951
98
    NEW_JUMP_TARGET_LABEL(c, exit);
4952
98
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
4953
4954
98
    USE_LABEL(c, cleanup);
4955
98
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
4956
4957
98
    USE_LABEL(c, exit);
4958
98
    return SUCCESS;
4959
98
}
4960
4961
/*
4962
   Implements the async with statement.
4963
4964
   The semantics outlined in that PEP are as follows:
4965
4966
   async with EXPR as VAR:
4967
       BLOCK
4968
4969
   It is implemented roughly as:
4970
4971
   context = EXPR
4972
   exit = context.__aexit__  # not calling it
4973
   value = await context.__aenter__()
4974
   try:
4975
       VAR = value  # if VAR present in the syntax
4976
       BLOCK
4977
   finally:
4978
       if an exception was raised:
4979
           exc = copy of (exception, instance, traceback)
4980
       else:
4981
           exc = (None, None, None)
4982
       if not (await exit(*exc)):
4983
           raise
4984
 */
4985
static int
4986
codegen_async_with_inner(compiler *c, stmt_ty s, int pos)
4987
1
{
4988
1
    location loc = LOC(s);
4989
1
    withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
4990
4991
1
    assert(s->kind == AsyncWith_kind);
4992
4993
1
    NEW_JUMP_TARGET_LABEL(c, block);
4994
1
    NEW_JUMP_TARGET_LABEL(c, final);
4995
1
    NEW_JUMP_TARGET_LABEL(c, exit);
4996
1
    NEW_JUMP_TARGET_LABEL(c, cleanup);
4997
4998
    /* Evaluate EXPR */
4999
1
    VISIT(c, expr, item->context_expr);
5000
1
    loc = LOC(item->context_expr);
5001
1
    ADDOP_I(c, loc, COPY, 1);
5002
1
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AEXIT__);
5003
1
    ADDOP_I(c, loc, SWAP, 2);
5004
1
    ADDOP_I(c, loc, SWAP, 3);
5005
1
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AENTER__);
5006
1
    ADDOP_I(c, loc, CALL, 0);
5007
1
    ADDOP_I(c, loc, GET_AWAITABLE, 1);
5008
1
    ADDOP_LOAD_CONST(c, loc, Py_None);
5009
1
    ADD_YIELD_FROM(c, loc, 1);
5010
5011
1
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5012
5013
    /* SETUP_WITH pushes a finally block. */
5014
1
    USE_LABEL(c, block);
5015
1
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_WITH, block, final, s));
5016
5017
1
    if (item->optional_vars) {
5018
0
        VISIT(c, expr, item->optional_vars);
5019
0
    }
5020
1
    else {
5021
        /* Discard result from context.__aenter__() */
5022
1
        ADDOP(c, loc, POP_TOP);
5023
1
    }
5024
5025
1
    pos++;
5026
1
    if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) {
5027
        /* BLOCK code */
5028
1
        VISIT_SEQ(c, stmt, s->v.AsyncWith.body);
5029
1
    }
5030
0
    else {
5031
0
        RETURN_IF_ERROR(codegen_async_with_inner(c, s, pos));
5032
0
    }
5033
5034
1
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_WITH, block);
5035
5036
1
    ADDOP(c, loc, POP_BLOCK);
5037
    /* End of body; start the cleanup */
5038
5039
    /* For successful outcome:
5040
     * call __exit__(None, None, None)
5041
     */
5042
1
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5043
1
    ADDOP_I(c, loc, GET_AWAITABLE, 2);
5044
1
    ADDOP_LOAD_CONST(c, loc, Py_None);
5045
1
    ADD_YIELD_FROM(c, loc, 1);
5046
5047
1
    ADDOP(c, loc, POP_TOP);
5048
5049
1
    ADDOP_JUMP(c, loc, JUMP, exit);
5050
5051
    /* For exceptional outcome: */
5052
1
    USE_LABEL(c, final);
5053
5054
1
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5055
1
    ADDOP(c, loc, PUSH_EXC_INFO);
5056
1
    ADDOP(c, loc, WITH_EXCEPT_START);
5057
1
    ADDOP_I(c, loc, GET_AWAITABLE, 2);
5058
1
    ADDOP_LOAD_CONST(c, loc, Py_None);
5059
1
    ADD_YIELD_FROM(c, loc, 1);
5060
1
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5061
5062
1
    USE_LABEL(c, exit);
5063
1
    return SUCCESS;
5064
1
}
5065
5066
static int
5067
codegen_async_with(compiler *c, stmt_ty s)
5068
1
{
5069
1
    return codegen_async_with_inner(c, s, 0);
5070
1
}
5071
5072
5073
/*
5074
   Implements the with statement from PEP 343.
5075
   with EXPR as VAR:
5076
       BLOCK
5077
   is implemented as:
5078
        <code for EXPR>
5079
        SETUP_WITH  E
5080
        <code to store to VAR> or POP_TOP
5081
        <code for BLOCK>
5082
        LOAD_CONST (None, None, None)
5083
        CALL_FUNCTION_EX 0
5084
        JUMP  EXIT
5085
    E:  WITH_EXCEPT_START (calls EXPR.__exit__)
5086
        POP_JUMP_IF_TRUE T:
5087
        RERAISE
5088
    T:  POP_TOP (remove exception from stack)
5089
        POP_EXCEPT
5090
        POP_TOP
5091
    EXIT:
5092
 */
5093
5094
static int
5095
codegen_with_inner(compiler *c, stmt_ty s, int pos)
5096
97
{
5097
97
    withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
5098
5099
97
    assert(s->kind == With_kind);
5100
5101
97
    NEW_JUMP_TARGET_LABEL(c, block);
5102
97
    NEW_JUMP_TARGET_LABEL(c, final);
5103
97
    NEW_JUMP_TARGET_LABEL(c, exit);
5104
97
    NEW_JUMP_TARGET_LABEL(c, cleanup);
5105
5106
    /* Evaluate EXPR */
5107
97
    VISIT(c, expr, item->context_expr);
5108
    /* Will push bound __exit__ */
5109
97
    location loc = LOC(item->context_expr);
5110
97
    ADDOP_I(c, loc, COPY, 1);
5111
97
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___EXIT__);
5112
97
    ADDOP_I(c, loc, SWAP, 2);
5113
97
    ADDOP_I(c, loc, SWAP, 3);
5114
97
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___ENTER__);
5115
97
    ADDOP_I(c, loc, CALL, 0);
5116
97
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5117
5118
    /* SETUP_WITH pushes a finally block. */
5119
97
    USE_LABEL(c, block);
5120
97
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_WITH, block, final, s));
5121
5122
97
    if (item->optional_vars) {
5123
28
        VISIT(c, expr, item->optional_vars);
5124
28
    }
5125
69
    else {
5126
    /* Discard result from context.__enter__() */
5127
69
        ADDOP(c, loc, POP_TOP);
5128
69
    }
5129
5130
97
    pos++;
5131
97
    if (pos == asdl_seq_LEN(s->v.With.items)) {
5132
        /* BLOCK code */
5133
93
        VISIT_SEQ(c, stmt, s->v.With.body);
5134
93
    }
5135
4
    else {
5136
4
        RETURN_IF_ERROR(codegen_with_inner(c, s, pos));
5137
4
    }
5138
5139
97
    ADDOP(c, NO_LOCATION, POP_BLOCK);
5140
97
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_WITH, block);
5141
5142
    /* End of body; start the cleanup. */
5143
5144
    /* For successful outcome:
5145
     * call __exit__(None, None, None)
5146
     */
5147
97
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5148
97
    ADDOP(c, loc, POP_TOP);
5149
97
    ADDOP_JUMP(c, loc, JUMP, exit);
5150
5151
    /* For exceptional outcome: */
5152
97
    USE_LABEL(c, final);
5153
5154
97
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5155
97
    ADDOP(c, loc, PUSH_EXC_INFO);
5156
97
    ADDOP(c, loc, WITH_EXCEPT_START);
5157
97
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5158
5159
97
    USE_LABEL(c, exit);
5160
97
    return SUCCESS;
5161
97
}
5162
5163
static int
5164
codegen_with(compiler *c, stmt_ty s)
5165
93
{
5166
93
    return codegen_with_inner(c, s, 0);
5167
93
}
5168
5169
static int
5170
codegen_visit_expr(compiler *c, expr_ty e)
5171
158k
{
5172
158k
    if (Py_EnterRecursiveCall(" during compilation")) {
5173
0
        return ERROR;
5174
0
    }
5175
158k
    location loc = LOC(e);
5176
158k
    switch (e->kind) {
5177
24
    case NamedExpr_kind:
5178
24
        VISIT(c, expr, e->v.NamedExpr.value);
5179
24
        ADDOP_I(c, loc, COPY, 1);
5180
24
        VISIT(c, expr, e->v.NamedExpr.target);
5181
24
        break;
5182
369
    case BoolOp_kind:
5183
369
        return codegen_boolop(c, e);
5184
3.19k
    case BinOp_kind:
5185
3.19k
        VISIT(c, expr, e->v.BinOp.left);
5186
3.19k
        VISIT(c, expr, e->v.BinOp.right);
5187
3.19k
        ADDOP_BINARY(c, loc, e->v.BinOp.op);
5188
3.19k
        break;
5189
3.19k
    case UnaryOp_kind:
5190
622
        VISIT(c, expr, e->v.UnaryOp.operand);
5191
622
        if (e->v.UnaryOp.op == UAdd) {
5192
2
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE);
5193
2
        }
5194
620
        else if (e->v.UnaryOp.op == Not) {
5195
68
            ADDOP(c, loc, TO_BOOL);
5196
68
            ADDOP(c, loc, UNARY_NOT);
5197
68
        }
5198
552
        else {
5199
552
            ADDOP(c, loc, unaryop(e->v.UnaryOp.op));
5200
552
        }
5201
622
        break;
5202
622
    case Lambda_kind:
5203
121
        return codegen_lambda(c, e);
5204
148
    case IfExp_kind:
5205
148
        return codegen_ifexp(c, e);
5206
279
    case Dict_kind:
5207
279
        return codegen_dict(c, e);
5208
61
    case Set_kind:
5209
61
        return codegen_set(c, e);
5210
196
    case GeneratorExp_kind:
5211
196
        return codegen_genexp(c, e);
5212
164
    case ListComp_kind:
5213
164
        return codegen_listcomp(c, e);
5214
3
    case SetComp_kind:
5215
3
        return codegen_setcomp(c, e);
5216
18
    case DictComp_kind:
5217
18
        return codegen_dictcomp(c, e);
5218
183
    case Yield_kind:
5219
183
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5220
0
            return _PyCompile_Error(c, loc, "'yield' outside function");
5221
0
        }
5222
183
        if (e->v.Yield.value) {
5223
180
            VISIT(c, expr, e->v.Yield.value);
5224
180
        }
5225
3
        else {
5226
3
            ADDOP_LOAD_CONST(c, loc, Py_None);
5227
3
        }
5228
183
        ADDOP_YIELD(c, loc);
5229
183
        break;
5230
183
    case YieldFrom_kind:
5231
30
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5232
0
            return _PyCompile_Error(c, loc, "'yield from' outside function");
5233
0
        }
5234
30
        if (SCOPE_TYPE(c) == COMPILE_SCOPE_ASYNC_FUNCTION) {
5235
0
            return _PyCompile_Error(c, loc, "'yield from' inside async function");
5236
0
        }
5237
30
        VISIT(c, expr, e->v.YieldFrom.value);
5238
30
        ADDOP(c, loc, GET_YIELD_FROM_ITER);
5239
30
        ADDOP_LOAD_CONST(c, loc, Py_None);
5240
30
        ADD_YIELD_FROM(c, loc, 0);
5241
30
        break;
5242
30
    case Await_kind:
5243
13
        VISIT(c, expr, e->v.Await.value);
5244
13
        ADDOP_I(c, loc, GET_AWAITABLE, 0);
5245
13
        ADDOP_LOAD_CONST(c, loc, Py_None);
5246
13
        ADD_YIELD_FROM(c, loc, 1);
5247
13
        break;
5248
5.08k
    case Compare_kind:
5249
5.08k
        return codegen_compare(c, e);
5250
16.6k
    case Call_kind:
5251
16.6k
        return codegen_call(c, e);
5252
40.9k
    case Constant_kind:
5253
40.9k
        ADDOP_LOAD_CONST(c, loc, e->v.Constant.value);
5254
40.9k
        break;
5255
40.9k
    case JoinedStr_kind:
5256
651
        return codegen_joined_str(c, e);
5257
0
    case TemplateStr_kind:
5258
0
        return codegen_template_str(c, e);
5259
1.13k
    case FormattedValue_kind:
5260
1.13k
        return codegen_formatted_value(c, e);
5261
0
    case Interpolation_kind:
5262
0
        return codegen_interpolation(c, e);
5263
    /* The following exprs can be assignment targets. */
5264
11.4k
    case Attribute_kind:
5265
11.4k
        if (e->v.Attribute.ctx == Load) {
5266
9.95k
            int ret = can_optimize_super_call(c, e);
5267
9.95k
            RETURN_IF_ERROR(ret);
5268
9.95k
            if (ret) {
5269
61
                RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
5270
61
                int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
5271
45
                    LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
5272
61
                ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
5273
61
                loc = update_start_location_to_match_attr(c, loc, e);
5274
61
                ADDOP(c, loc, NOP);
5275
61
                return SUCCESS;
5276
61
            }
5277
9.95k
        }
5278
11.4k
        RETURN_IF_ERROR(_PyCompile_MaybeAddStaticAttributeToClass(c, e));
5279
11.4k
        VISIT(c, expr, e->v.Attribute.value);
5280
11.4k
        loc = LOC(e);
5281
11.4k
        loc = update_start_location_to_match_attr(c, loc, e);
5282
11.4k
        switch (e->v.Attribute.ctx) {
5283
9.89k
        case Load:
5284
9.89k
            ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5285
9.89k
            break;
5286
9.89k
        case Store:
5287
1.49k
            ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5288
1.49k
            break;
5289
1.49k
        case Del:
5290
15
            ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names);
5291
15
            break;
5292
11.4k
        }
5293
11.4k
        break;
5294
11.4k
    case Subscript_kind:
5295
3.38k
        return codegen_subscript(c, e);
5296
0
    case Starred_kind:
5297
0
        switch (e->v.Starred.ctx) {
5298
0
        case Store:
5299
            /* In all legitimate cases, the Starred node was already replaced
5300
             * by codegen_list/codegen_tuple. XXX: is that okay? */
5301
0
            return _PyCompile_Error(c, loc,
5302
0
                "starred assignment target must be in a list or tuple");
5303
0
        default:
5304
0
            return _PyCompile_Error(c, loc,
5305
0
                "can't use starred expression here");
5306
0
        }
5307
0
        break;
5308
323
    case Slice_kind:
5309
323
        RETURN_IF_ERROR(codegen_slice(c, e));
5310
323
        break;
5311
70.0k
    case Name_kind:
5312
70.0k
        return codegen_nameop(c, loc, e->v.Name.id, e->v.Name.ctx);
5313
    /* child nodes of List and Tuple will have expr_context set */
5314
766
    case List_kind:
5315
766
        return codegen_list(c, e);
5316
2.90k
    case Tuple_kind:
5317
2.90k
        return codegen_tuple(c, e);
5318
158k
    }
5319
56.7k
    return SUCCESS;
5320
158k
}
5321
5322
static bool
5323
is_constant_slice(expr_ty s)
5324
3.74k
{
5325
3.74k
    return s->kind == Slice_kind &&
5326
3.74k
        (s->v.Slice.lower == NULL ||
5327
1.08k
         s->v.Slice.lower->kind == Constant_kind) &&
5328
3.74k
        (s->v.Slice.upper == NULL ||
5329
781
         s->v.Slice.upper->kind == Constant_kind) &&
5330
3.74k
        (s->v.Slice.step == NULL ||
5331
642
         s->v.Slice.step->kind == Constant_kind);
5332
3.74k
}
5333
5334
static bool
5335
should_apply_two_element_slice_optimization(expr_ty s)
5336
3.42k
{
5337
3.42k
    return !is_constant_slice(s) &&
5338
3.42k
           s->kind == Slice_kind &&
5339
3.42k
           s->v.Slice.step == NULL;
5340
3.42k
}
5341
5342
static int
5343
codegen_augassign(compiler *c, stmt_ty s)
5344
577
{
5345
577
    assert(s->kind == AugAssign_kind);
5346
577
    expr_ty e = s->v.AugAssign.target;
5347
5348
577
    location loc = LOC(e);
5349
5350
577
    switch (e->kind) {
5351
63
    case Attribute_kind:
5352
63
        VISIT(c, expr, e->v.Attribute.value);
5353
63
        ADDOP_I(c, loc, COPY, 1);
5354
63
        loc = update_start_location_to_match_attr(c, loc, e);
5355
63
        ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5356
63
        break;
5357
63
    case Subscript_kind:
5358
17
        VISIT(c, expr, e->v.Subscript.value);
5359
17
        if (should_apply_two_element_slice_optimization(e->v.Subscript.slice)) {
5360
0
            RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5361
0
            ADDOP_I(c, loc, COPY, 3);
5362
0
            ADDOP_I(c, loc, COPY, 3);
5363
0
            ADDOP_I(c, loc, COPY, 3);
5364
0
            ADDOP(c, loc, BINARY_SLICE);
5365
0
        }
5366
17
        else {
5367
17
            VISIT(c, expr, e->v.Subscript.slice);
5368
17
            ADDOP_I(c, loc, COPY, 2);
5369
17
            ADDOP_I(c, loc, COPY, 2);
5370
17
            ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5371
17
        }
5372
17
        break;
5373
497
    case Name_kind:
5374
497
        RETURN_IF_ERROR(codegen_nameop(c, loc, e->v.Name.id, Load));
5375
497
        break;
5376
497
    default:
5377
0
        PyErr_Format(PyExc_SystemError,
5378
0
            "invalid node type (%d) for augmented assignment",
5379
0
            e->kind);
5380
0
        return ERROR;
5381
577
    }
5382
5383
577
    loc = LOC(s);
5384
5385
577
    VISIT(c, expr, s->v.AugAssign.value);
5386
577
    ADDOP_INPLACE(c, loc, s->v.AugAssign.op);
5387
5388
577
    loc = LOC(e);
5389
5390
577
    switch (e->kind) {
5391
63
    case Attribute_kind:
5392
63
        loc = update_start_location_to_match_attr(c, loc, e);
5393
63
        ADDOP_I(c, loc, SWAP, 2);
5394
63
        ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5395
63
        break;
5396
63
    case Subscript_kind:
5397
17
        if (should_apply_two_element_slice_optimization(e->v.Subscript.slice)) {
5398
0
            ADDOP_I(c, loc, SWAP, 4);
5399
0
            ADDOP_I(c, loc, SWAP, 3);
5400
0
            ADDOP_I(c, loc, SWAP, 2);
5401
0
            ADDOP(c, loc, STORE_SLICE);
5402
0
        }
5403
17
        else {
5404
17
            ADDOP_I(c, loc, SWAP, 3);
5405
17
            ADDOP_I(c, loc, SWAP, 2);
5406
17
            ADDOP(c, loc, STORE_SUBSCR);
5407
17
        }
5408
17
        break;
5409
497
    case Name_kind:
5410
497
        return codegen_nameop(c, loc, e->v.Name.id, Store);
5411
0
    default:
5412
0
        Py_UNREACHABLE();
5413
577
    }
5414
80
    return SUCCESS;
5415
577
}
5416
5417
static int
5418
codegen_check_ann_expr(compiler *c, expr_ty e)
5419
0
{
5420
0
    VISIT(c, expr, e);
5421
0
    ADDOP(c, LOC(e), POP_TOP);
5422
0
    return SUCCESS;
5423
0
}
5424
5425
static int
5426
codegen_check_annotation(compiler *c, stmt_ty s)
5427
0
{
5428
    /* Annotations of complex targets does not produce anything
5429
       under annotations future */
5430
0
    if (FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) {
5431
0
        return SUCCESS;
5432
0
    }
5433
5434
    /* Annotations are only evaluated in a module or class. */
5435
0
    if (SCOPE_TYPE(c) == COMPILE_SCOPE_MODULE ||
5436
0
        SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS) {
5437
0
        return codegen_check_ann_expr(c, s->v.AnnAssign.annotation);
5438
0
    }
5439
0
    return SUCCESS;
5440
0
}
5441
5442
static int
5443
codegen_check_ann_subscr(compiler *c, expr_ty e)
5444
0
{
5445
    /* We check that everything in a subscript is defined at runtime. */
5446
0
    switch (e->kind) {
5447
0
    case Slice_kind:
5448
0
        if (e->v.Slice.lower && codegen_check_ann_expr(c, e->v.Slice.lower) < 0) {
5449
0
            return ERROR;
5450
0
        }
5451
0
        if (e->v.Slice.upper && codegen_check_ann_expr(c, e->v.Slice.upper) < 0) {
5452
0
            return ERROR;
5453
0
        }
5454
0
        if (e->v.Slice.step && codegen_check_ann_expr(c, e->v.Slice.step) < 0) {
5455
0
            return ERROR;
5456
0
        }
5457
0
        return SUCCESS;
5458
0
    case Tuple_kind: {
5459
        /* extended slice */
5460
0
        asdl_expr_seq *elts = e->v.Tuple.elts;
5461
0
        Py_ssize_t i, n = asdl_seq_LEN(elts);
5462
0
        for (i = 0; i < n; i++) {
5463
0
            RETURN_IF_ERROR(codegen_check_ann_subscr(c, asdl_seq_GET(elts, i)));
5464
0
        }
5465
0
        return SUCCESS;
5466
0
    }
5467
0
    default:
5468
0
        return codegen_check_ann_expr(c, e);
5469
0
    }
5470
0
}
5471
5472
static int
5473
codegen_annassign(compiler *c, stmt_ty s)
5474
0
{
5475
0
    location loc = LOC(s);
5476
0
    expr_ty targ = s->v.AnnAssign.target;
5477
0
    bool future_annotations = FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS;
5478
0
    PyObject *mangled;
5479
5480
0
    assert(s->kind == AnnAssign_kind);
5481
5482
    /* We perform the actual assignment first. */
5483
0
    if (s->v.AnnAssign.value) {
5484
0
        VISIT(c, expr, s->v.AnnAssign.value);
5485
0
        VISIT(c, expr, targ);
5486
0
    }
5487
0
    switch (targ->kind) {
5488
0
    case Name_kind:
5489
        /* If we have a simple name in a module or class, store annotation. */
5490
0
        if (s->v.AnnAssign.simple &&
5491
0
            (SCOPE_TYPE(c) == COMPILE_SCOPE_MODULE ||
5492
0
             SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS)) {
5493
0
            if (future_annotations) {
5494
0
                VISIT(c, annexpr, s->v.AnnAssign.annotation);
5495
0
                ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
5496
0
                mangled = _PyCompile_MaybeMangle(c, targ->v.Name.id);
5497
0
                ADDOP_LOAD_CONST_NEW(c, loc, mangled);
5498
0
                ADDOP(c, loc, STORE_SUBSCR);
5499
0
            }
5500
0
            else {
5501
0
                PyObject *conditional_annotation_index = NULL;
5502
0
                RETURN_IF_ERROR(_PyCompile_AddDeferredAnnotation(
5503
0
                    c, s, &conditional_annotation_index));
5504
0
                if (conditional_annotation_index != NULL) {
5505
0
                    ADDOP_NAME(
5506
0
                        c, loc,
5507
0
                        SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS ? LOAD_DEREF : LOAD_NAME,
5508
0
                        &_Py_ID(__conditional_annotations__), cellvars);
5509
0
                    ADDOP_LOAD_CONST_NEW(c, loc, conditional_annotation_index);
5510
0
                    ADDOP_I(c, loc, SET_ADD, 1);
5511
0
                    ADDOP(c, loc, POP_TOP);
5512
0
                }
5513
0
            }
5514
0
        }
5515
0
        break;
5516
0
    case Attribute_kind:
5517
0
        if (!s->v.AnnAssign.value &&
5518
0
            codegen_check_ann_expr(c, targ->v.Attribute.value) < 0) {
5519
0
            return ERROR;
5520
0
        }
5521
0
        break;
5522
0
    case Subscript_kind:
5523
0
        if (!s->v.AnnAssign.value &&
5524
0
            (codegen_check_ann_expr(c, targ->v.Subscript.value) < 0 ||
5525
0
             codegen_check_ann_subscr(c, targ->v.Subscript.slice) < 0)) {
5526
0
                return ERROR;
5527
0
        }
5528
0
        break;
5529
0
    default:
5530
0
        PyErr_Format(PyExc_SystemError,
5531
0
                     "invalid node type (%d) for annotated assignment",
5532
0
                     targ->kind);
5533
0
        return ERROR;
5534
0
    }
5535
    /* Annotation is evaluated last. */
5536
0
    if (future_annotations && !s->v.AnnAssign.simple && codegen_check_annotation(c, s) < 0) {
5537
0
        return ERROR;
5538
0
    }
5539
0
    return SUCCESS;
5540
0
}
5541
5542
static int
5543
codegen_subscript(compiler *c, expr_ty e)
5544
3.38k
{
5545
3.38k
    location loc = LOC(e);
5546
3.38k
    expr_context_ty ctx = e->v.Subscript.ctx;
5547
5548
3.38k
    if (ctx == Load) {
5549
2.61k
        RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value));
5550
2.61k
        RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice));
5551
2.61k
    }
5552
5553
3.38k
    VISIT(c, expr, e->v.Subscript.value);
5554
3.38k
    if (should_apply_two_element_slice_optimization(e->v.Subscript.slice) &&
5555
3.38k
        ctx != Del
5556
3.38k
    ) {
5557
437
        RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5558
437
        if (ctx == Load) {
5559
415
            ADDOP(c, loc, BINARY_SLICE);
5560
415
        }
5561
22
        else {
5562
22
            assert(ctx == Store);
5563
22
            ADDOP(c, loc, STORE_SLICE);
5564
22
        }
5565
437
    }
5566
2.94k
    else {
5567
2.94k
        VISIT(c, expr, e->v.Subscript.slice);
5568
2.94k
        switch (ctx) {
5569
2.19k
            case Load:
5570
2.19k
                ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5571
2.19k
                break;
5572
2.19k
            case Store:
5573
687
                ADDOP(c, loc, STORE_SUBSCR);
5574
687
                break;
5575
687
            case Del:
5576
67
                ADDOP(c, loc, DELETE_SUBSCR);
5577
67
                break;
5578
2.94k
        }
5579
2.94k
    }
5580
3.38k
    return SUCCESS;
5581
3.38k
}
5582
5583
static int
5584
codegen_slice_two_parts(compiler *c, expr_ty s)
5585
454
{
5586
454
    if (s->v.Slice.lower) {
5587
323
        VISIT(c, expr, s->v.Slice.lower);
5588
323
    }
5589
131
    else {
5590
131
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5591
131
    }
5592
5593
454
    if (s->v.Slice.upper) {
5594
317
        VISIT(c, expr, s->v.Slice.upper);
5595
317
    }
5596
137
    else {
5597
137
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5598
137
    }
5599
5600
454
    return 0;
5601
454
}
5602
5603
static int
5604
codegen_slice(compiler *c, expr_ty s)
5605
323
{
5606
323
    int n = 2;
5607
323
    assert(s->kind == Slice_kind);
5608
5609
323
    if (is_constant_slice(s)) {
5610
306
        PyObject *start = NULL;
5611
306
        if (s->v.Slice.lower) {
5612
179
            start = s->v.Slice.lower->v.Constant.value;
5613
179
        }
5614
306
        PyObject *stop = NULL;
5615
306
        if (s->v.Slice.upper) {
5616
98
            stop = s->v.Slice.upper->v.Constant.value;
5617
98
        }
5618
306
        PyObject *step = NULL;
5619
306
        if (s->v.Slice.step) {
5620
8
            step = s->v.Slice.step->v.Constant.value;
5621
8
        }
5622
306
        PyObject *slice = PySlice_New(start, stop, step);
5623
306
        if (slice == NULL) {
5624
0
            return ERROR;
5625
0
        }
5626
306
        ADDOP_LOAD_CONST_NEW(c, LOC(s), slice);
5627
306
        return SUCCESS;
5628
306
    }
5629
5630
17
    RETURN_IF_ERROR(codegen_slice_two_parts(c, s));
5631
5632
17
    if (s->v.Slice.step) {
5633
15
        n++;
5634
15
        VISIT(c, expr, s->v.Slice.step);
5635
15
    }
5636
5637
17
    ADDOP_I(c, LOC(s), BUILD_SLICE, n);
5638
17
    return SUCCESS;
5639
17
}
5640
5641
5642
// PEP 634: Structural Pattern Matching
5643
5644
// To keep things simple, all codegen_pattern_* routines follow the convention
5645
// of consuming TOS (the subject for the given pattern) and calling
5646
// jump_to_fail_pop on failure (no match).
5647
5648
// When calling into these routines, it's important that pc->on_top be kept
5649
// updated to reflect the current number of items that we are using on the top
5650
// of the stack: they will be popped on failure, and any name captures will be
5651
// stored *underneath* them on success. This lets us defer all names stores
5652
// until the *entire* pattern matches.
5653
5654
#define WILDCARD_CHECK(N) \
5655
0
    ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name)
5656
5657
#define WILDCARD_STAR_CHECK(N) \
5658
0
    ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
5659
5660
// Limit permitted subexpressions, even if the parser & AST validator let them through
5661
#define MATCH_VALUE_EXPR(N) \
5662
0
    ((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
5663
5664
// Allocate or resize pc->fail_pop to allow for n items to be popped on failure.
5665
static int
5666
ensure_fail_pop(compiler *c, pattern_context *pc, Py_ssize_t n)
5667
0
{
5668
0
    Py_ssize_t size = n + 1;
5669
0
    if (size <= pc->fail_pop_size) {
5670
0
        return SUCCESS;
5671
0
    }
5672
0
    Py_ssize_t needed = sizeof(jump_target_label) * size;
5673
0
    jump_target_label *resized = PyMem_Realloc(pc->fail_pop, needed);
5674
0
    if (resized == NULL) {
5675
0
        PyErr_NoMemory();
5676
0
        return ERROR;
5677
0
    }
5678
0
    pc->fail_pop = resized;
5679
0
    while (pc->fail_pop_size < size) {
5680
0
        NEW_JUMP_TARGET_LABEL(c, new_block);
5681
0
        pc->fail_pop[pc->fail_pop_size++] = new_block;
5682
0
    }
5683
0
    return SUCCESS;
5684
0
}
5685
5686
// Use op to jump to the correct fail_pop block.
5687
static int
5688
jump_to_fail_pop(compiler *c, location loc,
5689
                 pattern_context *pc, int op)
5690
0
{
5691
    // Pop any items on the top of the stack, plus any objects we were going to
5692
    // capture on success:
5693
0
    Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
5694
0
    RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops));
5695
0
    ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
5696
0
    return SUCCESS;
5697
0
}
5698
5699
// Build all of the fail_pop blocks and reset fail_pop.
5700
static int
5701
emit_and_reset_fail_pop(compiler *c, location loc,
5702
                        pattern_context *pc)
5703
0
{
5704
0
    if (!pc->fail_pop_size) {
5705
0
        assert(pc->fail_pop == NULL);
5706
0
        return SUCCESS;
5707
0
    }
5708
0
    while (--pc->fail_pop_size) {
5709
0
        USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
5710
0
        if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, loc) < 0) {
5711
0
            pc->fail_pop_size = 0;
5712
0
            PyMem_Free(pc->fail_pop);
5713
0
            pc->fail_pop = NULL;
5714
0
            return ERROR;
5715
0
        }
5716
0
    }
5717
0
    USE_LABEL(c, pc->fail_pop[0]);
5718
0
    PyMem_Free(pc->fail_pop);
5719
0
    pc->fail_pop = NULL;
5720
0
    return SUCCESS;
5721
0
}
5722
5723
static int
5724
codegen_error_duplicate_store(compiler *c, location loc, identifier n)
5725
0
{
5726
0
    return _PyCompile_Error(c, loc,
5727
0
        "multiple assignments to name %R in pattern", n);
5728
0
}
5729
5730
// Duplicate the effect of 3.10's ROT_* instructions using SWAPs.
5731
static int
5732
codegen_pattern_helper_rotate(compiler *c, location loc, Py_ssize_t count)
5733
0
{
5734
0
    while (1 < count) {
5735
0
        ADDOP_I(c, loc, SWAP, count--);
5736
0
    }
5737
0
    return SUCCESS;
5738
0
}
5739
5740
static int
5741
codegen_pattern_helper_store_name(compiler *c, location loc,
5742
                                  identifier n, pattern_context *pc)
5743
0
{
5744
0
    if (n == NULL) {
5745
0
        ADDOP(c, loc, POP_TOP);
5746
0
        return SUCCESS;
5747
0
    }
5748
    // Can't assign to the same name twice:
5749
0
    int duplicate = PySequence_Contains(pc->stores, n);
5750
0
    RETURN_IF_ERROR(duplicate);
5751
0
    if (duplicate) {
5752
0
        return codegen_error_duplicate_store(c, loc, n);
5753
0
    }
5754
    // Rotate this object underneath any items we need to preserve:
5755
0
    Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
5756
0
    RETURN_IF_ERROR(codegen_pattern_helper_rotate(c, loc, rotations));
5757
0
    RETURN_IF_ERROR(PyList_Append(pc->stores, n));
5758
0
    return SUCCESS;
5759
0
}
5760
5761
5762
static int
5763
codegen_pattern_unpack_helper(compiler *c, location loc,
5764
                              asdl_pattern_seq *elts)
5765
0
{
5766
0
    Py_ssize_t n = asdl_seq_LEN(elts);
5767
0
    int seen_star = 0;
5768
0
    for (Py_ssize_t i = 0; i < n; i++) {
5769
0
        pattern_ty elt = asdl_seq_GET(elts, i);
5770
0
        if (elt->kind == MatchStar_kind && !seen_star) {
5771
0
            if ((i >= (1 << 8)) ||
5772
0
                (n-i-1 >= (INT_MAX >> 8))) {
5773
0
                return _PyCompile_Error(c, loc,
5774
0
                    "too many expressions in "
5775
0
                    "star-unpacking sequence pattern");
5776
0
            }
5777
0
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
5778
0
            seen_star = 1;
5779
0
        }
5780
0
        else if (elt->kind == MatchStar_kind) {
5781
0
            return _PyCompile_Error(c, loc,
5782
0
                "multiple starred expressions in sequence pattern");
5783
0
        }
5784
0
    }
5785
0
    if (!seen_star) {
5786
0
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
5787
0
    }
5788
0
    return SUCCESS;
5789
0
}
5790
5791
static int
5792
pattern_helper_sequence_unpack(compiler *c, location loc,
5793
                               asdl_pattern_seq *patterns, Py_ssize_t star,
5794
                               pattern_context *pc)
5795
0
{
5796
0
    RETURN_IF_ERROR(codegen_pattern_unpack_helper(c, loc, patterns));
5797
0
    Py_ssize_t size = asdl_seq_LEN(patterns);
5798
    // We've now got a bunch of new subjects on the stack. They need to remain
5799
    // there after each subpattern match:
5800
0
    pc->on_top += size;
5801
0
    for (Py_ssize_t i = 0; i < size; i++) {
5802
        // One less item to keep track of each time we loop through:
5803
0
        pc->on_top--;
5804
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
5805
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5806
0
    }
5807
0
    return SUCCESS;
5808
0
}
5809
5810
// Like pattern_helper_sequence_unpack, but uses BINARY_OP/NB_SUBSCR instead of
5811
// UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a
5812
// starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc.
5813
static int
5814
pattern_helper_sequence_subscr(compiler *c, location loc,
5815
                               asdl_pattern_seq *patterns, Py_ssize_t star,
5816
                               pattern_context *pc)
5817
0
{
5818
    // We need to keep the subject around for extracting elements:
5819
0
    pc->on_top++;
5820
0
    Py_ssize_t size = asdl_seq_LEN(patterns);
5821
0
    for (Py_ssize_t i = 0; i < size; i++) {
5822
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
5823
0
        if (WILDCARD_CHECK(pattern)) {
5824
0
            continue;
5825
0
        }
5826
0
        if (i == star) {
5827
0
            assert(WILDCARD_STAR_CHECK(pattern));
5828
0
            continue;
5829
0
        }
5830
0
        ADDOP_I(c, loc, COPY, 1);
5831
0
        if (i < star) {
5832
0
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i));
5833
0
        }
5834
0
        else {
5835
            // The subject may not support negative indexing! Compute a
5836
            // nonnegative index:
5837
0
            ADDOP(c, loc, GET_LEN);
5838
0
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i));
5839
0
            ADDOP_BINARY(c, loc, Sub);
5840
0
        }
5841
0
        ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5842
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5843
0
    }
5844
    // Pop the subject, we're done with it:
5845
0
    pc->on_top--;
5846
0
    ADDOP(c, loc, POP_TOP);
5847
0
    return SUCCESS;
5848
0
}
5849
5850
// Like codegen_pattern, but turn off checks for irrefutability.
5851
static int
5852
codegen_pattern_subpattern(compiler *c,
5853
                            pattern_ty p, pattern_context *pc)
5854
0
{
5855
0
    int allow_irrefutable = pc->allow_irrefutable;
5856
0
    pc->allow_irrefutable = 1;
5857
0
    RETURN_IF_ERROR(codegen_pattern(c, p, pc));
5858
0
    pc->allow_irrefutable = allow_irrefutable;
5859
0
    return SUCCESS;
5860
0
}
5861
5862
static int
5863
codegen_pattern_as(compiler *c, pattern_ty p, pattern_context *pc)
5864
0
{
5865
0
    assert(p->kind == MatchAs_kind);
5866
0
    if (p->v.MatchAs.pattern == NULL) {
5867
        // An irrefutable match:
5868
0
        if (!pc->allow_irrefutable) {
5869
0
            if (p->v.MatchAs.name) {
5870
0
                const char *e = "name capture %R makes remaining patterns unreachable";
5871
0
                return _PyCompile_Error(c, LOC(p), e, p->v.MatchAs.name);
5872
0
            }
5873
0
            const char *e = "wildcard makes remaining patterns unreachable";
5874
0
            return _PyCompile_Error(c, LOC(p), e);
5875
0
        }
5876
0
        return codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc);
5877
0
    }
5878
    // Need to make a copy for (possibly) storing later:
5879
0
    pc->on_top++;
5880
0
    ADDOP_I(c, LOC(p), COPY, 1);
5881
0
    RETURN_IF_ERROR(codegen_pattern(c, p->v.MatchAs.pattern, pc));
5882
    // Success! Store it:
5883
0
    pc->on_top--;
5884
0
    RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc));
5885
0
    return SUCCESS;
5886
0
}
5887
5888
static int
5889
codegen_pattern_star(compiler *c, pattern_ty p, pattern_context *pc)
5890
0
{
5891
0
    assert(p->kind == MatchStar_kind);
5892
0
    RETURN_IF_ERROR(
5893
0
        codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc));
5894
0
    return SUCCESS;
5895
0
}
5896
5897
static int
5898
validate_kwd_attrs(compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns)
5899
0
{
5900
    // Any errors will point to the pattern rather than the arg name as the
5901
    // parser is only supplying identifiers rather than Name or keyword nodes
5902
0
    Py_ssize_t nattrs = asdl_seq_LEN(attrs);
5903
0
    for (Py_ssize_t i = 0; i < nattrs; i++) {
5904
0
        identifier attr = ((identifier)asdl_seq_GET(attrs, i));
5905
0
        for (Py_ssize_t j = i + 1; j < nattrs; j++) {
5906
0
            identifier other = ((identifier)asdl_seq_GET(attrs, j));
5907
0
            if (!PyUnicode_Compare(attr, other)) {
5908
0
                location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j));
5909
0
                return _PyCompile_Error(c, loc, "attribute name repeated "
5910
0
                                                "in class pattern: %U", attr);
5911
0
            }
5912
0
        }
5913
0
    }
5914
0
    return SUCCESS;
5915
0
}
5916
5917
static int
5918
codegen_pattern_class(compiler *c, pattern_ty p, pattern_context *pc)
5919
0
{
5920
0
    assert(p->kind == MatchClass_kind);
5921
0
    asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
5922
0
    asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs;
5923
0
    asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns;
5924
0
    Py_ssize_t nargs = asdl_seq_LEN(patterns);
5925
0
    Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs);
5926
0
    Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns);
5927
0
    if (nattrs != nkwd_patterns) {
5928
        // AST validator shouldn't let this happen, but if it does,
5929
        // just fail, don't crash out of the interpreter
5930
0
        const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern";
5931
0
        return _PyCompile_Error(c, LOC(p), e, nattrs, nkwd_patterns);
5932
0
    }
5933
0
    if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) {
5934
0
        const char *e = "too many sub-patterns in class pattern %R";
5935
0
        return _PyCompile_Error(c, LOC(p), e, p->v.MatchClass.cls);
5936
0
    }
5937
0
    if (nattrs) {
5938
0
        RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
5939
0
    }
5940
0
    VISIT(c, expr, p->v.MatchClass.cls);
5941
0
    PyObject *attr_names = PyTuple_New(nattrs);
5942
0
    if (attr_names == NULL) {
5943
0
        return ERROR;
5944
0
    }
5945
0
    Py_ssize_t i;
5946
0
    for (i = 0; i < nattrs; i++) {
5947
0
        PyObject *name = asdl_seq_GET(kwd_attrs, i);
5948
0
        PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name));
5949
0
    }
5950
0
    ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names);
5951
0
    ADDOP_I(c, LOC(p), MATCH_CLASS, nargs);
5952
0
    ADDOP_I(c, LOC(p), COPY, 1);
5953
0
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
5954
0
    ADDOP_I(c, LOC(p), IS_OP, 1);
5955
    // TOS is now a tuple of (nargs + nattrs) attributes (or None):
5956
0
    pc->on_top++;
5957
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
5958
0
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs);
5959
0
    pc->on_top += nargs + nattrs - 1;
5960
0
    for (i = 0; i < nargs + nattrs; i++) {
5961
0
        pc->on_top--;
5962
0
        pattern_ty pattern;
5963
0
        if (i < nargs) {
5964
            // Positional:
5965
0
            pattern = asdl_seq_GET(patterns, i);
5966
0
        }
5967
0
        else {
5968
            // Keyword:
5969
0
            pattern = asdl_seq_GET(kwd_patterns, i - nargs);
5970
0
        }
5971
0
        if (WILDCARD_CHECK(pattern)) {
5972
0
            ADDOP(c, LOC(p), POP_TOP);
5973
0
            continue;
5974
0
        }
5975
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5976
0
    }
5977
    // Success! Pop the tuple of attributes:
5978
0
    return SUCCESS;
5979
0
}
5980
5981
static int
5982
codegen_pattern_mapping_key(compiler *c, PyObject *seen, pattern_ty p, Py_ssize_t i)
5983
0
{
5984
0
    asdl_expr_seq *keys = p->v.MatchMapping.keys;
5985
0
    asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
5986
0
    expr_ty key = asdl_seq_GET(keys, i);
5987
0
    if (key == NULL) {
5988
0
        const char *e = "can't use NULL keys in MatchMapping "
5989
0
                        "(set 'rest' parameter instead)";
5990
0
        location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
5991
0
        return _PyCompile_Error(c, loc, e);
5992
0
    }
5993
5994
0
    if (key->kind == Constant_kind) {
5995
0
        int in_seen = PySet_Contains(seen, key->v.Constant.value);
5996
0
        RETURN_IF_ERROR(in_seen);
5997
0
        if (in_seen) {
5998
0
            const char *e = "mapping pattern checks duplicate key (%R)";
5999
0
            return _PyCompile_Error(c, LOC(p), e, key->v.Constant.value);
6000
0
        }
6001
0
        RETURN_IF_ERROR(PySet_Add(seen, key->v.Constant.value));
6002
0
    }
6003
0
    else if (key->kind != Attribute_kind) {
6004
0
        const char *e = "mapping pattern keys may only match literals and attribute lookups";
6005
0
        return _PyCompile_Error(c, LOC(p), e);
6006
0
    }
6007
0
    VISIT(c, expr, key);
6008
0
    return SUCCESS;
6009
0
}
6010
6011
static int
6012
codegen_pattern_mapping(compiler *c, pattern_ty p,
6013
                        pattern_context *pc)
6014
0
{
6015
0
    assert(p->kind == MatchMapping_kind);
6016
0
    asdl_expr_seq *keys = p->v.MatchMapping.keys;
6017
0
    asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
6018
0
    Py_ssize_t size = asdl_seq_LEN(keys);
6019
0
    Py_ssize_t npatterns = asdl_seq_LEN(patterns);
6020
0
    if (size != npatterns) {
6021
        // AST validator shouldn't let this happen, but if it does,
6022
        // just fail, don't crash out of the interpreter
6023
0
        const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern";
6024
0
        return _PyCompile_Error(c, LOC(p), e, size, npatterns);
6025
0
    }
6026
    // We have a double-star target if "rest" is set
6027
0
    PyObject *star_target = p->v.MatchMapping.rest;
6028
    // We need to keep the subject on top during the mapping and length checks:
6029
0
    pc->on_top++;
6030
0
    ADDOP(c, LOC(p), MATCH_MAPPING);
6031
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6032
0
    if (!size && !star_target) {
6033
        // If the pattern is just "{}", we're done! Pop the subject:
6034
0
        pc->on_top--;
6035
0
        ADDOP(c, LOC(p), POP_TOP);
6036
0
        return SUCCESS;
6037
0
    }
6038
0
    if (size) {
6039
        // If the pattern has any keys in it, perform a length check:
6040
0
        ADDOP(c, LOC(p), GET_LEN);
6041
0
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6042
0
        ADDOP_COMPARE(c, LOC(p), GtE);
6043
0
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6044
0
    }
6045
0
    if (INT_MAX < size - 1) {
6046
0
        return _PyCompile_Error(c, LOC(p), "too many sub-patterns in mapping pattern");
6047
0
    }
6048
    // Collect all of the keys into a tuple for MATCH_KEYS and
6049
    // **rest. They can either be dotted names or literals:
6050
6051
    // Maintaining a set of Constant_kind kind keys allows us to raise a
6052
    // SyntaxError in the case of duplicates.
6053
0
    PyObject *seen = PySet_New(NULL);
6054
0
    if (seen == NULL) {
6055
0
        return ERROR;
6056
0
    }
6057
0
    for (Py_ssize_t i = 0; i < size; i++) {
6058
0
        if (codegen_pattern_mapping_key(c, seen, p, i) < 0) {
6059
0
            Py_DECREF(seen);
6060
0
            return ERROR;
6061
0
        }
6062
0
    }
6063
0
    Py_DECREF(seen);
6064
6065
    // all keys have been checked; there are no duplicates
6066
6067
0
    ADDOP_I(c, LOC(p), BUILD_TUPLE, size);
6068
0
    ADDOP(c, LOC(p), MATCH_KEYS);
6069
    // There's now a tuple of keys and a tuple of values on top of the subject:
6070
0
    pc->on_top += 2;
6071
0
    ADDOP_I(c, LOC(p), COPY, 1);
6072
0
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
6073
0
    ADDOP_I(c, LOC(p), IS_OP, 1);
6074
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6075
    // So far so good. Use that tuple of values on the stack to match
6076
    // sub-patterns against:
6077
0
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);
6078
0
    pc->on_top += size - 1;
6079
0
    for (Py_ssize_t i = 0; i < size; i++) {
6080
0
        pc->on_top--;
6081
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6082
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6083
0
    }
6084
    // If we get this far, it's a match! Whatever happens next should consume
6085
    // the tuple of keys and the subject:
6086
0
    pc->on_top -= 2;
6087
0
    if (star_target) {
6088
        // If we have a starred name, bind a dict of remaining items to it (this may
6089
        // seem a bit inefficient, but keys is rarely big enough to actually impact
6090
        // runtime):
6091
        // rest = dict(TOS1)
6092
        // for key in TOS:
6093
        //     del rest[key]
6094
0
        ADDOP_I(c, LOC(p), BUILD_MAP, 0);           // [subject, keys, empty]
6095
0
        ADDOP_I(c, LOC(p), SWAP, 3);                // [empty, keys, subject]
6096
0
        ADDOP_I(c, LOC(p), DICT_UPDATE, 2);         // [copy, keys]
6097
0
        ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);  // [copy, keys...]
6098
0
        while (size) {
6099
0
            ADDOP_I(c, LOC(p), COPY, 1 + size--);   // [copy, keys..., copy]
6100
0
            ADDOP_I(c, LOC(p), SWAP, 2);            // [copy, keys..., copy, key]
6101
0
            ADDOP(c, LOC(p), DELETE_SUBSCR);        // [copy, keys...]
6102
0
        }
6103
0
        RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), star_target, pc));
6104
0
    }
6105
0
    else {
6106
0
        ADDOP(c, LOC(p), POP_TOP);  // Tuple of keys.
6107
0
        ADDOP(c, LOC(p), POP_TOP);  // Subject.
6108
0
    }
6109
0
    return SUCCESS;
6110
0
}
6111
6112
static int
6113
codegen_pattern_or(compiler *c, pattern_ty p, pattern_context *pc)
6114
0
{
6115
0
    assert(p->kind == MatchOr_kind);
6116
0
    NEW_JUMP_TARGET_LABEL(c, end);
6117
0
    Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns);
6118
0
    assert(size > 1);
6119
    // We're going to be messing with pc. Keep the original info handy:
6120
0
    pattern_context old_pc = *pc;
6121
0
    Py_INCREF(pc->stores);
6122
    // control is the list of names bound by the first alternative. It is used
6123
    // for checking different name bindings in alternatives, and for correcting
6124
    // the order in which extracted elements are placed on the stack.
6125
0
    PyObject *control = NULL;
6126
    // NOTE: We can't use returning macros anymore! goto error on error.
6127
0
    for (Py_ssize_t i = 0; i < size; i++) {
6128
0
        pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i);
6129
0
        PyObject *pc_stores = PyList_New(0);
6130
0
        if (pc_stores == NULL) {
6131
0
            goto error;
6132
0
        }
6133
0
        Py_SETREF(pc->stores, pc_stores);
6134
        // An irrefutable sub-pattern must be last, if it is allowed at all:
6135
0
        pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable;
6136
0
        pc->fail_pop = NULL;
6137
0
        pc->fail_pop_size = 0;
6138
0
        pc->on_top = 0;
6139
0
        if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 ||
6140
0
            codegen_pattern(c, alt, pc) < 0) {
6141
0
            goto error;
6142
0
        }
6143
        // Success!
6144
0
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6145
0
        if (!i) {
6146
            // This is the first alternative, so save its stores as a "control"
6147
            // for the others (they can't bind a different set of names, and
6148
            // might need to be reordered):
6149
0
            assert(control == NULL);
6150
0
            control = Py_NewRef(pc->stores);
6151
0
        }
6152
0
        else if (nstores != PyList_GET_SIZE(control)) {
6153
0
            goto diff;
6154
0
        }
6155
0
        else if (nstores) {
6156
            // There were captures. Check to see if we differ from control:
6157
0
            Py_ssize_t icontrol = nstores;
6158
0
            while (icontrol--) {
6159
0
                PyObject *name = PyList_GET_ITEM(control, icontrol);
6160
0
                Py_ssize_t istores = PySequence_Index(pc->stores, name);
6161
0
                if (istores < 0) {
6162
0
                    PyErr_Clear();
6163
0
                    goto diff;
6164
0
                }
6165
0
                if (icontrol != istores) {
6166
                    // Reorder the names on the stack to match the order of the
6167
                    // names in control. There's probably a better way of doing
6168
                    // this; the current solution is potentially very
6169
                    // inefficient when each alternative subpattern binds lots
6170
                    // of names in different orders. It's fine for reasonable
6171
                    // cases, though, and the peephole optimizer will ensure
6172
                    // that the final code is as efficient as possible.
6173
0
                    assert(istores < icontrol);
6174
0
                    Py_ssize_t rotations = istores + 1;
6175
                    // Perform the same rotation on pc->stores:
6176
0
                    PyObject *rotated = PyList_GetSlice(pc->stores, 0,
6177
0
                                                        rotations);
6178
0
                    if (rotated == NULL ||
6179
0
                        PyList_SetSlice(pc->stores, 0, rotations, NULL) ||
6180
0
                        PyList_SetSlice(pc->stores, icontrol - istores,
6181
0
                                        icontrol - istores, rotated))
6182
0
                    {
6183
0
                        Py_XDECREF(rotated);
6184
0
                        goto error;
6185
0
                    }
6186
0
                    Py_DECREF(rotated);
6187
                    // That just did:
6188
                    // rotated = pc_stores[:rotations]
6189
                    // del pc_stores[:rotations]
6190
                    // pc_stores[icontrol-istores:icontrol-istores] = rotated
6191
                    // Do the same thing to the stack, using several
6192
                    // rotations:
6193
0
                    while (rotations--) {
6194
0
                        if (codegen_pattern_helper_rotate(c, LOC(alt), icontrol + 1) < 0) {
6195
0
                            goto error;
6196
0
                        }
6197
0
                    }
6198
0
                }
6199
0
            }
6200
0
        }
6201
0
        assert(control);
6202
0
        if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 ||
6203
0
            emit_and_reset_fail_pop(c, LOC(alt), pc) < 0)
6204
0
        {
6205
0
            goto error;
6206
0
        }
6207
0
    }
6208
0
    Py_DECREF(pc->stores);
6209
0
    *pc = old_pc;
6210
0
    Py_INCREF(pc->stores);
6211
    // Need to NULL this for the PyMem_Free call in the error block.
6212
0
    old_pc.fail_pop = NULL;
6213
    // No match. Pop the remaining copy of the subject and fail:
6214
0
    if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 ||
6215
0
        jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) {
6216
0
        goto error;
6217
0
    }
6218
6219
0
    USE_LABEL(c, end);
6220
0
    Py_ssize_t nstores = PyList_GET_SIZE(control);
6221
    // There's a bunch of stuff on the stack between where the new stores
6222
    // are and where they need to be:
6223
    // - The other stores.
6224
    // - A copy of the subject.
6225
    // - Anything else that may be on top of the stack.
6226
    // - Any previous stores we've already stashed away on the stack.
6227
0
    Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
6228
0
    for (Py_ssize_t i = 0; i < nstores; i++) {
6229
        // Rotate this capture to its proper place on the stack:
6230
0
        if (codegen_pattern_helper_rotate(c, LOC(p), nrots) < 0) {
6231
0
            goto error;
6232
0
        }
6233
        // Update the list of previous stores with this new name, checking for
6234
        // duplicates:
6235
0
        PyObject *name = PyList_GET_ITEM(control, i);
6236
0
        int dupe = PySequence_Contains(pc->stores, name);
6237
0
        if (dupe < 0) {
6238
0
            goto error;
6239
0
        }
6240
0
        if (dupe) {
6241
0
            codegen_error_duplicate_store(c, LOC(p), name);
6242
0
            goto error;
6243
0
        }
6244
0
        if (PyList_Append(pc->stores, name)) {
6245
0
            goto error;
6246
0
        }
6247
0
    }
6248
0
    Py_DECREF(old_pc.stores);
6249
0
    Py_DECREF(control);
6250
    // NOTE: Returning macros are safe again.
6251
    // Pop the copy of the subject:
6252
0
    ADDOP(c, LOC(p), POP_TOP);
6253
0
    return SUCCESS;
6254
0
diff:
6255
0
    _PyCompile_Error(c, LOC(p), "alternative patterns bind different names");
6256
0
error:
6257
0
    PyMem_Free(old_pc.fail_pop);
6258
0
    Py_DECREF(old_pc.stores);
6259
0
    Py_XDECREF(control);
6260
0
    return ERROR;
6261
0
}
6262
6263
6264
static int
6265
codegen_pattern_sequence(compiler *c, pattern_ty p,
6266
                         pattern_context *pc)
6267
0
{
6268
0
    assert(p->kind == MatchSequence_kind);
6269
0
    asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
6270
0
    Py_ssize_t size = asdl_seq_LEN(patterns);
6271
0
    Py_ssize_t star = -1;
6272
0
    int only_wildcard = 1;
6273
0
    int star_wildcard = 0;
6274
    // Find a starred name, if it exists. There may be at most one:
6275
0
    for (Py_ssize_t i = 0; i < size; i++) {
6276
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6277
0
        if (pattern->kind == MatchStar_kind) {
6278
0
            if (star >= 0) {
6279
0
                const char *e = "multiple starred names in sequence pattern";
6280
0
                return _PyCompile_Error(c, LOC(p), e);
6281
0
            }
6282
0
            star_wildcard = WILDCARD_STAR_CHECK(pattern);
6283
0
            only_wildcard &= star_wildcard;
6284
0
            star = i;
6285
0
            continue;
6286
0
        }
6287
0
        only_wildcard &= WILDCARD_CHECK(pattern);
6288
0
    }
6289
    // We need to keep the subject on top during the sequence and length checks:
6290
0
    pc->on_top++;
6291
0
    ADDOP(c, LOC(p), MATCH_SEQUENCE);
6292
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6293
0
    if (star < 0) {
6294
        // No star: len(subject) == size
6295
0
        ADDOP(c, LOC(p), GET_LEN);
6296
0
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6297
0
        ADDOP_COMPARE(c, LOC(p), Eq);
6298
0
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6299
0
    }
6300
0
    else if (size > 1) {
6301
        // Star: len(subject) >= size - 1
6302
0
        ADDOP(c, LOC(p), GET_LEN);
6303
0
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1));
6304
0
        ADDOP_COMPARE(c, LOC(p), GtE);
6305
0
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6306
0
    }
6307
    // Whatever comes next should consume the subject:
6308
0
    pc->on_top--;
6309
0
    if (only_wildcard) {
6310
        // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
6311
0
        ADDOP(c, LOC(p), POP_TOP);
6312
0
    }
6313
0
    else if (star_wildcard) {
6314
0
        RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc));
6315
0
    }
6316
0
    else {
6317
0
        RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc));
6318
0
    }
6319
0
    return SUCCESS;
6320
0
}
6321
6322
static int
6323
codegen_pattern_value(compiler *c, pattern_ty p, pattern_context *pc)
6324
0
{
6325
0
    assert(p->kind == MatchValue_kind);
6326
0
    expr_ty value = p->v.MatchValue.value;
6327
0
    if (!MATCH_VALUE_EXPR(value)) {
6328
0
        const char *e = "patterns may only match literals and attribute lookups";
6329
0
        return _PyCompile_Error(c, LOC(p), e);
6330
0
    }
6331
0
    VISIT(c, expr, value);
6332
0
    ADDOP_COMPARE(c, LOC(p), Eq);
6333
0
    ADDOP(c, LOC(p), TO_BOOL);
6334
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6335
0
    return SUCCESS;
6336
0
}
6337
6338
static int
6339
codegen_pattern_singleton(compiler *c, pattern_ty p, pattern_context *pc)
6340
0
{
6341
0
    assert(p->kind == MatchSingleton_kind);
6342
0
    ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value);
6343
0
    ADDOP_COMPARE(c, LOC(p), Is);
6344
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6345
0
    return SUCCESS;
6346
0
}
6347
6348
static int
6349
codegen_pattern(compiler *c, pattern_ty p, pattern_context *pc)
6350
0
{
6351
0
    switch (p->kind) {
6352
0
        case MatchValue_kind:
6353
0
            return codegen_pattern_value(c, p, pc);
6354
0
        case MatchSingleton_kind:
6355
0
            return codegen_pattern_singleton(c, p, pc);
6356
0
        case MatchSequence_kind:
6357
0
            return codegen_pattern_sequence(c, p, pc);
6358
0
        case MatchMapping_kind:
6359
0
            return codegen_pattern_mapping(c, p, pc);
6360
0
        case MatchClass_kind:
6361
0
            return codegen_pattern_class(c, p, pc);
6362
0
        case MatchStar_kind:
6363
0
            return codegen_pattern_star(c, p, pc);
6364
0
        case MatchAs_kind:
6365
0
            return codegen_pattern_as(c, p, pc);
6366
0
        case MatchOr_kind:
6367
0
            return codegen_pattern_or(c, p, pc);
6368
0
    }
6369
    // AST validator shouldn't let this happen, but if it does,
6370
    // just fail, don't crash out of the interpreter
6371
0
    const char *e = "invalid match pattern node in AST (kind=%d)";
6372
0
    return _PyCompile_Error(c, LOC(p), e, p->kind);
6373
0
}
6374
6375
static int
6376
codegen_match_inner(compiler *c, stmt_ty s, pattern_context *pc)
6377
0
{
6378
0
    VISIT(c, expr, s->v.Match.subject);
6379
0
    NEW_JUMP_TARGET_LABEL(c, end);
6380
0
    Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases);
6381
0
    assert(cases > 0);
6382
0
    match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6383
0
    int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases;
6384
0
    for (Py_ssize_t i = 0; i < cases - has_default; i++) {
6385
0
        m = asdl_seq_GET(s->v.Match.cases, i);
6386
        // Only copy the subject if we're *not* on the last case:
6387
0
        if (i != cases - has_default - 1) {
6388
0
            ADDOP_I(c, LOC(m->pattern), COPY, 1);
6389
0
        }
6390
0
        pc->stores = PyList_New(0);
6391
0
        if (pc->stores == NULL) {
6392
0
            return ERROR;
6393
0
        }
6394
        // Irrefutable cases must be either guarded, last, or both:
6395
0
        pc->allow_irrefutable = m->guard != NULL || i == cases - 1;
6396
0
        pc->fail_pop = NULL;
6397
0
        pc->fail_pop_size = 0;
6398
0
        pc->on_top = 0;
6399
        // NOTE: Can't use returning macros here (they'll leak pc->stores)!
6400
0
        if (codegen_pattern(c, m->pattern, pc) < 0) {
6401
0
            Py_DECREF(pc->stores);
6402
0
            return ERROR;
6403
0
        }
6404
0
        assert(!pc->on_top);
6405
        // It's a match! Store all of the captured names (they're on the stack).
6406
0
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6407
0
        for (Py_ssize_t n = 0; n < nstores; n++) {
6408
0
            PyObject *name = PyList_GET_ITEM(pc->stores, n);
6409
0
            if (codegen_nameop(c, LOC(m->pattern), name, Store) < 0) {
6410
0
                Py_DECREF(pc->stores);
6411
0
                return ERROR;
6412
0
            }
6413
0
        }
6414
0
        Py_DECREF(pc->stores);
6415
        // NOTE: Returning macros are safe again.
6416
0
        if (m->guard) {
6417
0
            RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0));
6418
0
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0));
6419
0
        }
6420
        // Success! Pop the subject off, we're done with it:
6421
0
        if (i != cases - has_default - 1) {
6422
            /* Use the next location to give better locations for branch events */
6423
0
            ADDOP(c, NEXT_LOCATION, POP_TOP);
6424
0
        }
6425
0
        VISIT_SEQ(c, stmt, m->body);
6426
0
        ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
6427
        // If the pattern fails to match, we want the line number of the
6428
        // cleanup to be associated with the failed pattern, not the last line
6429
        // of the body
6430
0
        RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc));
6431
0
    }
6432
0
    if (has_default) {
6433
        // A trailing "case _" is common, and lets us save a bit of redundant
6434
        // pushing and popping in the loop above:
6435
0
        m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6436
0
        if (cases == 1) {
6437
            // No matches. Done with the subject:
6438
0
            ADDOP(c, LOC(m->pattern), POP_TOP);
6439
0
        }
6440
0
        else {
6441
            // Show line coverage for default case (it doesn't create bytecode)
6442
0
            ADDOP(c, LOC(m->pattern), NOP);
6443
0
        }
6444
0
        if (m->guard) {
6445
0
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, end, 0));
6446
0
        }
6447
0
        VISIT_SEQ(c, stmt, m->body);
6448
0
    }
6449
0
    USE_LABEL(c, end);
6450
0
    return SUCCESS;
6451
0
}
6452
6453
static int
6454
codegen_match(compiler *c, stmt_ty s)
6455
0
{
6456
0
    pattern_context pc;
6457
0
    pc.fail_pop = NULL;
6458
0
    int result = codegen_match_inner(c, s, &pc);
6459
0
    PyMem_Free(pc.fail_pop);
6460
0
    return result;
6461
0
}
6462
6463
#undef WILDCARD_CHECK
6464
#undef WILDCARD_STAR_CHECK
6465
6466
6467
int
6468
_PyCodegen_AddReturnAtEnd(compiler *c, int addNone)
6469
5.78k
{
6470
    /* Make sure every instruction stream that falls off the end returns None.
6471
     * This also ensures that no jump target offsets are out of bounds.
6472
     */
6473
5.78k
    if (addNone) {
6474
5.74k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
6475
5.74k
    }
6476
5.78k
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
6477
5.78k
    return SUCCESS;
6478
5.78k
}