Coverage Report

Created: 2025-12-07 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/codegen.c
Line
Count
Source
1
/*
2
 * This file implements the compiler's code generation stage, which
3
 * produces a sequence of pseudo-instructions from an AST.
4
 *
5
 * The primary entry point is _PyCodegen_Module() for modules, and
6
 * _PyCodegen_Expression() for expressions.
7
 *
8
 * CAUTION: The VISIT_* macros abort the current function when they
9
 * encounter a problem. So don't invoke them when there is memory
10
 * which needs to be released. Code blocks are OK, as the compiler
11
 * structure takes care of releasing those.  Use the arena to manage
12
 * objects.
13
 */
14
15
#include "Python.h"
16
#include "opcode.h"
17
#include "pycore_ast.h"           // _PyAST_GetDocString()
18
#define NEED_OPCODE_TABLES
19
#include "pycore_opcode_utils.h"
20
#undef NEED_OPCODE_TABLES
21
#include "pycore_c_array.h"       // _Py_c_array_t
22
#include "pycore_code.h"          // COMPARISON_LESS_THAN
23
#include "pycore_compile.h"
24
#include "pycore_instruction_sequence.h" // _PyInstructionSequence_NewLabel()
25
#include "pycore_intrinsics.h"
26
#include "pycore_long.h"          // _PyLong_GetZero()
27
#include "pycore_object.h"        // _Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS
28
#include "pycore_pystate.h"       // _Py_GetConfig()
29
#include "pycore_symtable.h"      // PySTEntryObject
30
#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString
31
#include "pycore_ceval.h"         // SPECIAL___ENTER__
32
#include "pycore_template.h"      // _PyTemplate_Type
33
34
#define NEED_OPCODE_METADATA
35
#include "pycore_opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
36
#undef NEED_OPCODE_METADATA
37
38
#include <stdbool.h>
39
40
1.80k
#define COMP_GENEXP   0
41
663
#define COMP_LISTCOMP 1
42
3
#define COMP_SETCOMP  2
43
126
#define COMP_DICTCOMP 3
44
45
#undef SUCCESS
46
#undef ERROR
47
2.32M
#define SUCCESS 0
48
1
#define ERROR -1
49
50
#define RETURN_IF_ERROR(X)  \
51
1.57M
    do {                    \
52
1.57M
        if ((X) == -1) {    \
53
0
            return ERROR;   \
54
0
        }                   \
55
1.57M
    } while (0)
56
57
#define RETURN_IF_ERROR_IN_SCOPE(C, CALL)   \
58
33.2k
    do {                                    \
59
33.2k
        if ((CALL) < 0) {                   \
60
0
            _PyCompile_ExitScope((C));      \
61
0
            return ERROR;                   \
62
0
        }                                   \
63
33.2k
    } while (0)
64
65
struct _PyCompiler;
66
typedef struct _PyCompiler compiler;
67
68
58.3k
#define INSTR_SEQUENCE(C) _PyCompile_InstrSequence(C)
69
3.63k
#define FUTURE_FEATURES(C) _PyCompile_FutureFeatures(C)
70
10.8k
#define SYMTABLE(C) _PyCompile_Symtable(C)
71
195k
#define SYMTABLE_ENTRY(C) _PyCompile_SymtableEntry(C)
72
209
#define OPTIMIZATION_LEVEL(C) _PyCompile_OptimizationLevel(C)
73
6.44k
#define IS_INTERACTIVE_TOP_LEVEL(C) _PyCompile_IsInteractiveTopLevel(C)
74
228
#define SCOPE_TYPE(C) _PyCompile_ScopeType(C)
75
#define QUALNAME(C) _PyCompile_Qualname(C)
76
86.7k
#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
9.86k
    ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})
87
88
397k
#define LOC(x) SRC_LOCATION_FROM_AST(x)
89
90
#define NEW_JUMP_TARGET_LABEL(C, NAME) \
91
58.3k
    jump_target_label NAME = _PyInstructionSequence_NewLabel(INSTR_SEQUENCE(C)); \
92
58.3k
    if (!IS_JUMP_TARGET_LABEL(NAME)) { \
93
0
        return ERROR; \
94
0
    }
95
96
#define USE_LABEL(C, LBL) \
97
58.3k
    RETURN_IF_ERROR(_PyInstructionSequence_UseLabel(INSTR_SEQUENCE(C), (LBL).id))
98
99
static const int compare_masks[] = {
100
    [Py_LT] = COMPARISON_LESS_THAN,
101
    [Py_LE] = COMPARISON_LESS_THAN | COMPARISON_EQUALS,
102
    [Py_EQ] = COMPARISON_EQUALS,
103
    [Py_NE] = COMPARISON_NOT_EQUALS,
104
    [Py_GT] = COMPARISON_GREATER_THAN,
105
    [Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS,
106
};
107
108
109
int
110
6.52k
_Py_CArray_Init(_Py_c_array_t* array, int item_size, int initial_num_entries) {
111
6.52k
    memset(array, 0, sizeof(_Py_c_array_t));
112
6.52k
    array->item_size = item_size;
113
6.52k
    array->initial_num_entries = initial_num_entries;
114
6.52k
    return 0;
115
6.52k
}
116
117
void
118
_Py_CArray_Fini(_Py_c_array_t* array)
119
6.52k
{
120
6.52k
    if (array->array) {
121
732
        PyMem_Free(array->array);
122
732
        array->allocated_entries = 0;
123
732
    }
124
6.52k
}
125
126
int
127
_Py_CArray_EnsureCapacity(_Py_c_array_t *c_array, int idx)
128
1.60M
{
129
1.60M
    void *arr = c_array->array;
130
1.60M
    int alloc = c_array->allocated_entries;
131
1.60M
    if (arr == NULL) {
132
96.0k
        int new_alloc = c_array->initial_num_entries;
133
96.0k
        if (idx >= new_alloc) {
134
0
            new_alloc = idx + c_array->initial_num_entries;
135
0
        }
136
96.0k
        arr = PyMem_Calloc(new_alloc, c_array->item_size);
137
96.0k
        if (arr == NULL) {
138
0
            PyErr_NoMemory();
139
0
            return ERROR;
140
0
        }
141
96.0k
        alloc = new_alloc;
142
96.0k
    }
143
1.50M
    else if (idx >= alloc) {
144
15.0k
        size_t oldsize = alloc * c_array->item_size;
145
15.0k
        int new_alloc = alloc << 1;
146
15.0k
        if (idx >= new_alloc) {
147
0
            new_alloc = idx + c_array->initial_num_entries;
148
0
        }
149
15.0k
        size_t newsize = new_alloc * c_array->item_size;
150
151
15.0k
        if (oldsize > (SIZE_MAX >> 1)) {
152
0
            PyErr_NoMemory();
153
0
            return ERROR;
154
0
        }
155
156
15.0k
        assert(newsize > 0);
157
15.0k
        void *tmp = PyMem_Realloc(arr, newsize);
158
15.0k
        if (tmp == NULL) {
159
0
            PyErr_NoMemory();
160
0
            return ERROR;
161
0
        }
162
15.0k
        alloc = new_alloc;
163
15.0k
        arr = tmp;
164
15.0k
        memset((char *)arr + oldsize, 0, newsize - oldsize);
165
15.0k
    }
166
167
1.60M
    c_array->array = arr;
168
1.60M
    c_array->allocated_entries = alloc;
169
1.60M
    return SUCCESS;
170
1.60M
}
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
364k
{
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
364k
    int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
265
364k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
266
364k
    return _PyInstructionSequence_Addop(seq, opcode, oparg_, loc);
267
364k
}
268
269
#define ADDOP_I(C, LOC, OP, O) \
270
364k
    RETURN_IF_ERROR(codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
271
272
#define ADDOP_I_IN_SCOPE(C, LOC, OP, O) \
273
8
    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
96.9k
{
278
96.9k
    assert(!OPCODE_HAS_ARG(opcode));
279
96.9k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
280
96.9k
    return _PyInstructionSequence_Addop(seq, opcode, 0, loc);
281
96.9k
}
282
283
#define ADDOP(C, LOC, OP) \
284
95.2k
    RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
285
286
#define ADDOP_IN_SCOPE(C, LOC, OP) \
287
1.59k
    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
88.9k
{
292
88.9k
    Py_ssize_t arg = _PyCompile_AddConst(c, o);
293
88.9k
    if (arg < 0) {
294
0
        return ERROR;
295
0
    }
296
88.9k
    ADDOP_I(c, loc, LOAD_CONST, arg);
297
88.9k
    return SUCCESS;
298
88.9k
}
299
300
#define ADDOP_LOAD_CONST(C, LOC, O) \
301
84.1k
    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
4.77k
    do {                                                                \
309
4.77k
        PyObject *__new_const = (O);                                    \
310
4.77k
        if (__new_const == NULL) {                                      \
311
0
            return ERROR;                                               \
312
0
        }                                                               \
313
4.77k
        if (codegen_addop_load_const((C), (LOC), __new_const) < 0) {    \
314
0
            Py_DECREF(__new_const);                                     \
315
0
            return ERROR;                                               \
316
0
        }                                                               \
317
4.77k
        Py_DECREF(__new_const);                                         \
318
4.77k
    } while (0)
319
320
static int
321
codegen_addop_o(compiler *c, location loc,
322
                int opcode, PyObject *dict, PyObject *o)
323
86.2k
{
324
86.2k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, o);
325
86.2k
    RETURN_IF_ERROR(arg);
326
86.2k
    ADDOP_I(c, loc, opcode, arg);
327
86.2k
    return SUCCESS;
328
86.2k
}
329
330
#define ADDOP_N(C, LOC, OP, O, TYPE)                                    \
331
85.4k
    do {                                                                \
332
85.4k
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
333
85.4k
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
334
85.4k
                                  METADATA(C)->u_ ## TYPE, (O));        \
335
85.4k
        Py_DECREF((O));                                                 \
336
85.4k
        RETURN_IF_ERROR(ret);                                           \
337
85.4k
    } while (0)
338
339
#define ADDOP_N_IN_SCOPE(C, LOC, OP, O, TYPE)                           \
340
794
    do {                                                                \
341
794
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
342
794
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
343
794
                                  METADATA(C)->u_ ## TYPE, (O));        \
344
794
        Py_DECREF((O));                                                 \
345
794
        RETURN_IF_ERROR_IN_SCOPE((C), ret);                             \
346
794
    } while (0)
347
348
33.5k
#define LOAD_METHOD -1
349
33.6k
#define LOAD_SUPER_METHOD -2
350
33.6k
#define LOAD_ZERO_SUPER_ATTR -3
351
33.7k
#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
33.5k
{
357
33.5k
    PyObject *mangled = _PyCompile_MaybeMangle(c, o);
358
33.5k
    if (!mangled) {
359
0
        return ERROR;
360
0
    }
361
33.5k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, mangled);
362
33.5k
    Py_DECREF(mangled);
363
33.5k
    if (arg < 0) {
364
0
        return ERROR;
365
0
    }
366
33.5k
    if (opcode == LOAD_ATTR) {
367
16.7k
        arg <<= 1;
368
16.7k
    }
369
33.5k
    if (opcode == LOAD_METHOD) {
370
10.7k
        opcode = LOAD_ATTR;
371
10.7k
        arg <<= 1;
372
10.7k
        arg |= 1;
373
10.7k
    }
374
33.5k
    if (opcode == LOAD_SUPER_ATTR) {
375
18
        arg <<= 2;
376
18
        arg |= 2;
377
18
    }
378
33.5k
    if (opcode == LOAD_SUPER_METHOD) {
379
36
        opcode = LOAD_SUPER_ATTR;
380
36
        arg <<= 2;
381
36
        arg |= 3;
382
36
    }
383
33.5k
    if (opcode == LOAD_ZERO_SUPER_ATTR) {
384
54
        opcode = LOAD_SUPER_ATTR;
385
54
        arg <<= 2;
386
54
    }
387
33.5k
    if (opcode == LOAD_ZERO_SUPER_METHOD) {
388
160
        opcode = LOAD_SUPER_ATTR;
389
160
        arg <<= 2;
390
160
        arg |= 1;
391
160
    }
392
33.5k
    ADDOP_I(c, loc, opcode, arg);
393
33.5k
    return SUCCESS;
394
33.5k
}
395
396
#define ADDOP_NAME(C, LOC, OP, O, TYPE) \
397
33.5k
    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
32.3k
{
403
32.3k
    assert(IS_JUMP_TARGET_LABEL(target));
404
32.3k
    assert(HAS_TARGET(opcode));
405
32.3k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
406
32.3k
    return _PyInstructionSequence_Addop(seq, opcode, target.id, loc);
407
32.3k
}
408
409
#define ADDOP_JUMP(C, LOC, OP, O) \
410
32.3k
    RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O)))
411
412
#define ADDOP_COMPARE(C, LOC, CMP) \
413
8.94k
    RETURN_IF_ERROR(codegen_addcompare((C), (LOC), (cmpop_ty)(CMP)))
414
415
#define ADDOP_BINARY(C, LOC, BINOP) \
416
5.52k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false))
417
418
#define ADDOP_INPLACE(C, LOC, BINOP) \
419
1.05k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true))
420
421
#define ADD_YIELD_FROM(C, LOC, await) \
422
61
    RETURN_IF_ERROR(codegen_add_yield_from((C), (LOC), (await)))
423
424
#define POP_EXCEPT_AND_RERAISE(C, LOC) \
425
1.34k
    RETURN_IF_ERROR(codegen_pop_except_and_reraise((C), (LOC)))
426
427
#define ADDOP_YIELD(C, LOC) \
428
531
    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
248k
    RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), (V)))
436
437
#define VISIT_IN_SCOPE(C, TYPE, V) \
438
18.9k
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_visit_ ## TYPE((C), (V)))
439
440
#define VISIT_SEQ(C, TYPE, SEQ)                                             \
441
35.5k
    do {                                                                    \
442
35.5k
        asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */    \
443
85.6k
        for (int _i = 0; _i < asdl_seq_LEN(seq); _i++) {                    \
444
50.0k
            TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i);           \
445
50.0k
            RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), elt));              \
446
50.0k
        }                                                                   \
447
35.5k
    } 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
214
{
464
214
    ADDOP_LOAD_CONST(c, loc, Py_None);
465
214
    ADDOP_LOAD_CONST(c, loc, Py_None);
466
214
    ADDOP_LOAD_CONST(c, loc, Py_None);
467
214
    ADDOP_I(c, loc, CALL, 3);
468
214
    return SUCCESS;
469
214
}
470
471
static int
472
codegen_add_yield_from(compiler *c, location loc, int await)
473
61
{
474
61
    NEW_JUMP_TARGET_LABEL(c, send);
475
61
    NEW_JUMP_TARGET_LABEL(c, fail);
476
61
    NEW_JUMP_TARGET_LABEL(c, exit);
477
478
61
    USE_LABEL(c, send);
479
61
    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
61
    ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
483
61
    ADDOP_I(c, loc, YIELD_VALUE, 1);
484
61
    ADDOP(c, NO_LOCATION, POP_BLOCK);
485
61
    ADDOP_I(c, loc, RESUME, await ? RESUME_AFTER_AWAIT : RESUME_AFTER_YIELD_FROM);
486
61
    ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
487
488
61
    USE_LABEL(c, fail);
489
61
    ADDOP(c, loc, CLEANUP_THROW);
490
491
61
    USE_LABEL(c, exit);
492
61
    ADDOP(c, loc, END_SEND);
493
61
    return SUCCESS;
494
61
}
495
496
static int
497
codegen_pop_except_and_reraise(compiler *c, location loc)
498
1.34k
{
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
1.34k
    ADDOP_I(c, loc, COPY, 3);
507
1.34k
    ADDOP(c, loc, POP_EXCEPT);
508
1.34k
    ADDOP_I(c, loc, RERAISE, 1);
509
1.34k
    return SUCCESS;
510
1.34k
}
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.85k
{
521
1.85k
    switch (info->fb_type) {
522
366
        case COMPILE_FBLOCK_WHILE_LOOP:
523
686
        case COMPILE_FBLOCK_EXCEPTION_HANDLER:
524
686
        case COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER:
525
686
        case COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR:
526
735
        case COMPILE_FBLOCK_STOP_ITERATION:
527
735
            return SUCCESS;
528
529
369
        case COMPILE_FBLOCK_FOR_LOOP:
530
            /* Pop the iterator */
531
369
            if (preserve_tos) {
532
106
                ADDOP_I(c, *ploc, SWAP, 3);
533
106
            }
534
369
            ADDOP(c, *ploc, POP_TOP);
535
369
            ADDOP(c, *ploc, POP_TOP);
536
369
            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
364
        case COMPILE_FBLOCK_TRY_EXCEPT:
547
364
            ADDOP(c, *ploc, POP_BLOCK);
548
364
            return SUCCESS;
549
550
23
        case COMPILE_FBLOCK_FINALLY_TRY:
551
            /* This POP_BLOCK gets the line number of the unwinding statement */
552
23
            ADDOP(c, *ploc, POP_BLOCK);
553
23
            if (preserve_tos) {
554
17
                RETURN_IF_ERROR(
555
17
                    _PyCompile_PushFBlock(c, *ploc, COMPILE_FBLOCK_POP_VALUE,
556
17
                                          NO_LABEL, NO_LABEL, NULL));
557
17
            }
558
            /* Emit the finally block */
559
23
            VISIT_SEQ(c, stmt, info->fb_datum);
560
23
            if (preserve_tos) {
561
17
                _PyCompile_PopFBlock(c, COMPILE_FBLOCK_POP_VALUE, NO_LABEL);
562
17
            }
563
            /* The finally block should appear to execute after the
564
             * statement causing the unwinding, so make the unwinding
565
             * instruction artificial */
566
23
            *ploc = NO_LOCATION;
567
23
            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
45
        case COMPILE_FBLOCK_WITH:
582
46
        case COMPILE_FBLOCK_ASYNC_WITH:
583
46
            *ploc = info->fb_loc;
584
46
            ADDOP(c, *ploc, POP_BLOCK);
585
46
            if (preserve_tos) {
586
28
                ADDOP_I(c, *ploc, SWAP, 3);
587
28
                ADDOP_I(c, *ploc, SWAP, 2);
588
28
            }
589
46
            RETURN_IF_ERROR(codegen_call_exit_with_nones(c, *ploc));
590
46
            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
46
            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
46
            *ploc = NO_LOCATION;
600
46
            return SUCCESS;
601
602
320
        case COMPILE_FBLOCK_HANDLER_CLEANUP: {
603
320
            if (info->fb_datum) {
604
35
                ADDOP(c, *ploc, POP_BLOCK);
605
35
            }
606
320
            if (preserve_tos) {
607
106
                ADDOP_I(c, *ploc, SWAP, 2);
608
106
            }
609
320
            ADDOP(c, *ploc, POP_BLOCK);
610
320
            ADDOP(c, *ploc, POP_EXCEPT);
611
320
            if (info->fb_datum) {
612
35
                ADDOP_LOAD_CONST(c, *ploc, Py_None);
613
35
                RETURN_IF_ERROR(codegen_nameop(c, *ploc, info->fb_datum, Store));
614
35
                RETURN_IF_ERROR(codegen_nameop(c, *ploc, info->fb_datum, Del));
615
35
            }
616
320
            return SUCCESS;
617
320
        }
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.85k
    }
626
1.85k
    Py_UNREACHABLE();
627
1.85k
}
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
9.04k
{
634
9.04k
    fblockinfo *top = _PyCompile_TopFBlock(c);
635
9.04k
    if (top == NULL) {
636
6.83k
        return SUCCESS;
637
6.83k
    }
638
2.20k
    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
2.20k
    if (loop != NULL && (top->fb_type == COMPILE_FBLOCK_WHILE_LOOP ||
643
532
                         top->fb_type == COMPILE_FBLOCK_FOR_LOOP ||
644
806
                         top->fb_type == COMPILE_FBLOCK_ASYNC_FOR_LOOP)) {
645
806
        *loop = top;
646
806
        return SUCCESS;
647
806
    }
648
1.40k
    fblockinfo copy = *top;
649
1.40k
    _PyCompile_PopFBlock(c, top->fb_type, top->fb_block);
650
1.40k
    RETURN_IF_ERROR(codegen_unwind_fblock(c, ploc, &copy, preserve_tos));
651
1.40k
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, ploc, preserve_tos, loop));
652
1.40k
    _PyCompile_PushFBlock(c, copy.fb_loc, copy.fb_type, copy.fb_block,
653
1.40k
                          copy.fb_exit, copy.fb_datum);
654
1.40k
    return SUCCESS;
655
1.40k
}
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
8.54k
{
662
8.54k
    RETURN_IF_ERROR(
663
8.54k
        _PyCompile_EnterScope(c, name, scope_type, key, lineno, private, umd));
664
8.54k
    location loc = LOCATION(lineno, lineno, 0, 0);
665
8.54k
    if (scope_type == COMPILE_SCOPE_MODULE) {
666
454
        loc.lineno = 0;
667
454
    }
668
8.54k
    ADDOP_I(c, loc, RESUME, RESUME_AT_FUNC_START);
669
8.54k
    if (scope_type == COMPILE_SCOPE_MODULE) {
670
454
        ADDOP(c, loc, ANNOTATIONS_PLACEHOLDER);
671
454
    }
672
8.54k
    return SUCCESS;
673
8.54k
}
674
675
static int
676
codegen_setup_annotations_scope(compiler *c, location loc,
677
                                void *key, PyObject *name)
678
138
{
679
138
    _PyCompile_CodeUnitMetadata umd = {
680
138
        .u_posonlyargcount = 1,
681
138
    };
682
138
    RETURN_IF_ERROR(
683
138
        codegen_enter_scope(c, name, COMPILE_SCOPE_ANNOTATIONS,
684
138
                            key, loc.lineno, NULL, &umd));
685
686
    // if .format > VALUE_WITH_FAKE_GLOBALS: raise NotImplementedError
687
138
    PyObject *value_with_fake_globals = PyLong_FromLong(_Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS);
688
138
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
689
138
    _Py_DECLARE_STR(format, ".format");
690
138
    ADDOP_I(c, loc, LOAD_FAST, 0);
691
138
    ADDOP_LOAD_CONST(c, loc, value_with_fake_globals);
692
138
    ADDOP_I(c, loc, COMPARE_OP, (Py_GT << 5) | compare_masks[Py_GT]);
693
138
    NEW_JUMP_TARGET_LABEL(c, body);
694
138
    ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, body);
695
138
    ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR);
696
138
    ADDOP_I(c, loc, RAISE_VARARGS, 1);
697
138
    USE_LABEL(c, body);
698
138
    return SUCCESS;
699
138
}
700
701
static int
702
codegen_leave_annotations_scope(compiler *c, location loc)
703
136
{
704
136
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
705
136
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
706
136
    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
136
    const Py_ssize_t size = PyObject_Size(co->co_localsplusnames);
717
136
    if (size == -1) {
718
0
        Py_DECREF(co);
719
0
        return ERROR;
720
0
    }
721
136
    PyObject *new_names = PyTuple_New(size);
722
136
    if (new_names == NULL) {
723
0
        Py_DECREF(co);
724
0
        return ERROR;
725
0
    }
726
136
    PyTuple_SET_ITEM(new_names, 0, Py_NewRef(&_Py_ID(format)));
727
210
    for (int i = 1; i < size; i++) {
728
74
        PyObject *item = PyTuple_GetItem(co->co_localsplusnames, i);
729
74
        if (item == NULL) {
730
0
            Py_DECREF(co);
731
0
            Py_DECREF(new_names);
732
0
            return ERROR;
733
0
        }
734
74
        Py_INCREF(item);
735
74
        PyTuple_SET_ITEM(new_names, i, item);
736
74
    }
737
136
    Py_SETREF(co->co_localsplusnames, new_names);
738
739
136
    _PyCompile_ExitScope(c);
740
136
    int ret = codegen_make_closure(c, loc, co, 0);
741
136
    Py_DECREF(co);
742
136
    RETURN_IF_ERROR(ret);
743
136
    return SUCCESS;
744
136
}
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
14
{
750
14
    Py_ssize_t annotations_len = PyList_GET_SIZE(deferred_anno);
751
752
14
    assert(PyList_CheckExact(conditional_annotation_indices));
753
14
    assert(annotations_len == PyList_Size(conditional_annotation_indices));
754
755
14
    ADDOP_I(c, loc, BUILD_MAP, 0); // stack now contains <annos>
756
757
86
    for (Py_ssize_t i = 0; i < annotations_len; i++) {
758
72
        PyObject *ptr = PyList_GET_ITEM(deferred_anno, i);
759
72
        stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr);
760
72
        if (st == NULL) {
761
0
            return ERROR;
762
0
        }
763
72
        PyObject *mangled = _PyCompile_Mangle(c, st->v.AnnAssign.target->v.Name.id);
764
72
        if (!mangled) {
765
0
            return ERROR;
766
0
        }
767
72
        PyObject *cond_index = PyList_GET_ITEM(conditional_annotation_indices, i);
768
72
        assert(PyLong_CheckExact(cond_index));
769
72
        long idx = PyLong_AS_LONG(cond_index);
770
72
        NEW_JUMP_TARGET_LABEL(c, not_set);
771
772
72
        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
72
        VISIT(c, expr, st->v.AnnAssign.annotation);
788
72
        ADDOP_I(c, LOC(st), COPY, 2);
789
72
        ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
790
        // stack now contains <annos> <name> <annos> <value>
791
72
        ADDOP(c, loc, STORE_SUBSCR);
792
        // stack now contains <annos>
793
794
72
        USE_LABEL(c, not_set);
795
72
    }
796
14
    return SUCCESS;
