Coverage Report

Created: 2025-07-11 06:24

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