Coverage Report

Created: 2025-09-05 07:10

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