797
14
}
798
799
static int
800
codegen_process_deferred_annotations(compiler *c, location loc)
801
1.63k
{
802
1.63k
    PyObject *deferred_anno = NULL;
803
1.63k
    PyObject *conditional_annotation_indices = NULL;
804
1.63k
    _PyCompile_DeferredAnnotations(c, &deferred_anno, &conditional_annotation_indices);
805
1.63k
    if (deferred_anno == NULL) {
806
1.61k
        assert(conditional_annotation_indices == NULL);
807
1.61k
        return SUCCESS;
808
1.61k
    }
809
810
14
    int scope_type = SCOPE_TYPE(c);
811
14
    bool need_separate_block = scope_type == COMPILE_SCOPE_MODULE;
812
14
    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
14
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
824
14
    assert(ste->ste_annotation_block != NULL);
825
14
    void *key = (void *)((uintptr_t)ste->ste_id + 1);
826
14
    if (codegen_setup_annotations_scope(c, loc, key,
827
14
                                        ste->ste_annotation_block->ste_name) < 0) {
828
0
        goto error;
829
0
    }
830
14
    if (codegen_deferred_annotations_body(c, loc, deferred_anno,
831
14
                                          conditional_annotation_indices, scope_type) < 0) {
832
0
        _PyCompile_ExitScope(c);
833
0
        goto error;
834
0
    }
835
836
14
    Py_DECREF(deferred_anno);
837
14
    Py_DECREF(conditional_annotation_indices);
838
839
14
    RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
840
14
    RETURN_IF_ERROR(codegen_nameop(
841
14
        c, loc,
842
14
        ste->ste_type == ClassBlock ? &_Py_ID(__annotate_func__) : &_Py_ID(__annotate__),
843
14
        Store));
844
845
14
    if (need_separate_block) {
846
1
        RETURN_IF_ERROR(_PyCompile_EndAnnotationSetup(c));
847
1
    }
848
849
14
    return SUCCESS;
850
0
error:
851
0
    Py_XDECREF(deferred_anno);
852
0
    Py_XDECREF(conditional_annotation_indices);
853
0
    return ERROR;
854
14
}
855
856
/* Compile an expression */
857
int
858
_PyCodegen_Expression(compiler *c, expr_ty e)
859
86
{
860
86
    VISIT(c, expr, e);
861
86
    return SUCCESS;
862
86
}
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
368
{
870
368
    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
368
    return codegen_body(c, loc, stmts, is_interactive);
875
368
}
876
877
int
878
codegen_body(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interactive)
879
1.64k
{
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.64k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
884
1.64k
    if ((FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) && ste->ste_annotations_used) {
885
0
        ADDOP(c, loc, SETUP_ANNOTATIONS);
886
0
    }
887
1.64k
    if (!asdl_seq_LEN(stmts)) {
888
3
        return SUCCESS;
889
3
    }
890
1.63k
    Py_ssize_t first_instr = 0;
891
1.63k
    if (!is_interactive) { /* A string literal on REPL prompt is not a docstring */
892
1.63k
        if (ste->ste_has_docstring) {
893
614
            PyObject *docstring = _PyAST_GetDocString(stmts);
894
614
            assert(docstring);
895
614
            first_instr = 1;
896
            /* set docstring */
897
614
            assert(OPTIMIZATION_LEVEL(c) < 2);
898
614
            PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
899
614
            if (cleandoc == NULL) {
900
0
                return ERROR;
901
0
            }
902
614
            stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
903
614
            assert(st->kind == Expr_kind);
904
614
            location loc = LOC(st->v.Expr.value);
905
614
            ADDOP_LOAD_CONST(c, loc, cleandoc);
906
614
            Py_DECREF(cleandoc);
907
614
            RETURN_IF_ERROR(codegen_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
908
614
        }
909
1.63k
    }
910
13.2k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(stmts); i++) {
911
11.6k
        VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
912
11.6k
    }
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.63k
    if (!(FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS)) {
917
1.63k
        RETURN_IF_ERROR(codegen_process_deferred_annotations(c, loc));
918
1.63k
    }
919
1.63k
    return SUCCESS;
920
1.63k
}
921
922
int
923
_PyCodegen_EnterAnonymousScope(compiler* c, mod_ty mod)
924
454
{
925
454
    _Py_DECLARE_STR(anon_module, "<module>");
926
454
    RETURN_IF_ERROR(
927
454
        codegen_enter_scope(c, &_Py_STR(anon_module), COMPILE_SCOPE_MODULE,
928
454
                            mod, 1, NULL, NULL));
929
454
    return SUCCESS;
930
454
}
931
932
static int
933
codegen_make_closure(compiler *c, location loc,
934
                     PyCodeObject *co, Py_ssize_t flags)
935
8.09k
{
936
8.09k
    if (co->co_nfreevars) {
937
680
        int i = PyUnstable_Code_GetFirstFree(co);
938
1.76k
        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
1.08k
            PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
943
1.08k
            int arg = _PyCompile_LookupArg(c, co, name);
944
1.08k
            RETURN_IF_ERROR(arg);
945
1.08k
            ADDOP_I(c, loc, LOAD_CLOSURE, arg);
946
1.08k
        }
947
680
        flags |= MAKE_FUNCTION_CLOSURE;
948
680
        ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
949
680
    }
950
8.09k
    ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
951
952
8.09k
    ADDOP(c, loc, MAKE_FUNCTION);
953
954
8.09k
    if (flags & MAKE_FUNCTION_CLOSURE) {
955
680
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_CLOSURE);
956
680
    }
957
8.09k
    if (flags & MAKE_FUNCTION_ANNOTATIONS) {
958
0
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATIONS);
959
0
    }
960
8.09k
    if (flags & MAKE_FUNCTION_ANNOTATE) {
961
122
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATE);
962
122
    }
963
8.09k
    if (flags & MAKE_FUNCTION_KWDEFAULTS) {
964
250
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_KWDEFAULTS);
965
250
    }
966
8.09k
    if (flags & MAKE_FUNCTION_DEFAULTS) {
967
1.22k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_DEFAULTS);
968
1.22k
    }
969
8.09k
    return SUCCESS;
970
8.09k
}
971
972
static int
973
codegen_decorators(compiler *c, asdl_expr_seq* decos)
974
7.45k
{
975
7.45k
    if (!decos) {
976
6.58k
        return SUCCESS;
977
6.58k
    }
978
979
1.76k
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) {
980
895
        VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
981
895
    }
982
866
    return SUCCESS;
983
866
}
984
985
static int
986
codegen_apply_decorators(compiler *c, asdl_expr_seq* decos)
987
7.45k
{
988
7.45k
    if (!decos) {
989
6.58k
        return SUCCESS;
990
6.58k
    }
991
992
1.76k
    for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
993
895
        location loc = LOC((expr_ty)asdl_seq_GET(decos, i));
994
895
        ADDOP_I(c, loc, CALL, 0);
995
895
    }
996
866
    return SUCCESS;
997
866
}
998
999
static int
1000
codegen_kwonlydefaults(compiler *c, location loc,
1001
                       asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
1002
6.36k
{
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
6.36k
    int default_count = 0;
1008
7.09k
    for (int i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
1009
728
        arg_ty arg = asdl_seq_GET(kwonlyargs, i);
1010
728
        expr_ty default_ = asdl_seq_GET(kw_defaults, i);
1011
728
        if (default_) {
1012
710
            default_count++;
1013
710
            PyObject *mangled = _PyCompile_MaybeMangle(c, arg->arg);
1014
710
            if (!mangled) {
1015
0
                return ERROR;
1016
0
            }
1017
710
            ADDOP_LOAD_CONST_NEW(c, loc, mangled);
1018
710
            VISIT(c, expr, default_);
1019
710
        }
1020
728
    }
1021
6.36k
    if (default_count) {
1022
250
        ADDOP_I(c, loc, BUILD_MAP, default_count);
1023
250
        return 1;
1024
250
    }
1025
6.11k
    else {
1026
6.11k
        return 0;
1027
6.11k
    }
1028
6.36k
}
1029
1030
static int
1031
codegen_visit_annexpr(compiler *c, expr_ty annotation)
1032
125
{
1033
125
    location loc = LOC(annotation);
1034
125
    ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation));
1035
125
    return SUCCESS;
1036
125
}
1037
1038
static int
1039
codegen_argannotation(compiler *c, identifier id,
1040
    expr_ty annotation, Py_ssize_t *annotations_len, location loc)
1041
341
{
1042
341
    if (!annotation) {
1043
75
        return SUCCESS;
1044
75
    }
1045
266
    PyObject *mangled = _PyCompile_MaybeMangle(c, id);
1046
266
    if (!mangled) {
1047
0
        return ERROR;
1048
0
    }
1049
266
    ADDOP_LOAD_CONST(c, loc, mangled);
1050
266
    Py_DECREF(mangled);
1051
1052
266
    if (FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) {
1053
125
        VISIT(c, annexpr, annotation);
1054
125
    }
1055
141
    else {
1056
141
        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
141
        else {
1065
141
            VISIT(c, expr, annotation);
1066
141
        }
1067
141
    }
1068
266
    *annotations_len += 1;
1069
266
    return SUCCESS;
1070
266
}
1071
1072
static int
1073
codegen_argannotations(compiler *c, asdl_arg_seq* args,
1074
                       Py_ssize_t *annotations_len, location loc)
1075
366
{
1076
366
    int i;
1077
582
    for (i = 0; i < asdl_seq_LEN(args); i++) {
1078
216
        arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
1079
216
        RETURN_IF_ERROR(
1080
216
            codegen_argannotation(
1081
216
                        c,
1082
216
                        arg->arg,
1083
216
                        arg->annotation,
1084
216
                        annotations_len,
1085
216
                        loc));
1086
216
    }
1087
366
    return SUCCESS;
1088
366
}
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
122
{
1095
122
    RETURN_IF_ERROR(
1096
122
        codegen_argannotations(c, args->args, annotations_len, loc));
1097
1098
122
    RETURN_IF_ERROR(
1099
122
        codegen_argannotations(c, args->posonlyargs, annotations_len, loc));
1100
1101
122
    if (args->vararg && args->vararg->annotation) {
1102
1
        RETURN_IF_ERROR(
1103
1
            codegen_argannotation(c, args->vararg->arg,
1104
1
                                     args->vararg->annotation, annotations_len, loc));
1105
1
    }
1106
1107
122
    RETURN_IF_ERROR(
1108
122
        codegen_argannotations(c, args->kwonlyargs, annotations_len, loc));
1109
1110
122
    if (args->kwarg && args->kwarg->annotation) {
1111
2
        RETURN_IF_ERROR(
1112
2
            codegen_argannotation(c, args->kwarg->arg,
1113
2
                                     args->kwarg->annotation, annotations_len, loc));
1114
2
    }
1115
1116
122
    RETURN_IF_ERROR(
1117
122
        codegen_argannotation(c, &_Py_ID(return), returns, annotations_len, loc));
1118
1119
122
    return 0;
1120
122
}
1121
1122
static int
1123
codegen_function_annotations(compiler *c, location loc,
1124
                             arguments_ty args, expr_ty returns)
1125
6.18k
{
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
6.18k
    Py_ssize_t annotations_len = 0;
1132
1133
6.18k
    PySTEntryObject *ste;
1134
6.18k
    RETURN_IF_ERROR(_PySymtable_LookupOptional(SYMTABLE(c), args, &ste));
1135
6.18k
    assert(ste != NULL);
1136
1137
6.18k
    if (ste->ste_annotations_used) {
1138
122
        int err = codegen_setup_annotations_scope(c, loc, (void *)args, ste->ste_name);
1139
122
        Py_DECREF(ste);
1140
122
        RETURN_IF_ERROR(err);
1141
122
        RETURN_IF_ERROR_IN_SCOPE(
1142
122
            c, codegen_annotations_in_scope(c, loc, args, returns, &annotations_len)
1143
122
        );
1144
122
        ADDOP_I(c, loc, BUILD_MAP, annotations_len);
1145
122
        RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
1146
122
        return MAKE_FUNCTION_ANNOTATE;
1147
122
    }
1148
6.05k
    else {
1149
6.05k
        Py_DECREF(ste);
1150
6.05k
    }
1151
1152
6.05k
    return 0;
1153
6.18k
}
1154
1155
static int
1156
codegen_defaults(compiler *c, arguments_ty args,
1157
                        location loc)
1158
1.22k
{
1159
1.22k
    VISIT_SEQ(c, expr, args->defaults);
1160
1.22k
    ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
1161
1.22k
    return SUCCESS;
1162
1.22k
}
1163
1164
static Py_ssize_t
1165
codegen_default_arguments(compiler *c, location loc,
1166
                          arguments_ty args)
1167
6.36k
{
1168
6.36k
    Py_ssize_t funcflags = 0;
1169
6.36k
    if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
1170
1.22k
        RETURN_IF_ERROR(codegen_defaults(c, args, loc));
1171
1.22k
        funcflags |= MAKE_FUNCTION_DEFAULTS;
1172
1.22k
    }
1173
6.36k
    if (args->kwonlyargs) {
1174
6.36k
        int res = codegen_kwonlydefaults(c, loc,
1175
6.36k
                                         args->kwonlyargs,
1176
6.36k
                                         args->kw_defaults);
1177
6.36k
        RETURN_IF_ERROR(res);
1178
6.36k
        if (res > 0) {
1179
250
            funcflags |= MAKE_FUNCTION_KWDEFAULTS;
1180
250
        }
1181
6.36k
    }
1182
6.36k
    return funcflags;
1183
6.36k
}
1184
1185
static int
1186
codegen_wrap_in_stopiteration_handler(compiler *c)
1187
453
{
1188
453
    NEW_JUMP_TARGET_LABEL(c, handler);
1189
1190
    /* Insert SETUP_CLEANUP at start */
1191
453
    RETURN_IF_ERROR(
1192
453
        _PyInstructionSequence_InsertInstruction(
1193
453
            INSTR_SEQUENCE(c), 0,
1194
453
            SETUP_CLEANUP, handler.id, NO_LOCATION));
1195
1196
453
    ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1197
453
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
1198
453
    USE_LABEL(c, handler);
1199
453
    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
1200
453
    ADDOP_I(c, NO_LOCATION, RERAISE, 1);
1201
453
    return SUCCESS;
1202
453
}
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
1
{
1209
1
    PyObject *defaults = PyTuple_Pack(1, _PyLong_GetOne());
1210
1
    ADDOP_LOAD_CONST_NEW(c, LOC(e), defaults);
1211
1
    RETURN_IF_ERROR(codegen_setup_annotations_scope(c, LOC(e), key, name));
1212
1
    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
1
    else {
1217
1
        VISIT(c, expr, e);
1218
1
    }
1219
1
    ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE);
1220
1
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1221
1
    _PyCompile_ExitScope(c);
1222
1
    if (co == NULL) {
1223
0
        return ERROR;
1224
0
    }
1225
1
    int ret = codegen_make_closure(c, LOC(e), co, MAKE_FUNCTION_DEFAULTS);
1226
1
    Py_DECREF(co);
1227
1
    RETURN_IF_ERROR(ret);
1228
1
    return SUCCESS;
1229
1
}
1230
1231
static int
1232
codegen_type_params(compiler *c, asdl_type_param_seq *type_params)
1233
5
{
1234
5
    if (!type_params) {
1235
0
        return SUCCESS;
1236
0
    }
1237
5
    Py_ssize_t n = asdl_seq_LEN(type_params);
1238
5
    bool seen_default = false;
1239
1240
10
    for (Py_ssize_t i = 0; i < n; i++) {
1241
5
        type_param_ty typeparam = asdl_seq_GET(type_params, i);
1242
5
        location loc = LOC(typeparam);
1243
5
        switch(typeparam->kind) {
1244
5
        case TypeVar_kind:
1245
5
            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVar.name);
1246
5
            if (typeparam->v.TypeVar.bound) {
1247
1
                expr_ty bound = typeparam->v.TypeVar.bound;
1248
1
                RETURN_IF_ERROR(
1249
1
                    codegen_type_param_bound_or_default(c, bound, typeparam->v.TypeVar.name,
1250
1
                                                        (void *)typeparam, false));
1251
1252
1
                int intrinsic = bound->kind == Tuple_kind
1253
1
                    ? INTRINSIC_TYPEVAR_WITH_CONSTRAINTS
1254
1
                    : INTRINSIC_TYPEVAR_WITH_BOUND;
1255
1
                ADDOP_I(c, loc, CALL_INTRINSIC_2, intrinsic);
1256
1
            }
1257
4
            else {
1258
4
                ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVAR);
1259
4
            }
1260
5
            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
5
            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
5
            ADDOP_I(c, loc, COPY, 1);
1274
5
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.TypeVar.name, Store));
1275
5
            break;
1276
5
        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
5
        }
1315
5
    }
1316
5
    ADDOP_I(c, LOC(asdl_seq_GET(type_params, 0)), BUILD_TUPLE, n);
1317
5
    return SUCCESS;
1318
5
}
1319
1320
static int
1321
codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags,
1322
                      int firstlineno)
1323
6.18k
{
1324
6.18k
    arguments_ty args;
1325
6.18k
    identifier name;
1326
6.18k
    asdl_stmt_seq *body;
1327
6.18k
    int scope_type;
1328
1329
6.18k
    if (is_async) {
1330
18
        assert(s->kind == AsyncFunctionDef_kind);
1331
1332
18
        args = s->v.AsyncFunctionDef.args;
1333
18
        name = s->v.AsyncFunctionDef.name;
1334
18
        body = s->v.AsyncFunctionDef.body;
1335
1336
18
        scope_type = COMPILE_SCOPE_ASYNC_FUNCTION;
1337
6.16k
    } else {
1338
6.16k
        assert(s->kind == FunctionDef_kind);
1339
1340
6.16k
        args = s->v.FunctionDef.args;
1341
6.16k
        name = s->v.FunctionDef.name;
1342
6.16k
        body = s->v.FunctionDef.body;
1343
1344
6.16k
        scope_type = COMPILE_SCOPE_FUNCTION;
1345
6.16k
    }
1346
1347
6.18k
    _PyCompile_CodeUnitMetadata umd = {
1348
6.18k
        .u_argcount = asdl_seq_LEN(args->args),
1349
6.18k
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
1350
6.18k
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
1351
6.18k
    };
1352
6.18k
    RETURN_IF_ERROR(
1353
6.18k
        codegen_enter_scope(c, name, scope_type, (void *)s, firstlineno, NULL, &umd));
1354
1355
6.18k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1356
6.18k
    Py_ssize_t first_instr = 0;
1357
6.18k
    if (ste->ste_has_docstring) {
1358
2.16k
        PyObject *docstring = _PyAST_GetDocString(body);
1359
2.16k
        assert(docstring);
1360
2.16k
        first_instr = 1;
1361
2.16k
        docstring = _PyCompile_CleanDoc(docstring);
1362
2.16k
        if (docstring == NULL) {
1363
0
            _PyCompile_ExitScope(c);
1364
0
            return ERROR;
1365
0
        }
1366
2.16k
        Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1367
2.16k
        Py_DECREF(docstring);
1368
2.16k
        RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
1369
2.16k
    }
1370
1371
6.18k
    NEW_JUMP_TARGET_LABEL(c, start);
1372
6.18k
    USE_LABEL(c, start);
1373
6.18k
    bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1374
6.18k
    if (add_stopiteration_handler) {
1375
        /* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1376
144
        RETURN_IF_ERROR(
1377
144
            _PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1378
144
                                  start, NO_LABEL, NULL));
1379
144
    }
1380
1381
24.9k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1382
18.7k
        VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1383
18.7k
    }
1384
6.18k
    if (add_stopiteration_handler) {
1385
144
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_wrap_in_stopiteration_handler(c));
1386
144
        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1387
144
    }
1388
6.18k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1389
6.18k
    _PyCompile_ExitScope(c);
1390
6.18k
    if (co == NULL) {
1391
0
        Py_XDECREF(co);
1392
0
        return ERROR;
1393
0
    }
1394
6.18k
    int ret = codegen_make_closure(c, LOC(s), co, funcflags);
1395
6.18k
    Py_DECREF(co);
1396
6.18k
    return ret;
1397
6.18k
}
1398
1399
static int
1400
codegen_function(compiler *c, stmt_ty s, int is_async)
1401
6.18k
{
1402
6.18k
    arguments_ty args;
1403
6.18k
    expr_ty returns;
1404
6.18k
    identifier name;
1405
6.18k
    asdl_expr_seq *decos;
1406
6.18k
    asdl_type_param_seq *type_params;
1407
6.18k
    Py_ssize_t funcflags;
1408
6.18k
    int firstlineno;
1409
1410
6.18k
    if (is_async) {
1411
18
        assert(s->kind == AsyncFunctionDef_kind);
1412
1413
18
        args = s->v.AsyncFunctionDef.args;
1414
18
        returns = s->v.AsyncFunctionDef.returns;
1415
18
        decos = s->v.AsyncFunctionDef.decorator_list;
1416
18
        name = s->v.AsyncFunctionDef.name;
1417
18
        type_params = s->v.AsyncFunctionDef.type_params;
1418
6.16k
    } else {
1419
6.16k
        assert(s->kind == FunctionDef_kind);
1420
1421
6.16k
        args = s->v.FunctionDef.args;
1422
6.16k
        returns = s->v.FunctionDef.returns;
1423
6.16k
        decos = s->v.FunctionDef.decorator_list;
1424
6.16k
        name = s->v.FunctionDef.name;
1425
6.16k
        type_params = s->v.FunctionDef.type_params;
1426
6.16k
    }
1427
1428
6.18k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1429
1430
6.18k
    firstlineno = s->lineno;
1431
6.18k
    if (asdl_seq_LEN(decos)) {
1432
828
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1433
828
    }
1434
1435
6.18k
    location loc = LOC(s);
1436
1437
6.18k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1438
1439
6.18k
    funcflags = codegen_default_arguments(c, loc, args);
1440
6.18k
    RETURN_IF_ERROR(funcflags);
1441
1442
6.18k
    int num_typeparam_args = 0;
1443
1444
6.18k
    if (is_generic) {
1445
3
        if (funcflags & MAKE_FUNCTION_DEFAULTS) {
1446
0
            num_typeparam_args += 1;
1447
0
        }
1448
3
        if (funcflags & MAKE_FUNCTION_KWDEFAULTS) {
1449
0
            num_typeparam_args += 1;
1450
0
        }
1451
3
        if (num_typeparam_args == 2) {
1452
0
            ADDOP_I(c, loc, SWAP, 2);
1453
0
        }
1454
3
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>", name);
1455
3
        if (!type_params_name) {
1456
0
            return ERROR;
1457
0
        }
1458
3
        _PyCompile_CodeUnitMetadata umd = {
1459
3
            .u_argcount = num_typeparam_args,
1460
3
        };
1461
3
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1462
3
                                      (void *)type_params, firstlineno, NULL, &umd);
1463
3
        Py_DECREF(type_params_name);
1464
3
        RETURN_IF_ERROR(ret);
1465
3
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1466
3
        for (int i = 0; i < num_typeparam_args; i++) {
1467
0
            ADDOP_I_IN_SCOPE(c, loc, LOAD_FAST, i);
1468
0
        }
1469
3
    }
1470
1471
6.18k
    int annotations_flag = codegen_function_annotations(c, loc, args, returns);
1472
6.18k
    if (annotations_flag < 0) {
1473
0
        if (is_generic) {
1474
0
            _PyCompile_ExitScope(c);
1475
0
        }
1476
0
        return ERROR;
1477
0
    }
1478
6.18k
    funcflags |= annotations_flag;
1479
1480
6.18k
    int ret = codegen_function_body(c, s, is_async, funcflags, firstlineno);
1481
6.18k
    if (is_generic) {
1482
3
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1483
3
    }
1484
6.17k
    else {
1485
6.17k
        RETURN_IF_ERROR(ret);
1486
6.17k
    }
1487
1488
6.18k
    if (is_generic) {
1489
3
        ADDOP_I_IN_SCOPE(c, loc, SWAP, 2);
1490
3
        ADDOP_I_IN_SCOPE(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_FUNCTION_TYPE_PARAMS);
1491
1492
3
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1493
3
        _PyCompile_ExitScope(c);
1494
3
        if (co == NULL) {
1495
0
            return ERROR;
1496
0
        }
1497
3
        int ret = codegen_make_closure(c, loc, co, 0);
1498
3
        Py_DECREF(co);
1499
3
        RETURN_IF_ERROR(ret);
1500
3
        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
3
        else {
1505
3
            ADDOP(c, loc, PUSH_NULL);
1506
3
            ADDOP_I(c, loc, CALL, 0);
1507
3
        }
1508
3
    }
1509
1510
6.18k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1511
6.18k
    return codegen_nameop(c, loc, name, Store);
1512
6.18k
}
1513
1514
static int
1515
codegen_set_type_params_in_class(compiler *c, location loc)
1516
2
{
1517
2
    _Py_DECLARE_STR(type_params, ".type_params");
1518
2
    RETURN_IF_ERROR(codegen_nameop(c, loc, &_Py_STR(type_params), Load));
1519
2
    RETURN_IF_ERROR(codegen_nameop(c, loc, &_Py_ID(__type_params__), Store));
1520
2
    return SUCCESS;
1521
2
}
1522
1523
1524
static int
1525
codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
1526
1.27k
{
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.27k
    RETURN_IF_ERROR(
1540
1.27k
        codegen_enter_scope(c, s->v.ClassDef.name, COMPILE_SCOPE_CLASS,
1541
1.27k
                            (void *)s, firstlineno, s->v.ClassDef.name, NULL));
1542
1543
1.27k
    location loc = LOCATION(firstlineno, firstlineno, 0, 0);
1544
    /* load (global) __name__ ... */
1545
1.27k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__name__), Load));
1546
    /* ... and store it as __module__ */
1547
1.27k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__module__), Store));
1548
1.27k
    ADDOP_LOAD_CONST(c, loc, QUALNAME(c));
1549
1.27k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__qualname__), Store));
1550
1.27k
    ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
1551
1.27k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__firstlineno__), Store));
1552
1.27k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1553
1.27k
    if (asdl_seq_LEN(type_params) > 0) {
1554
2
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_set_type_params_in_class(c, loc));
1555
2
    }
1556
1.27k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1557
794
        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
794
        ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__classdict__), cellvars);
1563
794
    }
1564
1.27k
    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.27k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, false));
1570
1.27k
    PyObject *static_attributes = _PyCompile_StaticAttributesAsTuple(c);
1571
1.27k
    if (static_attributes == NULL) {
1572
0
        _PyCompile_ExitScope(c);
1573
0
        return ERROR;
1574
0
    }
1575
1.27k
    ADDOP_LOAD_CONST(c, NO_LOCATION, static_attributes);
1576
1.27k
    Py_CLEAR(static_attributes);
1577
1.27k
    RETURN_IF_ERROR_IN_SCOPE(
1578
1.27k
        c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__static_attributes__), Store));
1579
    /* The following code is artificial */
1580
    /* Set __classdictcell__ if necessary */
1581
1.27k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1582
        /* Store __classdictcell__ into class namespace */
1583
794
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__classdict__));
1584
794
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1585
794
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1586
794
        RETURN_IF_ERROR_IN_SCOPE(
1587
794
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store));
1588
794
    }
1589
    /* Return __classcell__ if it is referenced, otherwise return None */
1590
1.27k
    if (SYMTABLE_ENTRY(c)->ste_needs_class_closure) {
1591
        /* Store __classcell__ into class namespace & return it */
1592
110
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__class__));
1593
110
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1594
110
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1595
110
        ADDOP_I(c, NO_LOCATION, COPY, 1);
1596
110
        RETURN_IF_ERROR_IN_SCOPE(
1597
110
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store));
1598
110
    }
1599
1.16k
    else {
1600
        /* No methods referenced __class__, so just return None */
1601
1.16k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1602
1.16k
    }
1603
1.27k
    ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
1604
    /* create the code object */
1605
1.27k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1606
1607
    /* leave the new scope */
1608
1.27k
    _PyCompile_ExitScope(c);
1609
1.27k
    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.27k
    loc = LOC(s);
1618
1.27k
    ADDOP(c, loc, LOAD_BUILD_CLASS);
1619
1.27k
    ADDOP(c, loc, PUSH_NULL);
1620
1621
    /* 3. load a function (or closure) made from the code object */
1622
1.27k
    int ret = codegen_make_closure(c, loc, co, 0);
1623
1.27k
    Py_DECREF(co);
1624
1.27k
    RETURN_IF_ERROR(ret);
1625
1626
    /* 4. load class name */
1627
1.27k
    ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
1628
1629
1.27k
    return SUCCESS;
1630
1.27k
}
1631
1632
static int
1633
codegen_class(compiler *c, stmt_ty s)
1634
1.27k
{
1635
1.27k
    asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
1636
1637
1.27k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1638
1639
1.27k
    int firstlineno = s->lineno;
1640
1.27k
    if (asdl_seq_LEN(decos)) {
1641
38
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1642
38
    }
1643
1.27k
    location loc = LOC(s);
1644
1645
1.27k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1646
1.27k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1647
1.27k
    if (is_generic) {
1648
2
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>",
1649
2
                                                         s->v.ClassDef.name);
1650
2
        if (!type_params_name) {
1651
0
            return ERROR;
1652
0
        }
1653
2
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1654
2
                                      (void *)type_params, firstlineno, s->v.ClassDef.name, NULL);
1655
2
        Py_DECREF(type_params_name);
1656
2
        RETURN_IF_ERROR(ret);
1657
2
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1658
2
        _Py_DECLARE_STR(type_params, ".type_params");
1659
2
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(type_params), Store));
1660
2
    }
1661
1662
1.27k
    int ret = codegen_class_body(c, s, firstlineno);
1663
1.27k
    if (is_generic) {
1664
2
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1665
2
    }
1666
1.27k
    else {
1667
1.27k
        RETURN_IF_ERROR(ret);
1668
1.27k
    }
1669
1670
    /* generate the rest of the code for the call */
1671
1672
1.27k
    if (is_generic) {
1673
2
        _Py_DECLARE_STR(type_params, ".type_params");
1674
2
        _Py_DECLARE_STR(generic_base, ".generic_base");
1675
2
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(type_params), Load));
1676
2
        ADDOP_I_IN_SCOPE(c, loc, CALL_INTRINSIC_1, INTRINSIC_SUBSCRIPT_GENERIC);
1677
2
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(generic_base), Store));
1678
1679
2
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_call_helper_impl(c, loc, 2,
1680
2
                                                             s->v.ClassDef.bases,
1681
2
                                                             &_Py_STR(generic_base),
1682
2
                                                             s->v.ClassDef.keywords));
1683
1684
2
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1685
1686
2
        _PyCompile_ExitScope(c);
1687
2
        if (co == NULL) {
1688
0
            return ERROR;
1689
0
        }
1690
2
        int ret = codegen_make_closure(c, loc, co, 0);
1691
2
        Py_DECREF(co);
1692
2
        RETURN_IF_ERROR(ret);
1693
2
        ADDOP(c, loc, PUSH_NULL);
1694
2
        ADDOP_I(c, loc, CALL, 0);
1695
1.27k
    } else {
1696
1.27k
        RETURN_IF_ERROR(codegen_call_helper(c, loc, 2,
1697
1.27k
                                            s->v.ClassDef.bases,
1698
1.27k
                                            s->v.ClassDef.keywords));
1699
1.27k
    }
1700
1701
    /* 6. apply decorators */
1702
1.27k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1703
1704
    /* 7. store into <name> */
1705
1.27k
    RETURN_IF_ERROR(codegen_nameop(c, loc, s->v.ClassDef.name, Store));
1706
1.27k
    return SUCCESS;
1707
1.27k
}
1708
1709
static int
1710
codegen_typealias_body(compiler *c, stmt_ty s)
1711
1
{
1712
1
    location loc = LOC(s);
1713
1
    PyObject *name = s->v.TypeAlias.name->v.Name.id;
1714
1
    PyObject *defaults = PyTuple_Pack(1, _PyLong_GetOne());
1715
1
    ADDOP_LOAD_CONST_NEW(c, loc, defaults);
1716
1
    RETURN_IF_ERROR(
1717
1
        codegen_setup_annotations_scope(c, LOC(s), s, name));
1718
1719
1
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
1720
1
    VISIT_IN_SCOPE(c, expr, s->v.TypeAlias.value);
1721
1
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
1722
1
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1723
1
    _PyCompile_ExitScope(c);
1724
1
    if (co == NULL) {
1725
0
        return ERROR;
1726
0
    }
1727
1
    int ret = codegen_make_closure(c, loc, co, MAKE_FUNCTION_DEFAULTS);
1728
1
    Py_DECREF(co);
1729
1
    RETURN_IF_ERROR(ret);
1730
1731
1
    ADDOP_I(c, loc, BUILD_TUPLE, 3);
1732
1
    ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEALIAS);
1733
1
    return SUCCESS;
1734
1
}
1735
1736
static int
1737
codegen_typealias(compiler *c, stmt_ty s)
1738
1
{
1739
1
    location loc = LOC(s);
1740
1
    asdl_type_param_seq *type_params = s->v.TypeAlias.type_params;
1741
1
    int is_generic = asdl_seq_LEN(type_params) > 0;
1742
1
    PyObject *name = s->v.TypeAlias.name->v.Name.id;
1743
1
    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
1
    else {
1757
1
        ADDOP_LOAD_CONST(c, loc, name);
1758
1
        ADDOP_LOAD_CONST(c, loc, Py_None);
1759
1
    }
1760
1761
1
    int ret = codegen_typealias_body(c, s);
1762
1
    if (is_generic) {
1763
0
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1764
0
    }
1765
1
    else {
1766
1
        RETURN_IF_ERROR(ret);
1767
1
    }
1768
1769
1
    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
1
    RETURN_IF_ERROR(codegen_nameop(c, loc, name, Store));
1782
1
    return SUCCESS;
1783
1
}
1784
1785
static bool
1786
is_const_tuple(asdl_expr_seq *elts)
1787
269
{
1788
619
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(elts); i++) {
1789
497
        expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
1790
497
        if (e->kind != Constant_kind) {
1791
147
            return false;
1792
147
        }
1793
497
    }
1794
122
    return true;
1795
269
}
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
17.5k
{
1802
17.5k
    if (e->kind == Tuple_kind) {
1803
269
        return !is_const_tuple(e->v.Tuple.elts);
1804
269
    }
1805
17.3k
    if (e->kind != Constant_kind) {
1806
12.6k
        return true;
1807
12.6k
    }
1808
4.66k
    PyObject *value = e->v.Constant.value;
1809
4.66k
    return (value == Py_None
1810
4.66k
         || value == Py_False
1811
4.66k
         || value == Py_True
1812
2.78k
         || value == Py_Ellipsis);
1813
17.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
8.75k
{
1823
8.75k
    Py_ssize_t i, n;
1824
8.75k
    bool left = check_is_arg(e->v.Compare.left);
1825
8.75k
    expr_ty left_expr = e->v.Compare.left;
1826
8.75k
    n = asdl_seq_LEN(e->v.Compare.ops);
1827
17.5k
    for (i = 0; i < n; i++) {
1828
8.83k
        cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
1829
8.83k
        expr_ty right_expr = (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i);
1830
8.83k
        bool right = check_is_arg(right_expr);
1831
8.83k
        if (op == Is || op == IsNot) {
1832
2.94k
            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.94k
        }
1842
8.83k
        left = right;
1843
8.83k
        left_expr = right_expr;
1844
8.83k
    }
1845
8.75k
    return SUCCESS;
1846
8.75k
}
1847
1848
static int
1849
codegen_addcompare(compiler *c, location loc, cmpop_ty op)
1850
8.94k
{
1851
8.94k
    int cmp;
1852
8.94k
    switch (op) {
1853
2.30k
    case Eq:
1854
2.30k
        cmp = Py_EQ;
1855
2.30k
        break;
1856
641
    case NotEq:
1857
641
        cmp = Py_NE;
1858
641
        break;
1859
473
    case Lt:
1860
473
        cmp = Py_LT;
1861
473
        break;
1862
212
    case LtE:
1863
212
        cmp = Py_LE;
1864
212
        break;
1865
405
    case Gt:
1866
405
        cmp = Py_GT;
1867
405
        break;
1868
172
    case GtE:
1869
172
        cmp = Py_GE;
1870
172
        break;
1871
1.99k
    case Is:
1872
1.99k
        ADDOP_I(c, loc, IS_OP, 0);
1873
1.99k
        return SUCCESS;
1874
1.03k
    case IsNot:
1875
1.03k
        ADDOP_I(c, loc, IS_OP, 1);
1876
1.03k
        return SUCCESS;
1877
1.26k
    case In:
1878
1.26k
        ADDOP_I(c, loc, CONTAINS_OP, 0);
1879
1.26k
        return SUCCESS;
1880
442
    case NotIn:
1881
442
        ADDOP_I(c, loc, CONTAINS_OP, 1);
1882
442
        return SUCCESS;
1883
0
    default:
1884
0
        Py_UNREACHABLE();
1885
8.94k
    }
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
4.20k
    ADDOP_I(c, loc, COMPARE_OP, (cmp << 5) | compare_masks[cmp]);
1891
4.20k
    return SUCCESS;
1892
4.20k
}
1893
1894
static int
1895
codegen_jump_if(compiler *c, location loc,
1896
                expr_ty e, jump_target_label next, int cond)
1897
17.7k
{
1898
17.7k
    switch (e->kind) {
1899
1.80k
    case UnaryOp_kind:
1900
1.80k
        if (e->v.UnaryOp.op == Not) {
1901
1.80k
            return codegen_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond);
1902
1.80k
        }
1903
        /* fallback to general implementation */
1904
0
        break;
1905
1.70k
    case BoolOp_kind: {
1906
1.70k
        asdl_expr_seq *s = e->v.BoolOp.values;
1907
1.70k
        Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
1908
1.70k
        assert(n >= 0);
1909
1.70k
        int cond2 = e->v.BoolOp.op == Or;
1910
1.70k
        jump_target_label next2 = next;
1911
1.70k
        if (!cond2 != !cond) {
1912
550
            NEW_JUMP_TARGET_LABEL(c, new_next2);
1913
550
            next2 = new_next2;
1914
550
        }
1915
3.67k
        for (i = 0; i < n; ++i) {
1916
1.96k
            RETURN_IF_ERROR(
1917
1.96k
                codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2));
1918
1.96k
        }
1919
1.70k
        RETURN_IF_ERROR(
1920
1.70k
            codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond));
1921
1.70k
        if (!SAME_JUMP_TARGET_LABEL(next2, next)) {
1922
550
            USE_LABEL(c, next2);
1923
550
        }
1924
1.70k
        return SUCCESS;
1925
1.70k
    }
1926
2
    case IfExp_kind: {
1927
2
        NEW_JUMP_TARGET_LABEL(c, end);
1928
2
        NEW_JUMP_TARGET_LABEL(c, next2);
1929
2
        RETURN_IF_ERROR(
1930
2
            codegen_jump_if(c, loc, e->v.IfExp.test, next2, 0));
1931
2
        RETURN_IF_ERROR(
1932
2
            codegen_jump_if(c, loc, e->v.IfExp.body, next, cond));
1933
2
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1934
1935
2
        USE_LABEL(c, next2);
1936
2
        RETURN_IF_ERROR(
1937
2
            codegen_jump_if(c, loc, e->v.IfExp.orelse, next, cond));
1938
1939
2
        USE_LABEL(c, end);
1940
2
        return SUCCESS;
1941
2
    }
1942
8.02k
    case Compare_kind: {
1943
8.02k
        Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1;
1944
8.02k
        if (n > 0) {
1945
57
            RETURN_IF_ERROR(codegen_check_compare(c, e));
1946
57
            NEW_JUMP_TARGET_LABEL(c, cleanup);
1947
57
            VISIT(c, expr, e->v.Compare.left);
1948
114
            for (Py_ssize_t i = 0; i < n; i++) {
1949
57
                VISIT(c, expr,
1950
57
                    (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
1951
57
                ADDOP_I(c, LOC(e), SWAP, 2);
1952
57
                ADDOP_I(c, LOC(e), COPY, 2);
1953
57
                ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i));
1954
57
                ADDOP(c, LOC(e), TO_BOOL);
1955
57
                ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup);
1956
57
            }
1957
57
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
1958
57
            ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n));
1959
57
            ADDOP(c, LOC(e), TO_BOOL);
1960
57
            ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
1961
57
            NEW_JUMP_TARGET_LABEL(c, end);
1962
57
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1963
1964
57
            USE_LABEL(c, cleanup);
1965
57
            ADDOP(c, LOC(e), POP_TOP);
1966
57
            if (!cond) {
1967
30
                ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, next);
1968
30
            }
1969
1970
57
            USE_LABEL(c, end);
1971
57
            return SUCCESS;
1972
57
        }
1973
        /* fallback to general implementation */
1974
7.97k
        break;
1975
8.02k
    }
1976
7.97k
    default:
1977
        /* fallback to general implementation */
1978
6.25k
        break;
1979
17.7k
    }
1980
1981
    /* general implementation */
1982
14.2k
    VISIT(c, expr, e);
1983
14.2k
    ADDOP(c, LOC(e), TO_BOOL);
1984
14.2k
    ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
1985
14.2k
    return SUCCESS;
1986
14.2k
}
1987
1988
static int
1989
codegen_ifexp(compiler *c, expr_ty e)
1990
306
{
1991
306
    assert(e->kind == IfExp_kind);
1992
306
    NEW_JUMP_TARGET_LABEL(c, end);
1993
306
    NEW_JUMP_TARGET_LABEL(c, next);
1994
1995
306
    RETURN_IF_ERROR(
1996
306
        codegen_jump_if(c, LOC(e), e->v.IfExp.test, next, 0));
1997
1998
306
    VISIT(c, expr, e->v.IfExp.body);
1999
306
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2000
2001
306
    USE_LABEL(c, next);
2002
306
    VISIT(c, expr, e->v.IfExp.orelse);
2003
2004
306
    USE_LABEL(c, end);
2005
306
    return SUCCESS;
2006
306
}
2007
2008
static int
2009
codegen_lambda(compiler *c, expr_ty e)
2010
186
{
2011
186
    PyCodeObject *co;
2012
186
    Py_ssize_t funcflags;
2013
186
    arguments_ty args = e->v.Lambda.args;
2014
186
    assert(e->kind == Lambda_kind);
2015
2016
186
    location loc = LOC(e);
2017
186
    funcflags = codegen_default_arguments(c, loc, args);
2018
186
    RETURN_IF_ERROR(funcflags);
2019
2020
186
    _PyCompile_CodeUnitMetadata umd = {
2021
186
        .u_argcount = asdl_seq_LEN(args->args),
2022
186
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
2023
186
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
2024
186
    };
2025
186
    _Py_DECLARE_STR(anon_lambda, "<lambda>");
2026
186
    RETURN_IF_ERROR(
2027
186
        codegen_enter_scope(c, &_Py_STR(anon_lambda), COMPILE_SCOPE_LAMBDA,
2028
186
                            (void *)e, e->lineno, NULL, &umd));
2029
2030
186
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
2031
2032
186
    VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
2033
186
    if (SYMTABLE_ENTRY(c)->ste_generator) {
2034
0
        co = _PyCompile_OptimizeAndAssemble(c, 0);
2035
0
    }
2036
186
    else {
2037
186
        location loc = LOC(e->v.Lambda.body);
2038
186
        ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
2039
186
        co = _PyCompile_OptimizeAndAssemble(c, 1);
2040
186
    }
2041
186
    _PyCompile_ExitScope(c);
2042
186
    if (co == NULL) {
2043
0
        return ERROR;
2044
0
    }
2045
2046
186
    int ret = codegen_make_closure(c, loc, co, funcflags);
2047
186
    Py_DECREF(co);
2048
186
    RETURN_IF_ERROR(ret);
2049
186
    return SUCCESS;
2050
186
}
2051
2052
static int
2053
codegen_if(compiler *c, stmt_ty s)
2054
11.2k
{
2055
11.2k
    jump_target_label next;
2056
11.2k
    assert(s->kind == If_kind);
2057
11.2k
    NEW_JUMP_TARGET_LABEL(c, end);
2058
11.2k
    if (asdl_seq_LEN(s->v.If.orelse)) {
2059
3.60k
        NEW_JUMP_TARGET_LABEL(c, orelse);
2060
3.60k
        next = orelse;
2061
3.60k
    }
2062
7.66k
    else {
2063
7.66k
        next = end;
2064
7.66k
    }
2065
11.2k
    RETURN_IF_ERROR(
2066
11.2k
        codegen_jump_if(c, LOC(s), s->v.If.test, next, 0));
2067
2068
11.2k
    VISIT_SEQ(c, stmt, s->v.If.body);
2069
11.2k
    if (asdl_seq_LEN(s->v.If.orelse)) {
2070
3.60k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2071
2072
3.60k
        USE_LABEL(c, next);
2073
3.60k
        VISIT_SEQ(c, stmt, s->v.If.orelse);
2074
3.60k
    }
2075
2076
11.2k
    USE_LABEL(c, end);
2077
11.2k
    return SUCCESS;
2078
11.2k
}
2079
2080
static int
2081
codegen_for(compiler *c, stmt_ty s)
2082
1.32k
{
2083
1.32k
    location loc = LOC(s);
2084
1.32k
    NEW_JUMP_TARGET_LABEL(c, start);
2085
1.32k
    NEW_JUMP_TARGET_LABEL(c, body);
2086
1.32k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2087
1.32k
    NEW_JUMP_TARGET_LABEL(c, end);
2088
2089
1.32k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FOR_LOOP, start, end, NULL));
2090
2091
1.32k
    VISIT(c, expr, s->v.For.iter);
2092
2093
1.32k
    loc = LOC(s->v.For.iter);
2094
1.32k
    ADDOP(c, loc, GET_ITER);
2095
2096
1.32k
    USE_LABEL(c, start);
2097
1.32k
    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.32k
    ADDOP(c, LOC(s->v.For.target), NOP);
2103
2104
1.32k
    USE_LABEL(c, body);
2105
1.32k
    VISIT(c, expr, s->v.For.target);
2106
1.32k
    VISIT_SEQ(c, stmt, s->v.For.body);
2107
    /* Mark jump as artificial */
2108
1.32k
    ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
2109
2110
1.32k
    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.32k
    ADDOP(c, NO_LOCATION, END_FOR);
2116
1.32k
    ADDOP(c, NO_LOCATION, POP_ITER);
2117
2118
1.32k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FOR_LOOP, start);
2119
2120
1.32k
    VISIT_SEQ(c, stmt, s->v.For.orelse);
2121
2122
1.32k
    USE_LABEL(c, end);
2123
1.32k
    return SUCCESS;
2124
1.32k
}
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
427
{
2177
427
    NEW_JUMP_TARGET_LABEL(c, loop);
2178
427
    NEW_JUMP_TARGET_LABEL(c, end);
2179
427
    NEW_JUMP_TARGET_LABEL(c, anchor);
2180
2181
427
    USE_LABEL(c, loop);
2182
2183
427
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, LOC(s), COMPILE_FBLOCK_WHILE_LOOP, loop, end, NULL));
2184
427
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.While.test, anchor, 0));
2185
2186
427
    VISIT_SEQ(c, stmt, s->v.While.body);
2187
427
    ADDOP_JUMP(c, NO_LOCATION, JUMP, loop);
2188
2189
427
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_WHILE_LOOP, loop);
2190
2191
427
    USE_LABEL(c, anchor);
2192
427
    if (s->v.While.orelse) {
2193
8
        VISIT_SEQ(c, stmt, s->v.While.orelse);
2194
8
    }
2195
2196
427
    USE_LABEL(c, end);
2197
427
    return SUCCESS;
2198
427
}
2199
2200
static int
2201
codegen_return(compiler *c, stmt_ty s)
2202
6.83k
{
2203
6.83k
    location loc = LOC(s);
2204
6.83k
    int preserve_tos = ((s->v.Return.value != NULL) &&
2205
6.59k
                        (s->v.Return.value->kind != Constant_kind));
2206
2207
6.83k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
2208
6.83k
    if (!_PyST_IsFunctionLike(ste)) {
2209
0
        return _PyCompile_Error(c, loc, "'return' outside function");
2210
0
    }
2211
6.83k
    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
6.83k
    if (preserve_tos) {
2216
5.90k
        VISIT(c, expr, s->v.Return.value);
2217
5.90k
    } else {
2218
        /* Emit instruction with line number for return value */
2219
936
        if (s->v.Return.value != NULL) {
2220
695
            loc = LOC(s->v.Return.value);
2221
695
            ADDOP(c, loc, NOP);
2222
695
        }
2223
936
    }
2224
6.83k
    if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
2225
269
        loc = LOC(s);
2226
269
        ADDOP(c, loc, NOP);
2227
269
    }
2228
2229
6.83k
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, preserve_tos, NULL));
2230
6.83k
    if (s->v.Return.value == NULL) {
2231
241
        ADDOP_LOAD_CONST(c, loc, Py_None);
2232
241
    }
2233
6.59k
    else if (!preserve_tos) {
2234
695
        ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value);
2235
695
    }
2236
6.83k
    ADDOP(c, loc, RETURN_VALUE);
2237
2238
6.83k
    return SUCCESS;
2239
6.83k
}
2240
2241
static int
2242
codegen_break(compiler *c, location loc)
2243
455
{
2244
455
    fblockinfo *loop = NULL;
2245
455
    location origin_loc = loc;
2246
    /* Emit instruction with line number */
2247
455
    ADDOP(c, loc, NOP);
2248
455
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2249
455
    if (loop == NULL) {
2250
0
        return _PyCompile_Error(c, origin_loc, "'break' outside loop");
2251
0
    }
2252
455
    RETURN_IF_ERROR(codegen_unwind_fblock(c, &loc, loop, 0));
2253
455
    ADDOP_JUMP(c, loc, JUMP, loop->fb_exit);
2254
455
    return SUCCESS;
2255
455
}
2256
2257
static int
2258
codegen_continue(compiler *c, location loc)
2259
351
{
2260
351
    fblockinfo *loop = NULL;
2261
351
    location origin_loc = loc;
2262
    /* Emit instruction with line number */
2263
351
    ADDOP(c, loc, NOP);
2264
351
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2265
351
    if (loop == NULL) {
2266
0
        return _PyCompile_Error(c, origin_loc, "'continue' not properly in loop");
2267
0
    }
2268
351
    ADDOP_JUMP(c, loc, JUMP, loop->fb_block);
2269
351
    return SUCCESS;
2270
351
}
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
75
{
2305
75
    location loc = LOC(s);
2306
2307
75
    NEW_JUMP_TARGET_LABEL(c, body);
2308
75
    NEW_JUMP_TARGET_LABEL(c, end);
2309
75
    NEW_JUMP_TARGET_LABEL(c, exit);
2310
75
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2311
2312
    /* `try` block */
2313
75
    ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
2314
2315
75
    USE_LABEL(c, body);
2316
75
    RETURN_IF_ERROR(
2317
75
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_TRY, body, end,
2318
75
                              s->v.Try.finalbody));
2319
2320
75
    if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
2321
3
        RETURN_IF_ERROR(codegen_try_except(c, s));
2322
3
    }
2323
72
    else {
2324
72
        VISIT_SEQ(c, stmt, s->v.Try.body);
2325
72
    }
2326
75
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2327
75
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_TRY, body);
2328
75
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2329
2330
75
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
2331
    /* `finally` block */
2332
2333
75
    USE_LABEL(c, end);
2334
2335
75
    loc = NO_LOCATION;
2336
75
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
2337
75
    ADDOP(c, loc, PUSH_EXC_INFO);
2338
75
    RETURN_IF_ERROR(
2339
75
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_END, end, NO_LABEL, NULL));
2340
75
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2341
75
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_END, end);
2342
2343
75
    loc = NO_LOCATION;
2344
75
    ADDOP_I(c, loc, RERAISE, 0);
2345
2346
75
    USE_LABEL(c, cleanup);
2347
75
    POP_EXCEPT_AND_RERAISE(c, loc);
2348
2349
75
    USE_LABEL(c, exit);
2350
75
    return SUCCESS;
2351
75
}
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
1.10k
{
2436
1.10k
    location loc = LOC(s);
2437
1.10k
    Py_ssize_t i, n;
2438
2439
1.10k
    NEW_JUMP_TARGET_LABEL(c, body);
2440
1.10k
    NEW_JUMP_TARGET_LABEL(c, except);
2441
1.10k
    NEW_JUMP_TARGET_LABEL(c, end);
2442
1.10k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2443
2444
1.10k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2445
2446
1.10k
    USE_LABEL(c, body);
2447
1.10k
    RETURN_IF_ERROR(
2448
1.10k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_TRY_EXCEPT, body, NO_LABEL, NULL));
2449
1.10k
    VISIT_SEQ(c, stmt, s->v.Try.body);
2450
1.10k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_TRY_EXCEPT, body);
2451
1.10k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2452
1.10k
    if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
2453
110
        VISIT_SEQ(c, stmt, s->v.Try.orelse);
2454
110
    }
2455
1.10k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2456
1.10k
    n = asdl_seq_LEN(s->v.Try.handlers);
2457
2458
1.10k
    USE_LABEL(c, except);
2459
2460
1.10k
    ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
2461
1.10k
    ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
2462
2463
    /* Runtime will push a block here, so we need to account for that */
2464
1.10k
    RETURN_IF_ERROR(
2465
1.10k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_EXCEPTION_HANDLER,
2466
1.10k
                              NO_LABEL, NO_LABEL, NULL));
2467
2468
2.27k
    for (i = 0; i < n; i++) {
2469
1.17k
        excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
2470
1.17k
            s->v.Try.handlers, i);
2471
1.17k
        location loc = LOC(handler);
2472
1.17k
        if (!handler->v.ExceptHandler.type && i < n-1) {
2473
0
            return _PyCompile_Error(c, loc, "default 'except:' must be last");
2474
0
        }
2475
1.17k
        NEW_JUMP_TARGET_LABEL(c, next_except);
2476
1.17k
        except = next_except;
2477
1.17k
        if (handler->v.ExceptHandler.type) {
2478
1.13k
            VISIT(c, expr, handler->v.ExceptHandler.type);
2479
1.13k
            ADDOP(c, loc, CHECK_EXC_MATCH);
2480
1.13k
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
2481
1.13k
        }
2482
1.17k
        if (handler->v.ExceptHandler.name) {
2483
194
            NEW_JUMP_TARGET_LABEL(c, cleanup_end);
2484
194
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2485
2486
194
            RETURN_IF_ERROR(
2487
194
                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
194
            ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
2502
2503
194
            USE_LABEL(c, cleanup_body);
2504
194
            RETURN_IF_ERROR(
2505
194
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2506
194
                                      NO_LABEL, handler->v.ExceptHandler.name));
2507
2508
            /* second # body */
2509
194
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2510
194
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2511
            /* name = None; del name; # Mark as artificial */
2512
194
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2513
194
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2514
194
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2515
194
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2516
194
            RETURN_IF_ERROR(
2517
194
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2518
194
            RETURN_IF_ERROR(
2519
194
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2520
194
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2521
2522
            /* except: */
2523
194
            USE_LABEL(c, cleanup_end);
2524
2525
            /* name = None; del name; # artificial */
2526
194
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2527
194
            RETURN_IF_ERROR(
2528
194
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2529
194
            RETURN_IF_ERROR(
2530
194
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2531
2532
194
            ADDOP_I(c, NO_LOCATION, RERAISE, 1);
2533
194
        }
2534
981
        else {
2535
981
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2536
2537
981
            ADDOP(c, loc, POP_TOP); /* exc_value */
2538
2539
981
            USE_LABEL(c, cleanup_body);
2540
981
            RETURN_IF_ERROR(
2541
981
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2542
981
                                      NO_LABEL, NULL));
2543
2544
981
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2545
981
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2546
981
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2547
981
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2548
981
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2549
981
        }
2550
2551
1.17k
        USE_LABEL(c, except);
2552
1.17k
    }
2553
    /* artificial */
2554
1.10k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_EXCEPTION_HANDLER, NO_LABEL);
2555
1.10k
    ADDOP_I(c, NO_LOCATION, RERAISE, 0);
2556
2557
1.10k
    USE_LABEL(c, cleanup);
2558
1.10k
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
2559
2560
1.10k
    USE_LABEL(c, end);
2561
1.10k
    return SUCCESS;
2562
1.10k
}
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
1.17k
codegen_try(compiler *c, stmt_ty s) {
2785
1.17k
    if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
2786
75
        return codegen_try_finally(c, s);
2787
1.09k
    else
2788
1.09k
        return codegen_try_except(c, s);
2789
1.17k
}
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
49
{
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
49
    Py_ssize_t len = PyUnicode_GET_LENGTH(name);
2813
49
    Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
2814
49
    if (dot == -2) {
2815
0
        return ERROR;
2816
0
    }
2817
49
    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
49
    return codegen_nameop(c, loc, asname, Store);
2842
49
}
2843
2844
static int
2845
codegen_import(compiler *c, stmt_ty s)
2846
819
{
2847
819
    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
819
    Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
2856
2857
819
    PyObject *zero = _PyLong_GetZero();  // borrowed reference
2858
1.67k
    for (i = 0; i < n; i++) {
2859
855
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
2860
855
        int r;
2861
2862
855
        ADDOP_LOAD_CONST(c, loc, zero);
2863
855
        ADDOP_LOAD_CONST(c, loc, Py_None);
2864
855
        ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names);
2865
2866
855
        if (alias->asname) {
2867
49
            r = codegen_import_as(c, loc, alias->name, alias->asname);
2868
49
            RETURN_IF_ERROR(r);
2869
49
        }
2870
806
        else {
2871
806
            identifier tmp = alias->name;
2872
806
            Py_ssize_t dot = PyUnicode_FindChar(
2873
806
                alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
2874
806
            if (dot != -1) {
2875
31
                tmp = PyUnicode_Substring(alias->name, 0, dot);
2876
31
                if (tmp == NULL) {
2877
0
                    return ERROR;
2878
0
                }
2879
31
            }
2880
806
            r = codegen_nameop(c, loc, tmp, Store);
2881
806
            if (dot != -1) {
2882
31
                Py_DECREF(tmp);
2883
31
            }
2884
806
            RETURN_IF_ERROR(r);
2885
806
        }
2886
855
    }
2887
819
    return SUCCESS;
2888
819
}
2889
2890
static int
2891
codegen_from_import(compiler *c, stmt_ty s)
2892
398
{
2893
398
    Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names);
2894
2895
398
    ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level));
2896
2897
398
    PyObject *names = PyTuple_New(n);
2898
398
    if (!names) {
2899
0
        return ERROR;
2900
0
    }
2901
2902
    /* build up the names */
2903
1.09k
    for (Py_ssize_t i = 0; i < n; i++) {
2904
699
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
2905
699
        PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name));
2906
699
    }
2907
2908
398
    ADDOP_LOAD_CONST_NEW(c, LOC(s), names);
2909
2910
398
    if (s->v.ImportFrom.module) {
2911
385
        ADDOP_NAME(c, LOC(s), IMPORT_NAME, s->v.ImportFrom.module, names);
2912
385
    }
2913
13
    else {
2914
13
        _Py_DECLARE_STR(empty, "");
2915
13
        ADDOP_NAME(c, LOC(s), IMPORT_NAME, &_Py_STR(empty), names);
2916
13
    }
2917
1.06k
    for (Py_ssize_t i = 0; i < n; i++) {
2918
699
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
2919
699
        identifier store_name;
2920
2921
699
        if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
2922
33
            assert(n == 1);
2923
33
            ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
2924
33
            ADDOP(c, NO_LOCATION, POP_TOP);
2925
33
            return SUCCESS;
2926
33
        }
2927
2928
666
        ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names);
2929
666
        store_name = alias->name;
2930
666
        if (alias->asname) {
2931
87
            store_name = alias->asname;
2932
87
        }
2933
2934
666
        RETURN_IF_ERROR(codegen_nameop(c, LOC(s), store_name, Store));
2935
666
    }
2936
    /* remove imported module */
2937
365
    ADDOP(c, LOC(s), POP_TOP);
2938
365
    return SUCCESS;
2939
365
}
2940
2941
static int
2942
codegen_assert(compiler *c, stmt_ty s)
2943
209
{
2944
    /* Always emit a warning if the test is a non-zero length tuple */
2945
209
    if ((s->v.Assert.test->kind == Tuple_kind &&
2946
0
        asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
2947
209
        (s->v.Assert.test->kind == Constant_kind &&
2948
209
         PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
2949
0
         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
209
    if (OPTIMIZATION_LEVEL(c)) {
2956
0
        return SUCCESS;
2957
0
    }
2958
209
    NEW_JUMP_TARGET_LABEL(c, end);
2959
209
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.Assert.test, end, 1));
2960
209
    ADDOP_I(c, LOC(s), LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR);
2961
209
    if (s->v.Assert.msg) {
2962
50
        VISIT(c, expr, s->v.Assert.msg);
2963
50
        ADDOP_I(c, LOC(s), CALL, 0);
2964
50
    }
2965
209
    ADDOP_I(c, LOC(s->v.Assert.test), RAISE_VARARGS, 1);
2966
2967
209
    USE_LABEL(c, end);
2968
209
    return SUCCESS;
2969
209
}
2970
2971
static int
2972
codegen_stmt_expr(compiler *c, location loc, expr_ty value)
2973
6.44k
{
2974
6.44k
    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
6.44k
    if (value->kind == Constant_kind) {
2982
        /* ignore constant statement */
2983
4
        ADDOP(c, loc, NOP);
2984
4
        return SUCCESS;
2985
4
    }
2986
2987
6.44k
    VISIT(c, expr, value);
2988
6.44k
    ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */
2989
6.44k
    return SUCCESS;
2990
6.44k
}
2991
2992
#define CODEGEN_COND_BLOCK(FUNC, C, S) \
2993
14.3k
    do { \
2994
14.3k
        _PyCompile_EnterConditionalBlock((C)); \
2995
14.3k
        int result = FUNC((C), (S)); \
2996
14.3k
        _PyCompile_LeaveConditionalBlock((C)); \
2997
14.3k
        return result; \
2998
14.3k
    } while(0)
2999
3000
static int
3001
codegen_visit_stmt(compiler *c, stmt_ty s)
3002
60.6k
{
3003
3004
60.6k
    switch (s->kind) {
3005
6.16k
    case FunctionDef_kind:
3006
6.16k
        return codegen_function(c, s, 0);
3007
1.27k
    case ClassDef_kind:
3008
1.27k
        return codegen_class(c, s);
3009
1
    case TypeAlias_kind:
3010
1
        return codegen_typealias(c, s);
3011
6.83k
    case Return_kind:
3012
6.83k
        return codegen_return(c, s);
3013
159
    case Delete_kind:
3014
159
        VISIT_SEQ(c, expr, s->v.Delete.targets);
3015
159
        break;
3016
18.7k
    case Assign_kind:
3017
18.7k
    {
3018
18.7k
        Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets);
3019
18.7k
        VISIT(c, expr, s->v.Assign.value);
3020
37.7k
        for (Py_ssize_t i = 0; i < n; i++) {
3021
18.9k
            if (i < n - 1) {
3022
193
                ADDOP_I(c, LOC(s), COPY, 1);
3023
193
            }
3024
18.9k
            VISIT(c, expr,
3025
18.9k
                  (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
3026
18.9k
        }
3027
18.7k
        break;
3028
18.7k
    }
3029
18.7k
    case AugAssign_kind:
3030
1.05k
        return codegen_augassign(c, s);
3031
88
    case AnnAssign_kind:
3032
88
        return codegen_annassign(c, s);
3033
1.32k
    case For_kind:
3034
1.32k
        CODEGEN_COND_BLOCK(codegen_for, c, s);
3035
0
        break;
3036
427
    case While_kind:
3037
427
        CODEGEN_COND_BLOCK(codegen_while, c, s);
3038
0
        break;
3039
11.2k
    case If_kind:
3040
11.2k
        CODEGEN_COND_BLOCK(codegen_if, c, s);
3041
0
        break;
3042
8
    case Match_kind:
3043
8
        CODEGEN_COND_BLOCK(codegen_match, c, s);
3044
0
        break;
3045
2.66k
    case Raise_kind:
3046
2.66k
    {
3047
2.66k
        Py_ssize_t n = 0;
3048
2.66k
        if (s->v.Raise.exc) {
3049
2.53k
            VISIT(c, expr, s->v.Raise.exc);
3050
2.53k
            n++;
3051
2.53k
            if (s->v.Raise.cause) {
3052
215
                VISIT(c, expr, s->v.Raise.cause);
3053
215
                n++;
3054
215
            }
3055
2.53k
        }
3056
2.66k
        ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n);
3057
2.66k
        break;
3058
2.66k
    }
3059
2.66k
    case Try_kind:
3060
1.17k
        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
209
    case Assert_kind:
3066
209
        return codegen_assert(c, s);
3067
819
    case Import_kind:
3068
819
        return codegen_import(c, s);
3069
398
    case ImportFrom_kind:
3070
398
        return codegen_from_import(c, s);
3071
45
    case Global_kind:
3072
70
    case Nonlocal_kind:
3073
70
        break;
3074
6.44k
    case Expr_kind:
3075
6.44k
    {
3076
6.44k
        return codegen_stmt_expr(c, LOC(s), s->v.Expr.value);
3077
45
    }
3078
551
    case Pass_kind:
3079
551
    {
3080
551
        ADDOP(c, LOC(s), NOP);
3081
551
        break;
3082
551
    }
3083
551
    case Break_kind:
3084
455
    {
3085
455
        return codegen_break(c, LOC(s));
3086
551
    }
3087
351
    case Continue_kind:
3088
351
    {
3089
351
        return codegen_continue(c, LOC(s));
3090
551
    }
3091
157
    case With_kind:
3092
157
        CODEGEN_COND_BLOCK(codegen_with, c, s);
3093
0
        break;
3094
18
    case AsyncFunctionDef_kind:
3095
18
        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
60.6k
    }
3103
3104
22.2k
    return SUCCESS;
3105
60.6k
}
3106
3107
static int
3108
unaryop(unaryop_ty op)
3109
834
{
3110
834
    switch (op) {
3111
56
    case Invert:
3112
56
        return UNARY_INVERT;
3113
778
    case USub:
3114
778
        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
834
    }
3120
834
}
3121
3122
static int
3123
addop_binary(compiler *c, location loc, operator_ty binop,
3124
             bool inplace)
3125
6.57k
{
3126
6.57k
    int oparg;
3127
6.57k
    switch (binop) {
3128
3.11k
        case Add:
3129
3.11k
            oparg = inplace ? NB_INPLACE_ADD : NB_ADD;
3130
3.11k
            break;
3131
945
        case Sub:
3132
945
            oparg = inplace ? NB_INPLACE_SUBTRACT : NB_SUBTRACT;
3133
945
            break;
3134
368
        case Mult:
3135
368
            oparg = inplace ? NB_INPLACE_MULTIPLY : NB_MULTIPLY;
3136
368
            break;
3137
2
        case MatMult:
3138
2
            oparg = inplace ? NB_INPLACE_MATRIX_MULTIPLY : NB_MATRIX_MULTIPLY;
3139
2
            break;
3140
37
        case Div:
3141
37
            oparg = inplace ? NB_INPLACE_TRUE_DIVIDE : NB_TRUE_DIVIDE;
3142
37
            break;
3143
839
        case Mod:
3144
839
            oparg = inplace ? NB_INPLACE_REMAINDER : NB_REMAINDER;
3145
839
            break;
3146
63
        case Pow:
3147
63
            oparg = inplace ? NB_INPLACE_POWER : NB_POWER;
3148
63
            break;
3149
100
        case LShift:
3150
100
            oparg = inplace ? NB_INPLACE_LSHIFT : NB_LSHIFT;
3151
100
            break;
3152
62
        case RShift:
3153
62
            oparg = inplace ? NB_INPLACE_RSHIFT : NB_RSHIFT;
3154
62
            break;
3155
314
        case BitOr:
3156
314
            oparg = inplace ? NB_INPLACE_OR : NB_OR;
3157
314
            break;
3158
39
        case BitXor:
3159
39
            oparg = inplace ? NB_INPLACE_XOR : NB_XOR;
3160
39
            break;
3161
578
        case BitAnd:
3162
578
            oparg = inplace ? NB_INPLACE_AND : NB_AND;
3163
578
            break;
3164
120
        case FloorDiv:
3165
120
            oparg = inplace ? NB_INPLACE_FLOOR_DIVIDE : NB_FLOOR_DIVIDE;
3166
120
            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
6.57k
    }
3172
6.57k
    ADDOP_I(c, loc, BINARY_OP, oparg);
3173
6.57k
    return SUCCESS;
3174
6.57k
}
3175
3176
3177
static int
3178
531
codegen_addop_yield(compiler *c, location loc) {
3179
531
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
3180
531
    if (ste->ste_generator && ste->ste_coroutine) {
3181
2
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
3182
2
    }
3183
531
    ADDOP_I(c, loc, YIELD_VALUE, 0);
3184
531
    ADDOP_I(c, loc, RESUME, RESUME_AFTER_YIELD);
3185
531
    return SUCCESS;
3186
531
}
3187
3188
static int
3189
codegen_load_classdict_freevar(compiler *c, location loc)
3190
177
{
3191
177
    ADDOP_N(c, loc, LOAD_DEREF, &_Py_ID(__classdict__), freevars);
3192
177
    return SUCCESS;
3193
177
}
3194
3195
static int
3196
codegen_nameop(compiler *c, location loc,
3197
               identifier name, expr_context_ty ctx)
3198
137k
{
3199
137k
    assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
3200
137k
           !_PyUnicode_EqualToASCIIString(name, "True") &&
3201
137k
           !_PyUnicode_EqualToASCIIString(name, "False"));
3202
3203
137k
    PyObject *mangled = _PyCompile_MaybeMangle(c, name);
3204
137k
    if (!mangled) {
3205
0
        return ERROR;
3206
0
    }
3207
3208
137k
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), mangled);
3209
137k
    RETURN_IF_ERROR(scope);
3210
137k
    _PyCompile_optype optype;
3211
137k
    Py_ssize_t arg = 0;
3212
137k
    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
137k
    assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
3219
3220
137k
    int op = 0;
3221
137k
    switch (optype) {
3222
2.80k
    case COMPILE_OP_DEREF:
3223
2.80k
        switch (ctx) {
3224
2.40k
        case Load:
3225
2.40k
            if (SYMTABLE_ENTRY(c)->ste_type == ClassBlock && !_PyCompile_IsInInlinedComp(c)) {
3226
2
                op = LOAD_FROM_DICT_OR_DEREF;
3227
                // First load the locals
3228
2
                if (codegen_addop_noarg(INSTR_SEQUENCE(c), LOAD_LOCALS, loc) < 0) {
3229
0
                    goto error;
3230
0
                }
3231
2
            }
3232
2.40k
            else if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope) {
3233
4
                op = LOAD_FROM_DICT_OR_DEREF;
3234
                // First load the classdict
3235
4
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3236
0
                    goto error;
3237
0
                }
3238
4
            }
3239
2.39k
            else {
3240
2.39k
                op = LOAD_DEREF;
3241
2.39k
            }
3242
2.40k
            break;
3243
2.40k
        case Store: op = STORE_DEREF; break;
3244
6
        case Del: op = DELETE_DEREF; break;
3245
2.80k
        }
3246
2.80k
        break;
3247
85.3k
    case COMPILE_OP_FAST:
3248
85.3k
        switch (ctx) {
3249
67.0k
        case Load: op = LOAD_FAST; break;
3250
17.8k
        case Store: op = STORE_FAST; break;
3251
421
        case Del: op = DELETE_FAST; break;
3252
85.3k
        }
3253
85.3k
        ADDOP_N(c, loc, op, mangled, varnames);
3254
85.3k
        return SUCCESS;
3255
23.2k
    case COMPILE_OP_GLOBAL:
3256
23.2k
        switch (ctx) {
3257
23.1k
        case Load:
3258
23.1k
            if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) {
3259
173
                op = LOAD_FROM_DICT_OR_GLOBALS;
3260
                // First load the classdict
3261
173
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3262
0
                    goto error;
3263
0
                }
3264
23.0k
            } else {
3265
23.0k
                op = LOAD_GLOBAL;
3266
23.0k
            }
3267
23.1k
            break;
3268
23.1k
        case Store: op = STORE_GLOBAL; break;
3269
0
        case Del: op = DELETE_GLOBAL; break;
3270
23.2k
        }
3271
23.2k
        break;
3272
26.2k
    case COMPILE_OP_NAME:
3273
26.2k
        switch (ctx) {
3274
7.92k
        case Load:
3275
7.92k
            op = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock
3276
3.04k
                    && _PyCompile_IsInInlinedComp(c))
3277
7.92k
                ? LOAD_GLOBAL
3278
7.92k
                : LOAD_NAME;
3279
7.92k
            break;
3280
18.2k
        case Store: op = STORE_NAME; break;
3281
69
        case Del: op = DELETE_NAME; break;
3282
26.2k
        }
3283
26.2k
        break;
3284
137k
    }
3285
3286
137k
    assert(op);
3287
52.3k
    Py_DECREF(mangled);
3288
52.3k
    if (op == LOAD_GLOBAL) {
3289
23.0k
        arg <<= 1;
3290
23.0k
    }
3291
52.3k
    ADDOP_I(c, loc, op, arg);
3292
52.3k
    return SUCCESS;
3293
3294
0
error:
3295
0
    Py_DECREF(mangled);
3296
0
    return ERROR;
3297
52.3k
}
3298
3299
static int
3300
codegen_boolop(compiler *c, expr_ty e)
3301
546
{
3302
546
    int jumpi;
3303
546
    Py_ssize_t i, n;
3304
546
    asdl_expr_seq *s;
3305
3306
546
    location loc = LOC(e);
3307
546
    assert(e->kind == BoolOp_kind);
3308
546
    if (e->v.BoolOp.op == And)
3309
222
        jumpi = JUMP_IF_FALSE;
3310
324
    else
3311
324
        jumpi = JUMP_IF_TRUE;
3312
546
    NEW_JUMP_TARGET_LABEL(c, end);
3313
546
    s = e->v.BoolOp.values;
3314
546
    n = asdl_seq_LEN(s) - 1;
3315
546
    assert(n >= 0);
3316
1.23k
    for (i = 0; i < n; ++i) {
3317
684
        VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
3318
684
        ADDOP_JUMP(c, loc, jumpi, end);
3319
684
        ADDOP(c, loc, POP_TOP);
3320
684
    }
3321
546
    VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
3322
3323
546
    USE_LABEL(c, end);
3324
546
    return SUCCESS;
3325
546
}
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
4.82k
{
3332
4.82k
    Py_ssize_t n = asdl_seq_LEN(elts);
3333
4.82k
    int big = n + pushed + (injected_arg ? 1 : 0) > _PY_STACK_USE_GUIDELINE;
3334
4.82k
    int seen_star = 0;
3335
16.2k
    for (Py_ssize_t i = 0; i < n; i++) {
3336
11.5k
        expr_ty elt = asdl_seq_GET(elts, i);
3337
11.5k
        if (elt->kind == Starred_kind) {
3338
106
            seen_star = 1;
3339
106
            break;
3340
106
        }
3341
11.5k
    }
3342
4.82k
    if (!seen_star && !big) {
3343
15.2k
        for (Py_ssize_t i = 0; i < n; i++) {
3344
10.5k
            expr_ty elt = asdl_seq_GET(elts, i);
3345
10.5k
            VISIT(c, expr, elt);
3346
10.5k
        }
3347
4.70k
        if (injected_arg) {
3348
0
            RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
3349
0
            n++;
3350
0
        }
3351
4.70k
        if (tuple) {
3352
3.43k
            ADDOP_I(c, loc, BUILD_TUPLE, n+pushed);
3353
3.43k
        } else {
3354
1.27k
            ADDOP_I(c, loc, build, n+pushed);
3355
1.27k
        }
3356
4.70k
        return SUCCESS;
3357
4.70k
    }
3358
121
    int sequence_built = 0;
3359
121
    if (big) {
3360
15
        ADDOP_I(c, loc, build, pushed);
3361
15
        sequence_built = 1;
3362
15
    }
3363
1.14k
    for (Py_ssize_t i = 0; i < n; i++) {
3364
1.02k
        expr_ty elt = asdl_seq_GET(elts, i);
3365
1.02k
        if (elt->kind == Starred_kind) {
3366
117
            if (sequence_built == 0) {
3367
106
                ADDOP_I(c, loc, build, i+pushed);
3368
106
                sequence_built = 1;
3369
106
            }
3370
117
            VISIT(c, expr, elt->v.Starred.value);
3371
117
            ADDOP_I(c, loc, extend, 1);
3372
117
        }
3373
909
        else {
3374
909
            VISIT(c, expr, elt);
3375
909
            if (sequence_built) {
3376
800
                ADDOP_I(c, loc, add, 1);
3377
800
            }
3378
909
        }
3379
1.02k
    }
3380
121
    assert(sequence_built);
3381
121
    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
121
    if (tuple) {
3386
108
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
3387
108
    }
3388
121
    return SUCCESS;
3389
121
}
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
4.66k
{
3396
4.66k
    return starunpack_helper_impl(c, loc, elts, NULL, pushed,
3397
4.66k
                                  build, add, extend, tuple);
3398
4.66k
}
3399
3400
static int
3401
unpack_helper(compiler *c, location loc, asdl_expr_seq *elts)
3402
1.56k
{
3403
1.56k
    Py_ssize_t n = asdl_seq_LEN(elts);
3404
1.56k
    int seen_star = 0;
3405
5.26k
    for (Py_ssize_t i = 0; i < n; i++) {
3406
3.70k
        expr_ty elt = asdl_seq_GET(elts, i);
3407
3.70k
        if (elt->kind == Starred_kind && !seen_star) {
3408
17
            if ((i >= (1 << 8)) ||
3409
17
                (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
17
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
3415
17
            seen_star = 1;
3416
17
        }
3417
3.68k
        else if (elt->kind == Starred_kind) {
3418
0
            return _PyCompile_Error(c, loc,
3419
0
                "multiple starred expressions in assignment");
3420
0
        }
3421
3.70k
    }
3422
1.56k
    if (!seen_star) {
3423
1.54k
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
3424
1.54k
    }
3425
1.56k
    return SUCCESS;
3426
1.56k
}
3427
3428
static int
3429
assignment_helper(compiler *c, location loc, asdl_expr_seq *elts)
3430
1.56k
{
3431
1.56k
    Py_ssize_t n = asdl_seq_LEN(elts);
3432
1.56k
    RETURN_IF_ERROR(unpack_helper(c, loc, elts));
3433
5.26k
    for (Py_ssize_t i = 0; i < n; i++) {
3434
3.70k
        expr_ty elt = asdl_seq_GET(elts, i);
3435
3.70k
        VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
3436
3.70k
    }
3437
1.56k
    return SUCCESS;
3438
1.56k
}
3439
3440
static int
3441
codegen_list(compiler *c, expr_ty e)
3442
1.15k
{
3443
1.15k
    location loc = LOC(e);
3444
1.15k
    asdl_expr_seq *elts = e->v.List.elts;
3445
1.15k
    if (e->v.List.ctx == Store) {
3446
10
        return assignment_helper(c, loc, elts);
3447
10
    }
3448
1.14k
    else if (e->v.List.ctx == Load) {
3449
1.14k
        return starunpack_helper(c, loc, elts, 0,
3450
1.14k
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0);
3451
1.14k
    }
3452
0
    else {
3453
0
        VISIT_SEQ(c, expr, elts);
3454
0
    }
3455
0
    return SUCCESS;
3456
1.15k
}
3457
3458
static int
3459
codegen_tuple(compiler *c, expr_ty e)
3460
4.93k
{
3461
4.93k
    location loc = LOC(e);
3462
4.93k
    asdl_expr_seq *elts = e->v.Tuple.elts;
3463
4.93k
    if (e->v.Tuple.ctx == Store) {
3464
1.55k
        return assignment_helper(c, loc, elts);
3465
1.55k
    }
3466
3.38k
    else if (e->v.Tuple.ctx == Load) {
3467
3.38k
        return starunpack_helper(c, loc, elts, 0,
3468
3.38k
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1);
3469
3.38k
    }
3470
0
    else {
3471
0
        VISIT_SEQ(c, expr, elts);
3472
0
    }
3473
0
    return SUCCESS;
3474
4.93k
}
3475
3476
static int
3477
codegen_set(compiler *c, expr_ty e)
3478
143
{
3479
143
    location loc = LOC(e);
3480
143
    return starunpack_helper(c, loc, e->v.Set.elts, 0,
3481
143
                             BUILD_SET, SET_ADD, SET_UPDATE, 0);
3482
143
}
3483
3484
static int
3485
codegen_subdict(compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
3486
899
{
3487
899
    Py_ssize_t i, n = end - begin;
3488
899
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
3489
899
    location loc = LOC(e);
3490
899
    if (big) {
3491
704
        ADDOP_I(c, loc, BUILD_MAP, 0);
3492
704
    }
3493
13.8k
    for (i = begin; i < end; i++) {
3494
12.9k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
3495
12.9k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3496
12.9k
        if (big) {
3497
11.9k
            ADDOP_I(c, loc, MAP_ADD, 1);
3498
11.9k
        }
3499
12.9k
    }
3500
899
    if (!big) {
3501
195
        ADDOP_I(c, loc, BUILD_MAP, n);
3502
195
    }
3503
899
    return SUCCESS;
3504
899
}
3505
3506
static int
3507
codegen_dict(compiler *c, expr_ty e)
3508
480
{
3509
480
    location loc = LOC(e);
3510
480
    Py_ssize_t i, n, elements;
3511
480
    int have_dict;
3512
480
    int is_unpacking = 0;
3513
480
    n = asdl_seq_LEN(e->v.Dict.values);
3514
480
    have_dict = 0;
3515
480
    elements = 0;
3516
13.4k
    for (i = 0; i < n; i++) {
3517
12.9k
        is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
3518
12.9k
        if (is_unpacking) {
3519
13
            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
13
            if (have_dict == 0) {
3528
6
                ADDOP_I(c, loc, BUILD_MAP, 0);
3529
6
                have_dict = 1;
3530
6
            }
3531
13
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3532
13
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3533
13
        }
3534
12.9k
        else {
3535
12.9k
            if (elements*2 > _PY_STACK_USE_GUIDELINE) {
3536
699
                RETURN_IF_ERROR(codegen_subdict(c, e, i - elements, i + 1));
3537
699
                if (have_dict) {
3538
639
                    ADDOP_I(c, loc, DICT_UPDATE, 1);
3539
639
                }
3540
699
                have_dict = 1;
3541
699
                elements = 0;
3542
699
            }
3543
12.2k
            else {
3544
12.2k
                elements++;
3545
12.2k
            }
3546
12.9k
        }
3547
12.9k
    }
3548
480
    if (elements) {
3549
200
        RETURN_IF_ERROR(codegen_subdict(c, e, n - elements, n));
3550
200
        if (have_dict) {
3551
59
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3552
59
        }
3553
200
        have_dict = 1;
3554
200
    }
3555
480
    if (!have_dict) {
3556
273
        ADDOP_I(c, loc, BUILD_MAP, 0);
3557
273
    }
3558
480
    return SUCCESS;
3559
480
}
3560
3561
static int
3562
codegen_compare(compiler *c, expr_ty e)
3563
8.69k
{
3564
8.69k
    location loc = LOC(e);
3565
8.69k
    Py_ssize_t i, n;
3566
3567
8.69k
    RETURN_IF_ERROR(codegen_check_compare(c, e));
3568
8.69k
    VISIT(c, expr, e->v.Compare.left);
3569
8.69k
    assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
3570
8.69k
    n = asdl_seq_LEN(e->v.Compare.ops) - 1;
3571
8.69k
    if (n == 0) {
3572
8.67k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
3573
8.67k
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0));
3574
8.67k
    }
3575
24
    else {
3576
24
        NEW_JUMP_TARGET_LABEL(c, cleanup);
3577
48
        for (i = 0; i < n; i++) {
3578
24
            VISIT(c, expr,
3579
24
                (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
3580
24
            ADDOP_I(c, loc, SWAP, 2);
3581
24
            ADDOP_I(c, loc, COPY, 2);
3582
24
            ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i));
3583
24
            ADDOP_I(c, loc, COPY, 1);
3584
24
            ADDOP(c, loc, TO_BOOL);
3585
24
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, cleanup);
3586
24
            ADDOP(c, loc, POP_TOP);
3587
24
        }
3588
24
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
3589
24
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
3590
24
        NEW_JUMP_TARGET_LABEL(c, end);
3591
24
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
3592
3593
24
        USE_LABEL(c, cleanup);
3594
24
        ADDOP_I(c, loc, SWAP, 2);
3595
24
        ADDOP(c, loc, POP_TOP);
3596
3597
24
        USE_LABEL(c, end);
3598
24
    }
3599
8.69k
    return SUCCESS;
3600
8.69k
}
3601
3602
static PyTypeObject *
3603
infer_type(expr_ty e)
3604
4.29k
{
3605
4.29k
    switch (e->kind) {
3606
23
    case Tuple_kind:
3607
23
        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.78k
    case Constant_kind:
3628
1.78k
        return Py_TYPE(e->v.Constant.value);
3629
2.49k
    default:
3630
2.49k
        return NULL;
3631
4.29k
    }
3632
4.29k
}
3633
3634
static int
3635
check_caller(compiler *c, expr_ty e)
3636
16.8k
{
3637
16.8k
    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
16.8k
    default:
3657
16.8k
        return SUCCESS;
3658
16.8k
    }
3659
16.8k
}
3660
3661
static int
3662
check_subscripter(compiler *c, expr_ty e)
3663
4.29k
{
3664
4.29k
    PyObject *v;
3665
3666
4.29k
    switch (e->kind) {
3667
13
    case Constant_kind:
3668
13
        v = e->v.Constant.value;
3669
13
        if (!(v == Py_None || v == Py_Ellipsis ||
3670
13
              PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) ||
3671
13
              PyAnySet_Check(v)))
3672
13
        {
3673
13
            return SUCCESS;
3674
13
        }
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
4.28k
    default:
3688
4.28k
        return SUCCESS;
3689
4.29k
    }
3690
4.29k
}
3691
3692
static int
3693
check_index(compiler *c, expr_ty e, expr_ty s)
3694
4.29k
{
3695
4.29k
    PyObject *v;
3696
3697
4.29k
    PyTypeObject *index_type = infer_type(s);
3698
4.29k
    if (index_type == NULL
3699
1.80k
        || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
3700
4.14k
        || index_type == &PySlice_Type) {
3701
4.14k
        return SUCCESS;
3702
4.14k
    }
3703
3704
152
    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
152
    default:
3724
152
        return SUCCESS;
3725
152
    }
3726
152
}
3727
3728
static int
3729
is_import_originated(compiler *c, expr_ty e)
3730
13.0k
{
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
13.0k
    if (e->kind != Name_kind) {
3738
3.05k
        return 0;
3739
3.05k
    }
3740
3741
10.0k
    long flags = _PyST_GetSymbol(SYMTABLE(c)->st_top, e->v.Name.id);
3742
10.0k
    RETURN_IF_ERROR(flags);
3743
10.0k
    return flags & DEF_IMPORT;
3744
10.0k
}
3745
3746
static int
3747
can_optimize_super_call(compiler *c, expr_ty attr)
3748
27.6k
{
3749
27.6k
    expr_ty e = attr->v.Attribute.value;
3750
27.6k
    if (e->kind != Call_kind ||
3751
942
        e->v.Call.func->kind != Name_kind ||
3752
673
        !_PyUnicode_EqualToASCIIString(e->v.Call.func->v.Name.id, "super") ||
3753
268
        _PyUnicode_EqualToASCIIString(attr->v.Attribute.attr, "__class__") ||
3754
27.3k
        asdl_seq_LEN(e->v.Call.keywords) != 0) {
3755
27.3k
        return 0;
3756
27.3k
    }
3757
268
    Py_ssize_t num_args = asdl_seq_LEN(e->v.Call.args);
3758
3759
268
    PyObject *super_name = e->v.Call.func->v.Name.id;
3760
    // detect statically-visible shadowing of 'super' name
3761
268
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), super_name);
3762
268
    RETURN_IF_ERROR(scope);
3763
268
    if (scope != GLOBAL_IMPLICIT) {
3764
0
        return 0;
3765
0
    }
3766
268
    scope = _PyST_GetScope(SYMTABLE(c)->st_top, super_name);
3767
268
    RETURN_IF_ERROR(scope);
3768
268
    if (scope != 0) {
3769
0
        return 0;
3770
0
    }
3771
3772
268
    if (num_args == 2) {
3773
162
        for (Py_ssize_t i = 0; i < num_args; i++) {
3774
108
            expr_ty elt = asdl_seq_GET(e->v.Call.args, i);
3775
108
            if (elt->kind == Starred_kind) {
3776
0
                return 0;
3777
0
            }
3778
108
        }
3779
        // exactly two non-starred args; we can just load
3780
        // the provided args
3781
54
        return 1;
3782
54
    }
3783
3784
214
    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
214
    if (METADATA(c)->u_argcount == 0 &&
3791
3
        METADATA(c)->u_posonlyargcount == 0) {
3792
0
        return 0;
3793
0
    }
3794
    // __class__ cell should be available
3795
214
    if (_PyCompile_GetRefType(c, &_Py_ID(__class__)) == FREE) {
3796
214
        return 1;
3797
214
    }
3798
0
    return 0;
3799
214
}
3800
3801
static int
3802
268
load_args_for_super(compiler *c, expr_ty e) {
3803
268
    location loc = LOC(e);
3804
3805
    // load super() global
3806
268
    PyObject *super_name = e->v.Call.func->v.Name.id;
3807
268
    RETURN_IF_ERROR(codegen_nameop(c, LOC(e->v.Call.func), super_name, Load));
3808
3809
268
    if (asdl_seq_LEN(e->v.Call.args) == 2) {
3810
54
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0));
3811
54
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 1));
3812
54
        return SUCCESS;
3813
54
    }
3814
3815
    // load __class__ cell
3816
214
    PyObject *name = &_Py_ID(__class__);
3817
214
    assert(_PyCompile_GetRefType(c, name) == FREE);
3818
214
    RETURN_IF_ERROR(codegen_nameop(c, loc, name, Load));
3819
3820
    // load self (first argument)
3821
214
    Py_ssize_t i = 0;
3822
214
    PyObject *key, *value;
3823
214
    if (!PyDict_Next(METADATA(c)->u_varnames, &i, &key, &value)) {
3824
0
        return ERROR;
3825
0
    }
3826
214
    RETURN_IF_ERROR(codegen_nameop(c, loc, key, Load));
3827
3828
214
    return SUCCESS;
3829
214
}
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
41.6k
{
3837
41.6k
    assert(attr->kind == Attribute_kind);
3838
41.6k
    if (loc.lineno != attr->end_lineno) {
3839
134
        loc.lineno = attr->end_lineno;
3840
134
        int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
3841
134
        if (len <= attr->end_col_offset) {
3842
134
            loc.col_offset = attr->end_col_offset - len;
3843
134
        }
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
134
        loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno);
3852
134
        if (loc.lineno == loc.end_lineno) {
3853
127
            loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset);
3854
127
        }
3855
134
    }
3856
41.6k
    return loc;
3857
41.6k
}
3858
3859
static int
3860
maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
3861
16.8k
{
3862
16.8k
    asdl_expr_seq *args = e->v.Call.args;
3863
16.8k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
3864
16.8k
    expr_ty func = e->v.Call.func;
3865
3866
16.8k
    if (! (func->kind == Name_kind &&
3867
14.6k
           asdl_seq_LEN(args) == 1 &&
3868
9.03k
           asdl_seq_LEN(kwds) == 0 &&
3869
8.79k
           asdl_seq_GET(args, 0)->kind == GeneratorExp_kind))
3870
16.7k
    {
3871
16.7k
        return 0;
3872
16.7k
    }
3873
3874
114
    location loc = LOC(func);
3875
3876
114
    int optimized = 0;
3877
114
    NEW_JUMP_TARGET_LABEL(c, skip_optimization);
3878
3879
114
    int const_oparg = -1;
3880
114
    PyObject *initial_res = NULL;
3881
114
    int continue_jump_opcode = -1;
3882
114
    if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "all")) {
3883
16
        const_oparg = CONSTANT_BUILTIN_ALL;
3884
16
        initial_res = Py_True;
3885
16
        continue_jump_opcode = POP_JUMP_IF_TRUE;
3886
16
    }
3887
98
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "any")) {
3888
35
        const_oparg = CONSTANT_BUILTIN_ANY;
3889
35
        initial_res = Py_False;
3890
35
        continue_jump_opcode = POP_JUMP_IF_FALSE;
3891
35
    }
3892
63
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "tuple")) {
3893
37
        const_oparg = CONSTANT_BUILTIN_TUPLE;
3894
37
    }
3895
114
    if (const_oparg != -1) {
3896
88
        ADDOP_I(c, loc, COPY, 1); // the function
3897
88
        ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, const_oparg);
3898
88
        ADDOP_COMPARE(c, loc, Is);
3899
88
        ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, skip_optimization);
3900
88
        ADDOP(c, loc, POP_TOP);
3901
3902
88
        if (const_oparg == CONSTANT_BUILTIN_TUPLE) {
3903
37
            ADDOP_I(c, loc, BUILD_LIST, 0);
3904
37
        }
3905
88
        expr_ty generator_exp = asdl_seq_GET(args, 0);
3906
88
        VISIT(c, expr, generator_exp);
3907
3908
88
        NEW_JUMP_TARGET_LABEL(c, loop);
3909
88
        NEW_JUMP_TARGET_LABEL(c, cleanup);
3910
3911
88
        ADDOP(c, loc, PUSH_NULL); // Push NULL index for loop
3912
88
        USE_LABEL(c, loop);
3913
88
        ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
3914
88
        if (const_oparg == CONSTANT_BUILTIN_TUPLE) {
3915
37
            ADDOP_I(c, loc, LIST_APPEND, 3);
3916
37
            ADDOP_JUMP(c, loc, JUMP, loop);
3917
37
        }
3918
51
        else {
3919
51
            ADDOP(c, loc, TO_BOOL);
3920
51
            ADDOP_JUMP(c, loc, continue_jump_opcode, loop);
3921
51
        }
3922
3923
88
        ADDOP(c, NO_LOCATION, POP_ITER);
3924
88
        if (const_oparg != CONSTANT_BUILTIN_TUPLE) {
3925
51
            ADDOP_LOAD_CONST(c, loc, initial_res == Py_True ? Py_False : Py_True);
3926
51
        }
3927
88
        ADDOP_JUMP(c, loc, JUMP, end);
3928
3929
88
        USE_LABEL(c, cleanup);
3930
88
        ADDOP(c, NO_LOCATION, END_FOR);
3931
88
        ADDOP(c, NO_LOCATION, POP_ITER);
3932
88
        if (const_oparg == CONSTANT_BUILTIN_TUPLE) {
3933
37
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
3934
37
        }
3935
51
        else {
3936
51
            ADDOP_LOAD_CONST(c, loc, initial_res);
3937
51
        }
3938
3939
88
        optimized = 1;
3940
88
        ADDOP_JUMP(c, loc, JUMP, end);
3941
88
    }
3942
114
    USE_LABEL(c, skip_optimization);
3943
114
    return optimized;
3944
114
}
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
27.8k
{
3950
27.8k
    Py_ssize_t argsl, i, kwdsl;
3951
27.8k
    expr_ty meth = e->v.Call.func;
3952
27.8k
    asdl_expr_seq *args = e->v.Call.args;
3953
27.8k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
3954
3955
    /* Check that the call node is an attribute access */
3956
27.8k
    if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) {
3957
14.7k
        return 0;
3958
14.7k
    }
3959
3960
    /* Check that the base object is not something that is imported */
3961
13.0k
    int ret = is_import_originated(c, meth->v.Attribute.value);
3962
13.0k
    RETURN_IF_ERROR(ret);
3963
13.0k
    if (ret) {
3964
1.93k
        return 0;
3965
1.93k
    }
3966
3967
    /* Check that there aren't too many arguments */
3968
11.1k
    argsl = asdl_seq_LEN(args);
3969
11.1k
    kwdsl = asdl_seq_LEN(kwds);
3970
11.1k
    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
22.6k
    for (i = 0; i < argsl; i++) {
3975
11.6k
        expr_ty elt = asdl_seq_GET(args, i);
3976
11.6k
        if (elt->kind == Starred_kind) {
3977
112
            return 0;
3978
112
        }
3979
11.6k
    }
3980
3981
11.7k
    for (i = 0; i < kwdsl; i++) {
3982
715
        keyword_ty kw = asdl_seq_GET(kwds, i);
3983
715
        if (kw->arg == NULL) {
3984
43
            return 0;
3985
43
        }
3986
715
    }
3987
3988
    /* Alright, we can optimize the code. */
3989
10.9k
    location loc = LOC(meth);
3990
3991
10.9k
    ret = can_optimize_super_call(c, meth);
3992
10.9k
    RETURN_IF_ERROR(ret);
3993
10.9k
    if (ret) {
3994
196
        RETURN_IF_ERROR(load_args_for_super(c, meth->v.Attribute.value));
3995
196
        int opcode = asdl_seq_LEN(meth->v.Attribute.value->v.Call.args) ?
3996
160
            LOAD_SUPER_METHOD : LOAD_ZERO_SUPER_METHOD;
3997
196
        ADDOP_NAME(c, loc, opcode, meth->v.Attribute.attr, names);
3998
196
        loc = update_start_location_to_match_attr(c, loc, meth);
3999
196
        ADDOP(c, loc, NOP);
4000
10.7k
    } else {
4001
10.7k
        VISIT(c, expr, meth->v.Attribute.value);
4002
10.7k
        loc = update_start_location_to_match_attr(c, loc, meth);
4003
10.7k
        ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names);
4004
10.7k
    }
4005
4006
10.9k
    VISIT_SEQ(c, expr, e->v.Call.args);
4007
4008
10.9k
    if (kwdsl) {
4009
451
        VISIT_SEQ(c, keyword, kwds);
4010
451
        RETURN_IF_ERROR(
4011
451
            codegen_call_simple_kw_helper(c, loc, kwds, kwdsl));
4012
451
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4013
451
        ADDOP_I(c, loc, CALL_KW, argsl + kwdsl);
4014
451
    }
4015
10.5k
    else {
4016
10.5k
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4017
10.5k
        ADDOP_I(c, loc, CALL, argsl);
4018
10.5k
    }
4019
10.9k
    return 1;
4020
10.9k
}
4021
4022
static int
4023
codegen_validate_keywords(compiler *c, asdl_keyword_seq *keywords)
4024
45.9k
{
4025
45.9k
    Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
4026
50.8k
    for (Py_ssize_t i = 0; i < nkeywords; i++) {
4027
4.89k
        keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
4028
4.89k
        if (key->arg == NULL) {
4029
302
            continue;
4030
302
        }
4031
12.0k
        for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
4032
7.48k
            keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
4033
7.48k
            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
7.48k
        }
4037
4.59k
    }
4038
45.9k
    return SUCCESS;
4039
45.9k
}
4040
4041
static int
4042
codegen_call(compiler *c, expr_ty e)
4043
27.8k
{
4044
27.8k
    RETURN_IF_ERROR(codegen_validate_keywords(c, e->v.Call.keywords));
4045
27.8k
    int ret = maybe_optimize_method_call(c, e);
4046
27.8k
    if (ret < 0) {
4047
0
        return ERROR;
4048
0
    }
4049
27.8k
    if (ret == 1) {
4050
10.9k
        return SUCCESS;
4051
10.9k
    }
4052
16.8k
    NEW_JUMP_TARGET_LABEL(c, skip_normal_call);
4053
16.8k
    RETURN_IF_ERROR(check_caller(c, e->v.Call.func));
4054
16.8k
    VISIT(c, expr, e->v.Call.func);
4055
16.8k
    RETURN_IF_ERROR(maybe_optimize_function_call(c, e, skip_normal_call));
4056
16.8k
    location loc = LOC(e->v.Call.func);
4057
16.8k
    ADDOP(c, loc, PUSH_NULL);
4058
16.8k
    loc = LOC(e);
4059
16.8k
    ret = codegen_call_helper(c, loc, 0,
4060
16.8k
                              e->v.Call.args,
4061
16.8k
                              e->v.Call.keywords);
4062
16.8k
    USE_LABEL(c, skip_normal_call);
4063
16.8k
    return ret;
4064
16.8k
}
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
1.09k
{
4112
1.09k
    location loc = LOC(e);
4113
1.09k
    Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
4114
1.09k
    if (value_count > _PY_STACK_USE_GUIDELINE) {
4115
2
        _Py_DECLARE_STR(empty, "");
4116
2
        ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4117
2
        ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names);
4118
2
        ADDOP_I(c, loc, BUILD_LIST, 0);
4119
78
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
4120
76
            VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
4121
76
            ADDOP_I(c, loc, LIST_APPEND, 1);
4122
76
        }
4123
2
        ADDOP_I(c, loc, CALL, 1);
4124
2
    }
4125
1.08k
    else {
4126
1.08k
        VISIT_SEQ(c, expr, e->v.JoinedStr.values);
4127
1.08k
        if (value_count > 1) {
4128
1.06k
            ADDOP_I(c, loc, BUILD_STRING, value_count);
4129
1.06k
        }
4130
26
        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
1.08k
    }
4135
1.09k
    return SUCCESS;
4136
1.09k
}
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.90k
{
4173
1.90k
    int conversion = e->v.FormattedValue.conversion;
4174
1.90k
    int oparg;
4175
4176
    /* The expression to be formatted. */
4177
1.90k
    VISIT(c, expr, e->v.FormattedValue.value);
4178
4179
1.90k
    location loc = LOC(e);
4180
1.90k
    if (conversion != -1) {
4181
1.37k
        switch (conversion) {
4182
630
        case 's': oparg = FVC_STR;   break;
4183
746
        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.37k
        }
4190
1.37k
        ADDOP_I(c, loc, CONVERT_VALUE, oparg);
4191
1.37k
    }
4192
1.90k
    if (e->v.FormattedValue.format_spec) {
4193
        /* Evaluate the format spec, and update our opcode arg. */
4194
28
        VISIT(c, expr, e->v.FormattedValue.format_spec);
4195
28
        ADDOP(c, loc, FORMAT_WITH_SPEC);
4196
1.87k
    } else {
4197
1.87k
        ADDOP(c, loc, FORMAT_SIMPLE);
4198
1.87k
    }
4199
1.90k
    return SUCCESS;
4200
1.90k
}
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
21
{
4207
21
    Py_ssize_t i, n = end - begin;
4208
21
    keyword_ty kw;
4209
21
    assert(n > 0);
4210
21
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
4211
21
    if (big) {
4212
1
        ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0);
4213
1
    }
4214
89
    for (i = begin; i < end; i++) {
4215
68
        kw = asdl_seq_GET(keywords, i);
4216
68
        ADDOP_LOAD_CONST(c, loc, kw->arg);
4217
68
        VISIT(c, expr, kw->value);
4218
68
        if (big) {
4219
20
            ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
4220
20
        }
4221
68
    }
4222
21
    if (!big) {
4223
20
        ADDOP_I(c, loc, BUILD_MAP, n);
4224
20
    }
4225
21
    return SUCCESS;
4226
21
}
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
1.27k
{
4235
1.27k
    PyObject *names;
4236
1.27k
    names = PyTuple_New(nkwelts);
4237
1.27k
    if (names == NULL) {
4238
0
        return ERROR;
4239
0
    }
4240
3.85k
    for (Py_ssize_t i = 0; i < nkwelts; i++) {
4241
2.57k
        keyword_ty kw = asdl_seq_GET(keywords, i);
4242
2.57k
        PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
4243
2.57k
    }
4244
1.27k
    ADDOP_LOAD_CONST_NEW(c, loc, names);
4245
1.27k
    return SUCCESS;
4246
1.27k
}
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
18.0k
{
4256
18.0k
    Py_ssize_t i, nseen, nelts, nkwelts;
4257
4258
18.0k
    RETURN_IF_ERROR(codegen_validate_keywords(c, keywords));
4259
4260
18.0k
    nelts = asdl_seq_LEN(args);
4261
18.0k
    nkwelts = asdl_seq_LEN(keywords);
4262
4263
18.0k
    if (nelts + nkwelts*2 > _PY_STACK_USE_GUIDELINE) {
4264
4
         goto ex_call;
4265
4
    }
4266
42.4k
    for (i = 0; i < nelts; i++) {
4267
24.5k
        expr_ty elt = asdl_seq_GET(args, i);
4268
24.5k
        if (elt->kind == Starred_kind) {
4269
243
            goto ex_call;
4270
243
        }
4271
24.5k
    }
4272
19.8k
    for (i = 0; i < nkwelts; i++) {
4273
2.02k
        keyword_ty kw = asdl_seq_GET(keywords, i);
4274
2.02k
        if (kw->arg == NULL) {
4275
68
            goto ex_call;
4276
68
        }
4277
2.02k
    }
4278
4279
    /* No * or ** args, so can use faster calling sequence */
4280
41.8k
    for (i = 0; i < nelts; i++) {
4281
24.1k
        expr_ty elt = asdl_seq_GET(args, i);
4282
24.1k
        assert(elt->kind != Starred_kind);
4283
24.1k
        VISIT(c, expr, elt);
4284
24.1k
    }
4285
17.7k
    if (injected_arg) {
4286
2
        RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
4287
2
        nelts++;
4288
2
    }
4289
17.7k
    if (nkwelts) {
4290
826
        VISIT_SEQ(c, keyword, keywords);
4291
826
        RETURN_IF_ERROR(
4292
826
            codegen_call_simple_kw_helper(c, loc, keywords, nkwelts));
4293
826
        ADDOP_I(c, loc, CALL_KW, n + nelts + nkwelts);
4294
826
    }
4295
16.9k
    else {
4296
16.9k
        ADDOP_I(c, loc, CALL, n + nelts);
4297
16.9k
    }
4298
17.7k
    return SUCCESS;
4299
4300
315
ex_call:
4301
4302
    /* Do positional arguments. */
4303
315
    if (n == 0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
4304
160
        VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
4305
160
    }
4306
155
    else {
4307
155
        RETURN_IF_ERROR(starunpack_helper_impl(c, loc, args, injected_arg, n,
4308
155
                                               BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1));
4309
155
    }
4310
    /* Then keyword arguments */
4311
315
    if (nkwelts) {
4312
        /* Has a new dict been pushed */
4313
158
        int have_dict = 0;
4314
4315
158
        nseen = 0;  /* the number of keyword arguments on the stack following */
4316
377
        for (i = 0; i < nkwelts; i++) {
4317
219
            keyword_ty kw = asdl_seq_GET(keywords, i);
4318
219
            if (kw->arg == NULL) {
4319
                /* A keyword argument unpacking. */
4320
151
                if (nseen) {
4321
11
                    RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, i - nseen, i));
4322
11
                    if (have_dict) {
4323
0
                        ADDOP_I(c, loc, DICT_MERGE, 1);
4324
0
                    }
4325
11
                    have_dict = 1;
4326
11
                    nseen = 0;
4327
11
                }
4328
151
                if (!have_dict) {
4329
139
                    ADDOP_I(c, loc, BUILD_MAP, 0);
4330
139
                    have_dict = 1;
4331
139
                }
4332
151
                VISIT(c, expr, kw->value);
4333
151
                ADDOP_I(c, loc, DICT_MERGE, 1);
4334
151
            }
4335
68
            else {
4336
68
                nseen++;
4337
68
            }
4338
219
        }
4339
158
        if (nseen) {
4340
            /* Pack up any trailing keyword arguments. */
4341
10
            RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts));
4342
10
            if (have_dict) {
4343
2
                ADDOP_I(c, loc, DICT_MERGE, 1);
4344
2
            }
4345
10
            have_dict = 1;
4346
10
        }
4347
158
        assert(have_dict);
4348
158
    }
4349
315
    if (nkwelts == 0) {
4350
157
        ADDOP(c, loc, PUSH_NULL);
4351
157
    }
4352
315
    ADDOP(c, loc, CALL_FUNCTION_EX);
4353
315
    return SUCCESS;
4354
315
}
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
18.0k
{
4362
18.0k
    return codegen_call_helper_impl(c, loc, n, args, NULL, keywords);
4363
18.0k
}
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
594
{
4389
594
    comprehension_ty gen;
4390
594
    gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
4391
594
    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
594
    } else {
4396
594
        return codegen_sync_comprehension_generator(
4397
594
            c, loc, generators, gen_index, depth, elt, val, type,
4398
594
            iter_on_stack);
4399
594
    }
4400
594
}
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
594
{
4409
    /* generate code for the iterator, then each of the ifs,
4410
       and then write to the element */
4411
4412
594
    NEW_JUMP_TARGET_LABEL(c, start);
4413
594
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4414
594
    NEW_JUMP_TARGET_LABEL(c, anchor);
4415
4416
594
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4417
594
                                                          gen_index);
4418
4419
594
    if (!iter_on_stack) {
4420
330
        if (gen_index == 0) {
4421
309
            assert(METADATA(c)->u_argcount == 1);
4422
309
            ADDOP_I(c, loc, LOAD_FAST, 0);
4423
309
        }
4424
21
        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
21
            asdl_expr_seq *elts;
4430
21
            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
21
                default:
4438
21
                    elts = NULL;
4439
21
            }
4440
21
            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
21
            if (IS_JUMP_TARGET_LABEL(start)) {
4448
21
                VISIT(c, expr, gen->iter);
4449
21
            }
4450
21
        }
4451
330
    }
4452
4453
594
    if (IS_JUMP_TARGET_LABEL(start)) {
4454
594
        depth += 2;
4455
594
        ADDOP(c, LOC(gen->iter), GET_ITER);
4456
594
        USE_LABEL(c, start);
4457
594
        ADDOP_JUMP(c, LOC(gen->iter), FOR_ITER, anchor);
4458
594
    }
4459
594
    VISIT(c, expr, gen->target);
4460
4461
    /* XXX this needs to be cleaned up...a lot! */
4462
594
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4463
691
    for (Py_ssize_t i = 0; i < n; i++) {
4464
97
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4465
97
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4466
97
    }
4467
4468
594
    if (++gen_index < asdl_seq_LEN(generators)) {
4469
21
        RETURN_IF_ERROR(
4470
21
            codegen_comprehension_generator(c, loc,
4471
21
                                            generators, gen_index, depth,
4472
21
                                            elt, val, type, 0));
4473
21
    }
4474
4475
594
    location elt_loc = LOC(elt);
4476
4477
    /* only append after the last for generator */
4478
594
    if (gen_index >= asdl_seq_LEN(generators)) {
4479
        /* comprehension specific code */
4480
573
        switch (type) {
4481
309
        case COMP_GENEXP:
4482
309
            VISIT(c, expr, elt);
4483
309
            ADDOP_YIELD(c, elt_loc);
4484
309
            ADDOP(c, elt_loc, POP_TOP);
4485
309
            break;
4486
309
        case COMP_LISTCOMP:
4487
221
            VISIT(c, expr, elt);
4488
221
            ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4489
221
            break;
4490
221
        case COMP_SETCOMP:
4491
1
            VISIT(c, expr, elt);
4492
1
            ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4493
1
            break;
4494
42
        case COMP_DICTCOMP:
4495
            /* With '{k: v}', k is evaluated before v, so we do
4496
               the same. */
4497
42
            VISIT(c, expr, elt);
4498
42
            VISIT(c, expr, val);
4499
42
            elt_loc = LOCATION(elt->lineno,
4500
42
                               val->end_lineno,
4501
42
                               elt->col_offset,
4502
42
                               val->end_col_offset);
4503
42
            ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4504
42
            break;
4505
42
        default:
4506
0
            return ERROR;
4507
573
        }
4508
573
    }
4509
4510
594
    USE_LABEL(c, if_cleanup);
4511
594
    if (IS_JUMP_TARGET_LABEL(start)) {
4512
594
        ADDOP_JUMP(c, elt_loc, JUMP, start);
4513
4514
594
        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
594
        ADDOP(c, NO_LOCATION, END_FOR);
4520
594
        ADDOP(c, NO_LOCATION, POP_ITER);
4521
594
    }
4522
4523
594
    return SUCCESS;
4524
594
}
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
264
{
4632
264
    int in_class_block = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock) &&
4633
0
                          !_PyCompile_IsInInlinedComp(c);
4634
264
    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
264
    PyObject *k, *v;
4638
264
    Py_ssize_t pos = 0;
4639
1.14k
    while (PyDict_Next(comp->ste_symbols, &pos, &k, &v)) {
4640
876
        long symbol = PyLong_AsLong(v);
4641
876
        assert(symbol >= 0 || PyErr_Occurred());
4642
876
        RETURN_IF_ERROR(symbol);
4643
876
        long scope = SYMBOL_TO_SCOPE(symbol);
4644
4645
876
        long outsymbol = _PyST_GetSymbol(outer, k);
4646
876
        RETURN_IF_ERROR(outsymbol);
4647
876
        long outsc = SYMBOL_TO_SCOPE(outsymbol);
4648
4649
876
        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
348
            if (state->pushed_locals == NULL) {
4654
264
                state->pushed_locals = PyList_New(0);
4655
264
                if (state->pushed_locals == NULL) {
4656
0
                    return ERROR;
4657
0
                }
4658
264
            }
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
348
            ADDOP_NAME(c, loc, LOAD_FAST_AND_CLEAR, k, varnames);
4663
348
            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
348
            if (PyList_Append(state->pushed_locals, k) < 0) {
4671
0
                return ERROR;
4672
0
            }
4673
348
        }
4674
876
    }
4675
264
    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
264
        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
264
        NEW_JUMP_TARGET_LABEL(c, cleanup);
4686
264
        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
264
        ADDOP_JUMP(c, loc, SETUP_FINALLY, cleanup);
4691
264
    }
4692
264
    return SUCCESS;
4693
264
}
4694
4695
static int
4696
push_inlined_comprehension_state(compiler *c, location loc,
4697
                                 PySTEntryObject *comp,
4698
                                 _PyCompile_InlinedComprehensionState *state)
4699
264
{
4700
264
    RETURN_IF_ERROR(
4701
264
        _PyCompile_TweakInlinedComprehensionScopes(c, loc, comp, state));
4702
264
    RETURN_IF_ERROR(
4703
264
        codegen_push_inlined_comprehension_locals(c, loc, comp, state));
4704
264
    return SUCCESS;
4705
264
}
4706
4707
static int
4708
restore_inlined_comprehension_locals(compiler *c, location loc,
4709
                                     _PyCompile_InlinedComprehensionState *state)
4710
528
{
4711
528
    PyObject *k;
4712
    // pop names we pushed to stack earlier
4713
528
    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
528
    ADDOP_I(c, loc, SWAP, npops + 1);
4719
1.22k
    for (Py_ssize_t i = npops - 1; i >= 0; --i) {
4720
696
        k = PyList_GetItem(state->pushed_locals, i);
4721
696
        if (k == NULL) {
4722
0
            return ERROR;
4723
0
        }
4724
696
        ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames);
4725
696
    }
4726
528
    return SUCCESS;
4727
528
}
4728
4729
static int
4730
codegen_pop_inlined_comprehension_locals(compiler *c, location loc,
4731
                                         _PyCompile_InlinedComprehensionState *state)
4732
264
{
4733
264
    if (state->pushed_locals) {
4734
264
        ADDOP(c, NO_LOCATION, POP_BLOCK);
4735
4736
264
        NEW_JUMP_TARGET_LABEL(c, end);
4737
264
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
4738
4739
        // cleanup from an exception inside the comprehension
4740
264
        USE_LABEL(c, state->cleanup);
4741
        // discard incomplete comprehension result (beneath exc on stack)
4742
264
        ADDOP_I(c, NO_LOCATION, SWAP, 2);
4743
264
        ADDOP(c, NO_LOCATION, POP_TOP);
4744
264
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
4745
264
        ADDOP_I(c, NO_LOCATION, RERAISE, 0);
4746
4747
264
        USE_LABEL(c, end);
4748
264
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
4749
264
        Py_CLEAR(state->pushed_locals);
4750
264
    }
4751
264
    return SUCCESS;
4752
264
}
4753
4754
static int
4755
pop_inlined_comprehension_state(compiler *c, location loc,
4756
                                _PyCompile_InlinedComprehensionState *state)
4757
264
{
4758
264
    RETURN_IF_ERROR(codegen_pop_inlined_comprehension_locals(c, loc, state));
4759
264
    RETURN_IF_ERROR(_PyCompile_RevertInlinedComprehensionScopes(c, loc, state));
4760
264
    return SUCCESS;
4761
264
}
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
573
{
4768
573
    PyCodeObject *co = NULL;
4769
573
    _PyCompile_InlinedComprehensionState inline_state = {NULL, NULL, NULL, NO_LABEL};
4770
573
    comprehension_ty outermost;
4771
573
    PySTEntryObject *entry = _PySymtable_Lookup(SYMTABLE(c), (void *)e);
4772
573
    if (entry == NULL) {
4773
0
        goto error;
4774
0
    }
4775
573
    int is_inlined = entry->ste_comp_inlined;
4776
573
    int is_async_comprehension = entry->ste_coroutine;
4777
4778
573
    location loc = LOC(e);
4779
4780
573
    outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
4781
573
    if (is_inlined) {
4782
264
        VISIT(c, expr, outermost->iter);
4783
264
        if (push_inlined_comprehension_state(c, loc, entry, &inline_state)) {
4784
0
            goto error;
4785
0
        }
4786
264
    }
4787
309
    else {
4788
        /* Receive outermost iter as an implicit argument */
4789
309
        _PyCompile_CodeUnitMetadata umd = {
4790
309
            .u_argcount = 1,
4791
309
        };
4792
309
        if (codegen_enter_scope(c, name, COMPILE_SCOPE_COMPREHENSION,
4793
309
                                (void *)e, e->lineno, NULL, &umd) < 0) {
4794
0
            goto error;
4795
0
        }
4796
309
    }
4797
573
    Py_CLEAR(entry);
4798
4799
573
    if (type != COMP_GENEXP) {
4800
264
        int op;
4801
264
        switch (type) {
4802
221
        case COMP_LISTCOMP:
4803
221
            op = BUILD_LIST;
4804
221
            break;
4805
1
        case COMP_SETCOMP:
4806
1
            op = BUILD_SET;
4807
1
            break;
4808
42
        case COMP_DICTCOMP:
4809
42
            op = BUILD_MAP;
4810
42
            break;
4811
0
        default:
4812
0
            PyErr_Format(PyExc_SystemError,
4813
0
                         "unknown comprehension type %d", type);
4814
0
            goto error_in_scope;
4815
264
        }
4816
4817
264
        ADDOP_I(c, loc, op, 0);
4818
264
        if (is_inlined) {
4819
264
            ADDOP_I(c, loc, SWAP, 2);
4820
264
        }
4821
264
    }
4822
4823
573
    if (codegen_comprehension_generator(c, loc, generators, 0, 0,
4824
573
                                        elt, val, type, is_inlined) < 0) {
4825
0
        goto error_in_scope;
4826
0
    }
4827
4828
573
    if (is_inlined) {
4829
264
        if (pop_inlined_comprehension_state(c, loc, &inline_state)) {
4830
0
            goto error;
4831
0
        }
4832
264
        return SUCCESS;
4833
264
    }
4834
4835
309
    if (type != COMP_GENEXP) {
4836
0
        ADDOP(c, LOC(e), RETURN_VALUE);
4837
0
    }
4838
309
    if (type == COMP_GENEXP) {
4839
309
        if (codegen_wrap_in_stopiteration_handler(c) < 0) {
4840
0
            goto error_in_scope;
4841
0
        }
4842
309
    }
4843
4844
309
    co = _PyCompile_OptimizeAndAssemble(c, 1);
4845
309
    _PyCompile_ExitScope(c);
4846
309
    if (co == NULL) {
4847
0
        goto error;
4848
0
    }
4849
4850
309
    loc = LOC(e);
4851
309
    if (codegen_make_closure(c, loc, co, 0) < 0) {
4852
0
        goto error;
4853
0
    }
4854
309
    Py_CLEAR(co);
4855
4856
309
    VISIT(c, expr, outermost->iter);
4857
309
    ADDOP_I(c, loc, CALL, 0);
4858
4859
309
    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
309
    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
309
{
4882
309
    assert(e->kind == GeneratorExp_kind);
4883
309
    _Py_DECLARE_STR(anon_genexpr, "<genexpr>");
4884
309
    return codegen_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
4885
309
                                 e->v.GeneratorExp.generators,
4886
309
                                 e->v.GeneratorExp.elt, NULL);
4887
309
}
4888
4889
static int
4890
codegen_listcomp(compiler *c, expr_ty e)
4891
221
{
4892
221
    assert(e->kind == ListComp_kind);
4893
221
    _Py_DECLARE_STR(anon_listcomp, "<listcomp>");
4894
221
    return codegen_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
4895
221
                                 e->v.ListComp.generators,
4896
221
                                 e->v.ListComp.elt, NULL);
4897
221
}
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
42
{
4913
42
    assert(e->kind == DictComp_kind);
4914
42
    _Py_DECLARE_STR(anon_dictcomp, "<dictcomp>");
4915
42
    return codegen_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
4916
42
                                 e->v.DictComp.generators,
4917
42
                                 e->v.DictComp.key, e->v.DictComp.value);
4918
42
}
4919
4920
4921
static int
4922
codegen_visit_keyword(compiler *c, keyword_ty k)
4923
2.57k
{
4924
2.57k
    VISIT(c, expr, k->value);
4925
2.57k
    return SUCCESS;
4926
2.57k
}
4927
4928
4929
static int
4930
168
codegen_with_except_finish(compiler *c, jump_target_label cleanup) {
4931
168
    NEW_JUMP_TARGET_LABEL(c, suppress);
4932
168
    ADDOP(c, NO_LOCATION, TO_BOOL);
4933
168
    ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress);
4934
168
    ADDOP_I(c, NO_LOCATION, RERAISE, 2);
4935
4936
168
    USE_LABEL(c, suppress);
4937
168
    ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */
4938
168
    ADDOP(c, NO_LOCATION, POP_BLOCK);
4939
168
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
4940
168
    ADDOP(c, NO_LOCATION, POP_TOP);
4941
168
    ADDOP(c, NO_LOCATION, POP_TOP);
4942
168
    ADDOP(c, NO_LOCATION, POP_TOP);
4943
168
    NEW_JUMP_TARGET_LABEL(c, exit);
4944
168
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
4945
4946
168
    USE_LABEL(c, cleanup);
4947
168
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
4948
4949
168
    USE_LABEL(c, exit);
4950
168
    return SUCCESS;
4951
168
}
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
167
{
5089
167
    withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
5090
5091
167
    assert(s->kind == With_kind);
5092
5093
167
    NEW_JUMP_TARGET_LABEL(c, block);
5094
167
    NEW_JUMP_TARGET_LABEL(c, final);
5095
167
    NEW_JUMP_TARGET_LABEL(c, exit);
5096
167
    NEW_JUMP_TARGET_LABEL(c, cleanup);
5097
5098
    /* Evaluate EXPR */
5099
167
    VISIT(c, expr, item->context_expr);
5100
    /* Will push bound __exit__ */
5101
167
    location loc = LOC(item->context_expr);
5102
167
    ADDOP_I(c, loc, COPY, 1);
5103
167
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___EXIT__);
5104
167
    ADDOP_I(c, loc, SWAP, 2);
5105
167
    ADDOP_I(c, loc, SWAP, 3);
5106
167
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___ENTER__);
5107
167
    ADDOP_I(c, loc, CALL, 0);
5108
167
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5109
5110
    /* SETUP_WITH pushes a finally block. */
5111
167
    USE_LABEL(c, block);
5112
167
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_WITH, block, final, s));
5113
5114
167
    if (item->optional_vars) {
5115
80
        VISIT(c, expr, item->optional_vars);
5116
80
    }
5117
87
    else {
5118
    /* Discard result from context.__enter__() */
5119
87
        ADDOP(c, loc, POP_TOP);
5120
87
    }
5121
5122
167
    pos++;
5123
167
    if (pos == asdl_seq_LEN(s->v.With.items)) {
5124
        /* BLOCK code */
5125
157
        VISIT_SEQ(c, stmt, s->v.With.body);
5126
157
    }
5127
10
    else {
5128
10
        RETURN_IF_ERROR(codegen_with_inner(c, s, pos));
5129
10
    }
5130
5131
167
    ADDOP(c, NO_LOCATION, POP_BLOCK);
5132
167
    _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
167
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5140
167
    ADDOP(c, loc, POP_TOP);
5141
167
    ADDOP_JUMP(c, loc, JUMP, exit);
5142
5143
    /* For exceptional outcome: */
5144
167
    USE_LABEL(c, final);
5145
5146
167
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5147
167
    ADDOP(c, loc, PUSH_EXC_INFO);
5148
167
    ADDOP(c, loc, WITH_EXCEPT_START);
5149
167
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5150
5151
167
    USE_LABEL(c, exit);
5152
167
    return SUCCESS;
5153
167
}
5154
5155
static int
5156
codegen_with(compiler *c, stmt_ty s)
5157
157
{
5158
157
    return codegen_with_inner(c, s, 0);
5159
157
}
5160
5161
static int
5162
codegen_visit_expr(compiler *c, expr_ty e)
5163
253k
{
5164
253k
    if (Py_EnterRecursiveCall(" during compilation")) {
5165
0
        return ERROR;
5166
0
    }
5167
253k
    location loc = LOC(e);
5168
253k
    switch (e->kind) {
5169
39
    case NamedExpr_kind:
5170
39
        VISIT(c, expr, e->v.NamedExpr.value);
5171
39
        ADDOP_I(c, loc, COPY, 1);
5172
39
        VISIT(c, expr, e->v.NamedExpr.target);
5173
39
        break;
5174
546
    case BoolOp_kind:
5175
546
        return codegen_boolop(c, e);
5176
5.52k
    case BinOp_kind:
5177
5.52k
        VISIT(c, expr, e->v.BinOp.left);
5178
5.52k
        VISIT(c, expr, e->v.BinOp.right);
5179
5.52k
        ADDOP_BINARY(c, loc, e->v.BinOp.op);
5180
5.52k
        break;
5181
5.52k
    case UnaryOp_kind:
5182
915
        VISIT(c, expr, e->v.UnaryOp.operand);
5183
915
        if (e->v.UnaryOp.op == UAdd) {
5184
2
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE);
5185
2
        }
5186
913
        else if (e->v.UnaryOp.op == Not) {
5187
79
            ADDOP(c, loc, TO_BOOL);
5188
79
            ADDOP(c, loc, UNARY_NOT);
5189
79
        }
5190
834
        else {
5191
834
            ADDOP(c, loc, unaryop(e->v.UnaryOp.op));
5192
834
        }
5193
915
        break;
5194
915
    case Lambda_kind:
5195
186
        return codegen_lambda(c, e);
5196
306
    case IfExp_kind:
5197
306
        return codegen_ifexp(c, e);
5198
480
    case Dict_kind:
5199
480
        return codegen_dict(c, e);
5200
143
    case Set_kind:
5201
143
        return codegen_set(c, e);
5202
309
    case GeneratorExp_kind:
5203
309
        return codegen_genexp(c, e);
5204
221
    case ListComp_kind:
5205
221
        return codegen_listcomp(c, e);
5206
1
    case SetComp_kind:
5207
1
        return codegen_setcomp(c, e);
5208
42
    case DictComp_kind:
5209
42
        return codegen_dictcomp(c, e);
5210
222
    case Yield_kind:
5211
222
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5212
0
            return _PyCompile_Error(c, loc, "'yield' outside function");
5213
0
        }
5214
222
        if (e->v.Yield.value) {
5215
218
            VISIT(c, expr, e->v.Yield.value);
5216
218
        }
5217
4
        else {
5218
4
            ADDOP_LOAD_CONST(c, loc, Py_None);
5219
4
        }
5220
222
        ADDOP_YIELD(c, loc);
5221
222
        break;
5222
222
    case YieldFrom_kind:
5223
44
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5224
0
            return _PyCompile_Error(c, loc, "'yield from' outside function");
5225
0
        }
5226
44
        if (SCOPE_TYPE(c) == COMPILE_SCOPE_ASYNC_FUNCTION) {
5227
0
            return _PyCompile_Error(c, loc, "'yield from' inside async function");
5228
0
        }
5229
44
        VISIT(c, expr, e->v.YieldFrom.value);
5230
44
        ADDOP(c, loc, GET_YIELD_FROM_ITER);
5231
44
        ADDOP_LOAD_CONST(c, loc, Py_None);
5232
44
        ADD_YIELD_FROM(c, loc, 0);
5233
44
        break;
5234
44
    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
8.69k
    case Compare_kind:
5241
8.69k
        return codegen_compare(c, e);
5242
27.8k
    case Call_kind:
5243
27.8k
        return codegen_call(c, e);
5244
56.8k
    case Constant_kind:
5245
56.8k
        ADDOP_LOAD_CONST(c, loc, e->v.Constant.value);
5246
56.8k
        break;
5247
56.8k
    case JoinedStr_kind:
5248
1.09k
        return codegen_joined_str(c, e);
5249
1
    case TemplateStr_kind:
5250
1
        return codegen_template_str(c, e);
5251
1.90k
    case FormattedValue_kind:
5252
1.90k
        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
19.3k
    case Attribute_kind:
5257
19.3k
        if (e->v.Attribute.ctx == Load) {
5258
16.6k
            int ret = can_optimize_super_call(c, e);
5259
16.6k
            RETURN_IF_ERROR(ret);
5260
16.6k
            if (ret) {
5261
72
                RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
5262
72
                int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
5263
54
                    LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
5264
72
                ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
5265
72
                loc = update_start_location_to_match_attr(c, loc, e);
5266
72
                ADDOP(c, loc, NOP);
5267
72
                return SUCCESS;
5268
72
            }
5269
16.6k
        }
5270
19.2k
        RETURN_IF_ERROR(_PyCompile_MaybeAddStaticAttributeToClass(c, e));
5271
19.2k
        VISIT(c, expr, e->v.Attribute.value);
5272
19.2k
        loc = LOC(e);
5273
19.2k
        loc = update_start_location_to_match_attr(c, loc, e);
5274
19.2k
        switch (e->v.Attribute.ctx) {
5275
16.5k
        case Load:
5276
16.5k
            ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5277
16.5k
            break;
5278
16.5k
        case Store:
5279
2.65k
            ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5280
2.65k
            break;
5281
2.65k
        case Del:
5282
24
            ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names);
5283
24
            break;
5284
19.2k
        }
5285
19.2k
        break;
5286
19.2k
    case Subscript_kind:
5287
5.47k
        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
545
    case Slice_kind:
5301
545
        RETURN_IF_ERROR(codegen_slice(c, e));
5302
545
        break;
5303
117k
    case Name_kind:
5304
117k
        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
1.15k
    case List_kind:
5307
1.15k
        return codegen_list(c, e);
5308
4.93k
    case Tuple_kind:
5309
4.93k
        return codegen_tuple(c, e);
5310
253k
    }
5311
83.3k
    return SUCCESS;
5312
253k
}
5313
5314
static bool
5315
is_constant_slice(expr_ty s)
5316
6.06k
{
5317
6.06k
    return s->kind == Slice_kind &&
5318
1.75k
        (s->v.Slice.lower == NULL ||
5319
1.15k
         s->v.Slice.lower->kind == Constant_kind) &&
5320
1.30k
        (s->v.Slice.upper == NULL ||
5321
597
         s->v.Slice.upper->kind == Constant_kind) &&
5322
1.07k
        (s->v.Slice.step == NULL ||
5323
86
         s->v.Slice.step->kind == Constant_kind);
5324
6.06k
}
5325
5326
static bool
5327
should_apply_two_element_slice_optimization(expr_ty s)
5328
5.51k
{
5329
5.51k
    return !is_constant_slice(s) &&
5330
5.00k
           s->kind == Slice_kind &&
5331
700
           s->v.Slice.step == NULL;
5332
5.51k
}
5333
5334
static int
5335
codegen_augassign(compiler *c, stmt_ty s)
5336
1.05k
{
5337
1.05k
    assert(s->kind == AugAssign_kind);
5338
1.05k
    expr_ty e = s->v.AugAssign.target;
5339
5340
1.05k
    location loc = LOC(e);
5341
5342
1.05k
    switch (e->kind) {
5343
144
    case Attribute_kind:
5344
144
        VISIT(c, expr, e->v.Attribute.value);
5345
144
        ADDOP_I(c, loc, COPY, 1);
5346
144
        loc = update_start_location_to_match_attr(c, loc, e);
5347
144
        ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5348
144
        break;
5349
144
    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
888
    case Name_kind:
5366
888
        RETURN_IF_ERROR(codegen_nameop(c, loc, e->v.Name.id, Load));
5367
888
        break;
5368
888
    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
1.05k
    }
5374
5375
1.05k
    loc = LOC(s);
5376
5377
1.05k
    VISIT(c, expr, s->v.AugAssign.value);
5378
1.05k
    ADDOP_INPLACE(c, loc, s->v.AugAssign.op);
5379
5380
1.05k
    loc = LOC(e);
5381
5382
1.05k
    switch (e->kind) {
5383
144
    case Attribute_kind:
5384
144
        loc = update_start_location_to_match_attr(c, loc, e);
5385
144
        ADDOP_I(c, loc, SWAP, 2);
5386
144
        ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5387
144
        break;
5388
144
    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
888
    case Name_kind:
5402
888
        return codegen_nameop(c, loc, e->v.Name.id, Store);
5403
0
    default:
5404
0
        Py_UNREACHABLE();
5405
1.05k
    }
5406
164
    return SUCCESS;
5407
1.05k
}
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_ann_subscr(compiler *c, expr_ty e)
5419
0
{
5420
    /* We check that everything in a subscript is defined at runtime. */
5421
0
    switch (e->kind) {
5422
0
    case Slice_kind:
5423
0
        if (e->v.Slice.lower && codegen_check_ann_expr(c, e->v.Slice.lower) < 0) {
5424
0
            return ERROR;
5425
0
        }
5426
0
        if (e->v.Slice.upper && codegen_check_ann_expr(c, e->v.Slice.upper) < 0) {
5427
0
            return ERROR;
5428
0
        }
5429
0
        if (e->v.Slice.step && codegen_check_ann_expr(c, e->v.Slice.step) < 0) {
5430
0
            return ERROR;
5431
0
        }
5432
0
        return SUCCESS;
5433
0
    case Tuple_kind: {
5434
        /* extended slice */
5435
0
        asdl_expr_seq *elts = e->v.Tuple.elts;
5436
0
        Py_ssize_t i, n = asdl_seq_LEN(elts);
5437
0
        for (i = 0; i < n; i++) {
5438
0
            RETURN_IF_ERROR(codegen_check_ann_subscr(c, asdl_seq_GET(elts, i)));
5439
0
        }
5440
0
        return SUCCESS;
5441
0
    }
5442
0
    default:
5443
0
        return codegen_check_ann_expr(c, e);
5444
0
    }
5445
0
}
5446
5447
static int
5448
codegen_annassign(compiler *c, stmt_ty s)
5449
88
{
5450
88
    location loc = LOC(s);
5451
88
    expr_ty targ = s->v.AnnAssign.target;
5452
88
    bool future_annotations = FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS;
5453
88
    PyObject *mangled;
5454
5455
88
    assert(s->kind == AnnAssign_kind);
5456
5457
    /* We perform the actual assignment first. */
5458
88
    if (s->v.AnnAssign.value) {
5459
82
        VISIT(c, expr, s->v.AnnAssign.value);
5460
82
        VISIT(c, expr, targ);
5461
82
    }
5462
88
    switch (targ->kind) {
5463
85
    case Name_kind:
5464
        /* If we have a simple name in a module or class, store annotation. */
5465
85
        if (s->v.AnnAssign.simple &&
5466
85
            (SCOPE_TYPE(c) == COMPILE_SCOPE_MODULE ||
5467
84
             SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS)) {
5468
72
            if (future_annotations) {
5469
0
                VISIT(c, annexpr, s->v.AnnAssign.annotation);
5470
0
                ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
5471
0
                mangled = _PyCompile_MaybeMangle(c, targ->v.Name.id);
5472
0
                ADDOP_LOAD_CONST_NEW(c, loc, mangled);
5473
0
                ADDOP(c, loc, STORE_SUBSCR);
5474
0
            }
5475
72
            else {
5476
72
                PyObject *conditional_annotation_index = NULL;
5477
72
                RETURN_IF_ERROR(_PyCompile_AddDeferredAnnotation(
5478
72
                    c, s, &conditional_annotation_index));
5479
72
                if (conditional_annotation_index != NULL) {
5480
1
                    if (SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS) {
5481
0
                        ADDOP_NAME(c, loc, LOAD_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
5482
0
                    }
5483
1
                    else {
5484
1
                        ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__conditional_annotations__), names);
5485
1
                    }
5486
1
                    ADDOP_LOAD_CONST_NEW(c, loc, conditional_annotation_index);
5487
1
                    ADDOP_I(c, loc, SET_ADD, 1);
5488
1
                    ADDOP(c, loc, POP_TOP);
5489
1
                }
5490
72
            }
5491
72
        }
5492
85
        break;
5493
85
    case Attribute_kind:
5494
3
        if (!s->v.AnnAssign.value &&
5495
0
            codegen_check_ann_expr(c, targ->v.Attribute.value) < 0) {
5496
0
            return ERROR;
5497
0
        }
5498
3
        break;
5499
3
    case Subscript_kind:
5500
0
        if (!s->v.AnnAssign.value &&
5501
0
            (codegen_check_ann_expr(c, targ->v.Subscript.value) < 0 ||
5502
0
             codegen_check_ann_subscr(c, targ->v.Subscript.slice) < 0)) {
5503
0
                return ERROR;
5504
0
        }
5505
0
        break;
5506
0
    default:
5507
0
        PyErr_Format(PyExc_SystemError,
5508
0
                     "invalid node type (%d) for annotated assignment",
5509
0
                     targ->kind);
5510
0
        return ERROR;
5511
88
    }
5512
88
    return SUCCESS;
5513
88
}
5514
5515
static int
5516
codegen_subscript(compiler *c, expr_ty e)
5517
5.47k
{
5518
5.47k
    location loc = LOC(e);
5519
5.47k
    expr_context_ty ctx = e->v.Subscript.ctx;
5520
5521
5.47k
    if (ctx == Load) {
5522
4.29k
        RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value));
5523
4.29k
        RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice));
5524
4.29k
    }
5525
5526
5.47k
    VISIT(c, expr, e->v.Subscript.value);
5527
5.47k
    if (should_apply_two_element_slice_optimization(e->v.Subscript.slice) &&
5528
671
        ctx != Del
5529
5.47k
    ) {
5530
667
        RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5531
667
        if (ctx == Load) {
5532
636
            ADDOP(c, loc, BINARY_SLICE);
5533
636
        }
5534
31
        else {
5535
31
            assert(ctx == Store);
5536
31
            ADDOP(c, loc, STORE_SLICE);
5537
31
        }
5538
667
    }
5539
4.81k
    else {
5540
4.81k
        VISIT(c, expr, e->v.Subscript.slice);
5541
4.81k
        switch (ctx) {
5542
3.66k
            case Load:
5543
3.66k
                ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5544
3.66k
                break;
5545
3.66k
            case Store:
5546
1.05k
                ADDOP(c, loc, STORE_SUBSCR);
5547
1.05k
                break;
5548
1.05k
            case Del:
5549
99
                ADDOP(c, loc, DELETE_SUBSCR);
5550
99
                break;
5551
4.81k
        }
5552
4.81k
    }
5553
5.47k
    return SUCCESS;
5554
5.47k
}
5555
5556
static int
5557
codegen_slice_two_parts(compiler *c, expr_ty s)
5558
700
{
5559
700
    if (s->v.Slice.lower) {
5560
490
        VISIT(c, expr, s->v.Slice.lower);
5561
490
    }
5562
210
    else {
5563
210
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5564
210
    }
5565
5566
700
    if (s->v.Slice.upper) {
5567
499
        VISIT(c, expr, s->v.Slice.upper);
5568
499
    }
5569
201
    else {
5570
201
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5571
201
    }
5572
5573
700
    return 0;
5574
700
}
5575
5576
static int
5577
codegen_slice(compiler *c, expr_ty s)
5578
545
{
5579
545
    int n = 2;
5580
545
    assert(s->kind == Slice_kind);
5581
5582
545
    if (is_constant_slice(s)) {
5583
512
        PyObject *start = NULL;
5584
512
        if (s->v.Slice.lower) {
5585
327
            start = s->v.Slice.lower->v.Constant.value;
5586
327
        }
5587
512
        PyObject *stop = NULL;
5588
512
        if (s->v.Slice.upper) {
5589
187
            stop = s->v.Slice.upper->v.Constant.value;
5590
187
        }
5591
512
        PyObject *step = NULL;
5592
512
        if (s->v.Slice.step) {
5593
16
            step = s->v.Slice.step->v.Constant.value;
5594
16
        }
5595
512
        PyObject *slice = PySlice_New(start, stop, step);
5596
512
        if (slice == NULL) {
5597
0
            return ERROR;
5598
0
        }
5599
512
        ADDOP_LOAD_CONST_NEW(c, LOC(s), slice);
5600
512
        return SUCCESS;
5601
512
    }
5602
5603
33
    RETURN_IF_ERROR(codegen_slice_two_parts(c, s));
5604
5605
33
    if (s->v.Slice.step) {
5606
29
        n++;
5607
29
        VISIT(c, expr, s->v.Slice.step);
5608
29
    }
5609
5610
33
    ADDOP_I(c, LOC(s), BUILD_SLICE, n);
5611
33
    return SUCCESS;
5612
33
}
5613
5614
5615
// PEP 634: Structural Pattern Matching
5616
5617
// To keep things simple, all codegen_pattern_* routines follow the convention
5618
// of consuming TOS (the subject for the given pattern) and calling
5619
// jump_to_fail_pop on failure (no match).
5620
5621
// When calling into these routines, it's important that pc->on_top be kept
5622
// updated to reflect the current number of items that we are using on the top
5623
// of the stack: they will be popped on failure, and any name captures will be
5624
// stored *underneath* them on success. This lets us defer all names stores
5625
// until the *entire* pattern matches.
5626
5627
#define WILDCARD_CHECK(N) \
5628
17
    ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name)
5629
5630
#define WILDCARD_STAR_CHECK(N) \
5631
0
    ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
5632
5633
// Limit permitted subexpressions, even if the parser & AST validator let them through
5634
#define MATCH_VALUE_EXPR(N) \
5635
16
    ((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
5636
5637
// Allocate or resize pc->fail_pop to allow for n items to be popped on failure.
5638
static int
5639
ensure_fail_pop(compiler *c, pattern_context *pc, Py_ssize_t n)
5640
23
{
5641
23
    Py_ssize_t size = n + 1;
5642
23
    if (size <= pc->fail_pop_size) {
5643
0
        return SUCCESS;
5644
0
    }
5645
23
    Py_ssize_t needed = sizeof(jump_target_label) * size;
5646
23
    jump_target_label *resized = PyMem_Realloc(pc->fail_pop, needed);
5647
23
    if (resized == NULL) {
5648
0
        PyErr_NoMemory();
5649
0
        return ERROR;
5650
0
    }
5651
23
    pc->fail_pop = resized;
5652
49
    while (pc->fail_pop_size < size) {
5653
26
        NEW_JUMP_TARGET_LABEL(c, new_block);
5654
26
        pc->fail_pop[pc->fail_pop_size++] = new_block;
5655
26
    }
5656
23
    return SUCCESS;
5657
23
}
5658
5659
// Use op to jump to the correct fail_pop block.
5660
static int
5661
jump_to_fail_pop(compiler *c, location loc,
5662
                 pattern_context *pc, int op)
5663
22
{
5664
    // Pop any items on the top of the stack, plus any objects we were going to
5665
    // capture on success:
5666
22
    Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
5667
22
    RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops));
5668
22
    ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
5669
22
    return SUCCESS;
5670
22
}
5671
5672
// Build all of the fail_pop blocks and reset fail_pop.
5673
static int
5674
emit_and_reset_fail_pop(compiler *c, location loc,
5675
                        pattern_context *pc)
5676
23
{
5677
23
    if (!pc->fail_pop_size) {
5678
0
        assert(pc->fail_pop == NULL);
5679
0
        return SUCCESS;
5680
0
    }
5681
26
    while (--pc->fail_pop_size) {
5682
3
        USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
5683
3
        if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, loc) < 0) {
5684
0
            pc->fail_pop_size = 0;
5685
0
            PyMem_Free(pc->fail_pop);
5686
0
            pc->fail_pop = NULL;
5687
0
            return ERROR;
5688
0
        }
5689
3
    }
5690
23
    USE_LABEL(c, pc->fail_pop[0]);
5691
23
    PyMem_Free(pc->fail_pop);
5692
23
    pc->fail_pop = NULL;
5693
23
    return SUCCESS;
5694
23
}
5695
5696
static int
5697
codegen_error_duplicate_store(compiler *c, location loc, identifier n)
5698
0
{
5699
0
    return _PyCompile_Error(c, loc,
5700
0
        "multiple assignments to name %R in pattern", n);
5701
0
}
5702
5703
// Duplicate the effect of 3.10's ROT_* instructions using SWAPs.
5704
static int
5705
codegen_pattern_helper_rotate(compiler *c, location loc, Py_ssize_t count)
5706
2
{
5707
2
    while (1 < count) {
5708
0
        ADDOP_I(c, loc, SWAP, count--);
5709
0
    }
5710
2
    return SUCCESS;
5711
2
}
5712
5713
static int
5714
codegen_pattern_helper_store_name(compiler *c, location loc,
5715
                                  identifier n, pattern_context *pc)
5716
2
{
5717
2
    if (n == NULL) {
5718
0
        ADDOP(c, loc, POP_TOP);
5719
0
        return SUCCESS;
5720
0
    }
5721
    // Can't assign to the same name twice:
5722
2
    int duplicate = PySequence_Contains(pc->stores, n);
5723
2
    RETURN_IF_ERROR(duplicate);
5724
2
    if (duplicate) {
5725
0
        return codegen_error_duplicate_store(c, loc, n);
5726
0
    }
5727
    // Rotate this object underneath any items we need to preserve:
5728
2
    Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
5729
2
    RETURN_IF_ERROR(codegen_pattern_helper_rotate(c, loc, rotations));
5730
2
    RETURN_IF_ERROR(PyList_Append(pc->stores, n));
5731
2
    return SUCCESS;
5732
2
}
5733
5734
5735
static int
5736
codegen_pattern_unpack_helper(compiler *c, location loc,
5737
                              asdl_pattern_seq *elts)
5738
0
{
5739
0
    Py_ssize_t n = asdl_seq_LEN(elts);
5740
0
    int seen_star = 0;
5741
0
    for (Py_ssize_t i = 0; i < n; i++) {
5742
0
        pattern_ty elt = asdl_seq_GET(elts, i);
5743
0
        if (elt->kind == MatchStar_kind && !seen_star) {
5744
0
            if ((i >= (1 << 8)) ||
5745
0
                (n-i-1 >= (INT_MAX >> 8))) {
5746
0
                return _PyCompile_Error(c, loc,
5747
0
                    "too many expressions in "
5748
0
                    "star-unpacking sequence pattern");
5749
0
            }
5750
0
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
5751
0
            seen_star = 1;
5752
0
        }
5753
0
        else if (elt->kind == MatchStar_kind) {
5754
0
            return _PyCompile_Error(c, loc,
5755
0
                "multiple starred expressions in sequence pattern");
5756
0
        }
5757
0
    }
5758
0
    if (!seen_star) {
5759
0
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
5760
0
    }
5761
0
    return SUCCESS;
5762
0
}
5763
5764
static int
5765
pattern_helper_sequence_unpack(compiler *c, location loc,
5766
                               asdl_pattern_seq *patterns, Py_ssize_t star,
5767
                               pattern_context *pc)
5768
0
{
5769
0
    RETURN_IF_ERROR(codegen_pattern_unpack_helper(c, loc, patterns));
5770
0
    Py_ssize_t size = asdl_seq_LEN(patterns);
5771
    // We've now got a bunch of new subjects on the stack. They need to remain
5772
    // there after each subpattern match:
5773
0
    pc->on_top += size;
5774
0
    for (Py_ssize_t i = 0; i < size; i++) {
5775
        // One less item to keep track of each time we loop through:
5776
0
        pc->on_top--;
5777
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
5778
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5779
0
    }
5780
0
    return SUCCESS;
5781
0
}
5782
5783
// Like pattern_helper_sequence_unpack, but uses BINARY_OP/NB_SUBSCR instead of
5784
// UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a
5785
// starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc.
5786
static int
5787
pattern_helper_sequence_subscr(compiler *c, location loc,
5788
                               asdl_pattern_seq *patterns, Py_ssize_t star,
5789
                               pattern_context *pc)
5790
0
{
5791
    // We need to keep the subject around for extracting elements:
5792
0
    pc->on_top++;
5793
0
    Py_ssize_t size = asdl_seq_LEN(patterns);
5794
0
    for (Py_ssize_t i = 0; i < size; i++) {
5795
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
5796
0
        if (WILDCARD_CHECK(pattern)) {
5797
0
            continue;
5798
0
        }
5799
0
        if (i == star) {
5800
0
            assert(WILDCARD_STAR_CHECK(pattern));
5801
0
            continue;
5802
0
        }
5803
0
        ADDOP_I(c, loc, COPY, 1);
5804
0
        if (i < star) {
5805
0
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i));
5806
0
        }
5807
0
        else {
5808
            // The subject may not support negative indexing! Compute a
5809
            // nonnegative index:
5810
0
            ADDOP(c, loc, GET_LEN);
5811
0
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i));
5812
0
            ADDOP_BINARY(c, loc, Sub);
5813
0
        }
5814
0
        ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5815
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5816
0
    }
5817
    // Pop the subject, we're done with it:
5818
0
    pc->on_top--;
5819
0
    ADDOP(c, loc, POP_TOP);
5820
0
    return SUCCESS;
5821
0
}
5822
5823
// Like codegen_pattern, but turn off checks for irrefutability.
5824
static int
5825
codegen_pattern_subpattern(compiler *c,
5826
                            pattern_ty p, pattern_context *pc)
5827
1
{
5828
1
    int allow_irrefutable = pc->allow_irrefutable;
5829
1
    pc->allow_irrefutable = 1;
5830
1
    RETURN_IF_ERROR(codegen_pattern(c, p, pc));
5831
1
    pc->allow_irrefutable = allow_irrefutable;
5832
1
    return SUCCESS;
5833
1
}
5834
5835
static int
5836
codegen_pattern_as(compiler *c, pattern_ty p, pattern_context *pc)
5837
2
{
5838
2
    assert(p->kind == MatchAs_kind);
5839
2
    if (p->v.MatchAs.pattern == NULL) {
5840
        // An irrefutable match:
5841
2
        if (!pc->allow_irrefutable) {
5842
0
            if (p->v.MatchAs.name) {
5843
0
                const char *e = "name capture %R makes remaining patterns unreachable";
5844
0
                return _PyCompile_Error(c, LOC(p), e, p->v.MatchAs.name);
5845
0
            }
5846
0
            const char *e = "wildcard makes remaining patterns unreachable";
5847
0
            return _PyCompile_Error(c, LOC(p), e);
5848
0
        }
5849
2
        return codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc);
5850
2
    }
5851
    // Need to make a copy for (possibly) storing later:
5852
0
    pc->on_top++;
5853
0
    ADDOP_I(c, LOC(p), COPY, 1);
5854
0
    RETURN_IF_ERROR(codegen_pattern(c, p->v.MatchAs.pattern, pc));
5855
    // Success! Store it:
5856
0
    pc->on_top--;
5857
0
    RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc));
5858
0
    return SUCCESS;
5859
0
}
5860
5861
static int
5862
codegen_pattern_star(compiler *c, pattern_ty p, pattern_context *pc)
5863
0
{
5864
0
    assert(p->kind == MatchStar_kind);
5865
0
    RETURN_IF_ERROR(
5866
0
        codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc));
5867
0
    return SUCCESS;
5868
0
}
5869
5870
static int
5871
validate_kwd_attrs(compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns)
5872
0
{
5873
    // Any errors will point to the pattern rather than the arg name as the
5874
    // parser is only supplying identifiers rather than Name or keyword nodes
5875
0
    Py_ssize_t nattrs = asdl_seq_LEN(attrs);
5876
0
    for (Py_ssize_t i = 0; i < nattrs; i++) {
5877
0
        identifier attr = ((identifier)asdl_seq_GET(attrs, i));
5878
0
        for (Py_ssize_t j = i + 1; j < nattrs; j++) {
5879
0
            identifier other = ((identifier)asdl_seq_GET(attrs, j));
5880
0
            if (!PyUnicode_Compare(attr, other)) {
5881
0
                location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j));
5882
0
                return _PyCompile_Error(c, loc, "attribute name repeated "
5883
0
                                                "in class pattern: %U", attr);
5884
0
            }
5885
0
        }
5886
0
    }
5887
0
    return SUCCESS;
5888
0
}
5889
5890
static int
5891
codegen_pattern_class(compiler *c, pattern_ty p, pattern_context *pc)
5892
3
{
5893
3
    assert(p->kind == MatchClass_kind);
5894
3
    asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
5895
3
    asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs;
5896
3
    asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns;
5897
3
    Py_ssize_t nargs = asdl_seq_LEN(patterns);
5898
3
    Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs);
5899
3
    Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns);
5900
3
    if (nattrs != nkwd_patterns) {
5901
        // AST validator shouldn't let this happen, but if it does,
5902
        // just fail, don't crash out of the interpreter
5903
0
        const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern";
5904
0
        return _PyCompile_Error(c, LOC(p), e, nattrs, nkwd_patterns);
5905
0
    }
5906
3
    if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) {
5907
0
        const char *e = "too many sub-patterns in class pattern %R";
5908
0
        return _PyCompile_Error(c, LOC(p), e, p->v.MatchClass.cls);
5909
0
    }
5910
3
    if (nattrs) {
5911
0
        RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
5912
0
    }
5913
3
    VISIT(c, expr, p->v.MatchClass.cls);
5914
3
    PyObject *attr_names = PyTuple_New(nattrs);
5915
3
    if (attr_names == NULL) {
5916
0
        return ERROR;
5917
0
    }
5918
3
    Py_ssize_t i;
5919
3
    for (i = 0; i < nattrs; i++) {
5920
0
        PyObject *name = asdl_seq_GET(kwd_attrs, i);
5921
0
        PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name));
5922
0
    }
5923
3
    ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names);
5924
3
    ADDOP_I(c, LOC(p), MATCH_CLASS, nargs);
5925
3
    ADDOP_I(c, LOC(p), COPY, 1);
5926
3
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
5927
3
    ADDOP_I(c, LOC(p), IS_OP, 1);
5928
    // TOS is now a tuple of (nargs + nattrs) attributes (or None):
5929
3
    pc->on_top++;
5930
3
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
5931
3
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs);
5932
3
    pc->on_top += nargs + nattrs - 1;
5933
4
    for (i = 0; i < nargs + nattrs; i++) {
5934
1
        pc->on_top--;
5935
1
        pattern_ty pattern;
5936
1
        if (i < nargs) {
5937
            // Positional:
5938
1
            pattern = asdl_seq_GET(patterns, i);
5939
1
        }
5940
0
        else {
5941
            // Keyword:
5942
0
            pattern = asdl_seq_GET(kwd_patterns, i - nargs);
5943
0
        }
5944
1
        if (WILDCARD_CHECK(pattern)) {
5945
0
            ADDOP(c, LOC(p), POP_TOP);
5946
0
            continue;
5947
0
        }
5948
1
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5949
1
    }
5950
    // Success! Pop the tuple of attributes:
5951
3
    return SUCCESS;
5952
3
}
5953
5954
static int
5955
codegen_pattern_mapping_key(compiler *c, PyObject *seen, pattern_ty p, Py_ssize_t i)
5956
0
{
5957
0
    asdl_expr_seq *keys = p->v.MatchMapping.keys;
5958
0
    asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
5959
0
    expr_ty key = asdl_seq_GET(keys, i);
5960
0
    if (key == NULL) {
5961
0
        const char *e = "can't use NULL keys in MatchMapping "
5962
0
                        "(set 'rest' parameter instead)";
5963
0
        location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
5964
0
        return _PyCompile_Error(c, loc, e);
5965
0
    }
5966
5967
0
    if (key->kind == Constant_kind) {
5968
0
        int in_seen = PySet_Contains(seen, key->v.Constant.value);
5969
0
        RETURN_IF_ERROR(in_seen);
5970
0
        if (in_seen) {
5971
0
            const char *e = "mapping pattern checks duplicate key (%R)";
5972
0
            return _PyCompile_Error(c, LOC(p), e, key->v.Constant.value);
5973
0
        }
5974
0
        RETURN_IF_ERROR(PySet_Add(seen, key->v.Constant.value));
5975
0
    }
5976
0
    else if (key->kind != Attribute_kind) {
5977
0
        const char *e = "mapping pattern keys may only match literals and attribute lookups";
5978
0
        return _PyCompile_Error(c, LOC(p), e);
5979
0
    }
5980
0
    VISIT(c, expr, key);
5981
0
    return SUCCESS;
5982
0
}
5983
5984
static int
5985
codegen_pattern_mapping(compiler *c, pattern_ty p,
5986
                        pattern_context *pc)
5987
0
{
5988
0
    assert(p->kind == MatchMapping_kind);
5989
0
    asdl_expr_seq *keys = p->v.MatchMapping.keys;
5990
0
    asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
5991
0
    Py_ssize_t size = asdl_seq_LEN(keys);
5992
0
    Py_ssize_t npatterns = asdl_seq_LEN(patterns);
5993
0
    if (size != npatterns) {
5994
        // AST validator shouldn't let this happen, but if it does,
5995
        // just fail, don't crash out of the interpreter
5996
0
        const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern";
5997
0
        return _PyCompile_Error(c, LOC(p), e, size, npatterns);
5998
0
    }
5999
    // We have a double-star target if "rest" is set
6000
0
    PyObject *star_target = p->v.MatchMapping.rest;
6001
    // We need to keep the subject on top during the mapping and length checks:
6002
0
    pc->on_top++;
6003
0
    ADDOP(c, LOC(p), MATCH_MAPPING);
6004
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6005
0
    if (!size && !star_target) {
6006
        // If the pattern is just "{}", we're done! Pop the subject:
6007
0
        pc->on_top--;
6008
0
        ADDOP(c, LOC(p), POP_TOP);
6009
0
        return SUCCESS;
6010
0
    }
6011
0
    if (size) {
6012
        // If the pattern has any keys in it, perform a length check:
6013
0
        ADDOP(c, LOC(p), GET_LEN);
6014
0
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6015
0
        ADDOP_COMPARE(c, LOC(p), GtE);
6016
0
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6017
0
    }
6018
0
    if (INT_MAX < size - 1) {
6019
0
        return _PyCompile_Error(c, LOC(p), "too many sub-patterns in mapping pattern");
6020
0
    }
6021
    // Collect all of the keys into a tuple for MATCH_KEYS and
6022
    // **rest. They can either be dotted names or literals:
6023
6024
    // Maintaining a set of Constant_kind kind keys allows us to raise a
6025
    // SyntaxError in the case of duplicates.
6026
0
    PyObject *seen = PySet_New(NULL);
6027
0
    if (seen == NULL) {
6028
0
        return ERROR;
6029
0
    }
6030
0
    for (Py_ssize_t i = 0; i < size; i++) {
6031
0
        if (codegen_pattern_mapping_key(c, seen, p, i) < 0) {
6032
0
            Py_DECREF(seen);
6033
0
            return ERROR;
6034
0
        }
6035
0
    }
6036
0
    Py_DECREF(seen);
6037
6038
    // all keys have been checked; there are no duplicates
6039
6040
0
    ADDOP_I(c, LOC(p), BUILD_TUPLE, size);
6041
0
    ADDOP(c, LOC(p), MATCH_KEYS);
6042
    // There's now a tuple of keys and a tuple of values on top of the subject:
6043
0
    pc->on_top += 2;
6044
0
    ADDOP_I(c, LOC(p), COPY, 1);
6045
0
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
6046
0
    ADDOP_I(c, LOC(p), IS_OP, 1);
6047
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6048
    // So far so good. Use that tuple of values on the stack to match
6049
    // sub-patterns against:
6050
0
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);
6051
0
    pc->on_top += size - 1;
6052
0
    for (Py_ssize_t i = 0; i < size; i++) {
6053
0
        pc->on_top--;
6054
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6055
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6056
0
    }
6057
    // If we get this far, it's a match! Whatever happens next should consume
6058
    // the tuple of keys and the subject:
6059
0
    pc->on_top -= 2;
6060
0
    if (star_target) {
6061
        // If we have a starred name, bind a dict of remaining items to it (this may
6062
        // seem a bit inefficient, but keys is rarely big enough to actually impact
6063
        // runtime):
6064
        // rest = dict(TOS1)
6065
        // for key in TOS:
6066
        //     del rest[key]
6067
0
        ADDOP_I(c, LOC(p), BUILD_MAP, 0);           // [subject, keys, empty]
6068
0
        ADDOP_I(c, LOC(p), SWAP, 3);                // [empty, keys, subject]
6069
0
        ADDOP_I(c, LOC(p), DICT_UPDATE, 2);         // [copy, keys]
6070
0
        ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);  // [copy, keys...]
6071
0
        while (size) {
6072
0
            ADDOP_I(c, LOC(p), COPY, 1 + size--);   // [copy, keys..., copy]
6073
0
            ADDOP_I(c, LOC(p), SWAP, 2);            // [copy, keys..., copy, key]
6074
0
            ADDOP(c, LOC(p), DELETE_SUBSCR);        // [copy, keys...]
6075
0
        }
6076
0
        RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), star_target, pc));
6077
0
    }
6078
0
    else {
6079
0
        ADDOP(c, LOC(p), POP_TOP);  // Tuple of keys.
6080
0
        ADDOP(c, LOC(p), POP_TOP);  // Subject.
6081
0
    }
6082
0
    return SUCCESS;
6083
0
}
6084
6085
static int
6086
codegen_pattern_or(compiler *c, pattern_ty p, pattern_context *pc)
6087
2
{
6088
2
    assert(p->kind == MatchOr_kind);
6089
2
    NEW_JUMP_TARGET_LABEL(c, end);
6090
2
    Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns);
6091
2
    assert(size > 1);
6092
    // We're going to be messing with pc. Keep the original info handy:
6093
2
    pattern_context old_pc = *pc;
6094
2
    Py_INCREF(pc->stores);
6095
    // control is the list of names bound by the first alternative. It is used
6096
    // for checking different name bindings in alternatives, and for correcting
6097
    // the order in which extracted elements are placed on the stack.
6098
2
    PyObject *control = NULL;
6099
    // NOTE: We can't use returning macros anymore! goto error on error.
6100
7
    for (Py_ssize_t i = 0; i < size; i++) {
6101
5
        pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i);
6102
5
        PyObject *pc_stores = PyList_New(0);
6103
5
        if (pc_stores == NULL) {
6104
0
            goto error;
6105
0
        }
6106
5
        Py_SETREF(pc->stores, pc_stores);
6107
        // An irrefutable sub-pattern must be last, if it is allowed at all:
6108
5
        pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable;
6109
5
        pc->fail_pop = NULL;
6110
5
        pc->fail_pop_size = 0;
6111
5
        pc->on_top = 0;
6112
5
        if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 ||
6113
5
            codegen_pattern(c, alt, pc) < 0) {
6114
0
            goto error;
6115
0
        }
6116
        // Success!
6117
5
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6118
5
        if (!i) {
6119
            // This is the first alternative, so save its stores as a "control"
6120
            // for the others (they can't bind a different set of names, and
6121
            // might need to be reordered):
6122
2
            assert(control == NULL);
6123
2
            control = Py_NewRef(pc->stores);
6124
2
        }
6125
3
        else if (nstores != PyList_GET_SIZE(control)) {
6126
0
            goto diff;
6127
0
        }
6128
3
        else if (nstores) {
6129
            // There were captures. Check to see if we differ from control:
6130
0
            Py_ssize_t icontrol = nstores;
6131
0
            while (icontrol--) {
6132
0
                PyObject *name = PyList_GET_ITEM(control, icontrol);
6133
0
                Py_ssize_t istores = PySequence_Index(pc->stores, name);
6134
0
                if (istores < 0) {
6135
0
                    PyErr_Clear();
6136
0
                    goto diff;
6137
0
                }
6138
0
                if (icontrol != istores) {
6139
                    // Reorder the names on the stack to match the order of the
6140
                    // names in control. There's probably a better way of doing
6141
                    // this; the current solution is potentially very
6142
                    // inefficient when each alternative subpattern binds lots
6143
                    // of names in different orders. It's fine for reasonable
6144
                    // cases, though, and the peephole optimizer will ensure
6145
                    // that the final code is as efficient as possible.
6146
0
                    assert(istores < icontrol);
6147
0
                    Py_ssize_t rotations = istores + 1;
6148
                    // Perform the same rotation on pc->stores:
6149
0
                    PyObject *rotated = PyList_GetSlice(pc->stores, 0,
6150
0
                                                        rotations);
6151
0
                    if (rotated == NULL ||
6152
0
                        PyList_SetSlice(pc->stores, 0, rotations, NULL) ||
6153
0
                        PyList_SetSlice(pc->stores, icontrol - istores,
6154
0
                                        icontrol - istores, rotated))
6155
0
                    {
6156
0
                        Py_XDECREF(rotated);
6157
0
                        goto error;
6158
0
                    }
6159
0
                    Py_DECREF(rotated);
6160
                    // That just did:
6161
                    // rotated = pc_stores[:rotations]
6162
                    // del pc_stores[:rotations]
6163
                    // pc_stores[icontrol-istores:icontrol-istores] = rotated
6164
                    // Do the same thing to the stack, using several
6165
                    // rotations:
6166
0
                    while (rotations--) {
6167
0
                        if (codegen_pattern_helper_rotate(c, LOC(alt), icontrol + 1) < 0) {
6168
0
                            goto error;
6169
0
                        }
6170
0
                    }
6171
0
                }
6172
0
            }
6173
0
        }
6174
5
        assert(control);
6175
5
        if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 ||
6176
5
            emit_and_reset_fail_pop(c, LOC(alt), pc) < 0)
6177
0
        {
6178
0
            goto error;
6179
0
        }
6180
5
    }
6181
2
    Py_DECREF(pc->stores);
6182
2
    *pc = old_pc;
6183
2
    Py_INCREF(pc->stores);
6184
    // Need to NULL this for the PyMem_Free call in the error block.
6185
2
    old_pc.fail_pop = NULL;
6186
    // No match. Pop the remaining copy of the subject and fail:
6187
2
    if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 ||
6188
2
        jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) {
6189
0
        goto error;
6190
0
    }
6191
6192
2
    USE_LABEL(c, end);
6193
2
    Py_ssize_t nstores = PyList_GET_SIZE(control);
6194
    // There's a bunch of stuff on the stack between where the new stores
6195
    // are and where they need to be:
6196
    // - The other stores.
6197
    // - A copy of the subject.
6198
    // - Anything else that may be on top of the stack.
6199
    // - Any previous stores we've already stashed away on the stack.
6200
2
    Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
6201
2
    for (Py_ssize_t i = 0; i < nstores; i++) {
6202
        // Rotate this capture to its proper place on the stack:
6203
0
        if (codegen_pattern_helper_rotate(c, LOC(p), nrots) < 0) {
6204
0
            goto error;
6205
0
        }
6206
        // Update the list of previous stores with this new name, checking for
6207
        // duplicates:
6208
0
        PyObject *name = PyList_GET_ITEM(control, i);
6209
0
        int dupe = PySequence_Contains(pc->stores, name);
6210
0
        if (dupe < 0) {
6211
0
            goto error;
6212
0
        }
6213
0
        if (dupe) {
6214
0
            codegen_error_duplicate_store(c, LOC(p), name);
6215
0
            goto error;
6216
0
        }
6217
0
        if (PyList_Append(pc->stores, name)) {
6218
0
            goto error;
6219
0
        }
6220
0
    }
6221
2
    Py_DECREF(old_pc.stores);
6222
2
    Py_DECREF(control);
6223
    // NOTE: Returning macros are safe again.
6224
    // Pop the copy of the subject:
6225
2
    ADDOP(c, LOC(p), POP_TOP);
6226
2
    return SUCCESS;
6227
0
diff:
6228
0
    _PyCompile_Error(c, LOC(p), "alternative patterns bind different names");
6229
0
error:
6230
0
    PyMem_Free(old_pc.fail_pop);
6231
0
    Py_DECREF(old_pc.stores);
6232
0
    Py_XDECREF(control);
6233
0
    return ERROR;
6234
0
}
6235
6236
6237
static int
6238
codegen_pattern_sequence(compiler *c, pattern_ty p,
6239
                         pattern_context *pc)
6240
0
{
6241
0
    assert(p->kind == MatchSequence_kind);
6242
0
    asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
6243
0
    Py_ssize_t size = asdl_seq_LEN(patterns);
6244
0
    Py_ssize_t star = -1;
6245
0
    int only_wildcard = 1;
6246
0
    int star_wildcard = 0;
6247
    // Find a starred name, if it exists. There may be at most one:
6248
0
    for (Py_ssize_t i = 0; i < size; i++) {
6249
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6250
0
        if (pattern->kind == MatchStar_kind) {
6251
0
            if (star >= 0) {
6252
0
                const char *e = "multiple starred names in sequence pattern";
6253
0
                return _PyCompile_Error(c, LOC(p), e);
6254
0
            }
6255
0
            star_wildcard = WILDCARD_STAR_CHECK(pattern);
6256
0
            only_wildcard &= star_wildcard;
6257
0
            star = i;
6258
0
            continue;
6259
0
        }
6260
0
        only_wildcard &= WILDCARD_CHECK(pattern);
6261
0
    }
6262
    // We need to keep the subject on top during the sequence and length checks:
6263
0
    pc->on_top++;
6264
0
    ADDOP(c, LOC(p), MATCH_SEQUENCE);
6265
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6266
0
    if (star < 0) {
6267
        // No star: len(subject) == size
6268
0
        ADDOP(c, LOC(p), GET_LEN);
6269
0
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6270
0
        ADDOP_COMPARE(c, LOC(p), Eq);
6271
0
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6272
0
    }
6273
0
    else if (size > 1) {
6274
        // Star: len(subject) >= size - 1
6275
0
        ADDOP(c, LOC(p), GET_LEN);
6276
0
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1));
6277
0
        ADDOP_COMPARE(c, LOC(p), GtE);
6278
0
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6279
0
    }
6280
    // Whatever comes next should consume the subject:
6281
0
    pc->on_top--;
6282
0
    if (only_wildcard) {
6283
        // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
6284
0
        ADDOP(c, LOC(p), POP_TOP);
6285
0
    }
6286
0
    else if (star_wildcard) {
6287
0
        RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc));
6288
0
    }
6289
0
    else {
6290
0
        RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc));
6291
0
    }
6292
0
    return SUCCESS;
6293
0
}
6294
6295
static int
6296
codegen_pattern_value(compiler *c, pattern_ty p, pattern_context *pc)
6297
16
{
6298
16
    assert(p->kind == MatchValue_kind);
6299
16
    expr_ty value = p->v.MatchValue.value;
6300
16
    if (!MATCH_VALUE_EXPR(value)) {
6301
0
        const char *e = "patterns may only match literals and attribute lookups";
6302
0
        return _PyCompile_Error(c, LOC(p), e);
6303
0
    }
6304
16
    VISIT(c, expr, value);
6305
16
    ADDOP_COMPARE(c, LOC(p), Eq);
6306
16
    ADDOP(c, LOC(p), TO_BOOL);
6307
16
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6308
16
    return SUCCESS;
6309
16
}
6310
6311
static int
6312
codegen_pattern_singleton(compiler *c, pattern_ty p, pattern_context *pc)
6313
1
{
6314
1
    assert(p->kind == MatchSingleton_kind);
6315
1
    ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value);
6316
1
    ADDOP_COMPARE(c, LOC(p), Is);
6317
1
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6318
1
    return SUCCESS;
6319
1
}
6320
6321
static int
6322
codegen_pattern(compiler *c, pattern_ty p, pattern_context *pc)
6323
24
{
6324
24
    switch (p->kind) {
6325
16
        case MatchValue_kind:
6326
16
            return codegen_pattern_value(c, p, pc);
6327
1
        case MatchSingleton_kind:
6328
1
            return codegen_pattern_singleton(c, p, pc);
6329
0
        case MatchSequence_kind:
6330
0
            return codegen_pattern_sequence(c, p, pc);
6331
0
        case MatchMapping_kind:
6332
0
            return codegen_pattern_mapping(c, p, pc);
6333
3
        case MatchClass_kind:
6334
3
            return codegen_pattern_class(c, p, pc);
6335
0
        case MatchStar_kind:
6336
0
            return codegen_pattern_star(c, p, pc);
6337
2
        case MatchAs_kind:
6338
2
            return codegen_pattern_as(c, p, pc);
6339
2
        case MatchOr_kind:
6340
2
            return codegen_pattern_or(c, p, pc);
6341
24
    }
6342
    // AST validator shouldn't let this happen, but if it does,
6343
    // just fail, don't crash out of the interpreter
6344
0
    const char *e = "invalid match pattern node in AST (kind=%d)";
6345
0
    return _PyCompile_Error(c, LOC(p), e, p->kind);
6346
24
}
6347
6348
static int
6349
codegen_match_inner(compiler *c, stmt_ty s, pattern_context *pc)
6350
8
{
6351
8
    VISIT(c, expr, s->v.Match.subject);
6352
8
    NEW_JUMP_TARGET_LABEL(c, end);
6353
8
    Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases);
6354
8
    assert(cases > 0);
6355
8
    match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6356
8
    int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases;
6357
26
    for (Py_ssize_t i = 0; i < cases - has_default; i++) {
6358
18
        m = asdl_seq_GET(s->v.Match.cases, i);
6359
        // Only copy the subject if we're *not* on the last case:
6360
18
        if (i != cases - has_default - 1) {
6361
10
            ADDOP_I(c, LOC(m->pattern), COPY, 1);
6362
10
        }
6363
18
        pc->stores = PyList_New(0);
6364
18
        if (pc->stores == NULL) {
6365
0
            return ERROR;
6366
0
        }
6367
        // Irrefutable cases must be either guarded, last, or both:
6368
18
        pc->allow_irrefutable = m->guard != NULL || i == cases - 1;
6369
18
        pc->fail_pop = NULL;
6370
18
        pc->fail_pop_size = 0;
6371
18
        pc->on_top = 0;
6372
        // NOTE: Can't use returning macros here (they'll leak pc->stores)!
6373
18
        if (codegen_pattern(c, m->pattern, pc) < 0) {
6374
0
            Py_DECREF(pc->stores);
6375
0
            return ERROR;
6376
0
        }
6377
18
        assert(!pc->on_top);
6378
        // It's a match! Store all of the captured names (they're on the stack).
6379
18
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6380
20
        for (Py_ssize_t n = 0; n < nstores; n++) {
6381
2
            PyObject *name = PyList_GET_ITEM(pc->stores, n);
6382
2
            if (codegen_nameop(c, LOC(m->pattern), name, Store) < 0) {
6383
0
                Py_DECREF(pc->stores);
6384
0
                return ERROR;
6385
0
            }
6386
2
        }
6387
18
        Py_DECREF(pc->stores);
6388
        // NOTE: Returning macros are safe again.
6389
18
        if (m->guard) {
6390
1
            RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0));
6391
1
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0));
6392
1
        }
6393
        // Success! Pop the subject off, we're done with it:
6394
18
        if (i != cases - has_default - 1) {
6395
            /* Use the next location to give better locations for branch events */
6396
10
            ADDOP(c, NEXT_LOCATION, POP_TOP);
6397
10
        }
6398
18
        VISIT_SEQ(c, stmt, m->body);
6399
18
        ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
6400
        // If the pattern fails to match, we want the line number of the
6401
        // cleanup to be associated with the failed pattern, not the last line
6402
        // of the body
6403
18
        RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc));
6404
18
    }
6405
8
    if (has_default) {
6406
        // A trailing "case _" is common, and lets us save a bit of redundant
6407
        // pushing and popping in the loop above:
6408
8
        m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6409
8
        if (cases == 1) {
6410
            // No matches. Done with the subject:
6411
0
            ADDOP(c, LOC(m->pattern), POP_TOP);
6412
0
        }
6413
8
        else {
6414
            // Show line coverage for default case (it doesn't create bytecode)
6415
8
            ADDOP(c, LOC(m->pattern), NOP);
6416
8
        }
6417
8
        if (m->guard) {
6418
0
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, end, 0));
6419
0
        }
6420
8
        VISIT_SEQ(c, stmt, m->body);
6421
8
    }
6422
8
    USE_LABEL(c, end);
6423
8
    return SUCCESS;
6424
8
}
6425
6426
static int
6427
codegen_match(compiler *c, stmt_ty s)
6428
8
{
6429
8
    pattern_context pc;
6430
8
    pc.fail_pop = NULL;
6431
8
    int result = codegen_match_inner(c, s, &pc);
6432
8
    PyMem_Free(pc.fail_pop);
6433
8
    return result;
6434
8
}
6435
6436
#undef WILDCARD_CHECK
6437
#undef WILDCARD_STAR_CHECK
6438
6439
6440
int
6441
_PyCodegen_AddReturnAtEnd(compiler *c, int addNone)
6442
8.54k
{
6443
    /* Make sure every instruction stream that falls off the end returns None.
6444
     * This also ensures that no jump target offsets are out of bounds.
6445
     */
6446
8.54k
    if (addNone) {
6447
8.45k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
6448
8.45k
    }
6449
8.54k
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
6450
8.54k
    return SUCCESS;
6451
8.54k
}