Branch data Line data Source code
1 : : /*
2 : : * This file compiles an abstract syntax tree (AST) into Python bytecode.
3 : : *
4 : : * The primary entry point is _PyAST_Compile(), which returns a
5 : : * PyCodeObject. The compiler makes several passes to build the code
6 : : * object:
7 : : * 1. Checks for future statements. See future.c
8 : : * 2. Builds a symbol table. See symtable.c.
9 : : * 3. Generate code for basic blocks. See compiler_mod() in this file.
10 : : * 4. Assemble the basic blocks into final code. See assemble() in
11 : : * this file.
12 : : * 5. Optimize the byte code (peephole optimizations).
13 : : *
14 : : * Note that compiler_mod() suggests module, but the module ast type
15 : : * (mod_ty) has cases for expressions and interactive statements.
16 : : *
17 : : * CAUTION: The VISIT_* macros abort the current function when they
18 : : * encounter a problem. So don't invoke them when there is memory
19 : : * which needs to be released. Code blocks are OK, as the compiler
20 : : * structure takes care of releasing those. Use the arena to manage
21 : : * objects.
22 : : */
23 : :
24 : : #include <stdbool.h>
25 : :
26 : : // Need _PyOpcode_RelativeJump of pycore_opcode.h
27 : : #define NEED_OPCODE_TABLES
28 : :
29 : : #include "Python.h"
30 : : #include "pycore_ast.h" // _PyAST_GetDocString()
31 : : #include "pycore_code.h" // _PyCode_New()
32 : : #include "pycore_compile.h" // _PyFuture_FromAST()
33 : : #include "pycore_long.h" // _PyLong_GetZero()
34 : : #include "pycore_opcode.h" // _PyOpcode_Caches
35 : : #include "pycore_pymem.h" // _PyMem_IsPtrFreed()
36 : : #include "pycore_symtable.h" // PySTEntryObject
37 : :
38 : :
39 : : #define DEFAULT_BLOCK_SIZE 16
40 : : #define DEFAULT_CODE_SIZE 128
41 : : #define DEFAULT_LNOTAB_SIZE 16
42 : : #define DEFAULT_CNOTAB_SIZE 32
43 : :
44 : : #define COMP_GENEXP 0
45 : : #define COMP_LISTCOMP 1
46 : : #define COMP_SETCOMP 2
47 : : #define COMP_DICTCOMP 3
48 : :
49 : : /* A soft limit for stack use, to avoid excessive
50 : : * memory use for large constants, etc.
51 : : *
52 : : * The value 30 is plucked out of thin air.
53 : : * Code that could use more stack than this is
54 : : * rare, so the exact value is unimportant.
55 : : */
56 : : #define STACK_USE_GUIDELINE 30
57 : :
58 : : /* If we exceed this limit, it should
59 : : * be considered a compiler bug.
60 : : * Currently it should be impossible
61 : : * to exceed STACK_USE_GUIDELINE * 100,
62 : : * as 100 is the maximum parse depth.
63 : : * For performance reasons we will
64 : : * want to reduce this to a
65 : : * few hundred in the future.
66 : : *
67 : : * NOTE: Whatever MAX_ALLOWED_STACK_USE is
68 : : * set to, it should never restrict what Python
69 : : * we can write, just how we compile it.
70 : : */
71 : : #define MAX_ALLOWED_STACK_USE (STACK_USE_GUIDELINE * 100)
72 : :
73 : :
74 : : #define MAX_REAL_OPCODE 254
75 : :
76 : : #define IS_WITHIN_OPCODE_RANGE(opcode) \
77 : : (((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \
78 : : IS_PSEUDO_OPCODE(opcode))
79 : :
80 : : #define IS_JUMP_OPCODE(opcode) \
81 : : is_bit_set_in_table(_PyOpcode_Jump, opcode)
82 : :
83 : : #define IS_BLOCK_PUSH_OPCODE(opcode) \
84 : : ((opcode) == SETUP_FINALLY || \
85 : : (opcode) == SETUP_WITH || \
86 : : (opcode) == SETUP_CLEANUP)
87 : :
88 : : /* opcodes that must be last in the basicblock */
89 : : #define IS_TERMINATOR_OPCODE(opcode) \
90 : : (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode))
91 : :
92 : : /* opcodes which are not emitted in codegen stage, only by the assembler */
93 : : #define IS_ASSEMBLER_OPCODE(opcode) \
94 : : ((opcode) == JUMP_FORWARD || \
95 : : (opcode) == JUMP_BACKWARD || \
96 : : (opcode) == JUMP_BACKWARD_NO_INTERRUPT || \
97 : : (opcode) == POP_JUMP_FORWARD_IF_NONE || \
98 : : (opcode) == POP_JUMP_BACKWARD_IF_NONE || \
99 : : (opcode) == POP_JUMP_FORWARD_IF_NOT_NONE || \
100 : : (opcode) == POP_JUMP_BACKWARD_IF_NOT_NONE || \
101 : : (opcode) == POP_JUMP_FORWARD_IF_TRUE || \
102 : : (opcode) == POP_JUMP_BACKWARD_IF_TRUE || \
103 : : (opcode) == POP_JUMP_FORWARD_IF_FALSE || \
104 : : (opcode) == POP_JUMP_BACKWARD_IF_FALSE)
105 : :
106 : : #define IS_BACKWARDS_JUMP_OPCODE(opcode) \
107 : : ((opcode) == JUMP_BACKWARD || \
108 : : (opcode) == JUMP_BACKWARD_NO_INTERRUPT || \
109 : : (opcode) == POP_JUMP_BACKWARD_IF_NONE || \
110 : : (opcode) == POP_JUMP_BACKWARD_IF_NOT_NONE || \
111 : : (opcode) == POP_JUMP_BACKWARD_IF_TRUE || \
112 : : (opcode) == POP_JUMP_BACKWARD_IF_FALSE)
113 : :
114 : : #define IS_UNCONDITIONAL_JUMP_OPCODE(opcode) \
115 : : ((opcode) == JUMP || \
116 : : (opcode) == JUMP_NO_INTERRUPT || \
117 : : (opcode) == JUMP_FORWARD || \
118 : : (opcode) == JUMP_BACKWARD || \
119 : : (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
120 : :
121 : : #define IS_SCOPE_EXIT_OPCODE(opcode) \
122 : : ((opcode) == RETURN_VALUE || \
123 : : (opcode) == RAISE_VARARGS || \
124 : : (opcode) == RERAISE)
125 : :
126 : : #define IS_TOP_LEVEL_AWAIT(c) ( \
127 : : (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \
128 : : && (c->u->u_ste->ste_type == ModuleBlock))
129 : :
130 : : struct location {
131 : : int lineno;
132 : : int end_lineno;
133 : : int col_offset;
134 : : int end_col_offset;
135 : : };
136 : :
137 : : #define LOCATION(LNO, END_LNO, COL, END_COL) \
138 : : ((const struct location){(LNO), (END_LNO), (COL), (END_COL)})
139 : :
140 : : static struct location NO_LOCATION = {-1, -1, -1, -1};
141 : :
142 : : struct instr {
143 : : int i_opcode;
144 : : int i_oparg;
145 : : /* target block (if jump instruction) */
146 : : struct basicblock_ *i_target;
147 : : /* target block when exception is raised, should not be set by front-end. */
148 : : struct basicblock_ *i_except;
149 : : struct location i_loc;
150 : : };
151 : :
152 : : typedef struct exceptstack {
153 : : struct basicblock_ *handlers[CO_MAXBLOCKS+1];
154 : : int depth;
155 : : } ExceptStack;
156 : :
157 : : #define LOG_BITS_PER_INT 5
158 : : #define MASK_LOW_LOG_BITS 31
159 : :
160 : : static inline int
161 : 168461500 : is_bit_set_in_table(const uint32_t *table, int bitindex) {
162 : : /* Is the relevant bit set in the relevant word? */
163 : : /* 512 bits fit into 9 32-bits words.
164 : : * Word is indexed by (bitindex>>ln(size of int in bits)).
165 : : * Bit within word is the low bits of bitindex.
166 : : */
167 [ + - + - ]: 168461500 : if (bitindex >= 0 && bitindex < 512) {
168 : 168461500 : uint32_t word = table[bitindex >> LOG_BITS_PER_INT];
169 : 168461500 : return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1;
170 : : }
171 : : else {
172 : 0 : return 0;
173 : : }
174 : : }
175 : :
176 : : static inline int
177 : 1064981 : is_relative_jump(struct instr *i)
178 : : {
179 : 1064981 : return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode);
180 : : }
181 : :
182 : : static inline int
183 : 106451639 : is_block_push(struct instr *i)
184 : : {
185 [ + + + + : 106451639 : return IS_BLOCK_PUSH_OPCODE(i->i_opcode);
+ + ]
186 : : }
187 : :
188 : : static inline int
189 : 132407297 : is_jump(struct instr *i)
190 : : {
191 : 132407297 : return IS_JUMP_OPCODE(i->i_opcode);
192 : : }
193 : :
194 : : static int
195 : 92238362 : instr_size(struct instr *instruction)
196 : : {
197 : 92238362 : int opcode = instruction->i_opcode;
198 : : assert(!IS_PSEUDO_OPCODE(opcode));
199 [ + + - + : 92238362 : int oparg = HAS_ARG(opcode) ? instruction->i_oparg : 0;
- - + - +
- + - + -
+ - + - -
+ ]
200 : 92238362 : int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg);
201 : 92238362 : int caches = _PyOpcode_Caches[opcode];
202 : 92238362 : return extended_args + 1 + caches;
203 : : }
204 : :
205 : : static void
206 : 17283827 : write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen)
207 : : {
208 : 17283827 : int opcode = instruction->i_opcode;
209 : : assert(!IS_PSEUDO_OPCODE(opcode));
210 [ + + - + : 17283827 : int oparg = HAS_ARG(opcode) ? instruction->i_oparg : 0;
- - + - +
- + - + -
+ - + - -
+ ]
211 : 17283827 : int caches = _PyOpcode_Caches[opcode];
212 [ - - + + : 17283827 : switch (ilen - caches) {
- ]
213 : 0 : case 4:
214 : 0 : *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG_QUICK, (oparg >> 24) & 0xFF);
215 : : /* fall through */
216 : 0 : case 3:
217 : 0 : *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG_QUICK, (oparg >> 16) & 0xFF);
218 : : /* fall through */
219 : 401496 : case 2:
220 : 401496 : *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG_QUICK, (oparg >> 8) & 0xFF);
221 : : /* fall through */
222 : 17283827 : case 1:
223 : 17283827 : *codestr++ = _Py_MAKECODEUNIT(opcode, oparg & 0xFF);
224 : 17283827 : break;
225 : 0 : default:
226 : 0 : Py_UNREACHABLE();
227 : : }
228 [ + + ]: 38359902 : while (caches--) {
229 : 21076075 : *codestr++ = _Py_MAKECODEUNIT(CACHE, 0);
230 : : }
231 : 17283827 : }
232 : :
233 : : typedef struct basicblock_ {
234 : : /* Each basicblock in a compilation unit is linked via b_list in the
235 : : reverse order that the block are allocated. b_list points to the next
236 : : block, not to be confused with b_next, which is next by control flow. */
237 : : struct basicblock_ *b_list;
238 : : /* Exception stack at start of block, used by assembler to create the exception handling table */
239 : : ExceptStack *b_exceptstack;
240 : : /* pointer to an array of instructions, initially NULL */
241 : : struct instr *b_instr;
242 : : /* If b_next is non-NULL, it is a pointer to the next
243 : : block reached by normal control flow. */
244 : : struct basicblock_ *b_next;
245 : : /* number of instructions used */
246 : : int b_iused;
247 : : /* length of instruction array (b_instr) */
248 : : int b_ialloc;
249 : : /* Number of predecssors that a block has. */
250 : : int b_predecessors;
251 : : /* Number of predecssors that a block has as an exception handler. */
252 : : int b_except_predecessors;
253 : : /* depth of stack upon entry of block, computed by stackdepth() */
254 : : int b_startdepth;
255 : : /* instruction offset for block, computed by assemble_jump_offsets() */
256 : : int b_offset;
257 : : /* Basic block is an exception handler that preserves lasti */
258 : : unsigned b_preserve_lasti : 1;
259 : : /* Used by compiler passes to mark whether they have visited a basic block. */
260 : : unsigned b_visited : 1;
261 : : /* b_cold is true if this block is not perf critical (like an exception handler) */
262 : : unsigned b_cold : 1;
263 : : /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
264 : : unsigned b_warm : 1;
265 : : } basicblock;
266 : :
267 : :
268 : : static struct instr *
269 : 36144624 : basicblock_last_instr(const basicblock *b) {
270 [ + + ]: 36144624 : if (b->b_iused) {
271 : 34403543 : return &b->b_instr[b->b_iused - 1];
272 : : }
273 : 1741081 : return NULL;
274 : : }
275 : :
276 : : static inline int
277 : 461212 : basicblock_returns(const basicblock *b) {
278 : 461212 : struct instr *last = basicblock_last_instr(b);
279 [ + + + + ]: 461212 : return last && last->i_opcode == RETURN_VALUE;
280 : : }
281 : :
282 : : static inline int
283 : 2748126 : basicblock_exits_scope(const basicblock *b) {
284 : 2748126 : struct instr *last = basicblock_last_instr(b);
285 [ + + + + : 2748126 : return last && IS_SCOPE_EXIT_OPCODE(last->i_opcode);
+ + + + ]
286 : : }
287 : :
288 : : static inline int
289 : 14663585 : basicblock_nofallthrough(const basicblock *b) {
290 : 14663585 : struct instr *last = basicblock_last_instr(b);
291 [ + + ]: 29282889 : return (last &&
292 [ + + + + : 14619304 : (IS_SCOPE_EXIT_OPCODE(last->i_opcode) ||
+ + ]
293 [ + + + + : 11032562 : IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)));
+ + + + +
+ ]
294 : : }
295 : :
296 : : #define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B))
297 : : #define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B))
298 : :
299 : : /* fblockinfo tracks the current frame block.
300 : :
301 : : A frame block is used to handle loops, try/except, and try/finally.
302 : : It's called a frame block to distinguish it from a basic block in the
303 : : compiler IR.
304 : : */
305 : :
306 : : enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END,
307 : : WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER,
308 : : EXCEPTION_GROUP_HANDLER, ASYNC_COMPREHENSION_GENERATOR };
309 : :
310 : : struct fblockinfo {
311 : : enum fblocktype fb_type;
312 : : basicblock *fb_block;
313 : : /* (optional) type-specific exit or cleanup block */
314 : : basicblock *fb_exit;
315 : : /* (optional) additional information required for unwinding */
316 : : void *fb_datum;
317 : : };
318 : :
319 : : enum {
320 : : COMPILER_SCOPE_MODULE,
321 : : COMPILER_SCOPE_CLASS,
322 : : COMPILER_SCOPE_FUNCTION,
323 : : COMPILER_SCOPE_ASYNC_FUNCTION,
324 : : COMPILER_SCOPE_LAMBDA,
325 : : COMPILER_SCOPE_COMPREHENSION,
326 : : };
327 : :
328 : : /* The following items change on entry and exit of code blocks.
329 : : They must be saved and restored when returning to a block.
330 : : */
331 : : struct compiler_unit {
332 : : PySTEntryObject *u_ste;
333 : :
334 : : PyObject *u_name;
335 : : PyObject *u_qualname; /* dot-separated qualified name (lazy) */
336 : : int u_scope_type;
337 : :
338 : : /* The following fields are dicts that map objects to
339 : : the index of them in co_XXX. The index is used as
340 : : the argument for opcodes that refer to those collections.
341 : : */
342 : : PyObject *u_consts; /* all constants */
343 : : PyObject *u_names; /* all names */
344 : : PyObject *u_varnames; /* local variables */
345 : : PyObject *u_cellvars; /* cell variables */
346 : : PyObject *u_freevars; /* free variables */
347 : :
348 : : PyObject *u_private; /* for private name mangling */
349 : :
350 : : Py_ssize_t u_argcount; /* number of arguments for block */
351 : : Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */
352 : : Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */
353 : : /* Pointer to the most recently allocated block. By following b_list
354 : : members, you can reach all early allocated blocks. */
355 : : basicblock *u_blocks;
356 : : basicblock *u_curblock; /* pointer to current block */
357 : :
358 : : int u_nfblocks;
359 : : struct fblockinfo u_fblock[CO_MAXBLOCKS];
360 : :
361 : : int u_firstlineno; /* the first lineno of the block */
362 : : struct location u_loc; /* line/column info of the current stmt */
363 : : };
364 : :
365 : : /* This struct captures the global state of a compilation.
366 : :
367 : : The u pointer points to the current compilation unit, while units
368 : : for enclosing blocks are stored in c_stack. The u and c_stack are
369 : : managed by compiler_enter_scope() and compiler_exit_scope().
370 : :
371 : : Note that we don't track recursion levels during compilation - the
372 : : task of detecting and rejecting excessive levels of nesting is
373 : : handled by the symbol analysis pass.
374 : :
375 : : */
376 : :
377 : : struct compiler {
378 : : PyObject *c_filename;
379 : : struct symtable *c_st;
380 : : PyFutureFeatures *c_future; /* pointer to module's __future__ */
381 : : PyCompilerFlags *c_flags;
382 : :
383 : : int c_optimize; /* optimization level */
384 : : int c_interactive; /* true if in interactive mode */
385 : : int c_nestlevel;
386 : : PyObject *c_const_cache; /* Python dict holding all constants,
387 : : including names tuple */
388 : : struct compiler_unit *u; /* compiler state for current block */
389 : : PyObject *c_stack; /* Python list holding compiler_unit ptrs */
390 : : PyArena *c_arena; /* pointer to memory allocation arena */
391 : : };
392 : :
393 : : typedef struct {
394 : : // A list of strings corresponding to name captures. It is used to track:
395 : : // - Repeated name assignments in the same pattern.
396 : : // - Different name assignments in alternatives.
397 : : // - The order of name assignments in alternatives.
398 : : PyObject *stores;
399 : : // If 0, any name captures against our subject will raise.
400 : : int allow_irrefutable;
401 : : // An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop
402 : : // i items off of the stack. The end result looks like this (with each block
403 : : // falling through to the next):
404 : : // fail_pop[4]: POP_TOP
405 : : // fail_pop[3]: POP_TOP
406 : : // fail_pop[2]: POP_TOP
407 : : // fail_pop[1]: POP_TOP
408 : : // fail_pop[0]: NOP
409 : : basicblock **fail_pop;
410 : : // The current length of fail_pop.
411 : : Py_ssize_t fail_pop_size;
412 : : // The number of items on top of the stack that need to *stay* on top of the
413 : : // stack. Variable captures go beneath these. All of them will be popped on
414 : : // failure.
415 : : Py_ssize_t on_top;
416 : : } pattern_context;
417 : :
418 : : static int basicblock_next_instr(basicblock *);
419 : :
420 : : static int compiler_enter_scope(struct compiler *, identifier, int, void *, int);
421 : : static void compiler_free(struct compiler *);
422 : : static basicblock *compiler_new_block(struct compiler *);
423 : : static int compiler_addop(struct compiler *, int, bool);
424 : : static int compiler_addop_i(struct compiler *, int, Py_ssize_t, bool);
425 : : static int compiler_addop_j(struct compiler *, int, basicblock *, bool);
426 : : static int compiler_error(struct compiler *, const char *, ...);
427 : : static int compiler_warn(struct compiler *, const char *, ...);
428 : : static int compiler_nameop(struct compiler *, identifier, expr_context_ty);
429 : :
430 : : static PyCodeObject *compiler_mod(struct compiler *, mod_ty);
431 : : static int compiler_visit_stmt(struct compiler *, stmt_ty);
432 : : static int compiler_visit_keyword(struct compiler *, keyword_ty);
433 : : static int compiler_visit_expr(struct compiler *, expr_ty);
434 : : static int compiler_augassign(struct compiler *, stmt_ty);
435 : : static int compiler_annassign(struct compiler *, stmt_ty);
436 : : static int compiler_subscript(struct compiler *, expr_ty);
437 : : static int compiler_slice(struct compiler *, expr_ty);
438 : :
439 : : static int are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t);
440 : :
441 : :
442 : : static int compiler_with(struct compiler *, stmt_ty, int);
443 : : static int compiler_async_with(struct compiler *, stmt_ty, int);
444 : : static int compiler_async_for(struct compiler *, stmt_ty);
445 : : static int validate_keywords(struct compiler *c, asdl_keyword_seq *keywords);
446 : : static int compiler_call_simple_kw_helper(struct compiler *c,
447 : : asdl_keyword_seq *keywords,
448 : : Py_ssize_t nkwelts);
449 : : static int compiler_call_helper(struct compiler *c, int n,
450 : : asdl_expr_seq *args,
451 : : asdl_keyword_seq *keywords);
452 : : static int compiler_try_except(struct compiler *, stmt_ty);
453 : : static int compiler_try_star_except(struct compiler *, stmt_ty);
454 : : static int compiler_set_qualname(struct compiler *);
455 : :
456 : : static int compiler_sync_comprehension_generator(
457 : : struct compiler *c,
458 : : asdl_comprehension_seq *generators, int gen_index,
459 : : int depth,
460 : : expr_ty elt, expr_ty val, int type);
461 : :
462 : : static int compiler_async_comprehension_generator(
463 : : struct compiler *c,
464 : : asdl_comprehension_seq *generators, int gen_index,
465 : : int depth,
466 : : expr_ty elt, expr_ty val, int type);
467 : :
468 : : static int compiler_pattern(struct compiler *, pattern_ty, pattern_context *);
469 : : static int compiler_match(struct compiler *, stmt_ty);
470 : : static int compiler_pattern_subpattern(struct compiler *, pattern_ty,
471 : : pattern_context *);
472 : :
473 : : static void clean_basic_block(basicblock *bb);
474 : :
475 : : static PyCodeObject *assemble(struct compiler *, int addNone);
476 : :
477 : : #define CAPSULE_NAME "compile.c compiler unit"
478 : :
479 : : PyObject *
480 : 12945175 : _Py_Mangle(PyObject *privateobj, PyObject *ident)
481 : : {
482 : : /* Name mangling: __private becomes _classname__private.
483 : : This is independent from how the name is used. */
484 : : PyObject *result;
485 : : size_t nlen, plen, ipriv;
486 : : Py_UCS4 maxchar;
487 [ + + + - : 20316337 : if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
+ + ]
488 [ + + ]: 8087662 : PyUnicode_READ_CHAR(ident, 0) != '_' ||
489 : 716500 : PyUnicode_READ_CHAR(ident, 1) != '_') {
490 : 12608931 : Py_INCREF(ident);
491 : 12608931 : return ident;
492 : : }
493 : 336244 : nlen = PyUnicode_GET_LENGTH(ident);
494 : 336244 : plen = PyUnicode_GET_LENGTH(privateobj);
495 : : /* Don't mangle __id__ or names with dots.
496 : :
497 : : The only time a name with a dot can occur is when
498 : : we are compiling an import statement that has a
499 : : package name.
500 : :
501 : : TODO(jhylton): Decide whether we want to support
502 : : mangling of the module name, e.g. __M.X.
503 : : */
504 [ + + + + ]: 661764 : if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' &&
505 [ + + ]: 336246 : PyUnicode_READ_CHAR(ident, nlen-2) == '_') ||
506 : 10726 : PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) {
507 : 325523 : Py_INCREF(ident);
508 : 325523 : return ident; /* Don't mangle __whatever__ */
509 : : }
510 : : /* Strip leading underscores from class name */
511 : 10721 : ipriv = 0;
512 [ + + ]: 11693 : while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_')
513 : 972 : ipriv++;
514 [ + + ]: 10721 : if (ipriv == plen) {
515 : 1 : Py_INCREF(ident);
516 : 1 : return ident; /* Don't mangle if class is just underscores */
517 : : }
518 : 10720 : plen -= ipriv;
519 : :
520 [ - + ]: 10720 : if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
521 : 0 : PyErr_SetString(PyExc_OverflowError,
522 : : "private identifier too large to be mangled");
523 : 0 : return NULL;
524 : : }
525 : :
526 : 10720 : maxchar = PyUnicode_MAX_CHAR_VALUE(ident);
527 [ - + ]: 10720 : if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar)
528 : 0 : maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
529 : :
530 : 10720 : result = PyUnicode_New(1 + nlen + plen, maxchar);
531 [ - + ]: 10720 : if (!result)
532 : 0 : return 0;
533 : : /* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
534 : 10720 : PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
535 [ - + ]: 10720 : if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
536 : 0 : Py_DECREF(result);
537 : 0 : return NULL;
538 : : }
539 [ - + ]: 10720 : if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) {
540 : 0 : Py_DECREF(result);
541 : 0 : return NULL;
542 : : }
543 : : assert(_PyUnicode_CheckConsistency(result, 1));
544 : 10720 : return result;
545 : : }
546 : :
547 : : static int
548 : 113667 : compiler_init(struct compiler *c)
549 : : {
550 : 113667 : memset(c, 0, sizeof(struct compiler));
551 : :
552 : 113667 : c->c_const_cache = PyDict_New();
553 [ - + ]: 113667 : if (!c->c_const_cache) {
554 : 0 : return 0;
555 : : }
556 : :
557 : 113667 : c->c_stack = PyList_New(0);
558 [ - + ]: 113667 : if (!c->c_stack) {
559 [ # # ]: 0 : Py_CLEAR(c->c_const_cache);
560 : 0 : return 0;
561 : : }
562 : :
563 : 113667 : return 1;
564 : : }
565 : :
566 : : PyCodeObject *
567 : 113667 : _PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
568 : : int optimize, PyArena *arena)
569 : : {
570 : : struct compiler c;
571 : 113667 : PyCodeObject *co = NULL;
572 : 113667 : PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
573 : : int merged;
574 [ - + ]: 113667 : if (!compiler_init(&c))
575 : 0 : return NULL;
576 : 113667 : Py_INCREF(filename);
577 : 113667 : c.c_filename = filename;
578 : 113667 : c.c_arena = arena;
579 : 113667 : c.c_future = _PyFuture_FromAST(mod, filename);
580 [ + + ]: 113667 : if (c.c_future == NULL)
581 : 10 : goto finally;
582 [ + + ]: 113657 : if (!flags) {
583 : 180 : flags = &local_flags;
584 : : }
585 : 113657 : merged = c.c_future->ff_features | flags->cf_flags;
586 : 113657 : c.c_future->ff_features = merged;
587 : 113657 : flags->cf_flags = merged;
588 : 113657 : c.c_flags = flags;
589 [ + + ]: 113657 : c.c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
590 : 113657 : c.c_nestlevel = 0;
591 : :
592 : : _PyASTOptimizeState state;
593 : 113657 : state.optimize = c.c_optimize;
594 : 113657 : state.ff_features = merged;
595 : :
596 [ + + ]: 113657 : if (!_PyAST_Optimize(mod, arena, &state)) {
597 : 8 : goto finally;
598 : : }
599 : :
600 : 113649 : c.c_st = _PySymtable_Build(mod, filename, c.c_future);
601 [ + + ]: 113649 : if (c.c_st == NULL) {
602 [ - + ]: 152 : if (!PyErr_Occurred())
603 : 0 : PyErr_SetString(PyExc_SystemError, "no symtable");
604 : 152 : goto finally;
605 : : }
606 : :
607 : 113497 : co = compiler_mod(&c, mod);
608 : :
609 : 113667 : finally:
610 : 113667 : compiler_free(&c);
611 : : assert(co || PyErr_Occurred());
612 : 113667 : return co;
613 : : }
614 : :
615 : : static void
616 : 113667 : compiler_free(struct compiler *c)
617 : : {
618 [ + + ]: 113667 : if (c->c_st)
619 : 113497 : _PySymtable_Free(c->c_st);
620 [ + + ]: 113667 : if (c->c_future)
621 : 113657 : PyObject_Free(c->c_future);
622 : 113667 : Py_XDECREF(c->c_filename);
623 : 113667 : Py_DECREF(c->c_const_cache);
624 : 113667 : Py_DECREF(c->c_stack);
625 : 113667 : }
626 : :
627 : : static PyObject *
628 : 461631 : list2dict(PyObject *list)
629 : : {
630 : : Py_ssize_t i, n;
631 : : PyObject *v, *k;
632 : 461631 : PyObject *dict = PyDict_New();
633 [ - + ]: 461631 : if (!dict) return NULL;
634 : :
635 : 461631 : n = PyList_Size(list);
636 [ + + ]: 1156630 : for (i = 0; i < n; i++) {
637 : 694999 : v = PyLong_FromSsize_t(i);
638 [ - + ]: 694999 : if (!v) {
639 : 0 : Py_DECREF(dict);
640 : 0 : return NULL;
641 : : }
642 : 694999 : k = PyList_GET_ITEM(list, i);
643 [ - + ]: 694999 : if (PyDict_SetItem(dict, k, v) < 0) {
644 : 0 : Py_DECREF(v);
645 : 0 : Py_DECREF(dict);
646 : 0 : return NULL;
647 : : }
648 : 694999 : Py_DECREF(v);
649 : : }
650 : 461631 : return dict;
651 : : }
652 : :
653 : : /* Return new dict containing names from src that match scope(s).
654 : :
655 : : src is a symbol table dictionary. If the scope of a name matches
656 : : either scope_type or flag is set, insert it into the new dict. The
657 : : values are integers, starting at offset and increasing by one for
658 : : each key.
659 : : */
660 : :
661 : : static PyObject *
662 : 923262 : dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
663 : : {
664 : 923262 : Py_ssize_t i = offset, scope, num_keys, key_i;
665 : 923262 : PyObject *k, *v, *dest = PyDict_New();
666 : : PyObject *sorted_keys;
667 : :
668 : : assert(offset >= 0);
669 [ - + ]: 923262 : if (dest == NULL)
670 : 0 : return NULL;
671 : :
672 : : /* Sort the keys so that we have a deterministic order on the indexes
673 : : saved in the returned dictionary. These indexes are used as indexes
674 : : into the free and cell var storage. Therefore if they aren't
675 : : deterministic, then the generated bytecode is not deterministic.
676 : : */
677 : 923262 : sorted_keys = PyDict_Keys(src);
678 [ - + ]: 923262 : if (sorted_keys == NULL)
679 : 0 : return NULL;
680 [ - + ]: 923262 : if (PyList_Sort(sorted_keys) != 0) {
681 : 0 : Py_DECREF(sorted_keys);
682 : 0 : return NULL;
683 : : }
684 : 923262 : num_keys = PyList_GET_SIZE(sorted_keys);
685 : :
686 [ + + ]: 5361880 : for (key_i = 0; key_i < num_keys; key_i++) {
687 : : /* XXX this should probably be a macro in symtable.h */
688 : : long vi;
689 : 4438618 : k = PyList_GET_ITEM(sorted_keys, key_i);
690 : 4438618 : v = PyDict_GetItemWithError(src, k);
691 : : assert(v && PyLong_Check(v));
692 : 4438618 : vi = PyLong_AS_LONG(v);
693 : 4438618 : scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
694 : :
695 [ + + + + ]: 4438618 : if (scope == scope_type || vi & flag) {
696 : 56432 : PyObject *item = PyLong_FromSsize_t(i);
697 [ - + ]: 56432 : if (item == NULL) {
698 : 0 : Py_DECREF(sorted_keys);
699 : 0 : Py_DECREF(dest);
700 : 0 : return NULL;
701 : : }
702 : 56432 : i++;
703 [ - + ]: 56432 : if (PyDict_SetItem(dest, k, item) < 0) {
704 : 0 : Py_DECREF(sorted_keys);
705 : 0 : Py_DECREF(item);
706 : 0 : Py_DECREF(dest);
707 : 0 : return NULL;
708 : : }
709 : 56432 : Py_DECREF(item);
710 : : }
711 : : }
712 : 923262 : Py_DECREF(sorted_keys);
713 : 923262 : return dest;
714 : : }
715 : :
716 : : static void
717 : 809765 : compiler_unit_check(struct compiler_unit *u)
718 : : {
719 : : basicblock *block;
720 [ + + ]: 4485103 : for (block = u->u_blocks; block != NULL; block = block->b_list) {
721 : : assert(!_PyMem_IsPtrFreed(block));
722 : 3675338 : if (block->b_instr != NULL) {
723 : : assert(block->b_ialloc > 0);
724 : : assert(block->b_iused >= 0);
725 : : assert(block->b_ialloc >= block->b_iused);
726 : : }
727 : : else {
728 : : assert (block->b_iused == 0);
729 : : assert (block->b_ialloc == 0);
730 : : }
731 : : }
732 : 809765 : }
733 : :
734 : : static void
735 : 461631 : compiler_unit_free(struct compiler_unit *u)
736 : : {
737 : : basicblock *b, *next;
738 : :
739 : 461631 : compiler_unit_check(u);
740 : 461631 : b = u->u_blocks;
741 [ + + ]: 2924092 : while (b != NULL) {
742 [ + + ]: 2462461 : if (b->b_instr)
743 : 2320316 : PyObject_Free((void *)b->b_instr);
744 : 2462461 : next = b->b_list;
745 : 2462461 : PyObject_Free((void *)b);
746 : 2462461 : b = next;
747 : : }
748 [ + - ]: 461631 : Py_CLEAR(u->u_ste);
749 [ + - ]: 461631 : Py_CLEAR(u->u_name);
750 [ + + ]: 461631 : Py_CLEAR(u->u_qualname);
751 [ + - ]: 461631 : Py_CLEAR(u->u_consts);
752 [ + - ]: 461631 : Py_CLEAR(u->u_names);
753 [ + - ]: 461631 : Py_CLEAR(u->u_varnames);
754 [ + - ]: 461631 : Py_CLEAR(u->u_freevars);
755 [ + - ]: 461631 : Py_CLEAR(u->u_cellvars);
756 [ + + ]: 461631 : Py_CLEAR(u->u_private);
757 : 461631 : PyObject_Free(u);
758 : 461631 : }
759 : :
760 : : static int
761 : 348134 : compiler_set_qualname(struct compiler *c)
762 : : {
763 : : Py_ssize_t stack_size;
764 : 348134 : struct compiler_unit *u = c->u;
765 : : PyObject *name, *base;
766 : :
767 : 348134 : base = NULL;
768 : 348134 : stack_size = PyList_GET_SIZE(c->c_stack);
769 : : assert(stack_size >= 1);
770 [ + + ]: 348134 : if (stack_size > 1) {
771 : 213143 : int scope, force_global = 0;
772 : : struct compiler_unit *parent;
773 : : PyObject *mangled, *capsule;
774 : :
775 : 213143 : capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
776 : 213143 : parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
777 : : assert(parent);
778 : :
779 [ + + ]: 213143 : if (u->u_scope_type == COMPILER_SCOPE_FUNCTION
780 [ + + ]: 29274 : || u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
781 [ + + ]: 27503 : || u->u_scope_type == COMPILER_SCOPE_CLASS) {
782 : : assert(u->u_name);
783 : 191821 : mangled = _Py_Mangle(parent->u_private, u->u_name);
784 [ - + ]: 191821 : if (!mangled)
785 : 0 : return 0;
786 : 191821 : scope = _PyST_GetScope(parent->u_ste, mangled);
787 : 191821 : Py_DECREF(mangled);
788 : : assert(scope != GLOBAL_IMPLICIT);
789 [ + + ]: 191821 : if (scope == GLOBAL_EXPLICIT)
790 : 25 : force_global = 1;
791 : : }
792 : :
793 [ + + ]: 213143 : if (!force_global) {
794 [ + + ]: 213118 : if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION
795 [ + + ]: 174207 : || parent->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
796 [ + + ]: 173825 : || parent->u_scope_type == COMPILER_SCOPE_LAMBDA)
797 : : {
798 : : _Py_DECLARE_STR(dot_locals, ".<locals>");
799 : 39366 : base = PyUnicode_Concat(parent->u_qualname,
800 : : &_Py_STR(dot_locals));
801 [ - + ]: 39366 : if (base == NULL)
802 : 0 : return 0;
803 : : }
804 : : else {
805 : 173752 : Py_INCREF(parent->u_qualname);
806 : 173752 : base = parent->u_qualname;
807 : : }
808 : : }
809 : : }
810 : :
811 [ + + ]: 348134 : if (base != NULL) {
812 : : _Py_DECLARE_STR(dot, ".");
813 : 213118 : name = PyUnicode_Concat(base, &_Py_STR(dot));
814 : 213118 : Py_DECREF(base);
815 [ - + ]: 213118 : if (name == NULL)
816 : 0 : return 0;
817 : 213118 : PyUnicode_Append(&name, u->u_name);
818 [ - + ]: 213118 : if (name == NULL)
819 : 0 : return 0;
820 : : }
821 : : else {
822 : 135016 : Py_INCREF(u->u_name);
823 : 135016 : name = u->u_name;
824 : : }
825 : 348134 : u->u_qualname = name;
826 : :
827 : 348134 : return 1;
828 : : }
829 : :
830 : :
831 : : /* Allocate a new block and return a pointer to it.
832 : : Returns NULL on error.
833 : : */
834 : : static basicblock *
835 : 2462461 : new_basicblock()
836 : : {
837 : 2462461 : basicblock *b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock));
838 [ - + ]: 2462461 : if (b == NULL) {
839 : : PyErr_NoMemory();
840 : 0 : return NULL;
841 : : }
842 : 2462461 : return b;
843 : : }
844 : :
845 : : static basicblock *
846 : 2446587 : compiler_new_block(struct compiler *c)
847 : : {
848 : 2446587 : basicblock *b = new_basicblock();
849 [ - + ]: 2446587 : if (b == NULL) {
850 : 0 : return NULL;
851 : : }
852 : : /* Extend the singly linked list of blocks with new block. */
853 : 2446587 : struct compiler_unit *u = c->u;
854 : 2446587 : b->b_list = u->u_blocks;
855 : 2446587 : u->u_blocks = b;
856 : 2446587 : return b;
857 : : }
858 : :
859 : : static basicblock *
860 : 1984636 : compiler_use_next_block(struct compiler *c, basicblock *block)
861 : : {
862 : : assert(block != NULL);
863 : 1984636 : c->u->u_curblock->b_next = block;
864 : 1984636 : c->u->u_curblock = block;
865 : 1984636 : return block;
866 : : }
867 : :
868 : : static basicblock *
869 : 15874 : basicblock_new_b_list_successor(basicblock *prev)
870 : : {
871 : 15874 : basicblock *result = new_basicblock();
872 [ - + ]: 15874 : if (result == NULL) {
873 : 0 : return NULL;
874 : : }
875 : 15874 : result->b_list = prev->b_list;
876 : 15874 : prev->b_list = result;
877 : 15874 : return result;
878 : : }
879 : :
880 : : static basicblock *
881 : 15775 : copy_basicblock(basicblock *block)
882 : : {
883 : : /* Cannot copy a block if it has a fallthrough, since
884 : : * a block can only have one fallthrough predecessor.
885 : : */
886 : : assert(BB_NO_FALLTHROUGH(block));
887 : 15775 : basicblock *result = basicblock_new_b_list_successor(block);
888 [ - + ]: 15775 : if (result == NULL) {
889 : 0 : return NULL;
890 : : }
891 [ + + ]: 47564 : for (int i = 0; i < block->b_iused; i++) {
892 : 31789 : int n = basicblock_next_instr(result);
893 [ - + ]: 31789 : if (n < 0) {
894 : 0 : return NULL;
895 : : }
896 : 31789 : result->b_instr[n] = block->b_instr[i];
897 : : }
898 : 15775 : return result;
899 : : }
900 : :
901 : : /* Returns the offset of the next instruction in the current block's
902 : : b_instr array. Resizes the b_instr as necessary.
903 : : Returns -1 on failure.
904 : : */
905 : :
906 : : static int
907 : 18498706 : basicblock_next_instr(basicblock *b)
908 : : {
909 : : assert(b != NULL);
910 [ + + ]: 18498706 : if (b->b_instr == NULL) {
911 : 2320316 : b->b_instr = (struct instr *)PyObject_Calloc(
912 : : DEFAULT_BLOCK_SIZE, sizeof(struct instr));
913 [ - + ]: 2320316 : if (b->b_instr == NULL) {
914 : : PyErr_NoMemory();
915 : 0 : return -1;
916 : : }
917 : 2320316 : b->b_ialloc = DEFAULT_BLOCK_SIZE;
918 : : }
919 [ + + ]: 16178390 : else if (b->b_iused == b->b_ialloc) {
920 : : struct instr *tmp;
921 : : size_t oldsize, newsize;
922 : 235010 : oldsize = b->b_ialloc * sizeof(struct instr);
923 : 235010 : newsize = oldsize << 1;
924 : :
925 [ - + ]: 235010 : if (oldsize > (SIZE_MAX >> 1)) {
926 : : PyErr_NoMemory();
927 : 0 : return -1;
928 : : }
929 : :
930 [ - + ]: 235010 : if (newsize == 0) {
931 : : PyErr_NoMemory();
932 : 0 : return -1;
933 : : }
934 : 235010 : b->b_ialloc <<= 1;
935 : 235010 : tmp = (struct instr *)PyObject_Realloc(
936 : 235010 : (void *)b->b_instr, newsize);
937 [ - + ]: 235010 : if (tmp == NULL) {
938 : : PyErr_NoMemory();
939 : 0 : return -1;
940 : : }
941 : 235010 : b->b_instr = tmp;
942 : 235010 : memset((char *)b->b_instr + oldsize, 0, newsize - oldsize);
943 : : }
944 : 18498706 : return b->b_iused++;
945 : : }
946 : :
947 : : /* Set the line number and column offset for the following instructions.
948 : :
949 : : The line number is reset in the following cases:
950 : : - when entering a new scope
951 : : - on each statement
952 : : - on each expression and sub-expression
953 : : - before the "except" and "finally" clauses
954 : : */
955 : :
956 : : #define SET_LOC(c, x) \
957 : : (c)->u->u_loc.lineno = (x)->lineno; \
958 : : (c)->u->u_loc.end_lineno = (x)->end_lineno; \
959 : : (c)->u->u_loc.col_offset = (x)->col_offset; \
960 : : (c)->u->u_loc.end_col_offset = (x)->end_col_offset;
961 : :
962 : : // Artificial instructions
963 : : #define UNSET_LOC(c) \
964 : : (c)->u->u_loc.lineno = -1; \
965 : : (c)->u->u_loc.end_lineno = -1; \
966 : : (c)->u->u_loc.col_offset = -1; \
967 : : (c)->u->u_loc.end_col_offset = -1;
968 : :
969 : :
970 : : /* Return the stack effect of opcode with argument oparg.
971 : :
972 : : Some opcodes have different stack effect when jump to the target and
973 : : when not jump. The 'jump' parameter specifies the case:
974 : :
975 : : * 0 -- when not jump
976 : : * 1 -- when jump
977 : : * -1 -- maximal
978 : : */
979 : : static int
980 : 18600223 : stack_effect(int opcode, int oparg, int jump)
981 : : {
982 [ + + + + : 18600223 : switch (opcode) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + ]
983 : 518097 : case NOP:
984 : : case EXTENDED_ARG:
985 : : case RESUME:
986 : : case CACHE:
987 : 518097 : return 0;
988 : :
989 : : /* Stack manipulation */
990 : 752625 : case POP_TOP:
991 : 752625 : return -1;
992 : 17624 : case SWAP:
993 : 17624 : return 0;
994 : :
995 : : /* Unary operators */
996 : 7529 : case UNARY_POSITIVE:
997 : : case UNARY_NEGATIVE:
998 : : case UNARY_NOT:
999 : : case UNARY_INVERT:
1000 : 7529 : return 0;
1001 : :
1002 : 175524 : case SET_ADD:
1003 : : case LIST_APPEND:
1004 : 175524 : return -1;
1005 : 519121 : case MAP_ADD:
1006 : 519121 : return -2;
1007 : :
1008 : 125109 : case BINARY_SUBSCR:
1009 : 125109 : return -1;
1010 : 27659 : case BINARY_SLICE:
1011 : 27659 : return -2;
1012 : 33328 : case STORE_SUBSCR:
1013 : 33328 : return -3;
1014 : 1484 : case STORE_SLICE:
1015 : 1484 : return -4;
1016 : 3869 : case DELETE_SUBSCR:
1017 : 3869 : return -2;
1018 : :
1019 : 64160 : case GET_ITER:
1020 : 64160 : return 0;
1021 : :
1022 : 2626 : case PRINT_EXPR:
1023 : 2626 : return -1;
1024 : 37359 : case LOAD_BUILD_CLASS:
1025 : 37359 : return 1;
1026 : :
1027 : 554764 : case RETURN_VALUE:
1028 : 554764 : return -1;
1029 : 989 : case IMPORT_STAR:
1030 : 989 : return -1;
1031 : 2190 : case SETUP_ANNOTATIONS:
1032 : 2190 : return 0;
1033 : 23864 : case ASYNC_GEN_WRAP:
1034 : : case YIELD_VALUE:
1035 : 23864 : return 0;
1036 : 120026 : case POP_BLOCK:
1037 : 120026 : return 0;
1038 : 112409 : case POP_EXCEPT:
1039 : 112409 : return -1;
1040 : :
1041 : 586594 : case STORE_NAME:
1042 : 586594 : return -1;
1043 : 2451 : case DELETE_NAME:
1044 : 2451 : return 0;
1045 : 39330 : case UNPACK_SEQUENCE:
1046 : 39330 : return oparg-1;
1047 : 269 : case UNPACK_EX:
1048 : 269 : return (oparg&0xFF) + (oparg>>8);
1049 : 128347 : case FOR_ITER:
1050 : : /* -1 at end of iterator, 1 if continue iterating. */
1051 [ + + ]: 128347 : return jump > 0 ? -1 : 1;
1052 : 9006 : case SEND:
1053 [ + + ]: 9006 : return jump > 0 ? -1 : 0;
1054 : 124252 : case STORE_ATTR:
1055 : 124252 : return -2;
1056 : 1063 : case DELETE_ATTR:
1057 : 1063 : return -1;
1058 : 3548 : case STORE_GLOBAL:
1059 : 3548 : return -1;
1060 : 25 : case DELETE_GLOBAL:
1061 : 25 : return 0;
1062 : 3323281 : case LOAD_CONST:
1063 : 3323281 : return 1;
1064 : 913203 : case LOAD_NAME:
1065 : 913203 : return 1;
1066 : 283541 : case BUILD_TUPLE:
1067 : : case BUILD_LIST:
1068 : : case BUILD_SET:
1069 : : case BUILD_STRING:
1070 : 283541 : return 1-oparg;
1071 : 55875 : case BUILD_MAP:
1072 : 55875 : return 1 - 2*oparg;
1073 : 20063 : case BUILD_CONST_KEY_MAP:
1074 : 20063 : return -oparg;
1075 : 1206178 : case LOAD_ATTR:
1076 : 1206178 : return (oparg & 1);
1077 : 169870 : case COMPARE_OP:
1078 : : case IS_OP:
1079 : : case CONTAINS_OP:
1080 : 169870 : return -1;
1081 : 34942 : case CHECK_EXC_MATCH:
1082 : 34942 : return 0;
1083 : 124 : case CHECK_EG_MATCH:
1084 : 124 : return 0;
1085 : 78434 : case IMPORT_NAME:
1086 : 78434 : return -1;
1087 : 70337 : case IMPORT_FROM:
1088 : 70337 : return 1;
1089 : :
1090 : : /* Jumps */
1091 : 435991 : case JUMP_FORWARD:
1092 : : case JUMP_BACKWARD:
1093 : : case JUMP:
1094 : : case JUMP_BACKWARD_NO_INTERRUPT:
1095 : : case JUMP_NO_INTERRUPT:
1096 : 435991 : return 0;
1097 : :
1098 : 38221 : case JUMP_IF_TRUE_OR_POP:
1099 : : case JUMP_IF_FALSE_OR_POP:
1100 [ + + ]: 38221 : return jump ? 0 : -1;
1101 : :
1102 : 1254686 : case POP_JUMP_BACKWARD_IF_NONE:
1103 : : case POP_JUMP_FORWARD_IF_NONE:
1104 : : case POP_JUMP_IF_NONE:
1105 : : case POP_JUMP_BACKWARD_IF_NOT_NONE:
1106 : : case POP_JUMP_FORWARD_IF_NOT_NONE:
1107 : : case POP_JUMP_IF_NOT_NONE:
1108 : : case POP_JUMP_FORWARD_IF_FALSE:
1109 : : case POP_JUMP_BACKWARD_IF_FALSE:
1110 : : case POP_JUMP_IF_FALSE:
1111 : : case POP_JUMP_FORWARD_IF_TRUE:
1112 : : case POP_JUMP_BACKWARD_IF_TRUE:
1113 : : case POP_JUMP_IF_TRUE:
1114 : 1254686 : return -1;
1115 : :
1116 : 755952 : case LOAD_GLOBAL:
1117 : 755952 : return (oparg & 1) + 1;
1118 : :
1119 : : /* Exception handling pseudo-instructions */
1120 : 80742 : case SETUP_FINALLY:
1121 : : /* 0 in the normal flow.
1122 : : * Restore the stack position and push 1 value before jumping to
1123 : : * the handler if an exception be raised. */
1124 : 80742 : return jump ? 1 : 0;
1125 : 137458 : case SETUP_CLEANUP:
1126 : : /* As SETUP_FINALLY, but pushes lasti as well */
1127 [ + + ]: 137458 : return jump ? 2 : 0;
1128 : 42438 : case SETUP_WITH:
1129 : : /* 0 in the normal flow.
1130 : : * Restore the stack position to the position before the result
1131 : : * of __(a)enter__ and push 2 values before jumping to the handler
1132 : : * if an exception be raised. */
1133 : 42438 : return jump ? 1 : 0;
1134 : :
1135 : 104 : case PREP_RERAISE_STAR:
1136 : 104 : return -1;
1137 : 129289 : case RERAISE:
1138 : 129289 : return -1;
1139 : 61454 : case PUSH_EXC_INFO:
1140 : 61454 : return 1;
1141 : :
1142 : 21251 : case WITH_EXCEPT_START:
1143 : 21251 : return 1;
1144 : :
1145 : 2332194 : case LOAD_FAST:
1146 : : case LOAD_FAST_CHECK:
1147 : 2332194 : return 1;
1148 : 567707 : case STORE_FAST:
1149 : 567707 : return -1;
1150 : 12574 : case DELETE_FAST:
1151 : 12574 : return 0;
1152 : :
1153 : 16477 : case RETURN_GENERATOR:
1154 : 16477 : return 0;
1155 : :
1156 : 60305 : case RAISE_VARARGS:
1157 : 60305 : return -oparg;
1158 : :
1159 : : /* Functions and calls */
1160 : 67802 : case KW_NAMES:
1161 : 67802 : return 0;
1162 : 1213492 : case CALL:
1163 : 1213492 : return -1-oparg;
1164 : :
1165 : 12375 : case CALL_FUNCTION_EX:
1166 [ + + ]: 12375 : return -2 - ((oparg & 0x01) != 0);
1167 : 347981 : case MAKE_FUNCTION:
1168 : 347981 : return 0 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) -
1169 : 347981 : ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0);
1170 : 1750 : case BUILD_SLICE:
1171 [ + + ]: 1750 : if (oparg == 3)
1172 : 997 : return -2;
1173 : : else
1174 : 753 : return -1;
1175 : :
1176 : : /* Closures */
1177 : 50646 : case MAKE_CELL:
1178 : : case COPY_FREE_VARS:
1179 : 50646 : return 0;
1180 : 39680 : case LOAD_CLOSURE:
1181 : 39680 : return 1;
1182 : 75033 : case LOAD_DEREF:
1183 : : case LOAD_CLASSDEREF:
1184 : 75033 : return 1;
1185 : 15398 : case STORE_DEREF:
1186 : 15398 : return -1;
1187 : 14 : case DELETE_DEREF:
1188 : 14 : return 0;
1189 : :
1190 : : /* Iterators and generators */
1191 : 2551 : case GET_AWAITABLE:
1192 : 2551 : return 0;
1193 : :
1194 : 21283 : case BEFORE_ASYNC_WITH:
1195 : : case BEFORE_WITH:
1196 : 21283 : return 1;
1197 : 140 : case GET_AITER:
1198 : 140 : return 0;
1199 : 152 : case GET_ANEXT:
1200 : 152 : return 1;
1201 : 1893 : case GET_YIELD_FROM_ITER:
1202 : 1893 : return 0;
1203 : 140 : case END_ASYNC_FOR:
1204 : 140 : return -2;
1205 : 117903 : case FORMAT_VALUE:
1206 : : /* If there's a fmt_spec on the stack, we go from 2->1,
1207 : : else 1->1. */
1208 [ + + ]: 117903 : return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0;
1209 : 4 : case LOAD_METHOD:
1210 : 4 : return 1;
1211 : 7988 : case LOAD_ASSERTION_ERROR:
1212 : 7988 : return 1;
1213 : 3923 : case LIST_TO_TUPLE:
1214 : 3923 : return 0;
1215 : 53169 : case LIST_EXTEND:
1216 : : case SET_UPDATE:
1217 : : case DICT_MERGE:
1218 : : case DICT_UPDATE:
1219 : 53169 : return -1;
1220 : 186 : case MATCH_CLASS:
1221 : 186 : return -2;
1222 : 1594 : case GET_LEN:
1223 : : case MATCH_MAPPING:
1224 : : case MATCH_SEQUENCE:
1225 : : case MATCH_KEYS:
1226 : 1594 : return 1;
1227 : 249243 : case COPY:
1228 : : case PUSH_NULL:
1229 : 249243 : return 1;
1230 : 217806 : case BINARY_OP:
1231 : 217806 : return -1;
1232 : 145 : default:
1233 : 145 : return PY_INVALID_STACK_EFFECT;
1234 : : }
1235 : : return PY_INVALID_STACK_EFFECT; /* not reachable */
1236 : : }
1237 : :
1238 : : int
1239 : 646 : PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump)
1240 : : {
1241 : 646 : return stack_effect(opcode, oparg, jump);
1242 : : }
1243 : :
1244 : : int
1245 : 11173 : PyCompile_OpcodeStackEffect(int opcode, int oparg)
1246 : : {
1247 : 11173 : return stack_effect(opcode, oparg, -1);
1248 : : }
1249 : :
1250 : : static int
1251 : 18271701 : compiler_use_new_implicit_block_if_needed(struct compiler *c)
1252 : : {
1253 : 18271701 : basicblock *b = c->u->u_curblock;
1254 : 18271701 : struct instr *last = basicblock_last_instr(b);
1255 [ + + + + : 18271701 : if (last && IS_TERMINATOR_OPCODE(last->i_opcode)) {
+ + + + -
+ ]
1256 : 668158 : basicblock *b = compiler_new_block(c);
1257 [ - + ]: 668158 : if (b == NULL) {
1258 : 0 : return -1;
1259 : : }
1260 : 668158 : compiler_use_next_block(c, b);
1261 : : }
1262 : 18271701 : return 0;
1263 : : }
1264 : :
1265 : : /* Add an opcode with no argument.
1266 : : Returns 0 on failure, 1 on success.
1267 : : */
1268 : :
1269 : : static int
1270 : 18271800 : basicblock_addop(basicblock *b, int opcode, int oparg,
1271 : : basicblock *target, const struct location *loc)
1272 : : {
1273 : : assert(IS_WITHIN_OPCODE_RANGE(opcode));
1274 : : assert(!IS_ASSEMBLER_OPCODE(opcode));
1275 : : assert(HAS_ARG(opcode) || oparg == 0);
1276 : : assert(0 <= oparg && oparg < (1 << 30));
1277 : : assert((target == NULL) ||
1278 : : IS_JUMP_OPCODE(opcode) ||
1279 : : IS_BLOCK_PUSH_OPCODE(opcode));
1280 : : assert(oparg == 0 || target == NULL);
1281 : :
1282 : 18271800 : int off = basicblock_next_instr(b);
1283 [ - + ]: 18271800 : if (off < 0) {
1284 : 0 : return 0;
1285 : : }
1286 : 18271800 : struct instr *i = &b->b_instr[off];
1287 : 18271800 : i->i_opcode = opcode;
1288 : 18271800 : i->i_oparg = oparg;
1289 : 18271800 : i->i_target = target;
1290 [ + + ]: 18271800 : i->i_loc = loc ? *loc : NO_LOCATION;
1291 : :
1292 : 18271800 : return 1;
1293 : : }
1294 : :
1295 : : static int
1296 : 2720384 : compiler_addop(struct compiler *c, int opcode, bool line)
1297 : : {
1298 : : assert(!HAS_ARG(opcode));
1299 [ - + ]: 2720384 : if (compiler_use_new_implicit_block_if_needed(c) < 0) {
1300 : 0 : return -1;
1301 : : }
1302 : :
1303 [ + + ]: 2720384 : const struct location *loc = line ? &c->u->u_loc : NULL;
1304 : 2720384 : return basicblock_addop(c->u->u_curblock, opcode, 0, NULL, loc);
1305 : : }
1306 : :
1307 : : static Py_ssize_t
1308 : 10502774 : compiler_add_o(PyObject *dict, PyObject *o)
1309 : : {
1310 : : PyObject *v;
1311 : : Py_ssize_t arg;
1312 : :
1313 : 10502774 : v = PyDict_GetItemWithError(dict, o);
1314 [ + + ]: 10502774 : if (!v) {
1315 [ - + ]: 4688908 : if (PyErr_Occurred()) {
1316 : 0 : return -1;
1317 : : }
1318 : 4688908 : arg = PyDict_GET_SIZE(dict);
1319 : 4688908 : v = PyLong_FromSsize_t(arg);
1320 [ - + ]: 4688908 : if (!v) {
1321 : 0 : return -1;
1322 : : }
1323 [ - + ]: 4688908 : if (PyDict_SetItem(dict, o, v) < 0) {
1324 : 0 : Py_DECREF(v);
1325 : 0 : return -1;
1326 : : }
1327 : 4688908 : Py_DECREF(v);
1328 : : }
1329 : : else
1330 : 5813866 : arg = PyLong_AsLong(v);
1331 : 10502774 : return arg;
1332 : : }
1333 : :
1334 : : // Merge const *o* recursively and return constant key object.
1335 : : static PyObject*
1336 : 5065382 : merge_consts_recursive(PyObject *const_cache, PyObject *o)
1337 : : {
1338 : : assert(PyDict_CheckExact(const_cache));
1339 : : // None and Ellipsis are singleton, and key is the singleton.
1340 : : // No need to merge object and key.
1341 [ + + + + ]: 5065382 : if (o == Py_None || o == Py_Ellipsis) {
1342 : 741533 : Py_INCREF(o);
1343 : 741533 : return o;
1344 : : }
1345 : :
1346 : 4323849 : PyObject *key = _PyCode_ConstantKey(o);
1347 [ - + ]: 4323849 : if (key == NULL) {
1348 : 0 : return NULL;
1349 : : }
1350 : :
1351 : : // t is borrowed reference
1352 : 4323849 : PyObject *t = PyDict_SetDefault(const_cache, key, key);
1353 [ + + ]: 4323849 : if (t != key) {
1354 : : // o is registered in const_cache. Just use it.
1355 : 504852 : Py_XINCREF(t);
1356 : 504852 : Py_DECREF(key);
1357 : 504852 : return t;
1358 : : }
1359 : :
1360 : : // We registered o in const_cache.
1361 : : // When o is a tuple or frozenset, we want to merge its
1362 : : // items too.
1363 [ + + ]: 3818997 : if (PyTuple_CheckExact(o)) {
1364 : 189629 : Py_ssize_t len = PyTuple_GET_SIZE(o);
1365 [ + + ]: 1484882 : for (Py_ssize_t i = 0; i < len; i++) {
1366 : 1295253 : PyObject *item = PyTuple_GET_ITEM(o, i);
1367 : 1295253 : PyObject *u = merge_consts_recursive(const_cache, item);
1368 [ - + ]: 1295253 : if (u == NULL) {
1369 : 0 : Py_DECREF(key);
1370 : 0 : return NULL;
1371 : : }
1372 : :
1373 : : // See _PyCode_ConstantKey()
1374 : : PyObject *v; // borrowed
1375 [ + + ]: 1295253 : if (PyTuple_CheckExact(u)) {
1376 : 78677 : v = PyTuple_GET_ITEM(u, 1);
1377 : : }
1378 : : else {
1379 : 1216576 : v = u;
1380 : : }
1381 [ + + ]: 1295253 : if (v != item) {
1382 : 59062 : Py_INCREF(v);
1383 : 59062 : PyTuple_SET_ITEM(o, i, v);
1384 : 59062 : Py_DECREF(item);
1385 : : }
1386 : :
1387 : 1295253 : Py_DECREF(u);
1388 : : }
1389 : : }
1390 [ + + ]: 3629368 : else if (PyFrozenSet_CheckExact(o)) {
1391 : : // *key* is tuple. And its first item is frozenset of
1392 : : // constant keys.
1393 : : // See _PyCode_ConstantKey() for detail.
1394 : : assert(PyTuple_CheckExact(key));
1395 : : assert(PyTuple_GET_SIZE(key) == 2);
1396 : :
1397 : 1087 : Py_ssize_t len = PySet_GET_SIZE(o);
1398 [ + + ]: 1087 : if (len == 0) { // empty frozenset should not be re-created.
1399 : 1 : return key;
1400 : : }
1401 : 1086 : PyObject *tuple = PyTuple_New(len);
1402 [ - + ]: 1086 : if (tuple == NULL) {
1403 : 0 : Py_DECREF(key);
1404 : 0 : return NULL;
1405 : : }
1406 : 1086 : Py_ssize_t i = 0, pos = 0;
1407 : : PyObject *item;
1408 : : Py_hash_t hash;
1409 [ + + ]: 7671 : while (_PySet_NextEntry(o, &pos, &item, &hash)) {
1410 : 6585 : PyObject *k = merge_consts_recursive(const_cache, item);
1411 [ - + ]: 6585 : if (k == NULL) {
1412 : 0 : Py_DECREF(tuple);
1413 : 0 : Py_DECREF(key);
1414 : 0 : return NULL;
1415 : : }
1416 : : PyObject *u;
1417 [ + + ]: 6585 : if (PyTuple_CheckExact(k)) {
1418 : 79 : u = PyTuple_GET_ITEM(k, 1);
1419 : 79 : Py_INCREF(u);
1420 : 79 : Py_DECREF(k);
1421 : : }
1422 : : else {
1423 : 6506 : u = k;
1424 : : }
1425 : 6585 : PyTuple_SET_ITEM(tuple, i, u); // Steals reference of u.
1426 : 6585 : i++;
1427 : : }
1428 : :
1429 : : // Instead of rewriting o, we create new frozenset and embed in the
1430 : : // key tuple. Caller should get merged frozenset from the key tuple.
1431 : 1086 : PyObject *new = PyFrozenSet_New(tuple);
1432 : 1086 : Py_DECREF(tuple);
1433 [ - + ]: 1086 : if (new == NULL) {
1434 : 0 : Py_DECREF(key);
1435 : 0 : return NULL;
1436 : : }
1437 : : assert(PyTuple_GET_ITEM(key, 1) == o);
1438 : 1086 : Py_DECREF(o);
1439 : 1086 : PyTuple_SET_ITEM(key, 1, new);
1440 : : }
1441 : :
1442 : 3818996 : return key;
1443 : : }
1444 : :
1445 : : static Py_ssize_t
1446 : 3763544 : compiler_add_const(struct compiler *c, PyObject *o)
1447 : : {
1448 : 3763544 : PyObject *key = merge_consts_recursive(c->c_const_cache, o);
1449 [ - + ]: 3763544 : if (key == NULL) {
1450 : 0 : return -1;
1451 : : }
1452 : :
1453 : 3763544 : Py_ssize_t arg = compiler_add_o(c->u->u_consts, key);
1454 : 3763544 : Py_DECREF(key);
1455 : 3763544 : return arg;
1456 : : }
1457 : :
1458 : : static int
1459 : 3402719 : compiler_addop_load_const(struct compiler *c, PyObject *o)
1460 : : {
1461 : 3402719 : Py_ssize_t arg = compiler_add_const(c, o);
1462 [ - + ]: 3402719 : if (arg < 0)
1463 : 0 : return 0;
1464 : 3402719 : return compiler_addop_i(c, LOAD_CONST, arg, true);
1465 : : }
1466 : :
1467 : : static int
1468 : 2904437 : compiler_addop_o(struct compiler *c, int opcode, PyObject *dict,
1469 : : PyObject *o)
1470 : : {
1471 : 2904437 : Py_ssize_t arg = compiler_add_o(dict, o);
1472 [ - + ]: 2904437 : if (arg < 0)
1473 : 0 : return 0;
1474 : 2904437 : return compiler_addop_i(c, opcode, arg, true);
1475 : : }
1476 : :
1477 : : static int
1478 : 1486870 : compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
1479 : : PyObject *o)
1480 : : {
1481 : : Py_ssize_t arg;
1482 : :
1483 : 1486870 : PyObject *mangled = _Py_Mangle(c->u->u_private, o);
1484 [ - + ]: 1486870 : if (!mangled)
1485 : 0 : return 0;
1486 : 1486870 : arg = compiler_add_o(dict, mangled);
1487 : 1486870 : Py_DECREF(mangled);
1488 [ - + ]: 1486870 : if (arg < 0)
1489 : 0 : return 0;
1490 [ + + ]: 1486870 : if (opcode == LOAD_ATTR) {
1491 : 675649 : arg <<= 1;
1492 : : }
1493 [ + + ]: 1486870 : if (opcode == LOAD_METHOD) {
1494 : 531884 : opcode = LOAD_ATTR;
1495 : 531884 : arg <<= 1;
1496 : 531884 : arg |= 1;
1497 : : }
1498 : 1486870 : return compiler_addop_i(c, opcode, arg, true);
1499 : : }
1500 : :
1501 : : /* Add an opcode with an integer argument.
1502 : : Returns 0 on failure, 1 on success.
1503 : : */
1504 : : static int
1505 : 14393695 : compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg, bool line)
1506 : : {
1507 [ - + ]: 14393695 : if (compiler_use_new_implicit_block_if_needed(c) < 0) {
1508 : 0 : return -1;
1509 : : }
1510 : : /* oparg value is unsigned, but a signed C int is usually used to store
1511 : : it in the C code (like Python/ceval.c).
1512 : :
1513 : : Limit to 32-bit signed C int (rather than INT_MAX) for portability.
1514 : :
1515 : : The argument of a concrete bytecode instruction is limited to 8-bit.
1516 : : EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */
1517 : :
1518 : 14393695 : int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
1519 : :
1520 [ + + ]: 14393695 : const struct location *loc = line ? &c->u->u_loc : NULL;
1521 : 14393695 : return basicblock_addop(c->u->u_curblock, opcode, oparg_, NULL, loc);
1522 : : }
1523 : :
1524 : : static int
1525 : 1157622 : compiler_addop_j(struct compiler *c, int opcode, basicblock *target, bool line)
1526 : : {
1527 [ - + ]: 1157622 : if (compiler_use_new_implicit_block_if_needed(c) < 0) {
1528 : 0 : return -1;
1529 : : }
1530 [ + + ]: 1157622 : const struct location *loc = line ? &c->u->u_loc : NULL;
1531 : : assert(target != NULL);
1532 : : assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode));
1533 : 1157622 : return basicblock_addop(c->u->u_curblock, opcode, 0, target, loc);
1534 : : }
1535 : :
1536 : : #define ADDOP(C, OP) { \
1537 : : if (!compiler_addop((C), (OP), true)) \
1538 : : return 0; \
1539 : : }
1540 : :
1541 : : #define ADDOP_NOLINE(C, OP) { \
1542 : : if (!compiler_addop((C), (OP), false)) \
1543 : : return 0; \
1544 : : }
1545 : :
1546 : : #define ADDOP_IN_SCOPE(C, OP) { \
1547 : : if (!compiler_addop((C), (OP), true)) { \
1548 : : compiler_exit_scope(c); \
1549 : : return 0; \
1550 : : } \
1551 : : }
1552 : :
1553 : : #define ADDOP_LOAD_CONST(C, O) { \
1554 : : if (!compiler_addop_load_const((C), (O))) \
1555 : : return 0; \
1556 : : }
1557 : :
1558 : : /* Same as ADDOP_LOAD_CONST, but steals a reference. */
1559 : : #define ADDOP_LOAD_CONST_NEW(C, O) { \
1560 : : PyObject *__new_const = (O); \
1561 : : if (__new_const == NULL) { \
1562 : : return 0; \
1563 : : } \
1564 : : if (!compiler_addop_load_const((C), __new_const)) { \
1565 : : Py_DECREF(__new_const); \
1566 : : return 0; \
1567 : : } \
1568 : : Py_DECREF(__new_const); \
1569 : : }
1570 : :
1571 : : #define ADDOP_N(C, OP, O, TYPE) { \
1572 : : assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */ \
1573 : : if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \
1574 : : Py_DECREF((O)); \
1575 : : return 0; \
1576 : : } \
1577 : : Py_DECREF((O)); \
1578 : : }
1579 : :
1580 : : #define ADDOP_NAME(C, OP, O, TYPE) { \
1581 : : if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \
1582 : : return 0; \
1583 : : }
1584 : :
1585 : : #define ADDOP_I(C, OP, O) { \
1586 : : if (!compiler_addop_i((C), (OP), (O), true)) \
1587 : : return 0; \
1588 : : }
1589 : :
1590 : : #define ADDOP_I_NOLINE(C, OP, O) { \
1591 : : if (!compiler_addop_i((C), (OP), (O), false)) \
1592 : : return 0; \
1593 : : }
1594 : :
1595 : : #define ADDOP_JUMP(C, OP, O) { \
1596 : : if (!compiler_addop_j((C), (OP), (O), true)) \
1597 : : return 0; \
1598 : : }
1599 : :
1600 : : /* Add a jump with no line number.
1601 : : * Used for artificial jumps that have no corresponding
1602 : : * token in the source code. */
1603 : : #define ADDOP_JUMP_NOLINE(C, OP, O) { \
1604 : : if (!compiler_addop_j((C), (OP), (O), false)) \
1605 : : return 0; \
1606 : : }
1607 : :
1608 : : #define ADDOP_COMPARE(C, CMP) { \
1609 : : if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \
1610 : : return 0; \
1611 : : }
1612 : :
1613 : : #define ADDOP_BINARY(C, BINOP) \
1614 : : RETURN_IF_FALSE(addop_binary((C), (BINOP), false))
1615 : :
1616 : : #define ADDOP_INPLACE(C, BINOP) \
1617 : : RETURN_IF_FALSE(addop_binary((C), (BINOP), true))
1618 : :
1619 : : /* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use
1620 : : the ASDL name to synthesize the name of the C type and the visit function.
1621 : : */
1622 : :
1623 : : #define ADD_YIELD_FROM(C, await) \
1624 : : RETURN_IF_FALSE(compiler_add_yield_from((C), (await)))
1625 : :
1626 : : #define POP_EXCEPT_AND_RERAISE(C) \
1627 : : RETURN_IF_FALSE(compiler_pop_except_and_reraise((C)))
1628 : :
1629 : : #define ADDOP_YIELD(C) \
1630 : : RETURN_IF_FALSE(addop_yield(C))
1631 : :
1632 : : #define VISIT(C, TYPE, V) {\
1633 : : if (!compiler_visit_ ## TYPE((C), (V))) \
1634 : : return 0; \
1635 : : }
1636 : :
1637 : : #define VISIT_IN_SCOPE(C, TYPE, V) {\
1638 : : if (!compiler_visit_ ## TYPE((C), (V))) { \
1639 : : compiler_exit_scope(c); \
1640 : : return 0; \
1641 : : } \
1642 : : }
1643 : :
1644 : : #define VISIT_SEQ(C, TYPE, SEQ) { \
1645 : : int _i; \
1646 : : asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \
1647 : : for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
1648 : : TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
1649 : : if (!compiler_visit_ ## TYPE((C), elt)) \
1650 : : return 0; \
1651 : : } \
1652 : : }
1653 : :
1654 : : #define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \
1655 : : int _i; \
1656 : : asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \
1657 : : for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
1658 : : TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
1659 : : if (!compiler_visit_ ## TYPE((C), elt)) { \
1660 : : compiler_exit_scope(c); \
1661 : : return 0; \
1662 : : } \
1663 : : } \
1664 : : }
1665 : :
1666 : : #define RETURN_IF_FALSE(X) \
1667 : : if (!(X)) { \
1668 : : return 0; \
1669 : : }
1670 : :
1671 : : static int
1672 : 461631 : compiler_enter_scope(struct compiler *c, identifier name,
1673 : : int scope_type, void *key, int lineno)
1674 : : {
1675 : : struct compiler_unit *u;
1676 : : basicblock *block;
1677 : :
1678 : 461631 : u = (struct compiler_unit *)PyObject_Calloc(1, sizeof(
1679 : : struct compiler_unit));
1680 [ - + ]: 461631 : if (!u) {
1681 : : PyErr_NoMemory();
1682 : 0 : return 0;
1683 : : }
1684 : 461631 : u->u_scope_type = scope_type;
1685 : 461631 : u->u_argcount = 0;
1686 : 461631 : u->u_posonlyargcount = 0;
1687 : 461631 : u->u_kwonlyargcount = 0;
1688 : 461631 : u->u_ste = PySymtable_Lookup(c->c_st, key);
1689 [ - + ]: 461631 : if (!u->u_ste) {
1690 : 0 : compiler_unit_free(u);
1691 : 0 : return 0;
1692 : : }
1693 : 461631 : Py_INCREF(name);
1694 : 461631 : u->u_name = name;
1695 : 461631 : u->u_varnames = list2dict(u->u_ste->ste_varnames);
1696 : 461631 : u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0);
1697 [ + - - + ]: 461631 : if (!u->u_varnames || !u->u_cellvars) {
1698 : 0 : compiler_unit_free(u);
1699 : 0 : return 0;
1700 : : }
1701 [ + + ]: 461631 : if (u->u_ste->ste_needs_class_closure) {
1702 : : /* Cook up an implicit __class__ cell. */
1703 : : int res;
1704 : : assert(u->u_scope_type == COMPILER_SCOPE_CLASS);
1705 : : assert(PyDict_GET_SIZE(u->u_cellvars) == 0);
1706 : 4766 : res = PyDict_SetItem(u->u_cellvars, &_Py_ID(__class__),
1707 : : _PyLong_GetZero());
1708 [ - + ]: 4766 : if (res < 0) {
1709 : 0 : compiler_unit_free(u);
1710 : 0 : return 0;
1711 : : }
1712 : : }
1713 : :
1714 : 461631 : u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
1715 : : PyDict_GET_SIZE(u->u_cellvars));
1716 [ - + ]: 461631 : if (!u->u_freevars) {
1717 : 0 : compiler_unit_free(u);
1718 : 0 : return 0;
1719 : : }
1720 : :
1721 : 461631 : u->u_blocks = NULL;
1722 : 461631 : u->u_nfblocks = 0;
1723 : 461631 : u->u_firstlineno = lineno;
1724 : 461631 : u->u_loc = LOCATION(lineno, lineno, 0, 0);
1725 : 461631 : u->u_consts = PyDict_New();
1726 [ - + ]: 461631 : if (!u->u_consts) {
1727 : 0 : compiler_unit_free(u);
1728 : 0 : return 0;
1729 : : }
1730 : 461631 : u->u_names = PyDict_New();
1731 [ - + ]: 461631 : if (!u->u_names) {
1732 : 0 : compiler_unit_free(u);
1733 : 0 : return 0;
1734 : : }
1735 : :
1736 : 461631 : u->u_private = NULL;
1737 : :
1738 : : /* Push the old compiler_unit on the stack. */
1739 [ + + ]: 461631 : if (c->u) {
1740 : 348134 : PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL);
1741 [ + - - + ]: 348134 : if (!capsule || PyList_Append(c->c_stack, capsule) < 0) {
1742 : 0 : Py_XDECREF(capsule);
1743 : 0 : compiler_unit_free(u);
1744 : 0 : return 0;
1745 : : }
1746 : 348134 : Py_DECREF(capsule);
1747 : 348134 : u->u_private = c->u->u_private;
1748 : 348134 : Py_XINCREF(u->u_private);
1749 : : }
1750 : 461631 : c->u = u;
1751 : :
1752 : 461631 : c->c_nestlevel++;
1753 : :
1754 : 461631 : block = compiler_new_block(c);
1755 [ - + ]: 461631 : if (block == NULL)
1756 : 0 : return 0;
1757 : 461631 : c->u->u_curblock = block;
1758 : :
1759 [ + + ]: 461631 : if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
1760 : 113497 : c->u->u_loc.lineno = 0;
1761 : : }
1762 : : else {
1763 [ - + ]: 348134 : if (!compiler_set_qualname(c))
1764 : 0 : return 0;
1765 : : }
1766 [ - + ]: 461631 : ADDOP_I(c, RESUME, 0);
1767 : :
1768 [ + + ]: 461631 : if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
1769 : 113497 : c->u->u_loc.lineno = -1;
1770 : : }
1771 : 461631 : return 1;
1772 : : }
1773 : :
1774 : : static void
1775 : 461631 : compiler_exit_scope(struct compiler *c)
1776 : : {
1777 : : // Don't call PySequence_DelItem() with an exception raised
1778 : : PyObject *exc_type, *exc_val, *exc_tb;
1779 : 461631 : PyErr_Fetch(&exc_type, &exc_val, &exc_tb);
1780 : :
1781 : 461631 : c->c_nestlevel--;
1782 : 461631 : compiler_unit_free(c->u);
1783 : : /* Restore c->u to the parent unit. */
1784 : 461631 : Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1;
1785 [ + + ]: 461631 : if (n >= 0) {
1786 : 348134 : PyObject *capsule = PyList_GET_ITEM(c->c_stack, n);
1787 : 348134 : c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
1788 : : assert(c->u);
1789 : : /* we are deleting from a list so this really shouldn't fail */
1790 [ - + ]: 348134 : if (PySequence_DelItem(c->c_stack, n) < 0) {
1791 : 0 : _PyErr_WriteUnraisableMsg("on removing the last compiler "
1792 : : "stack item", NULL);
1793 : : }
1794 : 348134 : compiler_unit_check(c->u);
1795 : : }
1796 : : else {
1797 : 113497 : c->u = NULL;
1798 : : }
1799 : :
1800 : 461631 : PyErr_Restore(exc_type, exc_val, exc_tb);
1801 : 461631 : }
1802 : :
1803 : : /* Search if variable annotations are present statically in a block. */
1804 : :
1805 : : static int
1806 : 517722 : find_ann(asdl_stmt_seq *stmts)
1807 : : {
1808 : 517722 : int i, j, res = 0;
1809 : : stmt_ty st;
1810 : :
1811 [ + + + + ]: 1430413 : for (i = 0; i < asdl_seq_LEN(stmts); i++) {
1812 : 914904 : st = (stmt_ty)asdl_seq_GET(stmts, i);
1813 [ + + + + : 914904 : switch (st->kind) {
+ + + + +
+ ]
1814 : 2188 : case AnnAssign_kind:
1815 : 2188 : return 1;
1816 : 1334 : case For_kind:
1817 [ + - - + ]: 2668 : res = find_ann(st->v.For.body) ||
1818 : 1334 : find_ann(st->v.For.orelse);
1819 : 1334 : break;
1820 : 5 : case AsyncFor_kind:
1821 [ + - - + ]: 10 : res = find_ann(st->v.AsyncFor.body) ||
1822 : 5 : find_ann(st->v.AsyncFor.orelse);
1823 : 5 : break;
1824 : 140 : case While_kind:
1825 [ + - - + ]: 280 : res = find_ann(st->v.While.body) ||
1826 : 140 : find_ann(st->v.While.orelse);
1827 : 140 : break;
1828 : 210386 : case If_kind:
1829 [ + + - + ]: 420760 : res = find_ann(st->v.If.body) ||
1830 : 210374 : find_ann(st->v.If.orelse);
1831 : 210386 : break;
1832 : 464 : case With_kind:
1833 : 464 : res = find_ann(st->v.With.body);
1834 : 464 : break;
1835 : 5 : case AsyncWith_kind:
1836 : 5 : res = find_ann(st->v.AsyncWith.body);
1837 : 5 : break;
1838 : 3488 : case Try_kind:
1839 [ + + + + ]: 6993 : for (j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) {
1840 : 3505 : excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
1841 : : st->v.Try.handlers, j);
1842 [ - + ]: 3505 : if (find_ann(handler->v.ExceptHandler.body)) {
1843 : 0 : return 1;
1844 : : }
1845 : : }
1846 [ + - ]: 6976 : res = find_ann(st->v.Try.body) ||
1847 [ + - - + ]: 6976 : find_ann(st->v.Try.finalbody) ||
1848 : 3488 : find_ann(st->v.Try.orelse);
1849 : 3488 : break;
1850 : 8 : case TryStar_kind:
1851 [ + - + + ]: 16 : for (j = 0; j < asdl_seq_LEN(st->v.TryStar.handlers); j++) {
1852 : 8 : excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
1853 : : st->v.TryStar.handlers, j);
1854 [ - + ]: 8 : if (find_ann(handler->v.ExceptHandler.body)) {
1855 : 0 : return 1;
1856 : : }
1857 : : }
1858 [ + - ]: 16 : res = find_ann(st->v.TryStar.body) ||
1859 [ + - - + ]: 16 : find_ann(st->v.TryStar.finalbody) ||
1860 : 8 : find_ann(st->v.TryStar.orelse);
1861 : 8 : break;
1862 : 696886 : default:
1863 : 696886 : res = 0;
1864 : : }
1865 [ + + ]: 912716 : if (res) {
1866 : 25 : break;
1867 : : }
1868 : : }
1869 : 515534 : return res;
1870 : : }
1871 : :
1872 : : /*
1873 : : * Frame block handling functions
1874 : : */
1875 : :
1876 : : static int
1877 : 195792 : compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b,
1878 : : basicblock *exit, void *datum)
1879 : : {
1880 : : struct fblockinfo *f;
1881 [ + + ]: 195792 : if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
1882 : 2 : return compiler_error(c, "too many statically nested blocks");
1883 : : }
1884 : 195790 : f = &c->u->u_fblock[c->u->u_nfblocks++];
1885 : 195790 : f->fb_type = t;
1886 : 195790 : f->fb_block = b;
1887 : 195790 : f->fb_exit = exit;
1888 : 195790 : f->fb_datum = datum;
1889 : 195790 : return 1;
1890 : : }
1891 : :
1892 : : static void
1893 : 195716 : compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b)
1894 : : {
1895 : 195716 : struct compiler_unit *u = c->u;
1896 : : assert(u->u_nfblocks > 0);
1897 : 195716 : u->u_nfblocks--;
1898 : : assert(u->u_fblock[u->u_nfblocks].fb_type == t);
1899 : : assert(u->u_fblock[u->u_nfblocks].fb_block == b);
1900 : 195716 : }
1901 : :
1902 : : static int
1903 : 23626 : compiler_call_exit_with_nones(struct compiler *c) {
1904 [ - + ]: 23626 : ADDOP_LOAD_CONST(c, Py_None);
1905 [ - + ]: 23626 : ADDOP_LOAD_CONST(c, Py_None);
1906 [ - + ]: 23626 : ADDOP_LOAD_CONST(c, Py_None);
1907 [ - + ]: 23626 : ADDOP_I(c, CALL, 2);
1908 : 23626 : return 1;
1909 : : }
1910 : :
1911 : : static int
1912 : 4547 : compiler_add_yield_from(struct compiler *c, int await)
1913 : : {
1914 : : basicblock *start, *resume, *exit;
1915 : 4547 : start = compiler_new_block(c);
1916 : 4547 : resume = compiler_new_block(c);
1917 : 4547 : exit = compiler_new_block(c);
1918 [ + - + - : 4547 : if (start == NULL || resume == NULL || exit == NULL) {
- + ]
1919 : 0 : return 0;
1920 : : }
1921 : 4547 : compiler_use_next_block(c, start);
1922 [ - + ]: 4547 : ADDOP_JUMP(c, SEND, exit);
1923 : 4547 : compiler_use_next_block(c, resume);
1924 [ - + ]: 4547 : ADDOP_I(c, YIELD_VALUE, 0);
1925 [ + + - + ]: 4547 : ADDOP_I(c, RESUME, await ? 3 : 2);
1926 [ - + ]: 4547 : ADDOP_JUMP(c, JUMP_NO_INTERRUPT, start);
1927 : 4547 : compiler_use_next_block(c, exit);
1928 : 4547 : return 1;
1929 : : }
1930 : :
1931 : : static int
1932 : 61491 : compiler_pop_except_and_reraise(struct compiler *c)
1933 : : {
1934 : : /* Stack contents
1935 : : * [exc_info, lasti, exc] COPY 3
1936 : : * [exc_info, lasti, exc, exc_info] POP_EXCEPT
1937 : : * [exc_info, lasti, exc] RERAISE 1
1938 : : * (exception_unwind clears the stack)
1939 : : */
1940 : :
1941 [ - + ]: 61491 : ADDOP_I(c, COPY, 3);
1942 [ - + ]: 61491 : ADDOP(c, POP_EXCEPT);
1943 [ - + ]: 61491 : ADDOP_I(c, RERAISE, 1);
1944 : 61491 : return 1;
1945 : : }
1946 : :
1947 : : /* Unwind a frame block. If preserve_tos is true, the TOS before
1948 : : * popping the blocks will be restored afterwards, unless another
1949 : : * return, break or continue is found. In which case, the TOS will
1950 : : * be popped.
1951 : : */
1952 : : static int
1953 : 44149 : compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
1954 : : int preserve_tos)
1955 : : {
1956 [ + + + + : 44149 : switch (info->fb_type) {
+ + + +
- ]
1957 : 16883 : case WHILE_LOOP:
1958 : : case EXCEPTION_HANDLER:
1959 : : case EXCEPTION_GROUP_HANDLER:
1960 : : case ASYNC_COMPREHENSION_GENERATOR:
1961 : 16883 : return 1;
1962 : :
1963 : 7373 : case FOR_LOOP:
1964 : : /* Pop the iterator */
1965 [ + + ]: 7373 : if (preserve_tos) {
1966 [ - + ]: 2448 : ADDOP_I(c, SWAP, 2);
1967 : : }
1968 [ - + ]: 7373 : ADDOP(c, POP_TOP);
1969 : 7373 : return 1;
1970 : :
1971 : 6371 : case TRY_EXCEPT:
1972 [ - + ]: 6371 : ADDOP(c, POP_BLOCK);
1973 : 6371 : return 1;
1974 : :
1975 : 1529 : case FINALLY_TRY:
1976 : : /* This POP_BLOCK gets the line number of the unwinding statement */
1977 [ - + ]: 1529 : ADDOP(c, POP_BLOCK);
1978 [ + + ]: 1529 : if (preserve_tos) {
1979 [ - + ]: 1264 : if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) {
1980 : 0 : return 0;
1981 : : }
1982 : : }
1983 : : /* Emit the finally block */
1984 [ - + + - : 3278 : VISIT_SEQ(c, stmt, info->fb_datum);
+ + ]
1985 [ + + ]: 1529 : if (preserve_tos) {
1986 : 1264 : compiler_pop_fblock(c, POP_VALUE, NULL);
1987 : : }
1988 : : /* The finally block should appear to execute after the
1989 : : * statement causing the unwinding, so make the unwinding
1990 : : * instruction artificial */
1991 : 1529 : UNSET_LOC(c);
1992 : 1529 : return 1;
1993 : :
1994 : 116 : case FINALLY_END:
1995 [ + + ]: 116 : if (preserve_tos) {
1996 [ - + ]: 17 : ADDOP_I(c, SWAP, 2);
1997 : : }
1998 [ - + ]: 116 : ADDOP(c, POP_TOP); /* exc_value */
1999 [ + + ]: 116 : if (preserve_tos) {
2000 [ - + ]: 17 : ADDOP_I(c, SWAP, 2);
2001 : : }
2002 [ - + ]: 116 : ADDOP(c, POP_BLOCK);
2003 [ - + ]: 116 : ADDOP(c, POP_EXCEPT);
2004 : 116 : return 1;
2005 : :
2006 : 2408 : case WITH:
2007 : : case ASYNC_WITH:
2008 : 2408 : SET_LOC(c, (stmt_ty)info->fb_datum);
2009 [ - + ]: 2408 : ADDOP(c, POP_BLOCK);
2010 [ + + ]: 2408 : if (preserve_tos) {
2011 [ - + ]: 1785 : ADDOP_I(c, SWAP, 2);
2012 : : }
2013 [ - + ]: 2408 : if(!compiler_call_exit_with_nones(c)) {
2014 : 0 : return 0;
2015 : : }
2016 [ + + ]: 2408 : if (info->fb_type == ASYNC_WITH) {
2017 [ - + ]: 53 : ADDOP_I(c, GET_AWAITABLE, 2);
2018 [ - + ]: 53 : ADDOP_LOAD_CONST(c, Py_None);
2019 [ - + ]: 53 : ADD_YIELD_FROM(c, 1);
2020 : : }
2021 [ - + ]: 2408 : ADDOP(c, POP_TOP);
2022 : : /* The exit block should appear to execute after the
2023 : : * statement causing the unwinding, so make the unwinding
2024 : : * instruction artificial */
2025 : 2408 : UNSET_LOC(c);
2026 : 2408 : return 1;
2027 : :
2028 : 9461 : case HANDLER_CLEANUP:
2029 [ + + ]: 9461 : if (info->fb_datum) {
2030 [ - + ]: 1565 : ADDOP(c, POP_BLOCK);
2031 : : }
2032 [ + + ]: 9461 : if (preserve_tos) {
2033 [ - + ]: 2790 : ADDOP_I(c, SWAP, 2);
2034 : : }
2035 [ - + ]: 9461 : ADDOP(c, POP_BLOCK);
2036 [ - + ]: 9461 : ADDOP(c, POP_EXCEPT);
2037 [ + + ]: 9461 : if (info->fb_datum) {
2038 [ - + ]: 1565 : ADDOP_LOAD_CONST(c, Py_None);
2039 : 1565 : compiler_nameop(c, info->fb_datum, Store);
2040 : 1565 : compiler_nameop(c, info->fb_datum, Del);
2041 : : }
2042 : 9461 : return 1;
2043 : :
2044 : 8 : case POP_VALUE:
2045 [ - + ]: 8 : if (preserve_tos) {
2046 [ # # ]: 0 : ADDOP_I(c, SWAP, 2);
2047 : : }
2048 [ - + ]: 8 : ADDOP(c, POP_TOP);
2049 : 8 : return 1;
2050 : : }
2051 : 0 : Py_UNREACHABLE();
2052 : : }
2053 : :
2054 : : /** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */
2055 : : static int
2056 : 262026 : compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblockinfo **loop) {
2057 [ + + ]: 262026 : if (c->u->u_nfblocks == 0) {
2058 : 210386 : return 1;
2059 : : }
2060 : 51640 : struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1];
2061 [ + + ]: 51640 : if (top->fb_type == EXCEPTION_GROUP_HANDLER) {
2062 : 8 : return compiler_error(
2063 : : c, "'break', 'continue' and 'return' cannot appear in an except* block");
2064 : : }
2065 [ + + + + : 51632 : if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) {
+ + ]
2066 : 15906 : *loop = top;
2067 : 15906 : return 1;
2068 : : }
2069 : 35726 : struct fblockinfo copy = *top;
2070 : 35726 : c->u->u_nfblocks--;
2071 [ - + ]: 35726 : if (!compiler_unwind_fblock(c, ©, preserve_tos)) {
2072 : 0 : return 0;
2073 : : }
2074 [ + + ]: 35726 : if (!compiler_unwind_fblock_stack(c, preserve_tos, loop)) {
2075 : 8 : return 0;
2076 : : }
2077 : 35718 : c->u->u_fblock[c->u->u_nfblocks] = copy;
2078 : 35718 : c->u->u_nfblocks++;
2079 : 35718 : return 1;
2080 : : }
2081 : :
2082 : : /* Compile a sequence of statements, checking for a docstring
2083 : : and for annotations. */
2084 : :
2085 : : static int
2086 : 75406 : compiler_body(struct compiler *c, asdl_stmt_seq *stmts)
2087 : : {
2088 : 75406 : int i = 0;
2089 : : stmt_ty st;
2090 : : PyObject *docstring;
2091 : :
2092 : : /* Set current line number to the line number of first statement.
2093 : : This way line number for SETUP_ANNOTATIONS will always
2094 : : coincide with the line number of first "real" statement in module.
2095 : : If body is empty, then lineno will be set later in assemble. */
2096 [ + + + + : 75406 : if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) {
+ - ]
2097 : 37353 : st = (stmt_ty)asdl_seq_GET(stmts, 0);
2098 : 37353 : SET_LOC(c, st);
2099 : : }
2100 : : /* Every annotated class and module should have __annotations__. */
2101 [ + + ]: 75406 : if (find_ann(stmts)) {
2102 [ - + ]: 2187 : ADDOP(c, SETUP_ANNOTATIONS);
2103 : : }
2104 [ + + - + ]: 75406 : if (!asdl_seq_LEN(stmts))
2105 : 678 : return 1;
2106 : : /* if not -OO mode, set docstring */
2107 [ + + ]: 74728 : if (c->c_optimize < 2) {
2108 : 73758 : docstring = _PyAST_GetDocString(stmts);
2109 [ + + ]: 73758 : if (docstring) {
2110 : 21318 : i = 1;
2111 : 21318 : st = (stmt_ty)asdl_seq_GET(stmts, 0);
2112 : : assert(st->kind == Expr_kind);
2113 [ - + ]: 21318 : VISIT(c, expr, st->v.Expr.value);
2114 : 21318 : UNSET_LOC(c);
2115 [ - + ]: 21318 : if (!compiler_nameop(c, &_Py_ID(__doc__), Store))
2116 : 0 : return 0;
2117 : : }
2118 : : }
2119 [ + - + + ]: 732666 : for (; i < asdl_seq_LEN(stmts); i++)
2120 [ + + ]: 658193 : VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
2121 : 74473 : return 1;
2122 : : }
2123 : :
2124 : : static PyCodeObject *
2125 : 113497 : compiler_mod(struct compiler *c, mod_ty mod)
2126 : : {
2127 : : PyCodeObject *co;
2128 : 113497 : int addNone = 1;
2129 : : _Py_DECLARE_STR(anon_module, "<module>");
2130 [ - + ]: 113497 : if (!compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE,
2131 : : mod, 1)) {
2132 : 0 : return NULL;
2133 : : }
2134 : 113497 : c->u->u_loc.lineno = 1;
2135 [ + + + - ]: 113497 : switch (mod->kind) {
2136 : 38031 : case Module_kind:
2137 [ + + ]: 38031 : if (!compiler_body(c, mod->v.Module.body)) {
2138 : 238 : compiler_exit_scope(c);
2139 : 238 : return 0;
2140 : : }
2141 : 37793 : break;
2142 : 4128 : case Interactive_kind:
2143 [ + + ]: 4128 : if (find_ann(mod->v.Interactive.body)) {
2144 [ - + ]: 1 : ADDOP(c, SETUP_ANNOTATIONS);
2145 : : }
2146 : 4128 : c->c_interactive = 1;
2147 [ + + + - : 8267 : VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body);
+ + ]
2148 : 4078 : break;
2149 : 71338 : case Expression_kind:
2150 [ + + ]: 71338 : VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
2151 : 71337 : addNone = 0;
2152 : 71337 : break;
2153 : 0 : default:
2154 : 0 : PyErr_Format(PyExc_SystemError,
2155 : : "module kind %d should not be possible",
2156 : 0 : mod->kind);
2157 : 0 : return 0;
2158 : : }
2159 : 113208 : co = assemble(c, addNone);
2160 : 113208 : compiler_exit_scope(c);
2161 : 113208 : return co;
2162 : : }
2163 : :
2164 : : /* The test for LOCAL must come before the test for FREE in order to
2165 : : handle classes where name is both local and free. The local var is
2166 : : a method and the free var is a free var referenced within a method.
2167 : : */
2168 : :
2169 : : static int
2170 : 34907 : get_ref_type(struct compiler *c, PyObject *name)
2171 : : {
2172 : : int scope;
2173 [ + + + + ]: 43297 : if (c->u->u_scope_type == COMPILER_SCOPE_CLASS &&
2174 : 8390 : _PyUnicode_EqualToASCIIString(name, "__class__"))
2175 : 6736 : return CELL;
2176 : 28171 : scope = _PyST_GetScope(c->u->u_ste, name);
2177 [ - + ]: 28171 : if (scope == 0) {
2178 : 0 : PyErr_Format(PyExc_SystemError,
2179 : : "_PyST_GetScope(name=%R) failed: "
2180 : : "unknown scope in unit %S (%R); "
2181 : : "symbols: %R; locals: %R; globals: %R",
2182 : : name,
2183 : 0 : c->u->u_name, c->u->u_ste->ste_id,
2184 : 0 : c->u->u_ste->ste_symbols, c->u->u_varnames, c->u->u_names);
2185 : 0 : return -1;
2186 : : }
2187 : 28171 : return scope;
2188 : : }
2189 : :
2190 : : static int
2191 : 39673 : compiler_lookup_arg(PyObject *dict, PyObject *name)
2192 : : {
2193 : : PyObject *v;
2194 : 39673 : v = PyDict_GetItemWithError(dict, name);
2195 [ - + ]: 39673 : if (v == NULL)
2196 : 0 : return -1;
2197 : 39673 : return PyLong_AS_LONG(v);
2198 : : }
2199 : :
2200 : : static int
2201 : 348004 : compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags,
2202 : : PyObject *qualname)
2203 : : {
2204 [ + + ]: 348004 : if (qualname == NULL)
2205 : 37358 : qualname = co->co_name;
2206 : :
2207 [ + + ]: 348004 : if (co->co_nfreevars) {
2208 : 24345 : int i = co->co_nlocals + co->co_nplaincellvars;
2209 [ + + ]: 59252 : for (; i < co->co_nlocalsplus; ++i) {
2210 : : /* Bypass com_addop_varname because it will generate
2211 : : LOAD_DEREF but LOAD_CLOSURE is needed.
2212 : : */
2213 : 34907 : PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
2214 : :
2215 : : /* Special case: If a class contains a method with a
2216 : : free variable that has the same name as a method,
2217 : : the name will be considered free *and* local in the
2218 : : class. It should be handled by the closure, as
2219 : : well as by the normal name lookup logic.
2220 : : */
2221 : 34907 : int reftype = get_ref_type(c, name);
2222 [ - + ]: 34907 : if (reftype == -1) {
2223 : 0 : return 0;
2224 : : }
2225 : : int arg;
2226 [ + + ]: 34907 : if (reftype == CELL) {
2227 : 32640 : arg = compiler_lookup_arg(c->u->u_cellvars, name);
2228 : : }
2229 : : else {
2230 : 2267 : arg = compiler_lookup_arg(c->u->u_freevars, name);
2231 : : }
2232 [ - + ]: 34907 : if (arg == -1) {
2233 : 0 : PyObject *freevars = _PyCode_GetFreevars(co);
2234 [ # # ]: 0 : if (freevars == NULL) {
2235 : 0 : PyErr_Clear();
2236 : : }
2237 : 0 : PyErr_Format(PyExc_SystemError,
2238 : : "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
2239 : : "freevars of code %S: %R",
2240 : : name,
2241 : : reftype,
2242 : 0 : c->u->u_name,
2243 : : co->co_name,
2244 : : freevars);
2245 : 0 : Py_DECREF(freevars);
2246 : 0 : return 0;
2247 : : }
2248 [ - + ]: 34907 : ADDOP_I(c, LOAD_CLOSURE, arg);
2249 : : }
2250 : 24345 : flags |= 0x08;
2251 [ - + ]: 24345 : ADDOP_I(c, BUILD_TUPLE, co->co_nfreevars);
2252 : : }
2253 [ - + ]: 348004 : ADDOP_LOAD_CONST(c, (PyObject*)co);
2254 [ - + ]: 348004 : ADDOP_I(c, MAKE_FUNCTION, flags);
2255 : 348004 : return 1;
2256 : : }
2257 : :
2258 : : static int
2259 : 295942 : compiler_decorators(struct compiler *c, asdl_expr_seq* decos)
2260 : : {
2261 : : int i;
2262 : :
2263 [ + + ]: 295942 : if (!decos)
2264 : 263695 : return 1;
2265 : :
2266 [ + - + + ]: 57988 : for (i = 0; i < asdl_seq_LEN(decos); i++) {
2267 [ - + ]: 25741 : VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
2268 : : }
2269 : 32247 : return 1;
2270 : : }
2271 : :
2272 : : static int
2273 : 295844 : compiler_apply_decorators(struct compiler *c, asdl_expr_seq* decos)
2274 : : {
2275 [ + + ]: 295844 : if (!decos)
2276 : 263597 : return 1;
2277 : :
2278 : 32247 : struct location old_loc = c->u->u_loc;
2279 [ + - + + ]: 57988 : for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
2280 : 25741 : SET_LOC(c, (expr_ty)asdl_seq_GET(decos, i));
2281 [ - + ]: 25741 : ADDOP_I(c, CALL, 0);
2282 : : }
2283 : 32247 : c->u->u_loc = old_loc;
2284 : 32247 : return 1;
2285 : : }
2286 : :
2287 : : static int
2288 : 293028 : compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs,
2289 : : asdl_expr_seq *kw_defaults)
2290 : : {
2291 : : /* Push a dict of keyword-only default values.
2292 : :
2293 : : Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed.
2294 : : */
2295 : : int i;
2296 : 293028 : PyObject *keys = NULL;
2297 : :
2298 [ + - + + ]: 309692 : for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
2299 : 16665 : arg_ty arg = asdl_seq_GET(kwonlyargs, i);
2300 : 16665 : expr_ty default_ = asdl_seq_GET(kw_defaults, i);
2301 [ + + ]: 16665 : if (default_) {
2302 : 13502 : PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
2303 [ - + ]: 13502 : if (!mangled) {
2304 : 0 : goto error;
2305 : : }
2306 [ + + ]: 13502 : if (keys == NULL) {
2307 : 4756 : keys = PyList_New(1);
2308 [ - + ]: 4756 : if (keys == NULL) {
2309 : 0 : Py_DECREF(mangled);
2310 : 0 : return 0;
2311 : : }
2312 : 4756 : PyList_SET_ITEM(keys, 0, mangled);
2313 : : }
2314 : : else {
2315 : 8746 : int res = PyList_Append(keys, mangled);
2316 : 8746 : Py_DECREF(mangled);
2317 [ - + ]: 8746 : if (res == -1) {
2318 : 0 : goto error;
2319 : : }
2320 : : }
2321 [ + + ]: 13502 : if (!compiler_visit_expr(c, default_)) {
2322 : 1 : goto error;
2323 : : }
2324 : : }
2325 : : }
2326 [ + + ]: 293027 : if (keys != NULL) {
2327 : 4755 : Py_ssize_t default_count = PyList_GET_SIZE(keys);
2328 : 4755 : PyObject *keys_tuple = PyList_AsTuple(keys);
2329 : 4755 : Py_DECREF(keys);
2330 [ - + - + ]: 4755 : ADDOP_LOAD_CONST_NEW(c, keys_tuple);
2331 [ - + ]: 4755 : ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count);
2332 : : assert(default_count > 0);
2333 : 4755 : return 1;
2334 : : }
2335 : : else {
2336 : 288272 : return -1;
2337 : : }
2338 : :
2339 : 1 : error:
2340 : 1 : Py_XDECREF(keys);
2341 : 1 : return 0;
2342 : : }
2343 : :
2344 : : static int
2345 : 3493 : compiler_visit_annexpr(struct compiler *c, expr_ty annotation)
2346 : : {
2347 [ - + - + ]: 3493 : ADDOP_LOAD_CONST_NEW(c, _PyAST_ExprAsUnicode(annotation));
2348 : 3493 : return 1;
2349 : : }
2350 : :
2351 : : static int
2352 : 723592 : compiler_visit_argannotation(struct compiler *c, identifier id,
2353 : : expr_ty annotation, Py_ssize_t *annotations_len)
2354 : : {
2355 [ + + ]: 723592 : if (!annotation) {
2356 : 640216 : return 1;
2357 : : }
2358 : :
2359 : 83376 : PyObject *mangled = _Py_Mangle(c->u->u_private, id);
2360 [ - + ]: 83376 : if (!mangled) {
2361 : 0 : return 0;
2362 : : }
2363 [ - + ]: 83376 : ADDOP_LOAD_CONST(c, mangled);
2364 : 83376 : Py_DECREF(mangled);
2365 : :
2366 [ + + ]: 83376 : if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) {
2367 [ - + ]: 2936 : VISIT(c, annexpr, annotation);
2368 : : }
2369 : : else {
2370 [ + + ]: 80440 : if (annotation->kind == Starred_kind) {
2371 : : // *args: *Ts (where Ts is a TypeVarTuple).
2372 : : // Do [annotation_value] = [*Ts].
2373 : : // (Note that in theory we could end up here even for an argument
2374 : : // other than *args, but in practice the grammar doesn't allow it.)
2375 [ - + ]: 10 : VISIT(c, expr, annotation->v.Starred.value);
2376 [ - + ]: 10 : ADDOP_I(c, UNPACK_SEQUENCE, (Py_ssize_t) 1);
2377 : : }
2378 : : else {
2379 [ + + ]: 80430 : VISIT(c, expr, annotation);
2380 : : }
2381 : : }
2382 : 83371 : *annotations_len += 2;
2383 : 83371 : return 1;
2384 : : }
2385 : :
2386 : : static int
2387 : 775682 : compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args,
2388 : : Py_ssize_t *annotations_len)
2389 : : {
2390 : : int i;
2391 [ + - + + ]: 1239396 : for (i = 0; i < asdl_seq_LEN(args); i++) {
2392 : 463717 : arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
2393 [ + + ]: 463717 : if (!compiler_visit_argannotation(
2394 : : c,
2395 : : arg->arg,
2396 : : arg->annotation,
2397 : : annotations_len))
2398 : 3 : return 0;
2399 : : }
2400 : 775679 : return 1;
2401 : : }
2402 : :
2403 : : static int
2404 : 258563 : compiler_visit_annotations(struct compiler *c, arguments_ty args,
2405 : : expr_ty returns)
2406 : : {
2407 : : /* Push arg annotation names and values.
2408 : : The expressions are evaluated out-of-order wrt the source code.
2409 : :
2410 : : Return 0 on error, -1 if no annotations pushed, 1 if a annotations is pushed.
2411 : : */
2412 : 258563 : Py_ssize_t annotations_len = 0;
2413 : :
2414 [ + + ]: 258563 : if (!compiler_visit_argannotations(c, args->args, &annotations_len))
2415 : 3 : return 0;
2416 [ - + ]: 258560 : if (!compiler_visit_argannotations(c, args->posonlyargs, &annotations_len))
2417 : 0 : return 0;
2418 [ + + + + : 259337 : if (args->vararg && args->vararg->annotation &&
+ + ]
2419 : 777 : !compiler_visit_argannotation(c, args->vararg->arg,
2420 : 777 : args->vararg->annotation, &annotations_len))
2421 : 1 : return 0;
2422 [ - + ]: 258559 : if (!compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len))
2423 : 0 : return 0;
2424 [ + + + + : 259099 : if (args->kwarg && args->kwarg->annotation &&
+ + ]
2425 : 540 : !compiler_visit_argannotation(c, args->kwarg->arg,
2426 : 540 : args->kwarg->annotation, &annotations_len))
2427 : 1 : return 0;
2428 : :
2429 [ - + ]: 258558 : if (!compiler_visit_argannotation(c, &_Py_ID(return), returns,
2430 : : &annotations_len)) {
2431 : 0 : return 0;
2432 : : }
2433 : :
2434 [ + + ]: 258558 : if (annotations_len) {
2435 [ - + ]: 34056 : ADDOP_I(c, BUILD_TUPLE, annotations_len);
2436 : 34056 : return 1;
2437 : : }
2438 : :
2439 : 224502 : return -1;
2440 : : }
2441 : :
2442 : : static int
2443 : 34874 : compiler_visit_defaults(struct compiler *c, arguments_ty args)
2444 : : {
2445 [ + + + - : 100141 : VISIT_SEQ(c, expr, args->defaults);
+ + ]
2446 [ + - - + ]: 34871 : ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
2447 : 34871 : return 1;
2448 : : }
2449 : :
2450 : : static Py_ssize_t
2451 : 293031 : compiler_default_arguments(struct compiler *c, arguments_ty args)
2452 : : {
2453 : 293031 : Py_ssize_t funcflags = 0;
2454 [ + - + - : 293031 : if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
+ + ]
2455 [ + + ]: 34874 : if (!compiler_visit_defaults(c, args))
2456 : 3 : return -1;
2457 : 34871 : funcflags |= 0x01;
2458 : : }
2459 [ + - ]: 293028 : if (args->kwonlyargs) {
2460 : 293028 : int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
2461 : : args->kw_defaults);
2462 [ + + ]: 293028 : if (res == 0) {
2463 : 1 : return -1;
2464 : : }
2465 [ + + ]: 293027 : else if (res > 0) {
2466 : 4755 : funcflags |= 0x02;
2467 : : }
2468 : : }
2469 : 293027 : return funcflags;
2470 : : }
2471 : :
2472 : : static int
2473 : 6272209 : forbidden_name(struct compiler *c, identifier name, expr_context_ty ctx)
2474 : : {
2475 : :
2476 [ + + + + ]: 6272209 : if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
2477 : 15 : compiler_error(c, "cannot assign to __debug__");
2478 : 15 : return 1;
2479 : : }
2480 [ + + + + ]: 6272194 : if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
2481 : 1 : compiler_error(c, "cannot delete __debug__");
2482 : 1 : return 1;
2483 : : }
2484 : 6272193 : return 0;
2485 : : }
2486 : :
2487 : : static int
2488 : 1215731 : compiler_check_debug_one_arg(struct compiler *c, arg_ty arg)
2489 : : {
2490 [ + + ]: 1215731 : if (arg != NULL) {
2491 [ + + ]: 677277 : if (forbidden_name(c, arg->arg, Store))
2492 : 5 : return 0;
2493 : : }
2494 : 1215726 : return 1;
2495 : : }
2496 : :
2497 : : static int
2498 : 879105 : compiler_check_debug_args_seq(struct compiler *c, asdl_arg_seq *args)
2499 : : {
2500 [ + - ]: 879105 : if (args != NULL) {
2501 [ + - + + ]: 1508767 : for (Py_ssize_t i = 0, n = asdl_seq_LEN(args); i < n; i++) {
2502 [ + + ]: 629666 : if (!compiler_check_debug_one_arg(c, asdl_seq_GET(args, i)))
2503 : 4 : return 0;
2504 : : }
2505 : : }
2506 : 879101 : return 1;
2507 : : }
2508 : :
2509 : : static int
2510 : 293036 : compiler_check_debug_args(struct compiler *c, arguments_ty args)
2511 : : {
2512 [ - + ]: 293036 : if (!compiler_check_debug_args_seq(c, args->posonlyargs))
2513 : 0 : return 0;
2514 [ + + ]: 293036 : if (!compiler_check_debug_args_seq(c, args->args))
2515 : 3 : return 0;
2516 [ - + ]: 293033 : if (!compiler_check_debug_one_arg(c, args->vararg))
2517 : 0 : return 0;
2518 [ + + ]: 293033 : if (!compiler_check_debug_args_seq(c, args->kwonlyargs))
2519 : 1 : return 0;
2520 [ + + ]: 293032 : if (!compiler_check_debug_one_arg(c, args->kwarg))
2521 : 1 : return 0;
2522 : 293031 : return 1;
2523 : : }
2524 : :
2525 : : static int
2526 : 258569 : compiler_function(struct compiler *c, stmt_ty s, int is_async)
2527 : : {
2528 : : PyCodeObject *co;
2529 : 258569 : PyObject *qualname, *docstring = NULL;
2530 : : arguments_ty args;
2531 : : expr_ty returns;
2532 : : identifier name;
2533 : : asdl_expr_seq* decos;
2534 : : asdl_stmt_seq *body;
2535 : : Py_ssize_t i, funcflags;
2536 : : int annotations;
2537 : : int scope_type;
2538 : : int firstlineno;
2539 : :
2540 [ + + ]: 258569 : if (is_async) {
2541 : : assert(s->kind == AsyncFunctionDef_kind);
2542 : :
2543 : 2290 : args = s->v.AsyncFunctionDef.args;
2544 : 2290 : returns = s->v.AsyncFunctionDef.returns;
2545 : 2290 : decos = s->v.AsyncFunctionDef.decorator_list;
2546 : 2290 : name = s->v.AsyncFunctionDef.name;
2547 : 2290 : body = s->v.AsyncFunctionDef.body;
2548 : :
2549 : 2290 : scope_type = COMPILER_SCOPE_ASYNC_FUNCTION;
2550 : : } else {
2551 : : assert(s->kind == FunctionDef_kind);
2552 : :
2553 : 256279 : args = s->v.FunctionDef.args;
2554 : 256279 : returns = s->v.FunctionDef.returns;
2555 : 256279 : decos = s->v.FunctionDef.decorator_list;
2556 : 256279 : name = s->v.FunctionDef.name;
2557 : 256279 : body = s->v.FunctionDef.body;
2558 : :
2559 : 256279 : scope_type = COMPILER_SCOPE_FUNCTION;
2560 : : }
2561 : :
2562 [ + + ]: 258569 : if (!compiler_check_debug_args(c, args))
2563 : 2 : return 0;
2564 : :
2565 [ - + ]: 258567 : if (!compiler_decorators(c, decos))
2566 : 0 : return 0;
2567 : :
2568 : 258567 : firstlineno = s->lineno;
2569 [ + + + + ]: 258567 : if (asdl_seq_LEN(decos)) {
2570 : 23133 : firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
2571 : : }
2572 : :
2573 : 258567 : funcflags = compiler_default_arguments(c, args);
2574 [ + + ]: 258567 : if (funcflags == -1) {
2575 : 4 : return 0;
2576 : : }
2577 : :
2578 : 258563 : annotations = compiler_visit_annotations(c, args, returns);
2579 [ + + ]: 258563 : if (annotations == 0) {
2580 : 5 : return 0;
2581 : : }
2582 [ + + ]: 258558 : else if (annotations > 0) {
2583 : 34056 : funcflags |= 0x04;
2584 : : }
2585 : :
2586 [ - + ]: 258558 : if (!compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)) {
2587 : 0 : return 0;
2588 : : }
2589 : :
2590 : : /* if not -OO mode, add docstring */
2591 [ + + ]: 258558 : if (c->c_optimize < 2) {
2592 : 251840 : docstring = _PyAST_GetDocString(body);
2593 : : }
2594 [ + + - + ]: 258558 : if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) {
2595 : 0 : compiler_exit_scope(c);
2596 : 0 : return 0;
2597 : : }
2598 : :
2599 [ + - ]: 258558 : c->u->u_argcount = asdl_seq_LEN(args->args);
2600 [ + - ]: 258558 : c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
2601 [ + - ]: 258558 : c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
2602 [ + - + + ]: 1071245 : for (i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) {
2603 [ + + ]: 812758 : VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
2604 : : }
2605 : 258487 : co = assemble(c, 1);
2606 : 258487 : qualname = c->u->u_qualname;
2607 : 258487 : Py_INCREF(qualname);
2608 : 258487 : compiler_exit_scope(c);
2609 [ - + ]: 258487 : if (co == NULL) {
2610 : 0 : Py_XDECREF(qualname);
2611 : 0 : Py_XDECREF(co);
2612 : 0 : return 0;
2613 : : }
2614 : :
2615 [ - + ]: 258487 : if (!compiler_make_closure(c, co, funcflags, qualname)) {
2616 : 0 : Py_DECREF(qualname);
2617 : 0 : Py_DECREF(co);
2618 : 0 : return 0;
2619 : : }
2620 : 258487 : Py_DECREF(qualname);
2621 : 258487 : Py_DECREF(co);
2622 : :
2623 [ - + ]: 258487 : if (!compiler_apply_decorators(c, decos))
2624 : 0 : return 0;
2625 : 258487 : return compiler_nameop(c, name, Store);
2626 : : }
2627 : :
2628 : : static int
2629 : 37375 : compiler_class(struct compiler *c, stmt_ty s)
2630 : : {
2631 : : PyCodeObject *co;
2632 : : int i, firstlineno;
2633 : 37375 : asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
2634 : :
2635 [ - + ]: 37375 : if (!compiler_decorators(c, decos))
2636 : 0 : return 0;
2637 : :
2638 : 37375 : firstlineno = s->lineno;
2639 [ + + + + ]: 37375 : if (asdl_seq_LEN(decos)) {
2640 : 1501 : firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
2641 : : }
2642 : :
2643 : : /* ultimately generate code for:
2644 : : <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>)
2645 : : where:
2646 : : <func> is a zero arg function/closure created from the class body.
2647 : : It mutates its locals to build the class namespace.
2648 : : <name> is the class name
2649 : : <bases> is the positional arguments and *varargs argument
2650 : : <keywords> is the keyword arguments and **kwds argument
2651 : : This borrows from compiler_call.
2652 : : */
2653 : :
2654 : : /* 1. compile the class body into a code object */
2655 [ - + ]: 37375 : if (!compiler_enter_scope(c, s->v.ClassDef.name,
2656 : : COMPILER_SCOPE_CLASS, (void *)s, firstlineno)) {
2657 : 0 : return 0;
2658 : : }
2659 : : /* this block represents what we do in the new scope */
2660 : : {
2661 : : /* use the class name for name mangling */
2662 : 37375 : Py_INCREF(s->v.ClassDef.name);
2663 : 37375 : Py_XSETREF(c->u->u_private, s->v.ClassDef.name);
2664 : : /* load (global) __name__ ... */
2665 [ - + ]: 37375 : if (!compiler_nameop(c, &_Py_ID(__name__), Load)) {
2666 : 0 : compiler_exit_scope(c);
2667 : 0 : return 0;
2668 : : }
2669 : : /* ... and store it as __module__ */
2670 [ - + ]: 37375 : if (!compiler_nameop(c, &_Py_ID(__module__), Store)) {
2671 : 0 : compiler_exit_scope(c);
2672 : 0 : return 0;
2673 : : }
2674 : : assert(c->u->u_qualname);
2675 [ - + ]: 37375 : ADDOP_LOAD_CONST(c, c->u->u_qualname);
2676 [ - + ]: 37375 : if (!compiler_nameop(c, &_Py_ID(__qualname__), Store)) {
2677 : 0 : compiler_exit_scope(c);
2678 : 0 : return 0;
2679 : : }
2680 : : /* compile the body proper */
2681 [ + + ]: 37375 : if (!compiler_body(c, s->v.ClassDef.body)) {
2682 : 17 : compiler_exit_scope(c);
2683 : 17 : return 0;
2684 : : }
2685 : : /* The following code is artificial */
2686 : 37358 : UNSET_LOC(c);
2687 : : /* Return __classcell__ if it is referenced, otherwise return None */
2688 [ + + ]: 37358 : if (c->u->u_ste->ste_needs_class_closure) {
2689 : : /* Store __classcell__ into class namespace & return it */
2690 : 4766 : i = compiler_lookup_arg(c->u->u_cellvars, &_Py_ID(__class__));
2691 [ - + ]: 4766 : if (i < 0) {
2692 : 0 : compiler_exit_scope(c);
2693 : 0 : return 0;
2694 : : }
2695 : : assert(i == 0);
2696 : :
2697 [ - + ]: 4766 : ADDOP_I(c, LOAD_CLOSURE, i);
2698 [ - + ]: 4766 : ADDOP_I(c, COPY, 1);
2699 [ - + ]: 4766 : if (!compiler_nameop(c, &_Py_ID(__classcell__), Store)) {
2700 : 0 : compiler_exit_scope(c);
2701 : 0 : return 0;
2702 : : }
2703 : : }
2704 : : else {
2705 : : /* No methods referenced __class__, so just return None */
2706 : : assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0);
2707 [ - + ]: 32592 : ADDOP_LOAD_CONST(c, Py_None);
2708 : : }
2709 [ - + ]: 37358 : ADDOP_IN_SCOPE(c, RETURN_VALUE);
2710 : : /* create the code object */
2711 : 37358 : co = assemble(c, 1);
2712 : : }
2713 : : /* leave the new scope */
2714 : 37358 : compiler_exit_scope(c);
2715 [ - + ]: 37358 : if (co == NULL)
2716 : 0 : return 0;
2717 : :
2718 : : /* 2. load the 'build_class' function */
2719 [ - + ]: 37358 : ADDOP(c, PUSH_NULL);
2720 [ - + ]: 37358 : ADDOP(c, LOAD_BUILD_CLASS);
2721 : :
2722 : : /* 3. load a function (or closure) made from the code object */
2723 [ - + ]: 37358 : if (!compiler_make_closure(c, co, 0, NULL)) {
2724 : 0 : Py_DECREF(co);
2725 : 0 : return 0;
2726 : : }
2727 : 37358 : Py_DECREF(co);
2728 : :
2729 : : /* 4. load class name */
2730 [ - + ]: 37358 : ADDOP_LOAD_CONST(c, s->v.ClassDef.name);
2731 : :
2732 : : /* 5. generate the rest of the code for the call */
2733 [ + + ]: 37358 : if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords))
2734 : 1 : return 0;
2735 : : /* 6. apply decorators */
2736 [ - + ]: 37357 : if (!compiler_apply_decorators(c, decos))
2737 : 0 : return 0;
2738 : :
2739 : : /* 7. store into <name> */
2740 [ - + ]: 37357 : if (!compiler_nameop(c, s->v.ClassDef.name, Store))
2741 : 0 : return 0;
2742 : 37357 : return 1;
2743 : : }
2744 : :
2745 : : /* Return 0 if the expression is a constant value except named singletons.
2746 : : Return 1 otherwise. */
2747 : : static int
2748 : 426280 : check_is_arg(expr_ty e)
2749 : : {
2750 [ + + ]: 426280 : if (e->kind != Constant_kind) {
2751 : 291192 : return 1;
2752 : : }
2753 : 135088 : PyObject *value = e->v.Constant.value;
2754 : : return (value == Py_None
2755 [ + + ]: 87241 : || value == Py_False
2756 [ + + ]: 86947 : || value == Py_True
2757 [ + + + + ]: 222329 : || value == Py_Ellipsis);
2758 : : }
2759 : :
2760 : : /* Check operands of identity chacks ("is" and "is not").
2761 : : Emit a warning if any operand is a constant except named singletons.
2762 : : Return 0 on error.
2763 : : */
2764 : : static int
2765 : 211764 : check_compare(struct compiler *c, expr_ty e)
2766 : : {
2767 : : Py_ssize_t i, n;
2768 : 211764 : int left = check_is_arg(e->v.Compare.left);
2769 [ + - ]: 211764 : n = asdl_seq_LEN(e->v.Compare.ops);
2770 [ + + ]: 426259 : for (i = 0; i < n; i++) {
2771 : 214516 : cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
2772 : 214516 : int right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
2773 [ + + + + ]: 214516 : if (op == Is || op == IsNot) {
2774 [ + + + + ]: 60302 : if (!right || !left) {
2775 : 21 : const char *msg = (op == Is)
2776 : : ? "\"is\" with a literal. Did you mean \"==\"?"
2777 [ + + ]: 21 : : "\"is not\" with a literal. Did you mean \"!=\"?";
2778 : 21 : return compiler_warn(c, msg);
2779 : : }
2780 : : }
2781 : 214495 : left = right;
2782 : : }
2783 : 211743 : return 1;
2784 : : }
2785 : :
2786 : 215963 : static int compiler_addcompare(struct compiler *c, cmpop_ty op)
2787 : : {
2788 : : int cmp;
2789 [ + + + + : 215963 : switch (op) {
+ + + + +
+ - ]
2790 : 61758 : case Eq:
2791 : 61758 : cmp = Py_EQ;
2792 : 61758 : break;
2793 : 15170 : case NotEq:
2794 : 15170 : cmp = Py_NE;
2795 : 15170 : break;
2796 : 13895 : case Lt:
2797 : 13895 : cmp = Py_LT;
2798 : 13895 : break;
2799 : 7540 : case LtE:
2800 : 7540 : cmp = Py_LE;
2801 : 7540 : break;
2802 : 11857 : case Gt:
2803 : 11857 : cmp = Py_GT;
2804 : 11857 : break;
2805 : 7282 : case GtE:
2806 : 7282 : cmp = Py_GE;
2807 : 7282 : break;
2808 : 34598 : case Is:
2809 [ - + ]: 34598 : ADDOP_I(c, IS_OP, 0);
2810 : 34598 : return 1;
2811 : 25732 : case IsNot:
2812 [ - + ]: 25732 : ADDOP_I(c, IS_OP, 1);
2813 : 25732 : return 1;
2814 : 27796 : case In:
2815 [ - + ]: 27796 : ADDOP_I(c, CONTAINS_OP, 0);
2816 : 27796 : return 1;
2817 : 10335 : case NotIn:
2818 [ - + ]: 10335 : ADDOP_I(c, CONTAINS_OP, 1);
2819 : 10335 : return 1;
2820 : 0 : default:
2821 : 0 : Py_UNREACHABLE();
2822 : : }
2823 [ - + ]: 117502 : ADDOP_I(c, COMPARE_OP, cmp);
2824 : 117502 : return 1;
2825 : : }
2826 : :
2827 : :
2828 : :
2829 : : static int
2830 : 663254 : compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
2831 : : {
2832 [ + + + + : 663254 : switch (e->kind) {
+ ]
2833 : 47805 : case UnaryOp_kind:
2834 [ + - ]: 47805 : if (e->v.UnaryOp.op == Not)
2835 : 47805 : return compiler_jump_if(c, e->v.UnaryOp.operand, next, !cond);
2836 : : /* fallback to general implementation */
2837 : 0 : break;
2838 : 41709 : case BoolOp_kind: {
2839 : 41709 : asdl_expr_seq *s = e->v.BoolOp.values;
2840 [ + - ]: 41709 : Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
2841 : : assert(n >= 0);
2842 : 41709 : int cond2 = e->v.BoolOp.op == Or;
2843 : 41709 : basicblock *next2 = next;
2844 [ + + ]: 41709 : if (!cond2 != !cond) {
2845 : 13939 : next2 = compiler_new_block(c);
2846 [ - + ]: 13939 : if (next2 == NULL)
2847 : 0 : return 0;
2848 : : }
2849 [ + + ]: 89249 : for (i = 0; i < n; ++i) {
2850 [ - + ]: 47540 : if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, i), next2, cond2))
2851 : 0 : return 0;
2852 : : }
2853 [ - + ]: 41709 : if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, n), next, cond))
2854 : 0 : return 0;
2855 [ + + ]: 41709 : if (next2 != next)
2856 : 13939 : compiler_use_next_block(c, next2);
2857 : 41709 : return 1;
2858 : : }
2859 : 30 : case IfExp_kind: {
2860 : : basicblock *end, *next2;
2861 : 30 : end = compiler_new_block(c);
2862 [ - + ]: 30 : if (end == NULL)
2863 : 0 : return 0;
2864 : 30 : next2 = compiler_new_block(c);
2865 [ - + ]: 30 : if (next2 == NULL)
2866 : 0 : return 0;
2867 [ - + ]: 30 : if (!compiler_jump_if(c, e->v.IfExp.test, next2, 0))
2868 : 0 : return 0;
2869 [ - + ]: 30 : if (!compiler_jump_if(c, e->v.IfExp.body, next, cond))
2870 : 0 : return 0;
2871 [ - + ]: 30 : ADDOP_JUMP_NOLINE(c, JUMP, end);
2872 : 30 : compiler_use_next_block(c, next2);
2873 [ - + ]: 30 : if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond))
2874 : 0 : return 0;
2875 : 30 : compiler_use_next_block(c, end);
2876 : 30 : return 1;
2877 : : }
2878 : 188501 : case Compare_kind: {
2879 [ + - ]: 188501 : Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1;
2880 [ + + ]: 188501 : if (n > 0) {
2881 [ - + ]: 2251 : if (!check_compare(c, e)) {
2882 : 0 : return 0;
2883 : : }
2884 : 2251 : basicblock *cleanup = compiler_new_block(c);
2885 [ - + ]: 2251 : if (cleanup == NULL)
2886 : 0 : return 0;
2887 [ - + ]: 2251 : VISIT(c, expr, e->v.Compare.left);
2888 [ + + ]: 4598 : for (i = 0; i < n; i++) {
2889 [ - + ]: 2347 : VISIT(c, expr,
2890 : : (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
2891 [ - + ]: 2347 : ADDOP_I(c, SWAP, 2);
2892 [ - + ]: 2347 : ADDOP_I(c, COPY, 2);
2893 [ - + ]: 2347 : ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i));
2894 [ - + ]: 2347 : ADDOP_JUMP(c, POP_JUMP_IF_FALSE, cleanup);
2895 : : }
2896 [ - + ]: 2251 : VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
2897 [ - + ]: 2251 : ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n));
2898 [ + + - + ]: 2251 : ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2899 : 2251 : basicblock *end = compiler_new_block(c);
2900 [ - + ]: 2251 : if (end == NULL)
2901 : 0 : return 0;
2902 [ - + ]: 2251 : ADDOP_JUMP_NOLINE(c, JUMP, end);
2903 : 2251 : compiler_use_next_block(c, cleanup);
2904 [ - + ]: 2251 : ADDOP(c, POP_TOP);
2905 [ + + ]: 2251 : if (!cond) {
2906 [ - + ]: 1303 : ADDOP_JUMP_NOLINE(c, JUMP, next);
2907 : : }
2908 : 2251 : compiler_use_next_block(c, end);
2909 : 2251 : return 1;
2910 : : }
2911 : : /* fallback to general implementation */
2912 : 186250 : break;
2913 : : }
2914 : 385209 : default:
2915 : : /* fallback to general implementation */
2916 : 385209 : break;
2917 : : }
2918 : :
2919 : : /* general implementation */
2920 [ - + ]: 571459 : VISIT(c, expr, e);
2921 [ + + - + ]: 571459 : ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2922 : 571459 : return 1;
2923 : : }
2924 : :
2925 : : static int
2926 : 9745 : compiler_ifexp(struct compiler *c, expr_ty e)
2927 : : {
2928 : : basicblock *end, *next;
2929 : :
2930 : : assert(e->kind == IfExp_kind);
2931 : 9745 : end = compiler_new_block(c);
2932 [ - + ]: 9745 : if (end == NULL)
2933 : 0 : return 0;
2934 : 9745 : next = compiler_new_block(c);
2935 [ - + ]: 9745 : if (next == NULL)
2936 : 0 : return 0;
2937 [ - + ]: 9745 : if (!compiler_jump_if(c, e->v.IfExp.test, next, 0))
2938 : 0 : return 0;
2939 [ - + ]: 9745 : VISIT(c, expr, e->v.IfExp.body);
2940 [ - + ]: 9745 : ADDOP_JUMP_NOLINE(c, JUMP, end);
2941 : 9745 : compiler_use_next_block(c, next);
2942 [ - + ]: 9745 : VISIT(c, expr, e->v.IfExp.orelse);
2943 : 9745 : compiler_use_next_block(c, end);
2944 : 9745 : return 1;
2945 : : }
2946 : :
2947 : : static int
2948 : 34467 : compiler_lambda(struct compiler *c, expr_ty e)
2949 : : {
2950 : : PyCodeObject *co;
2951 : : PyObject *qualname;
2952 : : Py_ssize_t funcflags;
2953 : 34467 : arguments_ty args = e->v.Lambda.args;
2954 : : assert(e->kind == Lambda_kind);
2955 : :
2956 [ + + ]: 34467 : if (!compiler_check_debug_args(c, args))
2957 : 3 : return 0;
2958 : :
2959 : 34464 : funcflags = compiler_default_arguments(c, args);
2960 [ - + ]: 34464 : if (funcflags == -1) {
2961 : 0 : return 0;
2962 : : }
2963 : :
2964 : : _Py_DECLARE_STR(anon_lambda, "<lambda>");
2965 [ - + ]: 34464 : if (!compiler_enter_scope(c, &_Py_STR(anon_lambda), COMPILER_SCOPE_LAMBDA,
2966 : : (void *)e, e->lineno)) {
2967 : 0 : return 0;
2968 : : }
2969 : : /* Make None the first constant, so the lambda can't have a
2970 : : docstring. */
2971 [ - + ]: 34464 : if (compiler_add_const(c, Py_None) < 0)
2972 : 0 : return 0;
2973 : :
2974 [ + - ]: 34464 : c->u->u_argcount = asdl_seq_LEN(args->args);
2975 [ + - ]: 34464 : c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
2976 [ + - ]: 34464 : c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
2977 [ - + ]: 34464 : VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
2978 [ + + ]: 34464 : if (c->u->u_ste->ste_generator) {
2979 : 25 : co = assemble(c, 0);
2980 : : }
2981 : : else {
2982 [ - + ]: 34439 : ADDOP_IN_SCOPE(c, RETURN_VALUE);
2983 : 34439 : co = assemble(c, 1);
2984 : : }
2985 : 34464 : qualname = c->u->u_qualname;
2986 : 34464 : Py_INCREF(qualname);
2987 : 34464 : compiler_exit_scope(c);
2988 [ - + ]: 34464 : if (co == NULL) {
2989 : 0 : Py_DECREF(qualname);
2990 : 0 : return 0;
2991 : : }
2992 : :
2993 [ - + ]: 34464 : if (!compiler_make_closure(c, co, funcflags, qualname)) {
2994 : 0 : Py_DECREF(qualname);
2995 : 0 : Py_DECREF(co);
2996 : 0 : return 0;
2997 : : }
2998 : 34464 : Py_DECREF(qualname);
2999 : 34464 : Py_DECREF(co);
3000 : :
3001 : 34464 : return 1;
3002 : : }
3003 : :
3004 : : static int
3005 : 484350 : compiler_if(struct compiler *c, stmt_ty s)
3006 : : {
3007 : : basicblock *end, *next;
3008 : : assert(s->kind == If_kind);
3009 : 484350 : end = compiler_new_block(c);
3010 [ - + ]: 484350 : if (end == NULL) {
3011 : 0 : return 0;
3012 : : }
3013 [ + + + + ]: 484350 : if (asdl_seq_LEN(s->v.If.orelse)) {
3014 : 83553 : next = compiler_new_block(c);
3015 [ - + ]: 83553 : if (next == NULL) {
3016 : 0 : return 0;
3017 : : }
3018 : : }
3019 : : else {
3020 : 400797 : next = end;
3021 : : }
3022 [ - + ]: 484350 : if (!compiler_jump_if(c, s->v.If.test, next, 0)) {
3023 : 0 : return 0;
3024 : : }
3025 [ + + + - : 1107873 : VISIT_SEQ(c, stmt, s->v.If.body);
+ + ]
3026 [ + + + + ]: 484331 : if (asdl_seq_LEN(s->v.If.orelse)) {
3027 [ - + ]: 83548 : ADDOP_JUMP_NOLINE(c, JUMP, end);
3028 : 83548 : compiler_use_next_block(c, next);
3029 [ + + + - : 191990 : VISIT_SEQ(c, stmt, s->v.If.orelse);
+ + ]
3030 : : }
3031 : 484323 : compiler_use_next_block(c, end);
3032 : 484323 : return 1;
3033 : : }
3034 : :
3035 : : static int
3036 : 46021 : compiler_for(struct compiler *c, stmt_ty s)
3037 : : {
3038 : : basicblock *start, *body, *cleanup, *end;
3039 : :
3040 : 46021 : start = compiler_new_block(c);
3041 : 46021 : body = compiler_new_block(c);
3042 : 46021 : cleanup = compiler_new_block(c);
3043 : 46021 : end = compiler_new_block(c);
3044 [ + - + - : 46021 : if (start == NULL || body == NULL || end == NULL || cleanup == NULL) {
+ - - + ]
3045 : 0 : return 0;
3046 : : }
3047 [ - + ]: 46021 : if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) {
3048 : 0 : return 0;
3049 : : }
3050 [ - + ]: 46021 : VISIT(c, expr, s->v.For.iter);
3051 [ - + ]: 46021 : ADDOP(c, GET_ITER);
3052 : 46021 : compiler_use_next_block(c, start);
3053 [ - + ]: 46021 : ADDOP_JUMP(c, FOR_ITER, cleanup);
3054 : 46021 : compiler_use_next_block(c, body);
3055 [ - + ]: 46021 : VISIT(c, expr, s->v.For.target);
3056 [ + + + - : 140961 : VISIT_SEQ(c, stmt, s->v.For.body);
+ + ]
3057 : : /* Mark jump as artificial */
3058 : 46016 : UNSET_LOC(c);
3059 [ - + ]: 46016 : ADDOP_JUMP(c, JUMP, start);
3060 : 46016 : compiler_use_next_block(c, cleanup);
3061 : :
3062 : 46016 : compiler_pop_fblock(c, FOR_LOOP, start);
3063 : :
3064 [ - + + + : 47623 : VISIT_SEQ(c, stmt, s->v.For.orelse);
+ + ]
3065 : 46016 : compiler_use_next_block(c, end);
3066 : 46016 : return 1;
3067 : : }
3068 : :
3069 : :
3070 : : static int
3071 : 81 : compiler_async_for(struct compiler *c, stmt_ty s)
3072 : : {
3073 : : basicblock *start, *except, *end;
3074 [ + + + + ]: 81 : if (IS_TOP_LEVEL_AWAIT(c)){
3075 : 2 : c->u->u_ste->ste_coroutine = 1;
3076 [ + + ]: 79 : } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) {
3077 : 8 : return compiler_error(c, "'async for' outside async function");
3078 : : }
3079 : :
3080 : 73 : start = compiler_new_block(c);
3081 : 73 : except = compiler_new_block(c);
3082 : 73 : end = compiler_new_block(c);
3083 : :
3084 [ + - + - : 73 : if (start == NULL || except == NULL || end == NULL) {
- + ]
3085 : 0 : return 0;
3086 : : }
3087 [ - + ]: 73 : VISIT(c, expr, s->v.AsyncFor.iter);
3088 [ - + ]: 73 : ADDOP(c, GET_AITER);
3089 : :
3090 : 73 : compiler_use_next_block(c, start);
3091 [ - + ]: 73 : if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) {
3092 : 0 : return 0;
3093 : : }
3094 : : /* SETUP_FINALLY to guard the __anext__ call */
3095 [ - + ]: 73 : ADDOP_JUMP(c, SETUP_FINALLY, except);
3096 [ - + ]: 73 : ADDOP(c, GET_ANEXT);
3097 [ - + ]: 73 : ADDOP_LOAD_CONST(c, Py_None);
3098 [ - + ]: 73 : ADD_YIELD_FROM(c, 1);
3099 [ - + ]: 73 : ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */
3100 : :
3101 : : /* Success block for __anext__ */
3102 [ - + ]: 73 : VISIT(c, expr, s->v.AsyncFor.target);
3103 [ - + + - : 151 : VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
+ + ]
3104 : : /* Mark jump as artificial */
3105 : 73 : UNSET_LOC(c);
3106 [ - + ]: 73 : ADDOP_JUMP(c, JUMP, start);
3107 : :
3108 : 73 : compiler_pop_fblock(c, FOR_LOOP, start);
3109 : :
3110 : : /* Except block for __anext__ */
3111 : 73 : compiler_use_next_block(c, except);
3112 : :
3113 : : /* Use same line number as the iterator,
3114 : : * as the END_ASYNC_FOR succeeds the `for`, not the body. */
3115 : 73 : SET_LOC(c, s->v.AsyncFor.iter);
3116 [ - + ]: 73 : ADDOP(c, END_ASYNC_FOR);
3117 : :
3118 : : /* `else` block */
3119 [ - + + + : 90 : VISIT_SEQ(c, stmt, s->v.For.orelse);
+ + ]
3120 : :
3121 : 73 : compiler_use_next_block(c, end);
3122 : :
3123 : 73 : return 1;
3124 : : }
3125 : :
3126 : : static int
3127 : 9870 : compiler_while(struct compiler *c, stmt_ty s)
3128 : : {
3129 : 9870 : basicblock *loop, *body, *end, *anchor = NULL;
3130 : 9870 : loop = compiler_new_block(c);
3131 : 9870 : body = compiler_new_block(c);
3132 : 9870 : anchor = compiler_new_block(c);
3133 : 9870 : end = compiler_new_block(c);
3134 [ + - + - : 9870 : if (loop == NULL || body == NULL || anchor == NULL || end == NULL) {
+ - - + ]
3135 : 0 : return 0;
3136 : : }
3137 : 9870 : compiler_use_next_block(c, loop);
3138 [ + + ]: 9870 : if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) {
3139 : 1 : return 0;
3140 : : }
3141 [ - + ]: 9869 : if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) {
3142 : 0 : return 0;
3143 : : }
3144 : :
3145 : 9869 : compiler_use_next_block(c, body);
3146 [ + + + - : 42074 : VISIT_SEQ(c, stmt, s->v.While.body);
+ + ]
3147 : 9842 : SET_LOC(c, s);
3148 [ - + ]: 9842 : if (!compiler_jump_if(c, s->v.While.test, body, 1)) {
3149 : 0 : return 0;
3150 : : }
3151 : :
3152 : 9842 : compiler_pop_fblock(c, WHILE_LOOP, loop);
3153 : :
3154 : 9842 : compiler_use_next_block(c, anchor);
3155 [ + + ]: 9842 : if (s->v.While.orelse) {
3156 [ - + + - : 816 : VISIT_SEQ(c, stmt, s->v.While.orelse);
+ + ]
3157 : : }
3158 : 9842 : compiler_use_next_block(c, end);
3159 : :
3160 : 9842 : return 1;
3161 : : }
3162 : :
3163 : : static int
3164 : 210386 : compiler_return(struct compiler *c, stmt_ty s)
3165 : : {
3166 [ + + ]: 412105 : int preserve_tos = ((s->v.Return.value != NULL) &&
3167 [ + + ]: 201719 : (s->v.Return.value->kind != Constant_kind));
3168 [ + + ]: 210386 : if (c->u->u_ste->ste_type != FunctionBlock)
3169 : 15 : return compiler_error(c, "'return' outside function");
3170 [ + + ]: 210371 : if (s->v.Return.value != NULL &&
3171 [ + + + + ]: 201715 : c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator)
3172 : : {
3173 : 3 : return compiler_error(
3174 : : c, "'return' with value in async generator");
3175 : : }
3176 [ + + ]: 210368 : if (preserve_tos) {
3177 [ - + ]: 173843 : VISIT(c, expr, s->v.Return.value);
3178 : : } else {
3179 : : /* Emit instruction with line number for return value */
3180 [ + + ]: 36525 : if (s->v.Return.value != NULL) {
3181 : 27869 : SET_LOC(c, s->v.Return.value);
3182 [ - + ]: 27869 : ADDOP(c, NOP);
3183 : : }
3184 : : }
3185 [ + + + + ]: 210368 : if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
3186 : 9217 : SET_LOC(c, s);
3187 [ - + ]: 9217 : ADDOP(c, NOP);
3188 : : }
3189 : :
3190 [ + + ]: 210368 : if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL))
3191 : 2 : return 0;
3192 [ + + ]: 210366 : if (s->v.Return.value == NULL) {
3193 [ - + ]: 8656 : ADDOP_LOAD_CONST(c, Py_None);
3194 : : }
3195 [ + + ]: 201710 : else if (!preserve_tos) {
3196 [ - + ]: 27867 : ADDOP_LOAD_CONST(c, s->v.Return.value->v.Constant.value);
3197 : : }
3198 [ - + ]: 210366 : ADDOP(c, RETURN_VALUE);
3199 : :
3200 : 210366 : return 1;
3201 : : }
3202 : :
3203 : : static int
3204 : 8435 : compiler_break(struct compiler *c)
3205 : : {
3206 : 8435 : struct fblockinfo *loop = NULL;
3207 : : /* Emit instruction with line number */
3208 [ - + ]: 8435 : ADDOP(c, NOP);
3209 [ + + ]: 8435 : if (!compiler_unwind_fblock_stack(c, 0, &loop)) {
3210 : 3 : return 0;
3211 : : }
3212 [ + + ]: 8432 : if (loop == NULL) {
3213 : 9 : return compiler_error(c, "'break' outside loop");
3214 : : }
3215 [ - + ]: 8423 : if (!compiler_unwind_fblock(c, loop, 0)) {
3216 : 0 : return 0;
3217 : : }
3218 [ - + ]: 8423 : ADDOP_JUMP(c, JUMP, loop->fb_exit);
3219 : 8423 : return 1;
3220 : : }
3221 : :
3222 : : static int
3223 : 7497 : compiler_continue(struct compiler *c)
3224 : : {
3225 : 7497 : struct fblockinfo *loop = NULL;
3226 : : /* Emit instruction with line number */
3227 [ - + ]: 7497 : ADDOP(c, NOP);
3228 [ + + ]: 7497 : if (!compiler_unwind_fblock_stack(c, 0, &loop)) {
3229 : 3 : return 0;
3230 : : }
3231 [ + + ]: 7494 : if (loop == NULL) {
3232 : 11 : return compiler_error(c, "'continue' not properly in loop");
3233 : : }
3234 [ - + ]: 7483 : ADDOP_JUMP(c, JUMP, loop->fb_block);
3235 : 7483 : return 1;
3236 : : }
3237 : :
3238 : :
3239 : : /* Code generated for "try: <body> finally: <finalbody>" is as follows:
3240 : :
3241 : : SETUP_FINALLY L
3242 : : <code for body>
3243 : : POP_BLOCK
3244 : : <code for finalbody>
3245 : : JUMP E
3246 : : L:
3247 : : <code for finalbody>
3248 : : E:
3249 : :
3250 : : The special instructions use the block stack. Each block
3251 : : stack entry contains the instruction that created it (here
3252 : : SETUP_FINALLY), the level of the value stack at the time the
3253 : : block stack entry was created, and a label (here L).
3254 : :
3255 : : SETUP_FINALLY:
3256 : : Pushes the current value stack level and the label
3257 : : onto the block stack.
3258 : : POP_BLOCK:
3259 : : Pops en entry from the block stack.
3260 : :
3261 : : The block stack is unwound when an exception is raised:
3262 : : when a SETUP_FINALLY entry is found, the raised and the caught
3263 : : exceptions are pushed onto the value stack (and the exception
3264 : : condition is cleared), and the interpreter jumps to the label
3265 : : gotten from the block stack.
3266 : : */
3267 : :
3268 : : static int
3269 : 5903 : compiler_try_finally(struct compiler *c, stmt_ty s)
3270 : : {
3271 : : basicblock *body, *end, *exit, *cleanup;
3272 : :
3273 : 5903 : body = compiler_new_block(c);
3274 : 5903 : end = compiler_new_block(c);
3275 : 5903 : exit = compiler_new_block(c);
3276 : 5903 : cleanup = compiler_new_block(c);
3277 [ + - + - : 5903 : if (body == NULL || end == NULL || exit == NULL || cleanup == NULL) {
+ - - + ]
3278 : 0 : return 0;
3279 : : }
3280 : : /* `try` block */
3281 [ - + ]: 5903 : ADDOP_JUMP(c, SETUP_FINALLY, end);
3282 : 5903 : compiler_use_next_block(c, body);
3283 [ - + ]: 5903 : if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody))
3284 : 0 : return 0;
3285 [ + + + - : 5903 : if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
+ + ]
3286 [ - + ]: 469 : if (!compiler_try_except(c, s))
3287 : 0 : return 0;
3288 : : }
3289 : : else {
3290 [ + + + - : 16060 : VISIT_SEQ(c, stmt, s->v.Try.body);
+ + ]
3291 : : }
3292 [ - + ]: 5902 : ADDOP_NOLINE(c, POP_BLOCK);
3293 : 5902 : compiler_pop_fblock(c, FINALLY_TRY, body);
3294 [ + + + - : 13189 : VISIT_SEQ(c, stmt, s->v.Try.finalbody);
+ + ]
3295 [ - + ]: 5901 : ADDOP_JUMP_NOLINE(c, JUMP, exit);
3296 : : /* `finally` block */
3297 : 5901 : compiler_use_next_block(c, end);
3298 : :
3299 : 5901 : UNSET_LOC(c);
3300 [ - + ]: 5901 : ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
3301 [ - + ]: 5901 : ADDOP(c, PUSH_EXC_INFO);
3302 [ - + ]: 5901 : if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL))
3303 : 0 : return 0;
3304 [ - + + - : 13188 : VISIT_SEQ(c, stmt, s->v.Try.finalbody);
+ + ]
3305 : 5901 : compiler_pop_fblock(c, FINALLY_END, end);
3306 [ - + ]: 5901 : ADDOP_I(c, RERAISE, 0);
3307 : 5901 : compiler_use_next_block(c, cleanup);
3308 [ - + ]: 5901 : POP_EXCEPT_AND_RERAISE(c);
3309 : 5901 : compiler_use_next_block(c, exit);
3310 : 5901 : return 1;
3311 : : }
3312 : :
3313 : : static int
3314 : 25 : compiler_try_star_finally(struct compiler *c, stmt_ty s)
3315 : : {
3316 : 25 : basicblock *body = compiler_new_block(c);
3317 [ - + ]: 25 : if (body == NULL) {
3318 : 0 : return 0;
3319 : : }
3320 : 25 : basicblock *end = compiler_new_block(c);
3321 [ - + ]: 25 : if (!end) {
3322 : 0 : return 0;
3323 : : }
3324 : 25 : basicblock *exit = compiler_new_block(c);
3325 [ - + ]: 25 : if (!exit) {
3326 : 0 : return 0;
3327 : : }
3328 : 25 : basicblock *cleanup = compiler_new_block(c);
3329 [ - + ]: 25 : if (!cleanup) {
3330 : 0 : return 0;
3331 : : }
3332 : : /* `try` block */
3333 [ - + ]: 25 : ADDOP_JUMP(c, SETUP_FINALLY, end);
3334 : 25 : compiler_use_next_block(c, body);
3335 [ - + ]: 25 : if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.TryStar.finalbody)) {
3336 : 0 : return 0;
3337 : : }
3338 [ + - + - : 25 : if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) {
+ - ]
3339 [ + + ]: 25 : if (!compiler_try_star_except(c, s)) {
3340 : 3 : return 0;
3341 : : }
3342 : : }
3343 : : else {
3344 [ # # # # : 0 : VISIT_SEQ(c, stmt, s->v.TryStar.body);
# # ]
3345 : : }
3346 [ - + ]: 22 : ADDOP_NOLINE(c, POP_BLOCK);
3347 : 22 : compiler_pop_fblock(c, FINALLY_TRY, body);
3348 [ - + + - : 44 : VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
+ + ]
3349 [ - + ]: 22 : ADDOP_JUMP_NOLINE(c, JUMP, exit);
3350 : : /* `finally` block */
3351 : 22 : compiler_use_next_block(c, end);
3352 : :
3353 : 22 : UNSET_LOC(c);
3354 [ - + ]: 22 : ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
3355 [ - + ]: 22 : ADDOP(c, PUSH_EXC_INFO);
3356 [ - + ]: 22 : if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) {
3357 : 0 : return 0;
3358 : : }
3359 [ - + + - : 44 : VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
+ + ]
3360 : 22 : compiler_pop_fblock(c, FINALLY_END, end);
3361 [ - + ]: 22 : ADDOP_I(c, RERAISE, 0);
3362 : 22 : compiler_use_next_block(c, cleanup);
3363 [ - + ]: 22 : POP_EXCEPT_AND_RERAISE(c);
3364 : 22 : compiler_use_next_block(c, exit);
3365 : 22 : return 1;
3366 : : }
3367 : :
3368 : :
3369 : : /*
3370 : : Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
3371 : : (The contents of the value stack is shown in [], with the top
3372 : : at the right; 'tb' is trace-back info, 'val' the exception's
3373 : : associated value, and 'exc' the exception.)
3374 : :
3375 : : Value stack Label Instruction Argument
3376 : : [] SETUP_FINALLY L1
3377 : : [] <code for S>
3378 : : [] POP_BLOCK
3379 : : [] JUMP L0
3380 : :
3381 : : [exc] L1: <evaluate E1> )
3382 : : [exc, E1] CHECK_EXC_MATCH )
3383 : : [exc, bool] POP_JUMP_IF_FALSE L2 ) only if E1
3384 : : [exc] <assign to V1> (or POP if no V1)
3385 : : [] <code for S1>
3386 : : JUMP L0
3387 : :
3388 : : [exc] L2: <evaluate E2>
3389 : : .............................etc.......................
3390 : :
3391 : : [exc] Ln+1: RERAISE # re-raise exception
3392 : :
3393 : : [] L0: <next statement>
3394 : :
3395 : : Of course, parts are not generated if Vi or Ei is not present.
3396 : : */
3397 : : static int
3398 : 34263 : compiler_try_except(struct compiler *c, stmt_ty s)
3399 : : {
3400 : : basicblock *body, *except, *end, *cleanup;
3401 : : Py_ssize_t i, n;
3402 : :
3403 : 34263 : body = compiler_new_block(c);
3404 : 34263 : except = compiler_new_block(c);
3405 : 34263 : end = compiler_new_block(c);
3406 : 34263 : cleanup = compiler_new_block(c);
3407 [ + - + - : 34263 : if (body == NULL || except == NULL || end == NULL || cleanup == NULL)
+ - - + ]
3408 : 0 : return 0;
3409 [ - + ]: 34263 : ADDOP_JUMP(c, SETUP_FINALLY, except);
3410 : 34263 : compiler_use_next_block(c, body);
3411 [ + + ]: 34263 : if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL))
3412 : 1 : return 0;
3413 [ + + + - : 81981 : VISIT_SEQ(c, stmt, s->v.Try.body);
+ + ]
3414 : 34261 : compiler_pop_fblock(c, TRY_EXCEPT, body);
3415 [ - + ]: 34261 : ADDOP_NOLINE(c, POP_BLOCK);
3416 [ + + + - : 34261 : if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
+ + ]
3417 [ - + + - : 11732 : VISIT_SEQ(c, stmt, s->v.Try.orelse);
+ + ]
3418 : : }
3419 [ - + ]: 34261 : ADDOP_JUMP_NOLINE(c, JUMP, end);
3420 [ + - ]: 34261 : n = asdl_seq_LEN(s->v.Try.handlers);
3421 : 34261 : compiler_use_next_block(c, except);
3422 : :
3423 : 34261 : UNSET_LOC(c);
3424 [ - + ]: 34261 : ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
3425 [ - + ]: 34261 : ADDOP(c, PUSH_EXC_INFO);
3426 : : /* Runtime will push a block here, so we need to account for that */
3427 [ - + ]: 34261 : if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL))
3428 : 0 : return 0;
3429 [ + + ]: 70815 : for (i = 0; i < n; i++) {
3430 : 36565 : excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
3431 : : s->v.Try.handlers, i);
3432 : 36565 : SET_LOC(c, handler);
3433 [ + + + + ]: 36565 : if (!handler->v.ExceptHandler.type && i < n-1) {
3434 : 1 : return compiler_error(c, "default 'except:' must be last");
3435 : : }
3436 : 36564 : except = compiler_new_block(c);
3437 [ - + ]: 36564 : if (except == NULL)
3438 : 0 : return 0;
3439 [ + + ]: 36564 : if (handler->v.ExceptHandler.type) {
3440 [ - + ]: 34959 : VISIT(c, expr, handler->v.ExceptHandler.type);
3441 [ - + ]: 34959 : ADDOP(c, CHECK_EXC_MATCH);
3442 [ - + ]: 34959 : ADDOP_JUMP(c, POP_JUMP_IF_FALSE, except);
3443 : : }
3444 [ + + ]: 36564 : if (handler->v.ExceptHandler.name) {
3445 : : basicblock *cleanup_end, *cleanup_body;
3446 : :
3447 : 7167 : cleanup_end = compiler_new_block(c);
3448 : 7167 : cleanup_body = compiler_new_block(c);
3449 [ + - - + ]: 7167 : if (cleanup_end == NULL || cleanup_body == NULL) {
3450 : 0 : return 0;
3451 : : }
3452 : :
3453 : 7167 : compiler_nameop(c, handler->v.ExceptHandler.name, Store);
3454 : :
3455 : : /*
3456 : : try:
3457 : : # body
3458 : : except type as name:
3459 : : try:
3460 : : # body
3461 : : finally:
3462 : : name = None # in case body contains "del name"
3463 : : del name
3464 : : */
3465 : :
3466 : : /* second try: */
3467 [ - + ]: 7167 : ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end);
3468 : 7167 : compiler_use_next_block(c, cleanup_body);
3469 [ - + ]: 7167 : if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name))
3470 : 0 : return 0;
3471 : :
3472 : : /* second # body */
3473 [ + + + - : 18918 : VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
+ + ]
3474 : 7157 : compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
3475 : : /* name = None; del name; # Mark as artificial */
3476 : 7157 : UNSET_LOC(c);
3477 [ - + ]: 7157 : ADDOP(c, POP_BLOCK);
3478 [ - + ]: 7157 : ADDOP(c, POP_BLOCK);
3479 [ - + ]: 7157 : ADDOP(c, POP_EXCEPT);
3480 [ - + ]: 7157 : ADDOP_LOAD_CONST(c, Py_None);
3481 : 7157 : compiler_nameop(c, handler->v.ExceptHandler.name, Store);
3482 : 7157 : compiler_nameop(c, handler->v.ExceptHandler.name, Del);
3483 [ - + ]: 7157 : ADDOP_JUMP(c, JUMP, end);
3484 : :
3485 : : /* except: */
3486 : 7157 : compiler_use_next_block(c, cleanup_end);
3487 : :
3488 : : /* name = None; del name; # Mark as artificial */
3489 : 7157 : UNSET_LOC(c);
3490 : :
3491 [ - + ]: 7157 : ADDOP_LOAD_CONST(c, Py_None);
3492 : 7157 : compiler_nameop(c, handler->v.ExceptHandler.name, Store);
3493 : 7157 : compiler_nameop(c, handler->v.ExceptHandler.name, Del);
3494 : :
3495 [ - + ]: 7157 : ADDOP_I(c, RERAISE, 1);
3496 : : }
3497 : : else {
3498 : : basicblock *cleanup_body;
3499 : :
3500 : 29397 : cleanup_body = compiler_new_block(c);
3501 [ - + ]: 29397 : if (!cleanup_body)
3502 : 0 : return 0;
3503 : :
3504 [ - + ]: 29397 : ADDOP(c, POP_TOP); /* exc_value */
3505 : 29397 : compiler_use_next_block(c, cleanup_body);
3506 [ - + ]: 29397 : if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, NULL))
3507 : 0 : return 0;
3508 [ - + + - : 66726 : VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
+ + ]
3509 : 29397 : compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
3510 : 29397 : UNSET_LOC(c);
3511 [ - + ]: 29397 : ADDOP(c, POP_BLOCK);
3512 [ - + ]: 29397 : ADDOP(c, POP_EXCEPT);
3513 [ - + ]: 29397 : ADDOP_JUMP(c, JUMP, end);
3514 : : }
3515 : 36554 : compiler_use_next_block(c, except);
3516 : : }
3517 : : /* Mark as artificial */
3518 : 34250 : UNSET_LOC(c);
3519 : 34250 : compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL);
3520 [ - + ]: 34250 : ADDOP_I(c, RERAISE, 0);
3521 : 34250 : compiler_use_next_block(c, cleanup);
3522 [ - + ]: 34250 : POP_EXCEPT_AND_RERAISE(c);
3523 : 34250 : compiler_use_next_block(c, end);
3524 : 34250 : return 1;
3525 : : }
3526 : :
3527 : : /*
3528 : : Code generated for "try: S except* E1 as V1: S1 except* E2 as V2: S2 ...":
3529 : : (The contents of the value stack is shown in [], with the top
3530 : : at the right; 'tb' is trace-back info, 'val' the exception instance,
3531 : : and 'typ' the exception's type.)
3532 : :
3533 : : Value stack Label Instruction Argument
3534 : : [] SETUP_FINALLY L1
3535 : : [] <code for S>
3536 : : [] POP_BLOCK
3537 : : [] JUMP L0
3538 : :
3539 : : [exc] L1: COPY 1 ) save copy of the original exception
3540 : : [orig, exc] BUILD_LIST ) list for raised/reraised excs ("result")
3541 : : [orig, exc, res] SWAP 2
3542 : :
3543 : : [orig, res, exc] <evaluate E1>
3544 : : [orig, res, exc, E1] CHECK_EG_MATCH
3545 : : [orig, red, rest/exc, match?] COPY 1
3546 : : [orig, red, rest/exc, match?, match?] POP_JUMP_IF_NOT_NONE H1
3547 : : [orig, red, exc, None] POP_TOP
3548 : : [orig, red, exc] JUMP L2
3549 : :
3550 : : [orig, res, rest, match] H1: <assign to V1> (or POP if no V1)
3551 : :
3552 : : [orig, res, rest] SETUP_FINALLY R1
3553 : : [orig, res, rest] <code for S1>
3554 : : [orig, res, rest] JUMP L2
3555 : :
3556 : : [orig, res, rest, i, v] R1: LIST_APPEND 3 ) exc raised in except* body - add to res
3557 : : [orig, res, rest, i] POP
3558 : :
3559 : : [orig, res, rest] L2: <evaluate E2>
3560 : : .............................etc.......................
3561 : :
3562 : : [orig, res, rest] Ln+1: LIST_APPEND 1 ) add unhandled exc to res (could be None)
3563 : :
3564 : : [orig, res] PREP_RERAISE_STAR
3565 : : [exc] COPY 1
3566 : : [exc, exc] POP_JUMP_IF_NOT_NONE RER
3567 : : [exc] POP_TOP
3568 : : [] JUMP L0
3569 : :
3570 : : [exc] RER: SWAP 2
3571 : : [exc, prev_exc_info] POP_EXCEPT
3572 : : [exc] RERAISE 0
3573 : :
3574 : : [] L0: <next statement>
3575 : : */
3576 : : static int
3577 : 108 : compiler_try_star_except(struct compiler *c, stmt_ty s)
3578 : : {
3579 : 108 : basicblock *body = compiler_new_block(c);
3580 [ - + ]: 108 : if (body == NULL) {
3581 : 0 : return 0;
3582 : : }
3583 : 108 : basicblock *except = compiler_new_block(c);
3584 [ - + ]: 108 : if (except == NULL) {
3585 : 0 : return 0;
3586 : : }
3587 : 108 : basicblock *orelse = compiler_new_block(c);
3588 [ - + ]: 108 : if (orelse == NULL) {
3589 : 0 : return 0;
3590 : : }
3591 : 108 : basicblock *end = compiler_new_block(c);
3592 [ - + ]: 108 : if (end == NULL) {
3593 : 0 : return 0;
3594 : : }
3595 : 108 : basicblock *cleanup = compiler_new_block(c);
3596 [ - + ]: 108 : if (cleanup == NULL) {
3597 : 0 : return 0;
3598 : : }
3599 : 108 : basicblock *reraise_star = compiler_new_block(c);
3600 [ - + ]: 108 : if (reraise_star == NULL) {
3601 : 0 : return 0;
3602 : : }
3603 : :
3604 [ - + ]: 108 : ADDOP_JUMP(c, SETUP_FINALLY, except);
3605 : 108 : compiler_use_next_block(c, body);
3606 [ - + ]: 108 : if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) {
3607 : 0 : return 0;
3608 : : }
3609 [ - + + - : 218 : VISIT_SEQ(c, stmt, s->v.TryStar.body);
+ + ]
3610 : 108 : compiler_pop_fblock(c, TRY_EXCEPT, body);
3611 [ - + ]: 108 : ADDOP_NOLINE(c, POP_BLOCK);
3612 [ - + ]: 108 : ADDOP_JUMP_NOLINE(c, JUMP, orelse);
3613 [ + - ]: 108 : Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers);
3614 : 108 : compiler_use_next_block(c, except);
3615 : :
3616 : 108 : UNSET_LOC(c);
3617 [ - + ]: 108 : ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
3618 [ - + ]: 108 : ADDOP(c, PUSH_EXC_INFO);
3619 : : /* Runtime will push a block here, so we need to account for that */
3620 [ - + ]: 108 : if (!compiler_push_fblock(c, EXCEPTION_GROUP_HANDLER,
3621 : : NULL, NULL, "except handler")) {
3622 : 0 : return 0;
3623 : : }
3624 [ + + ]: 228 : for (Py_ssize_t i = 0; i < n; i++) {
3625 : 128 : excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
3626 : : s->v.TryStar.handlers, i);
3627 : 128 : SET_LOC(c, handler);
3628 : 128 : except = compiler_new_block(c);
3629 [ - + ]: 128 : if (except == NULL) {
3630 : 0 : return 0;
3631 : : }
3632 : 128 : basicblock *handle_match = compiler_new_block(c);
3633 [ - + ]: 128 : if (handle_match == NULL) {
3634 : 0 : return 0;
3635 : : }
3636 [ + + ]: 128 : if (i == 0) {
3637 : : /* Push the original EG into the stack */
3638 : : /*
3639 : : [exc] COPY 1
3640 : : [orig, exc]
3641 : : */
3642 [ - + ]: 108 : ADDOP_I(c, COPY, 1);
3643 : :
3644 : : /* create empty list for exceptions raised/reraise in the except* blocks */
3645 : : /*
3646 : : [orig, exc] BUILD_LIST
3647 : : [orig, exc, []] SWAP 2
3648 : : [orig, [], exc]
3649 : : */
3650 [ - + ]: 108 : ADDOP_I(c, BUILD_LIST, 0);
3651 [ - + ]: 108 : ADDOP_I(c, SWAP, 2);
3652 : : }
3653 [ + - ]: 128 : if (handler->v.ExceptHandler.type) {
3654 [ - + ]: 128 : VISIT(c, expr, handler->v.ExceptHandler.type);
3655 [ - + ]: 128 : ADDOP(c, CHECK_EG_MATCH);
3656 [ - + ]: 128 : ADDOP_I(c, COPY, 1);
3657 [ - + ]: 128 : ADDOP_JUMP(c, POP_JUMP_IF_NOT_NONE, handle_match);
3658 [ - + ]: 128 : ADDOP(c, POP_TOP); // match
3659 [ - + ]: 128 : ADDOP_JUMP(c, JUMP, except);
3660 : : }
3661 : :
3662 : 128 : compiler_use_next_block(c, handle_match);
3663 : :
3664 : 128 : basicblock *cleanup_end = compiler_new_block(c);
3665 [ - + ]: 128 : if (cleanup_end == NULL) {
3666 : 0 : return 0;
3667 : : }
3668 : 128 : basicblock *cleanup_body = compiler_new_block(c);
3669 [ - + ]: 128 : if (cleanup_body == NULL) {
3670 : 0 : return 0;
3671 : : }
3672 : :
3673 [ + + ]: 128 : if (handler->v.ExceptHandler.name) {
3674 : 53 : compiler_nameop(c, handler->v.ExceptHandler.name, Store);
3675 : : }
3676 : : else {
3677 [ - + ]: 75 : ADDOP(c, POP_TOP); // match
3678 : : }
3679 : :
3680 : : /*
3681 : : try:
3682 : : # body
3683 : : except type as name:
3684 : : try:
3685 : : # body
3686 : : finally:
3687 : : name = None # in case body contains "del name"
3688 : : del name
3689 : : */
3690 : : /* second try: */
3691 [ - + ]: 128 : ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end);
3692 : 128 : compiler_use_next_block(c, cleanup_body);
3693 [ - + ]: 128 : if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name))
3694 : 0 : return 0;
3695 : :
3696 : : /* second # body */
3697 [ + + + - : 268 : VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
+ + ]
3698 : 120 : compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
3699 : : /* name = None; del name; # Mark as artificial */
3700 : 120 : UNSET_LOC(c);
3701 [ - + ]: 120 : ADDOP(c, POP_BLOCK);
3702 [ + + ]: 120 : if (handler->v.ExceptHandler.name) {
3703 [ - + ]: 45 : ADDOP_LOAD_CONST(c, Py_None);
3704 : 45 : compiler_nameop(c, handler->v.ExceptHandler.name, Store);
3705 : 45 : compiler_nameop(c, handler->v.ExceptHandler.name, Del);
3706 : : }
3707 [ - + ]: 120 : ADDOP_JUMP(c, JUMP, except);
3708 : :
3709 : : /* except: */
3710 : 120 : compiler_use_next_block(c, cleanup_end);
3711 : :
3712 : : /* name = None; del name; # Mark as artificial */
3713 : 120 : UNSET_LOC(c);
3714 : :
3715 [ + + ]: 120 : if (handler->v.ExceptHandler.name) {
3716 [ - + ]: 45 : ADDOP_LOAD_CONST(c, Py_None);
3717 : 45 : compiler_nameop(c, handler->v.ExceptHandler.name, Store);
3718 : 45 : compiler_nameop(c, handler->v.ExceptHandler.name, Del);
3719 : : }
3720 : :
3721 : : /* add exception raised to the res list */
3722 [ - + ]: 120 : ADDOP_I(c, LIST_APPEND, 3); // exc
3723 [ - + ]: 120 : ADDOP(c, POP_TOP); // lasti
3724 : :
3725 [ - + ]: 120 : ADDOP_JUMP(c, JUMP, except);
3726 : 120 : compiler_use_next_block(c, except);
3727 : :
3728 [ + + ]: 120 : if (i == n - 1) {
3729 : : /* Add exc to the list (if not None it's the unhandled part of the EG) */
3730 [ - + ]: 100 : ADDOP_I(c, LIST_APPEND, 1);
3731 [ - + ]: 100 : ADDOP_JUMP(c, JUMP, reraise_star);
3732 : : }
3733 : : }
3734 : : /* Mark as artificial */
3735 : 100 : UNSET_LOC(c);
3736 : 100 : compiler_pop_fblock(c, EXCEPTION_GROUP_HANDLER, NULL);
3737 : 100 : basicblock *reraise = compiler_new_block(c);
3738 [ - + ]: 100 : if (!reraise) {
3739 : 0 : return 0;
3740 : : }
3741 : :
3742 : 100 : compiler_use_next_block(c, reraise_star);
3743 [ - + ]: 100 : ADDOP(c, PREP_RERAISE_STAR);
3744 [ - + ]: 100 : ADDOP_I(c, COPY, 1);
3745 [ - + ]: 100 : ADDOP_JUMP(c, POP_JUMP_IF_NOT_NONE, reraise);
3746 : :
3747 : : /* Nothing to reraise */
3748 [ - + ]: 100 : ADDOP(c, POP_TOP);
3749 [ - + ]: 100 : ADDOP(c, POP_BLOCK);
3750 [ - + ]: 100 : ADDOP(c, POP_EXCEPT);
3751 [ - + ]: 100 : ADDOP_JUMP(c, JUMP, end);
3752 : 100 : compiler_use_next_block(c, reraise);
3753 [ - + ]: 100 : ADDOP(c, POP_BLOCK);
3754 [ - + ]: 100 : ADDOP_I(c, SWAP, 2);
3755 [ - + ]: 100 : ADDOP(c, POP_EXCEPT);
3756 [ - + ]: 100 : ADDOP_I(c, RERAISE, 0);
3757 : 100 : compiler_use_next_block(c, cleanup);
3758 [ - + ]: 100 : POP_EXCEPT_AND_RERAISE(c);
3759 : 100 : compiler_use_next_block(c, orelse);
3760 [ - + + + : 144 : VISIT_SEQ(c, stmt, s->v.TryStar.orelse);
+ + ]
3761 : 100 : compiler_use_next_block(c, end);
3762 : 100 : return 1;
3763 : : }
3764 : :
3765 : : static int
3766 : 39697 : compiler_try(struct compiler *c, stmt_ty s) {
3767 [ + + + - : 39697 : if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
+ + ]
3768 : 5903 : return compiler_try_finally(c, s);
3769 : : else
3770 : 33794 : return compiler_try_except(c, s);
3771 : : }
3772 : :
3773 : : static int
3774 : 108 : compiler_try_star(struct compiler *c, stmt_ty s)
3775 : : {
3776 [ + + + - : 108 : if (s->v.TryStar.finalbody && asdl_seq_LEN(s->v.TryStar.finalbody)) {
+ + ]
3777 : 25 : return compiler_try_star_finally(c, s);
3778 : : }
3779 : : else {
3780 : 83 : return compiler_try_star_except(c, s);
3781 : : }
3782 : : }
3783 : :
3784 : : static int
3785 : 1314 : compiler_import_as(struct compiler *c, identifier name, identifier asname)
3786 : : {
3787 : : /* The IMPORT_NAME opcode was already generated. This function
3788 : : merely needs to bind the result to a name.
3789 : :
3790 : : If there is a dot in name, we need to split it and emit a
3791 : : IMPORT_FROM for each name.
3792 : : */
3793 : 1314 : Py_ssize_t len = PyUnicode_GET_LENGTH(name);
3794 : 1314 : Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
3795 [ - + ]: 1314 : if (dot == -2)
3796 : 0 : return 0;
3797 [ + + ]: 1314 : if (dot != -1) {
3798 : : /* Consume the base module name to get the first attribute */
3799 : 129 : while (1) {
3800 : 376 : Py_ssize_t pos = dot + 1;
3801 : : PyObject *attr;
3802 : 376 : dot = PyUnicode_FindChar(name, '.', pos, len, 1);
3803 [ - + ]: 376 : if (dot == -2)
3804 : 0 : return 0;
3805 [ + + ]: 376 : attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
3806 [ - + ]: 376 : if (!attr)
3807 : 0 : return 0;
3808 [ - + ]: 376 : ADDOP_N(c, IMPORT_FROM, attr, names);
3809 [ + + ]: 376 : if (dot == -1) {
3810 : 247 : break;
3811 : : }
3812 [ - + ]: 129 : ADDOP_I(c, SWAP, 2);
3813 [ - + ]: 129 : ADDOP(c, POP_TOP);
3814 : : }
3815 [ - + ]: 247 : if (!compiler_nameop(c, asname, Store)) {
3816 : 0 : return 0;
3817 : : }
3818 [ - + ]: 247 : ADDOP(c, POP_TOP);
3819 : 247 : return 1;
3820 : : }
3821 : 1067 : return compiler_nameop(c, asname, Store);
3822 : : }
3823 : :
3824 : : static int
3825 : 36137 : compiler_import(struct compiler *c, stmt_ty s)
3826 : : {
3827 : : /* The Import node stores a module name like a.b.c as a single
3828 : : string. This is convenient for all cases except
3829 : : import a.b.c as d
3830 : : where we need to parse that string to extract the individual
3831 : : module names.
3832 : : XXX Perhaps change the representation to make this case simpler?
3833 : : */
3834 [ + - ]: 36137 : Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
3835 : :
3836 : 36137 : PyObject *zero = _PyLong_GetZero(); // borrowed reference
3837 [ + + ]: 73348 : for (i = 0; i < n; i++) {
3838 : 37211 : alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
3839 : : int r;
3840 : :
3841 [ - + ]: 37211 : ADDOP_LOAD_CONST(c, zero);
3842 [ - + ]: 37211 : ADDOP_LOAD_CONST(c, Py_None);
3843 [ - + ]: 37211 : ADDOP_NAME(c, IMPORT_NAME, alias->name, names);
3844 : :
3845 [ + + ]: 37211 : if (alias->asname) {
3846 : 1314 : r = compiler_import_as(c, alias->name, alias->asname);
3847 [ - + ]: 1314 : if (!r)
3848 : 0 : return r;
3849 : : }
3850 : : else {
3851 : 35897 : identifier tmp = alias->name;
3852 : 35897 : Py_ssize_t dot = PyUnicode_FindChar(
3853 : 35897 : alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
3854 [ + + ]: 35897 : if (dot != -1) {
3855 : 2266 : tmp = PyUnicode_Substring(alias->name, 0, dot);
3856 [ - + ]: 2266 : if (tmp == NULL)
3857 : 0 : return 0;
3858 : : }
3859 : 35897 : r = compiler_nameop(c, tmp, Store);
3860 [ + + ]: 35897 : if (dot != -1) {
3861 : 2266 : Py_DECREF(tmp);
3862 : : }
3863 [ - + ]: 35897 : if (!r)
3864 : 0 : return r;
3865 : : }
3866 : : }
3867 : 36137 : return 1;
3868 : : }
3869 : :
3870 : : static int
3871 : 41269 : compiler_from_import(struct compiler *c, stmt_ty s)
3872 : : {
3873 [ + - ]: 41269 : Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names);
3874 : : PyObject *names;
3875 : :
3876 [ - + - + ]: 41269 : ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level));
3877 : :
3878 : 41269 : names = PyTuple_New(n);
3879 [ - + ]: 41269 : if (!names)
3880 : 0 : return 0;
3881 : :
3882 : : /* build up the names */
3883 [ + + ]: 112365 : for (i = 0; i < n; i++) {
3884 : 71096 : alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
3885 : 71096 : Py_INCREF(alias->name);
3886 : 71096 : PyTuple_SET_ITEM(names, i, alias->name);
3887 : : }
3888 : :
3889 [ + + + + : 80268 : if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module &&
+ + ]
3890 : 38999 : _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) {
3891 : 9 : Py_DECREF(names);
3892 : 9 : return compiler_error(c, "from __future__ imports must occur "
3893 : : "at the beginning of the file");
3894 : : }
3895 [ - + - + ]: 41260 : ADDOP_LOAD_CONST_NEW(c, names);
3896 : :
3897 [ + + ]: 41260 : if (s->v.ImportFrom.module) {
3898 [ - + ]: 40012 : ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
3899 : : }
3900 : : else {
3901 : : _Py_DECLARE_STR(empty, "");
3902 [ - + ]: 1248 : ADDOP_NAME(c, IMPORT_NAME, &_Py_STR(empty), names);
3903 : : }
3904 [ + + ]: 111362 : for (i = 0; i < n; i++) {
3905 : 71087 : alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
3906 : : identifier store_name;
3907 : :
3908 [ + + + + ]: 71087 : if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
3909 : : assert(n == 1);
3910 [ - + ]: 985 : ADDOP(c, IMPORT_STAR);
3911 : 985 : return 1;
3912 : : }
3913 : :
3914 [ - + ]: 70102 : ADDOP_NAME(c, IMPORT_FROM, alias->name, names);
3915 : 70102 : store_name = alias->name;
3916 [ + + ]: 70102 : if (alias->asname)
3917 : 2808 : store_name = alias->asname;
3918 : :
3919 [ - + ]: 70102 : if (!compiler_nameop(c, store_name, Store)) {
3920 : 0 : return 0;
3921 : : }
3922 : : }
3923 : : /* remove imported module */
3924 [ - + ]: 40275 : ADDOP(c, POP_TOP);
3925 : 40275 : return 1;
3926 : : }
3927 : :
3928 : : static int
3929 : 8478 : compiler_assert(struct compiler *c, stmt_ty s)
3930 : : {
3931 : : basicblock *end;
3932 : :
3933 : : /* Always emit a warning if the test is a non-zero length tuple */
3934 [ + + ]: 8478 : if ((s->v.Assert.test->kind == Tuple_kind &&
3935 [ + - - + ]: 3 : asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
3936 [ + + + + ]: 8731 : (s->v.Assert.test->kind == Constant_kind &&
3937 [ + - ]: 262 : PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
3938 : 6 : PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0))
3939 : : {
3940 [ + + ]: 9 : if (!compiler_warn(c, "assertion is always true, "
3941 : : "perhaps remove parentheses?"))
3942 : : {
3943 : 6 : return 0;
3944 : : }
3945 : : }
3946 [ + + ]: 8472 : if (c->c_optimize)
3947 : 465 : return 1;
3948 : 8007 : end = compiler_new_block(c);
3949 [ - + ]: 8007 : if (end == NULL)
3950 : 0 : return 0;
3951 [ - + ]: 8007 : if (!compiler_jump_if(c, s->v.Assert.test, end, 1))
3952 : 0 : return 0;
3953 [ - + ]: 8007 : ADDOP(c, LOAD_ASSERTION_ERROR);
3954 [ + + ]: 8007 : if (s->v.Assert.msg) {
3955 [ - + ]: 1838 : VISIT(c, expr, s->v.Assert.msg);
3956 [ - + ]: 1838 : ADDOP_I(c, CALL, 0);
3957 : : }
3958 [ - + ]: 8007 : ADDOP_I(c, RAISE_VARARGS, 1);
3959 : 8007 : compiler_use_next_block(c, end);
3960 : 8007 : return 1;
3961 : : }
3962 : :
3963 : : static int
3964 : 556393 : compiler_visit_stmt_expr(struct compiler *c, expr_ty value)
3965 : : {
3966 [ + + + + ]: 556393 : if (c->c_interactive && c->c_nestlevel <= 1) {
3967 [ + + ]: 2630 : VISIT(c, expr, value);
3968 [ - + ]: 2624 : ADDOP(c, PRINT_EXPR);
3969 : 2624 : return 1;
3970 : : }
3971 : :
3972 [ + + ]: 553763 : if (value->kind == Constant_kind) {
3973 : : /* ignore constant statement */
3974 [ - + ]: 5796 : ADDOP(c, NOP);
3975 : 5796 : return 1;
3976 : : }
3977 : :
3978 [ + + ]: 547967 : VISIT(c, expr, value);
3979 : : /* Mark POP_TOP as artificial */
3980 : 547840 : UNSET_LOC(c);
3981 [ - + ]: 547840 : ADDOP(c, POP_TOP);
3982 : 547840 : return 1;
3983 : : }
3984 : :
3985 : : static int
3986 : 2508656 : compiler_visit_stmt(struct compiler *c, stmt_ty s)
3987 : : {
3988 : : Py_ssize_t i, n;
3989 : :
3990 : : /* Always assign a lineno to the next instruction for a stmt. */
3991 : 2508656 : SET_LOC(c, s);
3992 : :
3993 [ + + + + : 2508656 : switch (s->kind) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + - ]
3994 : 256279 : case FunctionDef_kind:
3995 : 256279 : return compiler_function(c, s, 0);
3996 : 37375 : case ClassDef_kind:
3997 : 37375 : return compiler_class(c, s);
3998 : 210386 : case Return_kind:
3999 : 210386 : return compiler_return(c, s);
4000 : 6552 : case Delete_kind:
4001 [ + + + - : 14002 : VISIT_SEQ(c, expr, s->v.Delete.targets)
+ + ]
4002 : 6551 : break;
4003 : 633511 : case Assign_kind:
4004 [ + - ]: 633511 : n = asdl_seq_LEN(s->v.Assign.targets);
4005 [ + + ]: 633511 : VISIT(c, expr, s->v.Assign.value);
4006 [ + + ]: 1273372 : for (i = 0; i < n; i++) {
4007 [ + + ]: 639890 : if (i < n - 1) {
4008 [ - + ]: 6397 : ADDOP_I(c, COPY, 1);
4009 : : }
4010 [ + + ]: 639890 : VISIT(c, expr,
4011 : : (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
4012 : : }
4013 : 633482 : break;
4014 : 21488 : case AugAssign_kind:
4015 : 21488 : return compiler_augassign(c, s);
4016 : 9866 : case AnnAssign_kind:
4017 : 9866 : return compiler_annassign(c, s);
4018 : 46021 : case For_kind:
4019 : 46021 : return compiler_for(c, s);
4020 : 9870 : case While_kind:
4021 : 9870 : return compiler_while(c, s);
4022 : 484350 : case If_kind:
4023 : 484350 : return compiler_if(c, s);
4024 : 682 : case Match_kind:
4025 : 682 : return compiler_match(c, s);
4026 : 52348 : case Raise_kind:
4027 : 52348 : n = 0;
4028 [ + + ]: 52348 : if (s->v.Raise.exc) {
4029 [ - + ]: 48419 : VISIT(c, expr, s->v.Raise.exc);
4030 : 48419 : n++;
4031 [ + + ]: 48419 : if (s->v.Raise.cause) {
4032 [ - + ]: 2431 : VISIT(c, expr, s->v.Raise.cause);
4033 : 2431 : n++;
4034 : : }
4035 : : }
4036 [ - + ]: 52348 : ADDOP_I(c, RAISE_VARARGS, (int)n);
4037 : 52348 : break;
4038 : 39697 : case Try_kind:
4039 : 39697 : return compiler_try(c, s);
4040 : 108 : case TryStar_kind:
4041 : 108 : return compiler_try_star(c, s);
4042 : 8478 : case Assert_kind:
4043 : 8478 : return compiler_assert(c, s);
4044 : 36137 : case Import_kind:
4045 : 36137 : return compiler_import(c, s);
4046 : 41269 : case ImportFrom_kind:
4047 : 41269 : return compiler_from_import(c, s);
4048 : 2045 : case Global_kind:
4049 : : case Nonlocal_kind:
4050 : 2045 : break;
4051 : 556393 : case Expr_kind:
4052 : 556393 : return compiler_visit_stmt_expr(c, s->v.Expr.value);
4053 : 16656 : case Pass_kind:
4054 [ - + ]: 16656 : ADDOP(c, NOP);
4055 : 16656 : break;
4056 : 8435 : case Break_kind:
4057 : 8435 : return compiler_break(c);
4058 : 7497 : case Continue_kind:
4059 : 7497 : return compiler_continue(c);
4060 : 20615 : case With_kind:
4061 : 20615 : return compiler_with(c, s, 0);
4062 : 2290 : case AsyncFunctionDef_kind:
4063 : 2290 : return compiler_function(c, s, 1);
4064 : 227 : case AsyncWith_kind:
4065 : 227 : return compiler_async_with(c, s, 0);
4066 : 81 : case AsyncFor_kind:
4067 : 81 : return compiler_async_for(c, s);
4068 : : }
4069 : :
4070 : 711082 : return 1;
4071 : : }
4072 : :
4073 : : static int
4074 : 7513 : unaryop(unaryop_ty op)
4075 : : {
4076 [ + + + + : 7513 : switch (op) {
- ]
4077 : 746 : case Invert:
4078 : 746 : return UNARY_INVERT;
4079 : 2973 : case Not:
4080 : 2973 : return UNARY_NOT;
4081 : 87 : case UAdd:
4082 : 87 : return UNARY_POSITIVE;
4083 : 3707 : case USub:
4084 : 3707 : return UNARY_NEGATIVE;
4085 : 0 : default:
4086 : 0 : PyErr_Format(PyExc_SystemError,
4087 : : "unary op %d should not be possible", op);
4088 : 0 : return 0;
4089 : : }
4090 : : }
4091 : :
4092 : : static int
4093 : 217879 : addop_binary(struct compiler *c, operator_ty binop, bool inplace)
4094 : : {
4095 : : int oparg;
4096 [ + + + + : 217879 : switch (binop) {
+ + + + +
+ + + +
- ]
4097 : 88416 : case Add:
4098 [ + + ]: 88416 : oparg = inplace ? NB_INPLACE_ADD : NB_ADD;
4099 : 88416 : break;
4100 : 45616 : case Sub:
4101 [ + + ]: 45616 : oparg = inplace ? NB_INPLACE_SUBTRACT : NB_SUBTRACT;
4102 : 45616 : break;
4103 : 17977 : case Mult:
4104 [ + + ]: 17977 : oparg = inplace ? NB_INPLACE_MULTIPLY : NB_MULTIPLY;
4105 : 17977 : break;
4106 : 67 : case MatMult:
4107 [ + + ]: 67 : oparg = inplace ? NB_INPLACE_MATRIX_MULTIPLY : NB_MATRIX_MULTIPLY;
4108 : 67 : break;
4109 : 3778 : case Div:
4110 [ + + ]: 3778 : oparg = inplace ? NB_INPLACE_TRUE_DIVIDE : NB_TRUE_DIVIDE;
4111 : 3778 : break;
4112 : 42090 : case Mod:
4113 [ + + ]: 42090 : oparg = inplace ? NB_INPLACE_REMAINDER : NB_REMAINDER;
4114 : 42090 : break;
4115 : 1967 : case Pow:
4116 [ + + ]: 1967 : oparg = inplace ? NB_INPLACE_POWER : NB_POWER;
4117 : 1967 : break;
4118 : 1459 : case LShift:
4119 [ + + ]: 1459 : oparg = inplace ? NB_INPLACE_LSHIFT : NB_LSHIFT;
4120 : 1459 : break;
4121 : 1075 : case RShift:
4122 [ + + ]: 1075 : oparg = inplace ? NB_INPLACE_RSHIFT : NB_RSHIFT;
4123 : 1075 : break;
4124 : 6281 : case BitOr:
4125 [ + + ]: 6281 : oparg = inplace ? NB_INPLACE_OR : NB_OR;
4126 : 6281 : break;
4127 : 790 : case BitXor:
4128 [ + + ]: 790 : oparg = inplace ? NB_INPLACE_XOR : NB_XOR;
4129 : 790 : break;
4130 : 5589 : case BitAnd:
4131 [ + + ]: 5589 : oparg = inplace ? NB_INPLACE_AND : NB_AND;
4132 : 5589 : break;
4133 : 2774 : case FloorDiv:
4134 [ + + ]: 2774 : oparg = inplace ? NB_INPLACE_FLOOR_DIVIDE : NB_FLOOR_DIVIDE;
4135 : 2774 : break;
4136 : 0 : default:
4137 [ # # ]: 0 : PyErr_Format(PyExc_SystemError, "%s op %d should not be possible",
4138 : : inplace ? "inplace" : "binary", binop);
4139 : 0 : return 0;
4140 : : }
4141 [ - + ]: 217879 : ADDOP_I(c, BINARY_OP, oparg);
4142 : 217879 : return 1;
4143 : : }
4144 : :
4145 : :
4146 : : static int
4147 : 19134 : addop_yield(struct compiler *c) {
4148 [ + - + + ]: 19134 : if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) {
4149 [ - + ]: 216 : ADDOP(c, ASYNC_GEN_WRAP);
4150 : : }
4151 [ - + ]: 19134 : ADDOP_I(c, YIELD_VALUE, 0);
4152 [ - + ]: 19134 : ADDOP_I(c, RESUME, 1);
4153 : 19134 : return 1;
4154 : : }
4155 : :
4156 : : static int
4157 : 5251991 : compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
4158 : : {
4159 : : int op, scope;
4160 : : Py_ssize_t arg;
4161 : : enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
4162 : :
4163 : 5251991 : PyObject *dict = c->u->u_names;
4164 : : PyObject *mangled;
4165 : :
4166 : : assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
4167 : : !_PyUnicode_EqualToASCIIString(name, "True") &&
4168 : : !_PyUnicode_EqualToASCIIString(name, "False"));
4169 : :
4170 [ + + ]: 5251991 : if (forbidden_name(c, name, ctx))
4171 : 7 : return 0;
4172 : :
4173 : 5251984 : mangled = _Py_Mangle(c->u->u_private, name);
4174 [ - + ]: 5251984 : if (!mangled)
4175 : 0 : return 0;
4176 : :
4177 : 5251984 : op = 0;
4178 : 5251984 : optype = OP_NAME;
4179 : 5251984 : scope = _PyST_GetScope(c->u->u_ste, mangled);
4180 [ + + + + : 5251984 : switch (scope) {
+ + ]
4181 : 37090 : case FREE:
4182 : 37090 : dict = c->u->u_freevars;
4183 : 37090 : optype = OP_DEREF;
4184 : 37090 : break;
4185 : 53384 : case CELL:
4186 : 53384 : dict = c->u->u_cellvars;
4187 : 53384 : optype = OP_DEREF;
4188 : 53384 : break;
4189 : 3582028 : case LOCAL:
4190 [ + + ]: 3582028 : if (c->u->u_ste->ste_type == FunctionBlock)
4191 : 2904061 : optype = OP_FAST;
4192 : 3582028 : break;
4193 : 1434733 : case GLOBAL_IMPLICIT:
4194 [ + + ]: 1434733 : if (c->u->u_ste->ste_type == FunctionBlock)
4195 : 753310 : optype = OP_GLOBAL;
4196 : 1434733 : break;
4197 : 6651 : case GLOBAL_EXPLICIT:
4198 : 6651 : optype = OP_GLOBAL;
4199 : 6651 : break;
4200 : 138098 : default:
4201 : : /* scope can be 0 */
4202 : 138098 : break;
4203 : : }
4204 : :
4205 : : /* XXX Leave assert here, but handle __doc__ and the like better */
4206 : : assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
4207 : :
4208 [ + + + + : 5251984 : switch (optype) {
- ]
4209 [ + + + - ]: 90474 : case OP_DEREF:
4210 : : switch (ctx) {
4211 : 75063 : case Load:
4212 [ + + ]: 75063 : op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
4213 : 75063 : break;
4214 : 15401 : case Store: op = STORE_DEREF; break;
4215 : 10 : case Del: op = DELETE_DEREF; break;
4216 : : }
4217 : 90474 : break;
4218 [ + + + - ]: 2904061 : case OP_FAST:
4219 : : switch (ctx) {
4220 : 2315927 : case Load: op = LOAD_FAST; break;
4221 : 571710 : case Store: op = STORE_FAST; break;
4222 : 16424 : case Del: op = DELETE_FAST; break;
4223 : : }
4224 [ - + ]: 2904061 : ADDOP_N(c, op, mangled, varnames);
4225 : 2904061 : return 1;
4226 [ + + + - ]: 759961 : case OP_GLOBAL:
4227 : : switch (ctx) {
4228 : 756395 : case Load: op = LOAD_GLOBAL; break;
4229 : 3544 : case Store: op = STORE_GLOBAL; break;
4230 : 22 : case Del: op = DELETE_GLOBAL; break;
4231 : : }
4232 : 759961 : break;
4233 [ + + + - ]: 1497488 : case OP_NAME:
4234 : : switch (ctx) {
4235 : 908140 : case Load: op = LOAD_NAME; break;
4236 : 586861 : case Store: op = STORE_NAME; break;
4237 : 2487 : case Del: op = DELETE_NAME; break;
4238 : : }
4239 : 1497488 : break;
4240 : : }
4241 : :
4242 : : assert(op);
4243 : 2347923 : arg = compiler_add_o(dict, mangled);
4244 : 2347923 : Py_DECREF(mangled);
4245 [ - + ]: 2347923 : if (arg < 0) {
4246 : 0 : return 0;
4247 : : }
4248 [ + + ]: 2347923 : if (op == LOAD_GLOBAL) {
4249 : 756395 : arg <<= 1;
4250 : : }
4251 : 2347923 : return compiler_addop_i(c, op, arg, true);
4252 : : }
4253 : :
4254 : : static int
4255 : 17309 : compiler_boolop(struct compiler *c, expr_ty e)
4256 : : {
4257 : : basicblock *end;
4258 : : int jumpi;
4259 : : Py_ssize_t i, n;
4260 : : asdl_expr_seq *s;
4261 : :
4262 : : assert(e->kind == BoolOp_kind);
4263 [ + + ]: 17309 : if (e->v.BoolOp.op == And)
4264 : 6003 : jumpi = JUMP_IF_FALSE_OR_POP;
4265 : : else
4266 : 11306 : jumpi = JUMP_IF_TRUE_OR_POP;
4267 : 17309 : end = compiler_new_block(c);
4268 [ - + ]: 17309 : if (end == NULL)
4269 : 0 : return 0;
4270 : 17309 : s = e->v.BoolOp.values;
4271 [ + - ]: 17309 : n = asdl_seq_LEN(s) - 1;
4272 : : assert(n >= 0);
4273 [ + + ]: 37188 : for (i = 0; i < n; ++i) {
4274 [ - + ]: 19879 : VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
4275 [ - + ]: 19879 : ADDOP_JUMP(c, jumpi, end);
4276 : 19879 : basicblock *next = compiler_new_block(c);
4277 [ - + ]: 19879 : if (next == NULL) {
4278 : 0 : return 0;
4279 : : }
4280 : 19879 : compiler_use_next_block(c, next);
4281 : : }
4282 [ - + ]: 17309 : VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
4283 : 17309 : compiler_use_next_block(c, end);
4284 : 17309 : return 1;
4285 : : }
4286 : :
4287 : : static int
4288 : 195464 : starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed,
4289 : : int build, int add, int extend, int tuple)
4290 : : {
4291 [ + + ]: 195464 : Py_ssize_t n = asdl_seq_LEN(elts);
4292 [ + + + + ]: 195464 : if (n > 2 && are_all_items_const(elts, 0, n)) {
4293 : 10224 : PyObject *folded = PyTuple_New(n);
4294 [ - + ]: 10224 : if (folded == NULL) {
4295 : 0 : return 0;
4296 : : }
4297 : : PyObject *val;
4298 [ + + ]: 465788 : for (Py_ssize_t i = 0; i < n; i++) {
4299 : 455564 : val = ((expr_ty)asdl_seq_GET(elts, i))->v.Constant.value;
4300 : 455564 : Py_INCREF(val);
4301 : 455564 : PyTuple_SET_ITEM(folded, i, val);
4302 : : }
4303 [ + + + + ]: 10224 : if (tuple && !pushed) {
4304 [ - + - + ]: 20 : ADDOP_LOAD_CONST_NEW(c, folded);
4305 : : } else {
4306 [ + + ]: 10204 : if (add == SET_ADD) {
4307 : 442 : Py_SETREF(folded, PyFrozenSet_New(folded));
4308 [ - + ]: 442 : if (folded == NULL) {
4309 : 0 : return 0;
4310 : : }
4311 : : }
4312 [ - + ]: 10204 : ADDOP_I(c, build, pushed);
4313 [ - + - + ]: 10204 : ADDOP_LOAD_CONST_NEW(c, folded);
4314 [ - + ]: 10204 : ADDOP_I(c, extend, 1);
4315 [ + + ]: 10204 : if (tuple) {
4316 [ - + ]: 1 : ADDOP(c, LIST_TO_TUPLE);
4317 : : }
4318 : : }
4319 : 10224 : return 1;
4320 : : }
4321 : :
4322 : 185240 : int big = n+pushed > STACK_USE_GUIDELINE;
4323 : 185240 : int seen_star = 0;
4324 [ + + ]: 604683 : for (Py_ssize_t i = 0; i < n; i++) {
4325 : 423439 : expr_ty elt = asdl_seq_GET(elts, i);
4326 [ + + ]: 423439 : if (elt->kind == Starred_kind) {
4327 : 3996 : seen_star = 1;
4328 : 3996 : break;
4329 : : }
4330 : : }
4331 [ + + + + ]: 185240 : if (!seen_star && !big) {
4332 [ + + ]: 568922 : for (Py_ssize_t i = 0; i < n; i++) {
4333 : 388004 : expr_ty elt = asdl_seq_GET(elts, i);
4334 [ + + ]: 388004 : VISIT(c, expr, elt);
4335 : : }
4336 [ + + ]: 180918 : if (tuple) {
4337 [ - + ]: 126681 : ADDOP_I(c, BUILD_TUPLE, n+pushed);
4338 : : } else {
4339 [ - + ]: 54237 : ADDOP_I(c, build, n+pushed);
4340 : : }
4341 : 180918 : return 1;
4342 : : }
4343 : 4267 : int sequence_built = 0;
4344 [ + + ]: 4267 : if (big) {
4345 [ - + ]: 271 : ADDOP_I(c, build, pushed);
4346 : 271 : sequence_built = 1;
4347 : : }
4348 [ + + ]: 40571 : for (Py_ssize_t i = 0; i < n; i++) {
4349 : 36304 : expr_ty elt = asdl_seq_GET(elts, i);
4350 [ + + ]: 36304 : if (elt->kind == Starred_kind) {
4351 [ + + ]: 4280 : if (sequence_built == 0) {
4352 [ - + ]: 3996 : ADDOP_I(c, build, i+pushed);
4353 : 3996 : sequence_built = 1;
4354 : : }
4355 [ - + ]: 4280 : VISIT(c, expr, elt->v.Starred.value);
4356 [ - + ]: 4280 : ADDOP_I(c, extend, 1);
4357 : : }
4358 : : else {
4359 [ - + ]: 32024 : VISIT(c, expr, elt);
4360 [ + + ]: 32024 : if (sequence_built) {
4361 [ - + ]: 27394 : ADDOP_I(c, add, 1);
4362 : : }
4363 : : }
4364 : : }
4365 : : assert(sequence_built);
4366 [ + + ]: 4267 : if (tuple) {
4367 [ - + ]: 3918 : ADDOP(c, LIST_TO_TUPLE);
4368 : : }
4369 : 4267 : return 1;
4370 : : }
4371 : :
4372 : : static int
4373 : 42018 : unpack_helper(struct compiler *c, asdl_expr_seq *elts)
4374 : : {
4375 [ + + ]: 42018 : Py_ssize_t n = asdl_seq_LEN(elts);
4376 : 42018 : int seen_star = 0;
4377 [ + + ]: 145840 : for (Py_ssize_t i = 0; i < n; i++) {
4378 : 103827 : expr_ty elt = asdl_seq_GET(elts, i);
4379 [ + + + + ]: 103827 : if (elt->kind == Starred_kind && !seen_star) {
4380 [ + + ]: 207 : if ((i >= (1 << 8)) ||
4381 [ - + ]: 205 : (n-i-1 >= (INT_MAX >> 8)))
4382 : 2 : return compiler_error(c,
4383 : : "too many expressions in "
4384 : : "star-unpacking assignment");
4385 [ - + ]: 205 : ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
4386 : 205 : seen_star = 1;
4387 : : }
4388 [ + + ]: 103620 : else if (elt->kind == Starred_kind) {
4389 : 3 : return compiler_error(c,
4390 : : "multiple starred expressions in assignment");
4391 : : }
4392 : : }
4393 [ + + ]: 42013 : if (!seen_star) {
4394 [ - + ]: 41811 : ADDOP_I(c, UNPACK_SEQUENCE, n);
4395 : : }
4396 : 42013 : return 1;
4397 : : }
4398 : :
4399 : : static int
4400 : 42018 : assignment_helper(struct compiler *c, asdl_expr_seq *elts)
4401 : : {
4402 [ + + ]: 42018 : Py_ssize_t n = asdl_seq_LEN(elts);
4403 [ + + ]: 42018 : RETURN_IF_FALSE(unpack_helper(c, elts));
4404 [ + + ]: 145057 : for (Py_ssize_t i = 0; i < n; i++) {
4405 : 103046 : expr_ty elt = asdl_seq_GET(elts, i);
4406 [ + + + + ]: 103046 : VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
4407 : : }
4408 : 42011 : return 1;
4409 : : }
4410 : :
4411 : : static int
4412 : 63142 : compiler_list(struct compiler *c, expr_ty e)
4413 : : {
4414 : 63142 : asdl_expr_seq *elts = e->v.List.elts;
4415 [ + + ]: 63142 : if (e->v.List.ctx == Store) {
4416 : 104 : return assignment_helper(c, elts);
4417 : : }
4418 [ + + ]: 63038 : else if (e->v.List.ctx == Load) {
4419 : 63033 : return starunpack_helper(c, elts, 0, BUILD_LIST,
4420 : : LIST_APPEND, LIST_EXTEND, 0);
4421 : : }
4422 : : else
4423 [ - + + - : 14 : VISIT_SEQ(c, expr, elts);
+ + ]
4424 : 5 : return 1;
4425 : : }
4426 : :
4427 : : static int
4428 : 165685 : compiler_tuple(struct compiler *c, expr_ty e)
4429 : : {
4430 : 165685 : asdl_expr_seq *elts = e->v.Tuple.elts;
4431 [ + + ]: 165685 : if (e->v.Tuple.ctx == Store) {
4432 : 41914 : return assignment_helper(c, elts);
4433 : : }
4434 [ + + ]: 123771 : else if (e->v.Tuple.ctx == Load) {
4435 : 123745 : return starunpack_helper(c, elts, 0, BUILD_LIST,
4436 : : LIST_APPEND, LIST_EXTEND, 1);
4437 : : }
4438 : : else
4439 [ - + + + : 512 : VISIT_SEQ(c, expr, elts);
+ + ]
4440 : 26 : return 1;
4441 : : }
4442 : :
4443 : : static int
4444 : 1810 : compiler_set(struct compiler *c, expr_ty e)
4445 : : {
4446 : 1810 : return starunpack_helper(c, e->v.Set.elts, 0, BUILD_SET,
4447 : : SET_ADD, SET_UPDATE, 0);
4448 : : }
4449 : :
4450 : : static int
4451 : 77533 : are_all_items_const(asdl_expr_seq *seq, Py_ssize_t begin, Py_ssize_t end)
4452 : : {
4453 : : Py_ssize_t i;
4454 [ + + ]: 635068 : for (i = begin; i < end; i++) {
4455 : 610135 : expr_ty key = (expr_ty)asdl_seq_GET(seq, i);
4456 [ + - + + ]: 610135 : if (key == NULL || key->kind != Constant_kind)
4457 : 52600 : return 0;
4458 : : }
4459 : 24933 : return 1;
4460 : : }
4461 : :
4462 : : static int
4463 : 50970 : compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
4464 : : {
4465 : 50970 : Py_ssize_t i, n = end - begin;
4466 : : PyObject *keys, *key;
4467 : 50970 : int big = n*2 > STACK_USE_GUIDELINE;
4468 [ + + + + : 50970 : if (n > 1 && !big && are_all_items_const(e->v.Dict.keys, begin, end)) {
+ + ]
4469 [ + + ]: 106270 : for (i = begin; i < end; i++) {
4470 [ - + ]: 91561 : VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
4471 : : }
4472 : 14709 : keys = PyTuple_New(n);
4473 [ - + ]: 14709 : if (keys == NULL) {
4474 : 0 : return 0;
4475 : : }
4476 [ + + ]: 106270 : for (i = begin; i < end; i++) {
4477 : 91561 : key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value;
4478 : 91561 : Py_INCREF(key);
4479 : 91561 : PyTuple_SET_ITEM(keys, i - begin, key);
4480 : : }
4481 [ - + - + ]: 14709 : ADDOP_LOAD_CONST_NEW(c, keys);
4482 [ - + ]: 14709 : ADDOP_I(c, BUILD_CONST_KEY_MAP, n);
4483 : 14709 : return 1;
4484 : : }
4485 [ + + ]: 36261 : if (big) {
4486 [ - + ]: 30430 : ADDOP_I(c, BUILD_MAP, 0);
4487 : : }
4488 [ + + ]: 561108 : for (i = begin; i < end; i++) {
4489 [ - + ]: 524847 : VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
4490 [ - + ]: 524847 : VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
4491 [ + + ]: 524847 : if (big) {
4492 [ - + ]: 517193 : ADDOP_I(c, MAP_ADD, 1);
4493 : : }
4494 : : }
4495 [ + + ]: 36261 : if (!big) {
4496 [ - + ]: 5831 : ADDOP_I(c, BUILD_MAP, n);
4497 : : }
4498 : 36261 : return 1;
4499 : : }
4500 : :
4501 : : static int
4502 : 32228 : compiler_dict(struct compiler *c, expr_ty e)
4503 : : {
4504 : : Py_ssize_t i, n, elements;
4505 : : int have_dict;
4506 : 32228 : int is_unpacking = 0;
4507 [ + - ]: 32228 : n = asdl_seq_LEN(e->v.Dict.values);
4508 : 32228 : have_dict = 0;
4509 : 32228 : elements = 0;
4510 [ + + ]: 649920 : for (i = 0; i < n; i++) {
4511 : 617692 : is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
4512 [ + + ]: 617692 : if (is_unpacking) {
4513 [ + + ]: 1284 : if (elements) {
4514 [ - + ]: 8 : if (!compiler_subdict(c, e, i - elements, i)) {
4515 : 0 : return 0;
4516 : : }
4517 [ + + ]: 8 : if (have_dict) {
4518 [ - + ]: 2 : ADDOP_I(c, DICT_UPDATE, 1);
4519 : : }
4520 : 8 : have_dict = 1;
4521 : 8 : elements = 0;
4522 : : }
4523 [ + + ]: 1284 : if (have_dict == 0) {
4524 [ - + ]: 148 : ADDOP_I(c, BUILD_MAP, 0);
4525 : 148 : have_dict = 1;
4526 : : }
4527 [ - + ]: 1284 : VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
4528 [ - + ]: 1284 : ADDOP_I(c, DICT_UPDATE, 1);
4529 : : }
4530 : : else {
4531 [ + + ]: 616408 : if (elements*2 > STACK_USE_GUIDELINE) {
4532 [ - + ]: 30313 : if (!compiler_subdict(c, e, i - elements, i + 1)) {
4533 : 0 : return 0;
4534 : : }
4535 [ + + ]: 30313 : if (have_dict) {
4536 [ - + ]: 24631 : ADDOP_I(c, DICT_UPDATE, 1);
4537 : : }
4538 : 30313 : have_dict = 1;
4539 : 30313 : elements = 0;
4540 : : }
4541 : : else {
4542 : 586095 : elements++;
4543 : : }
4544 : : }
4545 : : }
4546 [ + + ]: 32228 : if (elements) {
4547 [ - + ]: 20649 : if (!compiler_subdict(c, e, n - elements, n)) {
4548 : 0 : return 0;
4549 : : }
4550 [ + + ]: 20649 : if (have_dict) {
4551 [ - + ]: 5652 : ADDOP_I(c, DICT_UPDATE, 1);
4552 : : }
4553 : 20649 : have_dict = 1;
4554 : : }
4555 [ + + ]: 32228 : if (!have_dict) {
4556 [ - + ]: 11395 : ADDOP_I(c, BUILD_MAP, 0);
4557 : : }
4558 : 32228 : return 1;
4559 : : }
4560 : :
4561 : : static int
4562 : 209513 : compiler_compare(struct compiler *c, expr_ty e)
4563 : : {
4564 : : Py_ssize_t i, n;
4565 : :
4566 [ + + ]: 209513 : if (!check_compare(c, e)) {
4567 : 7 : return 0;
4568 : : }
4569 [ - + ]: 209506 : VISIT(c, expr, e->v.Compare.left);
4570 : : assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
4571 [ + - ]: 209506 : n = asdl_seq_LEN(e->v.Compare.ops) - 1;
4572 [ + + ]: 209506 : if (n == 0) {
4573 [ + + ]: 209221 : VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
4574 [ - + ]: 209219 : ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, 0));
4575 : : }
4576 : : else {
4577 : 285 : basicblock *cleanup = compiler_new_block(c);
4578 [ - + ]: 285 : if (cleanup == NULL)
4579 : 0 : return 0;
4580 [ + + ]: 689 : for (i = 0; i < n; i++) {
4581 [ - + ]: 404 : VISIT(c, expr,
4582 : : (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
4583 [ - + ]: 404 : ADDOP_I(c, SWAP, 2);
4584 [ - + ]: 404 : ADDOP_I(c, COPY, 2);
4585 [ - + ]: 404 : ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i));
4586 [ - + ]: 404 : ADDOP_JUMP(c, JUMP_IF_FALSE_OR_POP, cleanup);
4587 : : }
4588 [ - + ]: 285 : VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
4589 [ - + ]: 285 : ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n));
4590 : 285 : basicblock *end = compiler_new_block(c);
4591 [ - + ]: 285 : if (end == NULL)
4592 : 0 : return 0;
4593 [ - + ]: 285 : ADDOP_JUMP_NOLINE(c, JUMP, end);
4594 : 285 : compiler_use_next_block(c, cleanup);
4595 [ - + ]: 285 : ADDOP_I(c, SWAP, 2);
4596 [ - + ]: 285 : ADDOP(c, POP_TOP);
4597 : 285 : compiler_use_next_block(c, end);
4598 : : }
4599 : 209504 : return 1;
4600 : : }
4601 : :
4602 : : static PyTypeObject *
4603 : 151697 : infer_type(expr_ty e)
4604 : : {
4605 [ + + + + : 151697 : switch (e->kind) {
+ + + +
+ ]
4606 : 12365 : case Tuple_kind:
4607 : 12365 : return &PyTuple_Type;
4608 : 54 : case List_kind:
4609 : : case ListComp_kind:
4610 : 54 : return &PyList_Type;
4611 : 9 : case Dict_kind:
4612 : : case DictComp_kind:
4613 : 9 : return &PyDict_Type;
4614 : 12 : case Set_kind:
4615 : : case SetComp_kind:
4616 : 12 : return &PySet_Type;
4617 : 6 : case GeneratorExp_kind:
4618 : 6 : return &PyGen_Type;
4619 : 4 : case Lambda_kind:
4620 : 4 : return &PyFunction_Type;
4621 : 14 : case JoinedStr_kind:
4622 : : case FormattedValue_kind:
4623 : 14 : return &PyUnicode_Type;
4624 : 64636 : case Constant_kind:
4625 : 64636 : return Py_TYPE(e->v.Constant.value);
4626 : 74597 : default:
4627 : 74597 : return NULL;
4628 : : }
4629 : : }
4630 : :
4631 : : static int
4632 : 590636 : check_caller(struct compiler *c, expr_ty e)
4633 : : {
4634 [ + + ]: 590636 : switch (e->kind) {
4635 : 38 : case Constant_kind:
4636 : : case Tuple_kind:
4637 : : case List_kind:
4638 : : case ListComp_kind:
4639 : : case Dict_kind:
4640 : : case DictComp_kind:
4641 : : case Set_kind:
4642 : : case SetComp_kind:
4643 : : case GeneratorExp_kind:
4644 : : case JoinedStr_kind:
4645 : : case FormattedValue_kind:
4646 : 38 : return compiler_warn(c, "'%.200s' object is not callable; "
4647 : : "perhaps you missed a comma?",
4648 : 38 : infer_type(e)->tp_name);
4649 : 590598 : default:
4650 : 590598 : return 1;
4651 : : }
4652 : : }
4653 : :
4654 : : static int
4655 : 151599 : check_subscripter(struct compiler *c, expr_ty e)
4656 : : {
4657 : : PyObject *v;
4658 : :
4659 [ + + + ]: 151599 : switch (e->kind) {
4660 : 101 : case Constant_kind:
4661 : 101 : v = e->v.Constant.value;
4662 [ + + + + : 287 : if (!(v == Py_None || v == Py_Ellipsis ||
+ + + - ]
4663 [ + + + + ]: 190 : PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) ||
4664 [ + - + - : 178 : PyAnySet_Check(v)))
+ - ]
4665 : : {
4666 : 89 : return 1;
4667 : : }
4668 : : /* fall through */
4669 : : case Set_kind:
4670 : : case SetComp_kind:
4671 : : case GeneratorExp_kind:
4672 : : case Lambda_kind:
4673 : 20 : return compiler_warn(c, "'%.200s' object is not subscriptable; "
4674 : : "perhaps you missed a comma?",
4675 : 20 : infer_type(e)->tp_name);
4676 : 151490 : default:
4677 : 151490 : return 1;
4678 : : }
4679 : : }
4680 : :
4681 : : static int
4682 : 151589 : check_index(struct compiler *c, expr_ty e, expr_ty s)
4683 : : {
4684 : : PyObject *v;
4685 : :
4686 : 151589 : PyTypeObject *index_type = infer_type(s);
4687 [ + + ]: 151589 : if (index_type == NULL
4688 [ + + ]: 76992 : || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
4689 [ - + ]: 33863 : || index_type == &PySlice_Type) {
4690 : 117726 : return 1;
4691 : : }
4692 : :
4693 [ + + + ]: 33863 : switch (e->kind) {
4694 : 12 : case Constant_kind:
4695 : 12 : v = e->v.Constant.value;
4696 [ + + + + : 12 : if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
+ + ]
4697 : 6 : return 1;
4698 : : }
4699 : : /* fall through */
4700 : : case Tuple_kind:
4701 : : case List_kind:
4702 : : case ListComp_kind:
4703 : : case JoinedStr_kind:
4704 : : case FormattedValue_kind:
4705 : 50 : return compiler_warn(c, "%.200s indices must be integers or slices, "
4706 : : "not %.200s; "
4707 : : "perhaps you missed a comma?",
4708 : 50 : infer_type(e)->tp_name,
4709 : : index_type->tp_name);
4710 : 33807 : default:
4711 : 33807 : return 1;
4712 : : }
4713 : : }
4714 : :
4715 : : static int
4716 : 631003 : is_import_originated(struct compiler *c, expr_ty e)
4717 : : {
4718 : : /* Check whether the global scope has an import named
4719 : : e, if it is a Name object. For not traversing all the
4720 : : scope stack every time this function is called, it will
4721 : : only check the global scope to determine whether something
4722 : : is imported or not. */
4723 : :
4724 [ + + ]: 631003 : if (e->kind != Name_kind) {
4725 : 143052 : return 0;
4726 : : }
4727 : :
4728 : 487951 : long flags = _PyST_GetSymbol(c->c_st->st_top, e->v.Name.id);
4729 : 487951 : return flags & DEF_IMPORT;
4730 : : }
4731 : :
4732 : : static void
4733 : 1063720 : update_location_to_match_attr(struct compiler *c, expr_ty meth)
4734 : : {
4735 [ + + ]: 1063720 : if (meth->lineno != meth->end_lineno) {
4736 : : // Make start location match attribute
4737 : 6258 : c->u->u_loc.lineno = c->u->u_loc.end_lineno = meth->end_lineno;
4738 : 6258 : int len = (int)PyUnicode_GET_LENGTH(meth->v.Attribute.attr);
4739 [ + + ]: 6258 : if (len <= meth->end_col_offset) {
4740 : 6256 : c->u->u_loc.col_offset = meth->end_col_offset - len;
4741 : : }
4742 : : else {
4743 : : // GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
4744 : 2 : c->u->u_loc.col_offset = c->u->u_loc.end_col_offset = -1;
4745 : : }
4746 : : }
4747 : 1063720 : }
4748 : :
4749 : : // Return 1 if the method call was optimized, -1 if not, and 0 on error.
4750 : : static int
4751 : 1122496 : maybe_optimize_method_call(struct compiler *c, expr_ty e)
4752 : : {
4753 : : Py_ssize_t argsl, i, kwdsl;
4754 : 1122496 : expr_ty meth = e->v.Call.func;
4755 : 1122496 : asdl_expr_seq *args = e->v.Call.args;
4756 : 1122496 : asdl_keyword_seq *kwds = e->v.Call.keywords;
4757 : :
4758 : : /* Check that the call node is an attribute access */
4759 [ + + - + ]: 1122496 : if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) {
4760 : 491493 : return -1;
4761 : : }
4762 : :
4763 : : /* Check that the base object is not something that is imported */
4764 [ + + ]: 631003 : if (is_import_originated(c, meth->v.Attribute.value)) {
4765 : 93559 : return -1;
4766 : : }
4767 : :
4768 : : /* Check that there aren't too many arguments */
4769 [ + + ]: 537444 : argsl = asdl_seq_LEN(args);
4770 [ + + ]: 537444 : kwdsl = asdl_seq_LEN(kwds);
4771 [ + + ]: 537444 : if (argsl + kwdsl + (kwdsl != 0) >= STACK_USE_GUIDELINE) {
4772 : 3 : return -1;
4773 : : }
4774 : : /* Check that there are no *varargs types of arguments. */
4775 [ + + ]: 1180703 : for (i = 0; i < argsl; i++) {
4776 : 647016 : expr_ty elt = asdl_seq_GET(args, i);
4777 [ + + ]: 647016 : if (elt->kind == Starred_kind) {
4778 : 3754 : return -1;
4779 : : }
4780 : : }
4781 : :
4782 [ + + ]: 576808 : for (i = 0; i < kwdsl; i++) {
4783 : 44948 : keyword_ty kw = asdl_seq_GET(kwds, i);
4784 [ + + ]: 44948 : if (kw->arg == NULL) {
4785 : 1827 : return -1;
4786 : : }
4787 : : }
4788 : : /* Alright, we can optimize the code. */
4789 [ - + ]: 531860 : VISIT(c, expr, meth->v.Attribute.value);
4790 : 531860 : SET_LOC(c, meth);
4791 : 531860 : update_location_to_match_attr(c, meth);
4792 [ - + ]: 531860 : ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names);
4793 [ - + + + : 1170439 : VISIT_SEQ(c, expr, e->v.Call.args);
+ + ]
4794 : :
4795 [ + + ]: 531860 : if (kwdsl) {
4796 [ - + + - : 67500 : VISIT_SEQ(c, keyword, kwds);
+ + ]
4797 [ - + ]: 25282 : if (!compiler_call_simple_kw_helper(c, kwds, kwdsl)) {
4798 : 0 : return 0;
4799 : : };
4800 : : }
4801 : 531860 : SET_LOC(c, e);
4802 : 531860 : update_location_to_match_attr(c, meth);
4803 [ - + ]: 531860 : ADDOP_I(c, CALL, argsl + kwdsl);
4804 : 531860 : return 1;
4805 : : }
4806 : :
4807 : : static int
4808 : 1750476 : validate_keywords(struct compiler *c, asdl_keyword_seq *keywords)
4809 : : {
4810 [ + + ]: 1750476 : Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
4811 [ + + ]: 1976394 : for (Py_ssize_t i = 0; i < nkeywords; i++) {
4812 : 225924 : keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
4813 [ + + ]: 225924 : if (key->arg == NULL) {
4814 : 14134 : continue;
4815 : : }
4816 [ + + ]: 211790 : if (forbidden_name(c, key->arg, Store)) {
4817 : 1 : return -1;
4818 : : }
4819 [ + + ]: 574186 : for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
4820 : 362402 : keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
4821 [ + + + + ]: 362402 : if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
4822 : 5 : SET_LOC(c, other);
4823 : 5 : compiler_error(c, "keyword argument repeated: %U", key->arg);
4824 : 5 : return -1;
4825 : : }
4826 : : }
4827 : : }
4828 : 1750470 : return 0;
4829 : : }
4830 : :
4831 : : static int
4832 : 1122501 : compiler_call(struct compiler *c, expr_ty e)
4833 : : {
4834 [ + + ]: 1122501 : if (validate_keywords(c, e->v.Call.keywords) == -1) {
4835 : 5 : return 0;
4836 : : }
4837 : 1122496 : int ret = maybe_optimize_method_call(c, e);
4838 [ + + ]: 1122496 : if (ret >= 0) {
4839 : 531860 : return ret;
4840 : : }
4841 [ + + ]: 590636 : if (!check_caller(c, e->v.Call.func)) {
4842 : 19 : return 0;
4843 : : }
4844 : 590617 : SET_LOC(c, e->v.Call.func);
4845 [ - + ]: 590617 : ADDOP(c, PUSH_NULL);
4846 : 590617 : SET_LOC(c, e);
4847 [ - + ]: 590617 : VISIT(c, expr, e->v.Call.func);
4848 : 590617 : return compiler_call_helper(c, 0,
4849 : : e->v.Call.args,
4850 : : e->v.Call.keywords);
4851 : : }
4852 : :
4853 : : static int
4854 : 30335 : compiler_joined_str(struct compiler *c, expr_ty e)
4855 : : {
4856 : :
4857 [ + - ]: 30335 : Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
4858 [ + + ]: 30335 : if (value_count > STACK_USE_GUIDELINE) {
4859 : : _Py_DECLARE_STR(empty, "");
4860 [ - + - + ]: 24 : ADDOP_LOAD_CONST_NEW(c, &_Py_STR(empty));
4861 [ - + ]: 24 : ADDOP_NAME(c, LOAD_METHOD, &_Py_ID(join), names);
4862 [ - + ]: 24 : ADDOP_I(c, BUILD_LIST, 0);
4863 [ + - + + ]: 139097 : for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
4864 [ - + ]: 139073 : VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
4865 [ - + ]: 139073 : ADDOP_I(c, LIST_APPEND, 1);
4866 : : }
4867 [ - + ]: 24 : ADDOP_I(c, CALL, 1);
4868 : : }
4869 : : else {
4870 [ - + + - : 125991 : VISIT_SEQ(c, expr, e->v.JoinedStr.values);
+ + ]
4871 [ + - + + ]: 30311 : if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) {
4872 [ + - - + ]: 24884 : ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
4873 : : }
4874 : : }
4875 : 30335 : return 1;
4876 : : }
4877 : :
4878 : : /* Used to implement f-strings. Format a single value. */
4879 : : static int
4880 : 117920 : compiler_formatted_value(struct compiler *c, expr_ty e)
4881 : : {
4882 : : /* Our oparg encodes 2 pieces of information: the conversion
4883 : : character, and whether or not a format_spec was provided.
4884 : :
4885 : : Convert the conversion char to 3 bits:
4886 : : : 000 0x0 FVC_NONE The default if nothing specified.
4887 : : !s : 001 0x1 FVC_STR
4888 : : !r : 010 0x2 FVC_REPR
4889 : : !a : 011 0x3 FVC_ASCII
4890 : :
4891 : : next bit is whether or not we have a format spec:
4892 : : yes : 100 0x4
4893 : : no : 000 0x0
4894 : : */
4895 : :
4896 : 117920 : int conversion = e->v.FormattedValue.conversion;
4897 : : int oparg;
4898 : :
4899 : : /* The expression to be formatted. */
4900 [ - + ]: 117920 : VISIT(c, expr, e->v.FormattedValue.value);
4901 : :
4902 [ + + + + : 117920 : switch (conversion) {
- ]
4903 : 18484 : case 's': oparg = FVC_STR; break;
4904 : 12635 : case 'r': oparg = FVC_REPR; break;
4905 : 1404 : case 'a': oparg = FVC_ASCII; break;
4906 : 85397 : case -1: oparg = FVC_NONE; break;
4907 : 0 : default:
4908 : 0 : PyErr_Format(PyExc_SystemError,
4909 : : "Unrecognized conversion character %d", conversion);
4910 : 0 : return 0;
4911 : : }
4912 [ + + ]: 117920 : if (e->v.FormattedValue.format_spec) {
4913 : : /* Evaluate the format spec, and update our opcode arg. */
4914 [ - + ]: 4424 : VISIT(c, expr, e->v.FormattedValue.format_spec);
4915 : 4424 : oparg |= FVS_HAVE_SPEC;
4916 : : }
4917 : :
4918 : : /* And push our opcode and oparg */
4919 [ - + ]: 117920 : ADDOP_I(c, FORMAT_VALUE, oparg);
4920 : :
4921 : 117920 : return 1;
4922 : : }
4923 : :
4924 : : static int
4925 : 1384 : compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t begin, Py_ssize_t end)
4926 : : {
4927 : 1384 : Py_ssize_t i, n = end - begin;
4928 : : keyword_ty kw;
4929 : : PyObject *keys, *key;
4930 : : assert(n > 0);
4931 : 1384 : int big = n*2 > STACK_USE_GUIDELINE;
4932 [ + + + + ]: 1384 : if (n > 1 && !big) {
4933 [ + + ]: 2850 : for (i = begin; i < end; i++) {
4934 : 2231 : kw = asdl_seq_GET(keywords, i);
4935 [ - + ]: 2231 : VISIT(c, expr, kw->value);
4936 : : }
4937 : 619 : keys = PyTuple_New(n);
4938 [ - + ]: 619 : if (keys == NULL) {
4939 : 0 : return 0;
4940 : : }
4941 [ + + ]: 2850 : for (i = begin; i < end; i++) {
4942 : 2231 : key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg;
4943 : 2231 : Py_INCREF(key);
4944 : 2231 : PyTuple_SET_ITEM(keys, i - begin, key);
4945 : : }
4946 [ - + - + ]: 619 : ADDOP_LOAD_CONST_NEW(c, keys);
4947 [ - + ]: 619 : ADDOP_I(c, BUILD_CONST_KEY_MAP, n);
4948 : 619 : return 1;
4949 : : }
4950 [ + + ]: 765 : if (big) {
4951 [ - + ]: 16 : ADDOP_I_NOLINE(c, BUILD_MAP, 0);
4952 : : }
4953 [ + + ]: 2276 : for (i = begin; i < end; i++) {
4954 : 1511 : kw = asdl_seq_GET(keywords, i);
4955 [ - + ]: 1511 : ADDOP_LOAD_CONST(c, kw->arg);
4956 [ - + ]: 1511 : VISIT(c, expr, kw->value);
4957 [ + + ]: 1511 : if (big) {
4958 [ - + ]: 762 : ADDOP_I_NOLINE(c, MAP_ADD, 1);
4959 : : }
4960 : : }
4961 [ + + ]: 765 : if (!big) {
4962 [ - + ]: 749 : ADDOP_I(c, BUILD_MAP, n);
4963 : : }
4964 : 765 : return 1;
4965 : : }
4966 : :
4967 : : /* Used by compiler_call_helper and maybe_optimize_method_call to emit
4968 : : * KW_NAMES before CALL.
4969 : : * Returns 1 on success, 0 on error.
4970 : : */
4971 : : static int
4972 : 67803 : compiler_call_simple_kw_helper(struct compiler *c,
4973 : : asdl_keyword_seq *keywords,
4974 : : Py_ssize_t nkwelts)
4975 : : {
4976 : : PyObject *names;
4977 : 67803 : names = PyTuple_New(nkwelts);
4978 [ - + ]: 67803 : if (names == NULL) {
4979 : 0 : return 0;
4980 : : }
4981 [ + + ]: 191602 : for (int i = 0; i < nkwelts; i++) {
4982 : 123799 : keyword_ty kw = asdl_seq_GET(keywords, i);
4983 : 123799 : Py_INCREF(kw->arg);
4984 : 123799 : PyTuple_SET_ITEM(names, i, kw->arg);
4985 : : }
4986 : 67803 : Py_ssize_t arg = compiler_add_const(c, names);
4987 [ - + ]: 67803 : if (arg < 0) {
4988 : 0 : return 0;
4989 : : }
4990 : 67803 : Py_DECREF(names);
4991 [ - + ]: 67803 : ADDOP_I(c, KW_NAMES, arg);
4992 : 67803 : return 1;
4993 : : }
4994 : :
4995 : :
4996 : : /* shared code between compiler_call and compiler_class */
4997 : : static int
4998 : 627975 : compiler_call_helper(struct compiler *c,
4999 : : int n, /* Args already pushed */
5000 : : asdl_expr_seq *args,
5001 : : asdl_keyword_seq *keywords)
5002 : : {
5003 : : Py_ssize_t i, nseen, nelts, nkwelts;
5004 : :
5005 [ + + ]: 627975 : if (validate_keywords(c, keywords) == -1) {
5006 : 1 : return 0;
5007 : : }
5008 : :
5009 [ + + ]: 627974 : nelts = asdl_seq_LEN(args);
5010 [ + + ]: 627974 : nkwelts = asdl_seq_LEN(keywords);
5011 : :
5012 [ + + ]: 627974 : if (nelts + nkwelts*2 > STACK_USE_GUIDELINE) {
5013 : 33 : goto ex_call;
5014 : : }
5015 [ + + ]: 1430354 : for (i = 0; i < nelts; i++) {
5016 : 810743 : expr_ty elt = asdl_seq_GET(args, i);
5017 [ + + ]: 810743 : if (elt->kind == Starred_kind) {
5018 : 8330 : goto ex_call;
5019 : : }
5020 : : }
5021 [ + + ]: 703267 : for (i = 0; i < nkwelts; i++) {
5022 : 87666 : keyword_ty kw = asdl_seq_GET(keywords, i);
5023 [ + + ]: 87666 : if (kw->arg == NULL) {
5024 : 4010 : goto ex_call;
5025 : : }
5026 : : }
5027 : :
5028 : : /* No * or ** args, so can use faster calling sequence */
5029 [ + + ]: 1409332 : for (i = 0; i < nelts; i++) {
5030 : 793731 : expr_ty elt = asdl_seq_GET(args, i);
5031 : : assert(elt->kind != Starred_kind);
5032 [ - + ]: 793731 : VISIT(c, expr, elt);
5033 : : }
5034 [ + + ]: 615601 : if (nkwelts) {
5035 [ - + + - : 124102 : VISIT_SEQ(c, keyword, keywords);
+ + ]
5036 [ - + ]: 42521 : if (!compiler_call_simple_kw_helper(c, keywords, nkwelts)) {
5037 : 0 : return 0;
5038 : : };
5039 : : }
5040 [ - + ]: 615601 : ADDOP_I(c, CALL, n + nelts + nkwelts);
5041 : 615601 : return 1;
5042 : :
5043 : 12373 : ex_call:
5044 : :
5045 : : /* Do positional arguments. */
5046 [ + + + + : 12373 : if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
+ + ]
5047 [ - + ]: 5497 : VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
5048 : : }
5049 [ - + ]: 6876 : else if (starunpack_helper(c, args, n, BUILD_LIST,
5050 : : LIST_APPEND, LIST_EXTEND, 1) == 0) {
5051 : 0 : return 0;
5052 : : }
5053 : : /* Then keyword arguments */
5054 [ + + ]: 12373 : if (nkwelts) {
5055 : : /* Has a new dict been pushed */
5056 : 7495 : int have_dict = 0;
5057 : :
5058 : 7495 : nseen = 0; /* the number of keyword arguments on the stack following */
5059 [ + + ]: 18308 : for (i = 0; i < nkwelts; i++) {
5060 : 10813 : keyword_ty kw = asdl_seq_GET(keywords, i);
5061 [ + + ]: 10813 : if (kw->arg == NULL) {
5062 : : /* A keyword argument unpacking. */
5063 [ + + ]: 7071 : if (nseen) {
5064 [ - + ]: 934 : if (!compiler_subkwargs(c, keywords, i - nseen, i)) {
5065 : 0 : return 0;
5066 : : }
5067 [ + + ]: 934 : if (have_dict) {
5068 [ - + ]: 2 : ADDOP_I(c, DICT_MERGE, 1);
5069 : : }
5070 : 934 : have_dict = 1;
5071 : 934 : nseen = 0;
5072 : : }
5073 [ + + ]: 7071 : if (!have_dict) {
5074 [ - + ]: 6124 : ADDOP_I(c, BUILD_MAP, 0);
5075 : 6124 : have_dict = 1;
5076 : : }
5077 [ - + ]: 7071 : VISIT(c, expr, kw->value);
5078 [ - + ]: 7071 : ADDOP_I(c, DICT_MERGE, 1);
5079 : : }
5080 : : else {
5081 : 3742 : nseen++;
5082 : : }
5083 : : }
5084 [ + + ]: 7495 : if (nseen) {
5085 : : /* Pack up any trailing keyword arguments. */
5086 [ - + ]: 450 : if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts)) {
5087 : 0 : return 0;
5088 : : }
5089 [ + + ]: 450 : if (have_dict) {
5090 [ - + ]: 11 : ADDOP_I(c, DICT_MERGE, 1);
5091 : : }
5092 : 450 : have_dict = 1;
5093 : : }
5094 : : assert(have_dict);
5095 : : }
5096 [ - + ]: 12373 : ADDOP_I(c, CALL_FUNCTION_EX, nkwelts > 0);
5097 : 12373 : return 1;
5098 : : }
5099 : :
5100 : :
5101 : : /* List and set comprehensions and generator expressions work by creating a
5102 : : nested function to perform the actual iteration. This means that the
5103 : : iteration variables don't leak into the current scope.
5104 : : The defined function is called immediately following its definition, with the
5105 : : result of that call being the result of the expression.
5106 : : The LC/SC version returns the populated container, while the GE version is
5107 : : flagged in symtable.c as a generator, so it returns the generator object
5108 : : when the function is called.
5109 : :
5110 : : Possible cleanups:
5111 : : - iterate over the generator sequence instead of using recursion
5112 : : */
5113 : :
5114 : :
5115 : : static int
5116 : 18262 : compiler_comprehension_generator(struct compiler *c,
5117 : : asdl_comprehension_seq *generators, int gen_index,
5118 : : int depth,
5119 : : expr_ty elt, expr_ty val, int type)
5120 : : {
5121 : : comprehension_ty gen;
5122 : 18262 : gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
5123 [ + + ]: 18262 : if (gen->is_async) {
5124 : 63 : return compiler_async_comprehension_generator(
5125 : : c, generators, gen_index, depth, elt, val, type);
5126 : : } else {
5127 : 18199 : return compiler_sync_comprehension_generator(
5128 : : c, generators, gen_index, depth, elt, val, type);
5129 : : }
5130 : : }
5131 : :
5132 : : static int
5133 : 18199 : compiler_sync_comprehension_generator(struct compiler *c,
5134 : : asdl_comprehension_seq *generators, int gen_index,
5135 : : int depth,
5136 : : expr_ty elt, expr_ty val, int type)
5137 : : {
5138 : : /* generate code for the iterator, then each of the ifs,
5139 : : and then write to the element */
5140 : :
5141 : : comprehension_ty gen;
5142 : : basicblock *start, *anchor, *if_cleanup;
5143 : : Py_ssize_t i, n;
5144 : :
5145 : 18199 : start = compiler_new_block(c);
5146 : 18199 : if_cleanup = compiler_new_block(c);
5147 : 18199 : anchor = compiler_new_block(c);
5148 : :
5149 [ + - + - : 18199 : if (start == NULL || if_cleanup == NULL || anchor == NULL) {
- + ]
5150 : 0 : return 0;
5151 : : }
5152 : :
5153 : 18199 : gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
5154 : :
5155 [ + + ]: 18199 : if (gen_index == 0) {
5156 : : /* Receive outermost iter as an implicit argument */
5157 : 17637 : c->u->u_argcount = 1;
5158 [ - + ]: 17637 : ADDOP_I(c, LOAD_FAST, 0);
5159 : : }
5160 : : else {
5161 : : /* Sub-iter - calculate on the fly */
5162 : : /* Fast path for the temporary variable assignment idiom:
5163 : : for y in [f(x)]
5164 : : */
5165 : : asdl_expr_seq *elts;
5166 [ - + + ]: 562 : switch (gen->iter->kind) {
5167 : 0 : case List_kind:
5168 : 0 : elts = gen->iter->v.List.elts;
5169 : 0 : break;
5170 : 22 : case Tuple_kind:
5171 : 22 : elts = gen->iter->v.Tuple.elts;
5172 : 22 : break;
5173 : 540 : default:
5174 : 540 : elts = NULL;
5175 : : }
5176 [ + + + + ]: 562 : if (asdl_seq_LEN(elts) == 1) {
5177 : 21 : expr_ty elt = asdl_seq_GET(elts, 0);
5178 [ + - ]: 21 : if (elt->kind != Starred_kind) {
5179 [ - + ]: 21 : VISIT(c, expr, elt);
5180 : 21 : start = NULL;
5181 : : }
5182 : : }
5183 [ + + ]: 562 : if (start) {
5184 [ - + ]: 541 : VISIT(c, expr, gen->iter);
5185 [ - + ]: 541 : ADDOP(c, GET_ITER);
5186 : : }
5187 : : }
5188 [ + + ]: 18199 : if (start) {
5189 : 18178 : depth++;
5190 : 18178 : compiler_use_next_block(c, start);
5191 [ - + ]: 18178 : ADDOP_JUMP(c, FOR_ITER, anchor);
5192 : : }
5193 [ - + ]: 18199 : VISIT(c, expr, gen->target);
5194 : :
5195 : : /* XXX this needs to be cleaned up...a lot! */
5196 [ + - ]: 18199 : n = asdl_seq_LEN(gen->ifs);
5197 [ + + ]: 22380 : for (i = 0; i < n; i++) {
5198 : 4181 : expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
5199 [ - + ]: 4181 : if (!compiler_jump_if(c, e, if_cleanup, 0))
5200 : 0 : return 0;
5201 : : }
5202 : :
5203 [ + - + + ]: 18199 : if (++gen_index < asdl_seq_LEN(generators))
5204 [ - + ]: 564 : if (!compiler_comprehension_generator(c,
5205 : : generators, gen_index, depth,
5206 : : elt, val, type))
5207 : 0 : return 0;
5208 : :
5209 : : /* only append after the last for generator */
5210 [ + - + + ]: 18199 : if (gen_index >= asdl_seq_LEN(generators)) {
5211 : : /* comprehension specific code */
5212 [ + + + + : 17635 : switch (type) {
- ]
5213 : 7694 : case COMP_GENEXP:
5214 [ - + ]: 7694 : VISIT(c, expr, elt);
5215 [ - + ]: 7694 : ADDOP_YIELD(c);
5216 [ - + ]: 7694 : ADDOP(c, POP_TOP);
5217 : 7694 : break;
5218 : 8388 : case COMP_LISTCOMP:
5219 [ - + ]: 8388 : VISIT(c, expr, elt);
5220 [ - + ]: 8388 : ADDOP_I(c, LIST_APPEND, depth + 1);
5221 : 8388 : break;
5222 : 397 : case COMP_SETCOMP:
5223 [ - + ]: 397 : VISIT(c, expr, elt);
5224 [ - + ]: 397 : ADDOP_I(c, SET_ADD, depth + 1);
5225 : 397 : break;
5226 : 1156 : case COMP_DICTCOMP:
5227 : : /* With '{k: v}', k is evaluated before v, so we do
5228 : : the same. */
5229 [ - + ]: 1156 : VISIT(c, expr, elt);
5230 [ - + ]: 1156 : VISIT(c, expr, val);
5231 [ - + ]: 1156 : ADDOP_I(c, MAP_ADD, depth + 1);
5232 : 1156 : break;
5233 : 0 : default:
5234 : 0 : return 0;
5235 : : }
5236 : : }
5237 : 18199 : compiler_use_next_block(c, if_cleanup);
5238 [ + + ]: 18199 : if (start) {
5239 [ - + ]: 18178 : ADDOP_JUMP(c, JUMP, start);
5240 : 18178 : compiler_use_next_block(c, anchor);
5241 : : }
5242 : :
5243 : 18199 : return 1;
5244 : : }
5245 : :
5246 : : static int
5247 : 63 : compiler_async_comprehension_generator(struct compiler *c,
5248 : : asdl_comprehension_seq *generators, int gen_index,
5249 : : int depth,
5250 : : expr_ty elt, expr_ty val, int type)
5251 : : {
5252 : : comprehension_ty gen;
5253 : : basicblock *start, *if_cleanup, *except;
5254 : : Py_ssize_t i, n;
5255 : 63 : start = compiler_new_block(c);
5256 : 63 : except = compiler_new_block(c);
5257 : 63 : if_cleanup = compiler_new_block(c);
5258 : :
5259 [ + - + - : 63 : if (start == NULL || if_cleanup == NULL || except == NULL) {
- + ]
5260 : 0 : return 0;
5261 : : }
5262 : :
5263 : 63 : gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
5264 : :
5265 [ + + ]: 63 : if (gen_index == 0) {
5266 : : /* Receive outermost iter as an implicit argument */
5267 : 58 : c->u->u_argcount = 1;
5268 [ - + ]: 58 : ADDOP_I(c, LOAD_FAST, 0);
5269 : : }
5270 : : else {
5271 : : /* Sub-iter - calculate on the fly */
5272 [ - + ]: 5 : VISIT(c, expr, gen->iter);
5273 [ - + ]: 5 : ADDOP(c, GET_AITER);
5274 : : }
5275 : :
5276 : 63 : compiler_use_next_block(c, start);
5277 : : /* Runtime will push a block here, so we need to account for that */
5278 [ - + ]: 63 : if (!compiler_push_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start,
5279 : : NULL, NULL)) {
5280 : 0 : return 0;
5281 : : }
5282 : :
5283 [ - + ]: 63 : ADDOP_JUMP(c, SETUP_FINALLY, except);
5284 [ - + ]: 63 : ADDOP(c, GET_ANEXT);
5285 [ - + ]: 63 : ADDOP_LOAD_CONST(c, Py_None);
5286 [ - + ]: 63 : ADD_YIELD_FROM(c, 1);
5287 [ - + ]: 63 : ADDOP(c, POP_BLOCK);
5288 [ - + ]: 63 : VISIT(c, expr, gen->target);
5289 : :
5290 [ + - ]: 63 : n = asdl_seq_LEN(gen->ifs);
5291 [ + + ]: 72 : for (i = 0; i < n; i++) {
5292 : 9 : expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
5293 [ - + ]: 9 : if (!compiler_jump_if(c, e, if_cleanup, 0))
5294 : 0 : return 0;
5295 : : }
5296 : :
5297 : 63 : depth++;
5298 [ + - + + ]: 63 : if (++gen_index < asdl_seq_LEN(generators))
5299 [ - + ]: 3 : if (!compiler_comprehension_generator(c,
5300 : : generators, gen_index, depth,
5301 : : elt, val, type))
5302 : 0 : return 0;
5303 : :
5304 : : /* only append after the last for generator */
5305 [ + - + + ]: 63 : if (gen_index >= asdl_seq_LEN(generators)) {
5306 : : /* comprehension specific code */
5307 [ + + + + : 60 : switch (type) {
- ]
5308 : 10 : case COMP_GENEXP:
5309 [ - + ]: 10 : VISIT(c, expr, elt);
5310 [ - + ]: 10 : ADDOP_YIELD(c);
5311 [ - + ]: 10 : ADDOP(c, POP_TOP);
5312 : 10 : break;
5313 : 36 : case COMP_LISTCOMP:
5314 [ - + ]: 36 : VISIT(c, expr, elt);
5315 [ - + ]: 36 : ADDOP_I(c, LIST_APPEND, depth + 1);
5316 : 36 : break;
5317 : 8 : case COMP_SETCOMP:
5318 [ - + ]: 8 : VISIT(c, expr, elt);
5319 [ - + ]: 8 : ADDOP_I(c, SET_ADD, depth + 1);
5320 : 8 : break;
5321 : 6 : case COMP_DICTCOMP:
5322 : : /* With '{k: v}', k is evaluated before v, so we do
5323 : : the same. */
5324 [ - + ]: 6 : VISIT(c, expr, elt);
5325 [ - + ]: 6 : VISIT(c, expr, val);
5326 [ - + ]: 6 : ADDOP_I(c, MAP_ADD, depth + 1);
5327 : 6 : break;
5328 : 0 : default:
5329 : 0 : return 0;
5330 : : }
5331 : : }
5332 : 63 : compiler_use_next_block(c, if_cleanup);
5333 [ - + ]: 63 : ADDOP_JUMP(c, JUMP, start);
5334 : :
5335 : 63 : compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start);
5336 : :
5337 : 63 : compiler_use_next_block(c, except);
5338 : : //UNSET_LOC(c);
5339 : :
5340 [ - + ]: 63 : ADDOP(c, END_ASYNC_FOR);
5341 : :
5342 : 63 : return 1;
5343 : : }
5344 : :
5345 : : static int
5346 : 17737 : compiler_comprehension(struct compiler *c, expr_ty e, int type,
5347 : : identifier name, asdl_comprehension_seq *generators, expr_ty elt,
5348 : : expr_ty val)
5349 : : {
5350 : 17737 : PyCodeObject *co = NULL;
5351 : : comprehension_ty outermost;
5352 : 17737 : PyObject *qualname = NULL;
5353 : 17737 : int scope_type = c->u->u_scope_type;
5354 : 17737 : int is_async_generator = 0;
5355 [ + + + + ]: 17737 : int is_top_level_await = IS_TOP_LEVEL_AWAIT(c);
5356 : :
5357 : 17737 : outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
5358 [ - + ]: 17737 : if (!compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION,
5359 : : (void *)e, e->lineno))
5360 : : {
5361 : 0 : goto error;
5362 : : }
5363 : 17737 : SET_LOC(c, e);
5364 : :
5365 : 17737 : is_async_generator = c->u->u_ste->ste_coroutine;
5366 : :
5367 [ + + + + : 17737 : if (is_async_generator && type != COMP_GENEXP &&
+ + ]
5368 [ + + ]: 63 : scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
5369 [ + + ]: 56 : scope_type != COMPILER_SCOPE_COMPREHENSION &&
5370 : : !is_top_level_await)
5371 : : {
5372 : 42 : compiler_error(c, "asynchronous comprehension outside of "
5373 : : "an asynchronous function");
5374 : 42 : goto error_in_scope;
5375 : : }
5376 : :
5377 [ + + ]: 17695 : if (type != COMP_GENEXP) {
5378 : : int op;
5379 [ + + + - ]: 9991 : switch (type) {
5380 : 8424 : case COMP_LISTCOMP:
5381 : 8424 : op = BUILD_LIST;
5382 : 8424 : break;
5383 : 405 : case COMP_SETCOMP:
5384 : 405 : op = BUILD_SET;
5385 : 405 : break;
5386 : 1162 : case COMP_DICTCOMP:
5387 : 1162 : op = BUILD_MAP;
5388 : 1162 : break;
5389 : 0 : default:
5390 : 0 : PyErr_Format(PyExc_SystemError,
5391 : : "unknown comprehension type %d", type);
5392 : 0 : goto error_in_scope;
5393 : : }
5394 : :
5395 [ - + ]: 9991 : ADDOP_I(c, op, 0);
5396 : : }
5397 : :
5398 [ - + ]: 17695 : if (!compiler_comprehension_generator(c, generators, 0, 0, elt,
5399 : : val, type))
5400 : 0 : goto error_in_scope;
5401 : :
5402 [ + + ]: 17695 : if (type != COMP_GENEXP) {
5403 [ - + ]: 9991 : ADDOP(c, RETURN_VALUE);
5404 : : }
5405 : :
5406 : 17695 : co = assemble(c, 1);
5407 : 17695 : qualname = c->u->u_qualname;
5408 : 17695 : Py_INCREF(qualname);
5409 : 17695 : compiler_exit_scope(c);
5410 [ + + + + ]: 17695 : if (is_top_level_await && is_async_generator){
5411 : 16 : c->u->u_ste->ste_coroutine = 1;
5412 : : }
5413 [ - + ]: 17695 : if (co == NULL)
5414 : 0 : goto error;
5415 : :
5416 [ - + ]: 17695 : if (!compiler_make_closure(c, co, 0, qualname)) {
5417 : 0 : goto error;
5418 : : }
5419 : 17695 : Py_DECREF(qualname);
5420 : 17695 : Py_DECREF(co);
5421 : :
5422 [ + + ]: 17695 : VISIT(c, expr, outermost->iter);
5423 : :
5424 [ + + ]: 17691 : if (outermost->is_async) {
5425 [ - + ]: 58 : ADDOP(c, GET_AITER);
5426 : : } else {
5427 [ - + ]: 17633 : ADDOP(c, GET_ITER);
5428 : : }
5429 : :
5430 [ - + ]: 17691 : ADDOP_I(c, CALL, 0);
5431 : :
5432 [ + + + + ]: 17691 : if (is_async_generator && type != COMP_GENEXP) {
5433 [ - + ]: 67 : ADDOP_I(c, GET_AWAITABLE, 0);
5434 [ - + ]: 67 : ADDOP_LOAD_CONST(c, Py_None);
5435 [ - + ]: 67 : ADD_YIELD_FROM(c, 1);
5436 : : }
5437 : :
5438 : 17691 : return 1;
5439 : 42 : error_in_scope:
5440 : 42 : compiler_exit_scope(c);
5441 : 42 : error:
5442 : 42 : Py_XDECREF(qualname);
5443 : 42 : Py_XDECREF(co);
5444 : 42 : return 0;
5445 : : }
5446 : :
5447 : : static int
5448 : 7704 : compiler_genexp(struct compiler *c, expr_ty e)
5449 : : {
5450 : : assert(e->kind == GeneratorExp_kind);
5451 : : _Py_DECLARE_STR(anon_genexpr, "<genexpr>");
5452 : 7704 : return compiler_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
5453 : : e->v.GeneratorExp.generators,
5454 : : e->v.GeneratorExp.elt, NULL);
5455 : : }
5456 : :
5457 : : static int
5458 : 8458 : compiler_listcomp(struct compiler *c, expr_ty e)
5459 : : {
5460 : : assert(e->kind == ListComp_kind);
5461 : : _Py_DECLARE_STR(anon_listcomp, "<listcomp>");
5462 : 8458 : return compiler_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
5463 : : e->v.ListComp.generators,
5464 : : e->v.ListComp.elt, NULL);
5465 : : }
5466 : :
5467 : : static int
5468 : 410 : compiler_setcomp(struct compiler *c, expr_ty e)
5469 : : {
5470 : : assert(e->kind == SetComp_kind);
5471 : : _Py_DECLARE_STR(anon_setcomp, "<setcomp>");
5472 : 410 : return compiler_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp),
5473 : : e->v.SetComp.generators,
5474 : : e->v.SetComp.elt, NULL);
5475 : : }
5476 : :
5477 : :
5478 : : static int
5479 : 1165 : compiler_dictcomp(struct compiler *c, expr_ty e)
5480 : : {
5481 : : assert(e->kind == DictComp_kind);
5482 : : _Py_DECLARE_STR(anon_dictcomp, "<dictcomp>");
5483 : 1165 : return compiler_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
5484 : : e->v.DictComp.generators,
5485 : : e->v.DictComp.key, e->v.DictComp.value);
5486 : : }
5487 : :
5488 : :
5489 : : static int
5490 : 123799 : compiler_visit_keyword(struct compiler *c, keyword_ty k)
5491 : : {
5492 [ - + ]: 123799 : VISIT(c, expr, k->value);
5493 : 123799 : return 1;
5494 : : }
5495 : :
5496 : :
5497 : : static int
5498 : 21218 : compiler_with_except_finish(struct compiler *c, basicblock * cleanup) {
5499 : 21218 : UNSET_LOC(c);
5500 : 21218 : basicblock *suppress = compiler_new_block(c);
5501 [ - + ]: 21218 : if (suppress == NULL) {
5502 : 0 : return 0;
5503 : : }
5504 [ - + ]: 21218 : ADDOP_JUMP(c, POP_JUMP_IF_TRUE, suppress);
5505 [ - + ]: 21218 : ADDOP_I(c, RERAISE, 2);
5506 : 21218 : compiler_use_next_block(c, suppress);
5507 [ - + ]: 21218 : ADDOP(c, POP_TOP); /* exc_value */
5508 [ - + ]: 21218 : ADDOP(c, POP_BLOCK);
5509 [ - + ]: 21218 : ADDOP(c, POP_EXCEPT);
5510 [ - + ]: 21218 : ADDOP(c, POP_TOP);
5511 [ - + ]: 21218 : ADDOP(c, POP_TOP);
5512 : 21218 : basicblock *exit = compiler_new_block(c);
5513 [ - + ]: 21218 : if (exit == NULL) {
5514 : 0 : return 0;
5515 : : }
5516 [ - + ]: 21218 : ADDOP_JUMP(c, JUMP, exit);
5517 : 21218 : compiler_use_next_block(c, cleanup);
5518 [ - + ]: 21218 : POP_EXCEPT_AND_RERAISE(c);
5519 : 21218 : compiler_use_next_block(c, exit);
5520 : 21218 : return 1;
5521 : : }
5522 : :
5523 : : /*
5524 : : Implements the async with statement.
5525 : :
5526 : : The semantics outlined in that PEP are as follows:
5527 : :
5528 : : async with EXPR as VAR:
5529 : : BLOCK
5530 : :
5531 : : It is implemented roughly as:
5532 : :
5533 : : context = EXPR
5534 : : exit = context.__aexit__ # not calling it
5535 : : value = await context.__aenter__()
5536 : : try:
5537 : : VAR = value # if VAR present in the syntax
5538 : : BLOCK
5539 : : finally:
5540 : : if an exception was raised:
5541 : : exc = copy of (exception, instance, traceback)
5542 : : else:
5543 : : exc = (None, None, None)
5544 : : if not (await exit(*exc)):
5545 : : raise
5546 : : */
5547 : : static int
5548 : 235 : compiler_async_with(struct compiler *c, stmt_ty s, int pos)
5549 : : {
5550 : : basicblock *block, *final, *exit, *cleanup;
5551 : 235 : withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
5552 : :
5553 : : assert(s->kind == AsyncWith_kind);
5554 [ + + + + ]: 235 : if (IS_TOP_LEVEL_AWAIT(c)){
5555 : 2 : c->u->u_ste->ste_coroutine = 1;
5556 [ + + ]: 233 : } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){
5557 : 8 : return compiler_error(c, "'async with' outside async function");
5558 : : }
5559 : :
5560 : 227 : block = compiler_new_block(c);
5561 : 227 : final = compiler_new_block(c);
5562 : 227 : exit = compiler_new_block(c);
5563 : 227 : cleanup = compiler_new_block(c);
5564 [ + - + - : 227 : if (!block || !final || !exit || !cleanup)
+ - - + ]
5565 : 0 : return 0;
5566 : :
5567 : : /* Evaluate EXPR */
5568 [ - + ]: 227 : VISIT(c, expr, item->context_expr);
5569 : :
5570 [ - + ]: 227 : ADDOP(c, BEFORE_ASYNC_WITH);
5571 [ - + ]: 227 : ADDOP_I(c, GET_AWAITABLE, 1);
5572 [ - + ]: 227 : ADDOP_LOAD_CONST(c, Py_None);
5573 [ - + ]: 227 : ADD_YIELD_FROM(c, 1);
5574 : :
5575 [ - + ]: 227 : ADDOP_JUMP(c, SETUP_WITH, final);
5576 : :
5577 : : /* SETUP_WITH pushes a finally block. */
5578 : 227 : compiler_use_next_block(c, block);
5579 [ - + ]: 227 : if (!compiler_push_fblock(c, ASYNC_WITH, block, final, s)) {
5580 : 0 : return 0;
5581 : : }
5582 : :
5583 [ + + ]: 227 : if (item->optional_vars) {
5584 [ - + ]: 109 : VISIT(c, expr, item->optional_vars);
5585 : : }
5586 : : else {
5587 : : /* Discard result from context.__aenter__() */
5588 [ - + ]: 118 : ADDOP(c, POP_TOP);
5589 : : }
5590 : :
5591 : 227 : pos++;
5592 [ + - + + ]: 227 : if (pos == asdl_seq_LEN(s->v.AsyncWith.items))
5593 : : /* BLOCK code */
5594 [ - + + - : 586 : VISIT_SEQ(c, stmt, s->v.AsyncWith.body)
+ + ]
5595 [ - + ]: 8 : else if (!compiler_async_with(c, s, pos))
5596 : 0 : return 0;
5597 : :
5598 : 227 : compiler_pop_fblock(c, ASYNC_WITH, block);
5599 [ - + ]: 227 : ADDOP(c, POP_BLOCK);
5600 : : /* End of body; start the cleanup */
5601 : :
5602 : : /* For successful outcome:
5603 : : * call __exit__(None, None, None)
5604 : : */
5605 : 227 : SET_LOC(c, s);
5606 [ - + ]: 227 : if(!compiler_call_exit_with_nones(c))
5607 : 0 : return 0;
5608 [ - + ]: 227 : ADDOP_I(c, GET_AWAITABLE, 2);
5609 [ - + ]: 227 : ADDOP_LOAD_CONST(c, Py_None);
5610 [ - + ]: 227 : ADD_YIELD_FROM(c, 1);
5611 : :
5612 [ - + ]: 227 : ADDOP(c, POP_TOP);
5613 : :
5614 [ - + ]: 227 : ADDOP_JUMP(c, JUMP, exit);
5615 : :
5616 : : /* For exceptional outcome: */
5617 : 227 : compiler_use_next_block(c, final);
5618 : :
5619 [ - + ]: 227 : ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
5620 [ - + ]: 227 : ADDOP(c, PUSH_EXC_INFO);
5621 [ - + ]: 227 : ADDOP(c, WITH_EXCEPT_START);
5622 [ - + ]: 227 : ADDOP_I(c, GET_AWAITABLE, 2);
5623 [ - + ]: 227 : ADDOP_LOAD_CONST(c, Py_None);
5624 [ - + ]: 227 : ADD_YIELD_FROM(c, 1);
5625 : 227 : compiler_with_except_finish(c, cleanup);
5626 : :
5627 : 227 : compiler_use_next_block(c, exit);
5628 : 227 : return 1;
5629 : : }
5630 : :
5631 : :
5632 : : /*
5633 : : Implements the with statement from PEP 343.
5634 : : with EXPR as VAR:
5635 : : BLOCK
5636 : : is implemented as:
5637 : : <code for EXPR>
5638 : : SETUP_WITH E
5639 : : <code to store to VAR> or POP_TOP
5640 : : <code for BLOCK>
5641 : : LOAD_CONST (None, None, None)
5642 : : CALL_FUNCTION_EX 0
5643 : : JUMP EXIT
5644 : : E: WITH_EXCEPT_START (calls EXPR.__exit__)
5645 : : POP_JUMP_IF_TRUE T:
5646 : : RERAISE
5647 : : T: POP_TOP (remove exception from stack)
5648 : : POP_EXCEPT
5649 : : POP_TOP
5650 : : EXIT:
5651 : : */
5652 : :
5653 : : static int
5654 : 20991 : compiler_with(struct compiler *c, stmt_ty s, int pos)
5655 : : {
5656 : : basicblock *block, *final, *exit, *cleanup;
5657 : 20991 : withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
5658 : :
5659 : : assert(s->kind == With_kind);
5660 : :
5661 : 20991 : block = compiler_new_block(c);
5662 : 20991 : final = compiler_new_block(c);
5663 : 20991 : exit = compiler_new_block(c);
5664 : 20991 : cleanup = compiler_new_block(c);
5665 [ + - + - : 20991 : if (!block || !final || !exit || !cleanup)
+ - - + ]
5666 : 0 : return 0;
5667 : :
5668 : : /* Evaluate EXPR */
5669 [ - + ]: 20991 : VISIT(c, expr, item->context_expr);
5670 : : /* Will push bound __exit__ */
5671 [ - + ]: 20991 : ADDOP(c, BEFORE_WITH);
5672 [ - + ]: 20991 : ADDOP_JUMP(c, SETUP_WITH, final);
5673 : :
5674 : : /* SETUP_WITH pushes a finally block. */
5675 : 20991 : compiler_use_next_block(c, block);
5676 [ - + ]: 20991 : if (!compiler_push_fblock(c, WITH, block, final, s)) {
5677 : 0 : return 0;
5678 : : }
5679 : :
5680 [ + + ]: 20991 : if (item->optional_vars) {
5681 [ - + ]: 9083 : VISIT(c, expr, item->optional_vars);
5682 : : }
5683 : : else {
5684 : : /* Discard result from context.__enter__() */
5685 [ - + ]: 11908 : ADDOP(c, POP_TOP);
5686 : : }
5687 : :
5688 : 20991 : pos++;
5689 [ + - + + ]: 20991 : if (pos == asdl_seq_LEN(s->v.With.items))
5690 : : /* BLOCK code */
5691 [ - + + - : 60226 : VISIT_SEQ(c, stmt, s->v.With.body)
+ + ]
5692 [ - + ]: 376 : else if (!compiler_with(c, s, pos))
5693 : 0 : return 0;
5694 : :
5695 : :
5696 : : /* Mark all following code as artificial */
5697 : 20991 : UNSET_LOC(c);
5698 [ - + ]: 20991 : ADDOP(c, POP_BLOCK);
5699 : 20991 : compiler_pop_fblock(c, WITH, block);
5700 : :
5701 : : /* End of body; start the cleanup. */
5702 : :
5703 : : /* For successful outcome:
5704 : : * call __exit__(None, None, None)
5705 : : */
5706 : 20991 : SET_LOC(c, s);
5707 [ - + ]: 20991 : if (!compiler_call_exit_with_nones(c))
5708 : 0 : return 0;
5709 [ - + ]: 20991 : ADDOP(c, POP_TOP);
5710 [ - + ]: 20991 : ADDOP_JUMP(c, JUMP, exit);
5711 : :
5712 : : /* For exceptional outcome: */
5713 : 20991 : compiler_use_next_block(c, final);
5714 : :
5715 [ - + ]: 20991 : ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
5716 [ - + ]: 20991 : ADDOP(c, PUSH_EXC_INFO);
5717 [ - + ]: 20991 : ADDOP(c, WITH_EXCEPT_START);
5718 : 20991 : compiler_with_except_finish(c, cleanup);
5719 : :
5720 : 20991 : compiler_use_next_block(c, exit);
5721 : 20991 : return 1;
5722 : : }
5723 : :
5724 : : static int
5725 : 9992319 : compiler_visit_expr1(struct compiler *c, expr_ty e)
5726 : : {
5727 [ + + + + : 9992319 : switch (e->kind) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - ]
5728 : 724 : case NamedExpr_kind:
5729 [ - + ]: 724 : VISIT(c, expr, e->v.NamedExpr.value);
5730 [ - + ]: 724 : ADDOP_I(c, COPY, 1);
5731 [ + + ]: 724 : VISIT(c, expr, e->v.NamedExpr.target);
5732 : 723 : break;
5733 : 17309 : case BoolOp_kind:
5734 : 17309 : return compiler_boolop(c, e);
5735 : 196377 : case BinOp_kind:
5736 [ - + ]: 196377 : VISIT(c, expr, e->v.BinOp.left);
5737 [ - + ]: 196377 : VISIT(c, expr, e->v.BinOp.right);
5738 [ - + ]: 196377 : ADDOP_BINARY(c, e->v.BinOp.op);
5739 : 196377 : break;
5740 : 7513 : case UnaryOp_kind:
5741 [ - + ]: 7513 : VISIT(c, expr, e->v.UnaryOp.operand);
5742 [ - + ]: 7513 : ADDOP(c, unaryop(e->v.UnaryOp.op));
5743 : 7513 : break;
5744 : 34467 : case Lambda_kind:
5745 : 34467 : return compiler_lambda(c, e);
5746 : 9745 : case IfExp_kind:
5747 : 9745 : return compiler_ifexp(c, e);
5748 : 32228 : case Dict_kind:
5749 : 32228 : return compiler_dict(c, e);
5750 : 1810 : case Set_kind:
5751 : 1810 : return compiler_set(c, e);
5752 : 7704 : case GeneratorExp_kind:
5753 : 7704 : return compiler_genexp(c, e);
5754 : 8458 : case ListComp_kind:
5755 : 8458 : return compiler_listcomp(c, e);
5756 : 410 : case SetComp_kind:
5757 : 410 : return compiler_setcomp(c, e);
5758 : 1165 : case DictComp_kind:
5759 : 1165 : return compiler_dictcomp(c, e);
5760 : 11445 : case Yield_kind:
5761 [ + + ]: 11445 : if (c->u->u_ste->ste_type != FunctionBlock)
5762 : 15 : return compiler_error(c, "'yield' outside function");
5763 [ + + ]: 11430 : if (e->v.Yield.value) {
5764 [ - + ]: 10690 : VISIT(c, expr, e->v.Yield.value);
5765 : : }
5766 : : else {
5767 [ - + ]: 740 : ADDOP_LOAD_CONST(c, Py_None);
5768 : : }
5769 [ - + ]: 11430 : ADDOP_YIELD(c);
5770 : 11430 : break;
5771 : 1895 : case YieldFrom_kind:
5772 [ + + ]: 1895 : if (c->u->u_ste->ste_type != FunctionBlock)
5773 : 3 : return compiler_error(c, "'yield' outside function");
5774 : :
5775 [ + + ]: 1892 : if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION)
5776 : 3 : return compiler_error(c, "'yield from' inside async function");
5777 : :
5778 [ - + ]: 1889 : VISIT(c, expr, e->v.YieldFrom.value);
5779 [ - + ]: 1889 : ADDOP(c, GET_YIELD_FROM_ITER);
5780 [ - + ]: 1889 : ADDOP_LOAD_CONST(c, Py_None);
5781 [ - + ]: 1889 : ADD_YIELD_FROM(c, 0);
5782 : 1889 : break;
5783 : 1746 : case Await_kind:
5784 [ + + + + ]: 1746 : if (!IS_TOP_LEVEL_AWAIT(c)){
5785 [ + + ]: 1744 : if (c->u->u_ste->ste_type != FunctionBlock){
5786 : 11 : return compiler_error(c, "'await' outside function");
5787 : : }
5788 : :
5789 [ + + ]: 1733 : if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
5790 [ + + ]: 29 : c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){
5791 : 14 : return compiler_error(c, "'await' outside async function");
5792 : : }
5793 : : }
5794 : :
5795 [ - + ]: 1721 : VISIT(c, expr, e->v.Await.value);
5796 [ - + ]: 1721 : ADDOP_I(c, GET_AWAITABLE, 0);
5797 [ - + ]: 1721 : ADDOP_LOAD_CONST(c, Py_None);
5798 [ - + ]: 1721 : ADD_YIELD_FROM(c, 1);
5799 : 1721 : break;
5800 : 209513 : case Compare_kind:
5801 : 209513 : return compiler_compare(c, e);
5802 : 1122501 : case Call_kind:
5803 : 1122501 : return compiler_call(c, e);
5804 : 2333145 : case Constant_kind:
5805 [ - + ]: 2333145 : ADDOP_LOAD_CONST(c, e->v.Constant.value);
5806 : 2333145 : break;
5807 : 30335 : case JoinedStr_kind:
5808 : 30335 : return compiler_joined_str(c, e);
5809 : 117920 : case FormattedValue_kind:
5810 : 117920 : return compiler_formatted_value(c, e);
5811 : : /* The following exprs can be assignment targets. */
5812 : 793248 : case Attribute_kind:
5813 [ - + ]: 793248 : VISIT(c, expr, e->v.Attribute.value);
5814 [ + + + - ]: 793248 : switch (e->v.Attribute.ctx) {
5815 : 671700 : case Load:
5816 : : {
5817 : 671700 : int old_lineno = c->u->u_loc.lineno;
5818 : 671700 : c->u->u_loc.lineno = e->end_lineno;
5819 [ - + ]: 671700 : ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
5820 : 671700 : c->u->u_loc.lineno = old_lineno;
5821 : 671700 : break;
5822 : : }
5823 : 120489 : case Store:
5824 [ + + ]: 120489 : if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) {
5825 : 1 : return 0;
5826 : : }
5827 : 120488 : int old_lineno = c->u->u_loc.lineno;
5828 : 120488 : c->u->u_loc.lineno = e->end_lineno;
5829 [ - + ]: 120488 : ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
5830 : 120488 : c->u->u_loc.lineno = old_lineno;
5831 : 120488 : break;
5832 : 1059 : case Del:
5833 [ - + ]: 1059 : ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names);
5834 : 1059 : break;
5835 : : }
5836 : 793247 : break;
5837 : 183832 : case Subscript_kind:
5838 : 183832 : return compiler_subscript(c, e);
5839 : 4 : case Starred_kind:
5840 [ + + ]: 4 : switch (e->v.Starred.ctx) {
5841 : 1 : case Store:
5842 : : /* In all legitimate cases, the Starred node was already replaced
5843 : : * by compiler_list/compiler_tuple. XXX: is that okay? */
5844 : 1 : return compiler_error(c,
5845 : : "starred assignment target must be in a list or tuple");
5846 : 3 : default:
5847 : 3 : return compiler_error(c,
5848 : : "can't use starred expression here");
5849 : : }
5850 : : break;
5851 : 1743 : case Slice_kind:
5852 : : {
5853 : 1743 : int n = compiler_slice(c, e);
5854 [ - + ]: 1743 : if (n == 0) {
5855 : 0 : return 0;
5856 : : }
5857 [ - + ]: 1743 : ADDOP_I(c, BUILD_SLICE, n);
5858 : 1743 : break;
5859 : : }
5860 : 4638255 : case Name_kind:
5861 : 4638255 : return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
5862 : : /* child nodes of List and Tuple will have expr_context set */
5863 : 63142 : case List_kind:
5864 : 63142 : return compiler_list(c, e);
5865 : 165685 : case Tuple_kind:
5866 : 165685 : return compiler_tuple(c, e);
5867 : : }
5868 : 3347788 : return 1;
5869 : : }
5870 : :
5871 : : static int
5872 : 9992319 : compiler_visit_expr(struct compiler *c, expr_ty e)
5873 : : {
5874 : 9992319 : struct location old_loc = c->u->u_loc;
5875 : 9992319 : SET_LOC(c, e);
5876 : 9992319 : int res = compiler_visit_expr1(c, e);
5877 : 9992319 : c->u->u_loc = old_loc;
5878 : 9992319 : return res;
5879 : : }
5880 : :
5881 : : static bool
5882 : 186235 : is_two_element_slice(expr_ty s)
5883 : : {
5884 [ + + ]: 216966 : return s->kind == Slice_kind &&
5885 [ + + ]: 30731 : s->v.Slice.step == NULL;
5886 : : }
5887 : :
5888 : : static int
5889 : 21488 : compiler_augassign(struct compiler *c, stmt_ty s)
5890 : : {
5891 : : assert(s->kind == AugAssign_kind);
5892 : 21488 : expr_ty e = s->v.AugAssign.target;
5893 : :
5894 : 21488 : struct location old_loc = c->u->u_loc;
5895 : 21488 : SET_LOC(c, e);
5896 : :
5897 [ + + + - ]: 21488 : switch (e->kind) {
5898 : 3949 : case Attribute_kind:
5899 [ - + ]: 3949 : VISIT(c, expr, e->v.Attribute.value);
5900 [ - + ]: 3949 : ADDOP_I(c, COPY, 1);
5901 : 3949 : int old_lineno = c->u->u_loc.lineno;
5902 : 3949 : c->u->u_loc.lineno = e->end_lineno;
5903 [ - + ]: 3949 : ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
5904 : 3949 : c->u->u_loc.lineno = old_lineno;
5905 : 3949 : break;
5906 : 1224 : case Subscript_kind:
5907 [ - + ]: 1224 : VISIT(c, expr, e->v.Subscript.value);
5908 [ + + ]: 1224 : if (is_two_element_slice(e->v.Subscript.slice)) {
5909 [ - + ]: 8 : if (!compiler_slice(c, e->v.Subscript.slice)) {
5910 : 0 : return 0;
5911 : : }
5912 [ - + ]: 8 : ADDOP_I(c, COPY, 3);
5913 [ - + ]: 8 : ADDOP_I(c, COPY, 3);
5914 [ - + ]: 8 : ADDOP_I(c, COPY, 3);
5915 [ - + ]: 8 : ADDOP(c, BINARY_SLICE);
5916 : : }
5917 : : else {
5918 [ - + ]: 1216 : VISIT(c, expr, e->v.Subscript.slice);
5919 [ - + ]: 1216 : ADDOP_I(c, COPY, 2);
5920 [ - + ]: 1216 : ADDOP_I(c, COPY, 2);
5921 [ - + ]: 1216 : ADDOP(c, BINARY_SUBSCR);
5922 : : }
5923 : 1224 : break;
5924 : 16315 : case Name_kind:
5925 [ - + ]: 16315 : if (!compiler_nameop(c, e->v.Name.id, Load))
5926 : 0 : return 0;
5927 : 16315 : break;
5928 : 0 : default:
5929 : 0 : PyErr_Format(PyExc_SystemError,
5930 : : "invalid node type (%d) for augmented assignment",
5931 : 0 : e->kind);
5932 : 0 : return 0;
5933 : : }
5934 : :
5935 : 21488 : c->u->u_loc = old_loc;
5936 : :
5937 [ - + ]: 21488 : VISIT(c, expr, s->v.AugAssign.value);
5938 [ - + ]: 21488 : ADDOP_INPLACE(c, s->v.AugAssign.op);
5939 : :
5940 : 21488 : SET_LOC(c, e);
5941 : :
5942 [ + + + - ]: 21488 : switch (e->kind) {
5943 : 3949 : case Attribute_kind:
5944 : 3949 : c->u->u_loc.lineno = e->end_lineno;
5945 [ - + ]: 3949 : ADDOP_I(c, SWAP, 2);
5946 [ - + ]: 3949 : ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
5947 : 3949 : break;
5948 : 1224 : case Subscript_kind:
5949 [ + + ]: 1224 : if (is_two_element_slice(e->v.Subscript.slice)) {
5950 [ - + ]: 8 : ADDOP_I(c, SWAP, 4);
5951 [ - + ]: 8 : ADDOP_I(c, SWAP, 3);
5952 [ - + ]: 8 : ADDOP_I(c, SWAP, 2);
5953 [ - + ]: 8 : ADDOP(c, STORE_SLICE);
5954 : : }
5955 : : else {
5956 [ - + ]: 1216 : ADDOP_I(c, SWAP, 3);
5957 [ - + ]: 1216 : ADDOP_I(c, SWAP, 2);
5958 [ - + ]: 1216 : ADDOP(c, STORE_SUBSCR);
5959 : : }
5960 : 1224 : break;
5961 : 16315 : case Name_kind:
5962 : 16315 : return compiler_nameop(c, e->v.Name.id, Store);
5963 : 0 : default:
5964 : 0 : Py_UNREACHABLE();
5965 : : }
5966 : 5173 : return 1;
5967 : : }
5968 : :
5969 : : static int
5970 : 385 : check_ann_expr(struct compiler *c, expr_ty e)
5971 : : {
5972 [ - + ]: 385 : VISIT(c, expr, e);
5973 [ - + ]: 385 : ADDOP(c, POP_TOP);
5974 : 385 : return 1;
5975 : : }
5976 : :
5977 : : static int
5978 : 1932 : check_annotation(struct compiler *c, stmt_ty s)
5979 : : {
5980 : : /* Annotations of complex targets does not produce anything
5981 : : under annotations future */
5982 [ + + ]: 1932 : if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) {
5983 : 349 : return 1;
5984 : : }
5985 : :
5986 : : /* Annotations are only evaluated in a module or class. */
5987 [ + + ]: 1583 : if (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
5988 [ + + ]: 1576 : c->u->u_scope_type == COMPILER_SCOPE_CLASS) {
5989 : 11 : return check_ann_expr(c, s->v.AnnAssign.annotation);
5990 : : }
5991 : 1572 : return 1;
5992 : : }
5993 : :
5994 : : static int
5995 : 2 : check_ann_subscr(struct compiler *c, expr_ty e)
5996 : : {
5997 : : /* We check that everything in a subscript is defined at runtime. */
5998 [ - - + ]: 2 : switch (e->kind) {
5999 : 0 : case Slice_kind:
6000 [ # # # # ]: 0 : if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) {
6001 : 0 : return 0;
6002 : : }
6003 [ # # # # ]: 0 : if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) {
6004 : 0 : return 0;
6005 : : }
6006 [ # # # # ]: 0 : if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) {
6007 : 0 : return 0;
6008 : : }
6009 : 0 : return 1;
6010 : 0 : case Tuple_kind: {
6011 : : /* extended slice */
6012 : 0 : asdl_expr_seq *elts = e->v.Tuple.elts;
6013 [ # # ]: 0 : Py_ssize_t i, n = asdl_seq_LEN(elts);
6014 [ # # ]: 0 : for (i = 0; i < n; i++) {
6015 [ # # ]: 0 : if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) {
6016 : 0 : return 0;
6017 : : }
6018 : : }
6019 : 0 : return 1;
6020 : : }
6021 : 2 : default:
6022 : 2 : return check_ann_expr(c, e);
6023 : : }
6024 : : }
6025 : :
6026 : : static int
6027 : 9866 : compiler_annassign(struct compiler *c, stmt_ty s)
6028 : : {
6029 : 9866 : expr_ty targ = s->v.AnnAssign.target;
6030 : : PyObject* mangled;
6031 : :
6032 : : assert(s->kind == AnnAssign_kind);
6033 : :
6034 : : /* We perform the actual assignment first. */
6035 [ + + ]: 9866 : if (s->v.AnnAssign.value) {
6036 [ - + ]: 7097 : VISIT(c, expr, s->v.AnnAssign.value);
6037 [ - + ]: 7097 : VISIT(c, expr, targ);
6038 : : }
6039 [ + + + - ]: 9866 : switch (targ->kind) {
6040 : 7938 : case Name_kind:
6041 [ + + ]: 7938 : if (forbidden_name(c, targ->v.Name.id, Store))
6042 : 1 : return 0;
6043 : : /* If we have a simple name in a module or class, store annotation. */
6044 [ + + ]: 7937 : if (s->v.AnnAssign.simple &&
6045 [ + + ]: 7932 : (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
6046 [ + + ]: 6380 : c->u->u_scope_type == COMPILER_SCOPE_CLASS)) {
6047 [ + + ]: 5268 : if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) {
6048 [ - + ]: 557 : VISIT(c, annexpr, s->v.AnnAssign.annotation)
6049 : : }
6050 : : else {
6051 [ - + ]: 4711 : VISIT(c, expr, s->v.AnnAssign.annotation);
6052 : : }
6053 [ - + ]: 5268 : ADDOP_NAME(c, LOAD_NAME, &_Py_ID(__annotations__), names);
6054 : 5268 : mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
6055 [ - + - + ]: 5268 : ADDOP_LOAD_CONST_NEW(c, mangled);
6056 [ - + ]: 5268 : ADDOP(c, STORE_SUBSCR);
6057 : : }
6058 : 7937 : break;
6059 : 1918 : case Attribute_kind:
6060 [ + + ]: 1918 : if (forbidden_name(c, targ->v.Attribute.attr, Store))
6061 : 1 : return 0;
6062 [ + + - + ]: 2287 : if (!s->v.AnnAssign.value &&
6063 : 370 : !check_ann_expr(c, targ->v.Attribute.value)) {
6064 : 0 : return 0;
6065 : : }
6066 : 1917 : break;
6067 : 10 : case Subscript_kind:
6068 [ + + + - ]: 12 : if (!s->v.AnnAssign.value &&
6069 [ - + ]: 4 : (!check_ann_expr(c, targ->v.Subscript.value) ||
6070 : 2 : !check_ann_subscr(c, targ->v.Subscript.slice))) {
6071 : 0 : return 0;
6072 : : }
6073 : 10 : break;
6074 : 0 : default:
6075 : 0 : PyErr_Format(PyExc_SystemError,
6076 : : "invalid node type (%d) for annotated assignment",
6077 : 0 : targ->kind);
6078 : 0 : return 0;
6079 : : }
6080 : : /* Annotation is evaluated last. */
6081 [ + + - + ]: 9864 : if (!s->v.AnnAssign.simple && !check_annotation(c, s)) {
6082 : 0 : return 0;
6083 : : }
6084 : 9864 : return 1;
6085 : : }
6086 : :
6087 : : /* Raises a SyntaxError and returns 0.
6088 : : If something goes wrong, a different exception may be raised.
6089 : : */
6090 : :
6091 : : static int
6092 : 289 : compiler_error(struct compiler *c, const char *format, ...)
6093 : : {
6094 : : va_list vargs;
6095 : 289 : va_start(vargs, format);
6096 : 289 : PyObject *msg = PyUnicode_FromFormatV(format, vargs);
6097 : 289 : va_end(vargs);
6098 [ - + ]: 289 : if (msg == NULL) {
6099 : 0 : return 0;
6100 : : }
6101 : 289 : PyObject *loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_loc.lineno);
6102 [ + + ]: 289 : if (loc == NULL) {
6103 : 281 : Py_INCREF(Py_None);
6104 : 281 : loc = Py_None;
6105 : : }
6106 : 289 : struct location u_loc = c->u->u_loc;
6107 : 289 : PyObject *args = Py_BuildValue("O(OiiOii)", msg, c->c_filename,
6108 : 289 : u_loc.lineno, u_loc.col_offset + 1, loc,
6109 : 289 : u_loc.end_lineno, u_loc.end_col_offset + 1);
6110 : 289 : Py_DECREF(msg);
6111 [ - + ]: 289 : if (args == NULL) {
6112 : 0 : goto exit;
6113 : : }
6114 : 289 : PyErr_SetObject(PyExc_SyntaxError, args);
6115 : 289 : exit:
6116 : 289 : Py_DECREF(loc);
6117 : 289 : Py_XDECREF(args);
6118 : 289 : return 0;
6119 : : }
6120 : :
6121 : : /* Emits a SyntaxWarning and returns 1 on success.
6122 : : If a SyntaxWarning raised as error, replaces it with a SyntaxError
6123 : : and returns 0.
6124 : : */
6125 : : static int
6126 : 138 : compiler_warn(struct compiler *c, const char *format, ...)
6127 : : {
6128 : : va_list vargs;
6129 : 138 : va_start(vargs, format);
6130 : 138 : PyObject *msg = PyUnicode_FromFormatV(format, vargs);
6131 : 138 : va_end(vargs);
6132 [ - + ]: 138 : if (msg == NULL) {
6133 : 0 : return 0;
6134 : : }
6135 [ + + ]: 138 : if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename,
6136 : 138 : c->u->u_loc.lineno, NULL, NULL) < 0)
6137 : : {
6138 [ + - ]: 67 : if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
6139 : : /* Replace the SyntaxWarning exception with a SyntaxError
6140 : : to get a more accurate error report */
6141 : 67 : PyErr_Clear();
6142 : : assert(PyUnicode_AsUTF8(msg) != NULL);
6143 : 67 : compiler_error(c, PyUnicode_AsUTF8(msg));
6144 : : }
6145 : 67 : Py_DECREF(msg);
6146 : 67 : return 0;
6147 : : }
6148 : 71 : Py_DECREF(msg);
6149 : 71 : return 1;
6150 : : }
6151 : :
6152 : : static int
6153 : 183832 : compiler_subscript(struct compiler *c, expr_ty e)
6154 : : {
6155 : 183832 : expr_context_ty ctx = e->v.Subscript.ctx;
6156 : 183832 : int op = 0;
6157 : :
6158 [ + + ]: 183832 : if (ctx == Load) {
6159 [ + + ]: 151599 : if (!check_subscripter(c, e->v.Subscript.value)) {
6160 : 10 : return 0;
6161 : : }
6162 [ + + ]: 151589 : if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) {
6163 : 25 : return 0;
6164 : : }
6165 : : }
6166 : :
6167 [ + + ]: 183797 : VISIT(c, expr, e->v.Subscript.value);
6168 [ + + + + ]: 183787 : if (is_two_element_slice(e->v.Subscript.slice) && ctx != Del) {
6169 [ - + ]: 29119 : if (!compiler_slice(c, e->v.Subscript.slice)) {
6170 : 0 : return 0;
6171 : : }
6172 [ + + ]: 29119 : if (ctx == Load) {
6173 [ - + ]: 27647 : ADDOP(c, BINARY_SLICE);
6174 : : }
6175 : : else {
6176 : : assert(ctx == Store);
6177 [ - + ]: 1472 : ADDOP(c, STORE_SLICE);
6178 : : }
6179 : : }
6180 : : else {
6181 [ - + ]: 154668 : VISIT(c, expr, e->v.Subscript.slice);
6182 [ + + + - ]: 154668 : switch (ctx) {
6183 : 123907 : case Load: op = BINARY_SUBSCR; break;
6184 : 26880 : case Store: op = STORE_SUBSCR; break;
6185 : 3881 : case Del: op = DELETE_SUBSCR; break;
6186 : : }
6187 : : assert(op);
6188 [ - + ]: 154668 : ADDOP(c, op);
6189 : : }
6190 : 183787 : return 1;
6191 : : }
6192 : :
6193 : : /* Returns the number of the values emitted,
6194 : : * thus are needed to build the slice, or 0 if there is an error. */
6195 : : static int
6196 : 30870 : compiler_slice(struct compiler *c, expr_ty s)
6197 : : {
6198 : 30870 : int n = 2;
6199 : : assert(s->kind == Slice_kind);
6200 : :
6201 : : /* only handles the cases where BUILD_SLICE is emitted */
6202 [ + + ]: 30870 : if (s->v.Slice.lower) {
6203 [ - + ]: 17219 : VISIT(c, expr, s->v.Slice.lower);
6204 : : }
6205 : : else {
6206 [ - + ]: 13651 : ADDOP_LOAD_CONST(c, Py_None);
6207 : : }
6208 : :
6209 [ + + ]: 30870 : if (s->v.Slice.upper) {
6210 [ - + ]: 17410 : VISIT(c, expr, s->v.Slice.upper);
6211 : : }
6212 : : else {
6213 [ - + ]: 13460 : ADDOP_LOAD_CONST(c, Py_None);
6214 : : }
6215 : :
6216 [ + + ]: 30870 : if (s->v.Slice.step) {
6217 : 996 : n++;
6218 [ - + ]: 996 : VISIT(c, expr, s->v.Slice.step);
6219 : : }
6220 : 30870 : return n;
6221 : : }
6222 : :
6223 : :
6224 : : // PEP 634: Structural Pattern Matching
6225 : :
6226 : : // To keep things simple, all compiler_pattern_* and pattern_helper_* routines
6227 : : // follow the convention of consuming TOS (the subject for the given pattern)
6228 : : // and calling jump_to_fail_pop on failure (no match).
6229 : :
6230 : : // When calling into these routines, it's important that pc->on_top be kept
6231 : : // updated to reflect the current number of items that we are using on the top
6232 : : // of the stack: they will be popped on failure, and any name captures will be
6233 : : // stored *underneath* them on success. This lets us defer all names stores
6234 : : // until the *entire* pattern matches.
6235 : :
6236 : : #define WILDCARD_CHECK(N) \
6237 : : ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name)
6238 : :
6239 : : #define WILDCARD_STAR_CHECK(N) \
6240 : : ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
6241 : :
6242 : : // Limit permitted subexpressions, even if the parser & AST validator let them through
6243 : : #define MATCH_VALUE_EXPR(N) \
6244 : : ((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
6245 : :
6246 : : // Allocate or resize pc->fail_pop to allow for n items to be popped on failure.
6247 : : static int
6248 : 2784 : ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n)
6249 : : {
6250 : 2784 : Py_ssize_t size = n + 1;
6251 [ + + ]: 2784 : if (size <= pc->fail_pop_size) {
6252 : 1281 : return 1;
6253 : : }
6254 : 1503 : Py_ssize_t needed = sizeof(basicblock*) * size;
6255 : 1503 : basicblock **resized = PyObject_Realloc(pc->fail_pop, needed);
6256 [ - + ]: 1503 : if (resized == NULL) {
6257 : : PyErr_NoMemory();
6258 : 0 : return 0;
6259 : : }
6260 : 1503 : pc->fail_pop = resized;
6261 [ + + ]: 4013 : while (pc->fail_pop_size < size) {
6262 : : basicblock *new_block;
6263 [ - + ]: 2510 : RETURN_IF_FALSE(new_block = compiler_new_block(c));
6264 : 2510 : pc->fail_pop[pc->fail_pop_size++] = new_block;
6265 : : }
6266 : 1503 : return 1;
6267 : : }
6268 : :
6269 : : // Use op to jump to the correct fail_pop block.
6270 : : static int
6271 : 2679 : jump_to_fail_pop(struct compiler *c, pattern_context *pc, int op)
6272 : : {
6273 : : // Pop any items on the top of the stack, plus any objects we were going to
6274 : : // capture on success:
6275 : 2679 : Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
6276 [ - + ]: 2679 : RETURN_IF_FALSE(ensure_fail_pop(c, pc, pops));
6277 [ - + ]: 2679 : ADDOP_JUMP(c, op, pc->fail_pop[pops]);
6278 : 2679 : return 1;
6279 : : }
6280 : :
6281 : : // Build all of the fail_pop blocks and reset fail_pop.
6282 : : static int
6283 : 1199 : emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc)
6284 : : {
6285 [ + + ]: 1199 : if (!pc->fail_pop_size) {
6286 : : assert(pc->fail_pop == NULL);
6287 : 30 : return 1;
6288 : : }
6289 [ + + ]: 2482 : while (--pc->fail_pop_size) {
6290 : 1313 : compiler_use_next_block(c, pc->fail_pop[pc->fail_pop_size]);
6291 [ - + ]: 1313 : if (!compiler_addop(c, POP_TOP, true)) {
6292 : 0 : pc->fail_pop_size = 0;
6293 : 0 : PyObject_Free(pc->fail_pop);
6294 : 0 : pc->fail_pop = NULL;
6295 : 0 : return 0;
6296 : : }
6297 : : }
6298 : 1169 : compiler_use_next_block(c, pc->fail_pop[0]);
6299 : 1169 : PyObject_Free(pc->fail_pop);
6300 : 1169 : pc->fail_pop = NULL;
6301 : 1169 : return 1;
6302 : : }
6303 : :
6304 : : static int
6305 : 6 : compiler_error_duplicate_store(struct compiler *c, identifier n)
6306 : : {
6307 : 6 : return compiler_error(c, "multiple assignments to name %R in pattern", n);
6308 : : }
6309 : :
6310 : : // Duplicate the effect of 3.10's ROT_* instructions using SWAPs.
6311 : : static int
6312 : 974 : pattern_helper_rotate(struct compiler *c, Py_ssize_t count)
6313 : : {
6314 [ + + ]: 4589 : while (1 < count) {
6315 [ - + ]: 3615 : ADDOP_I(c, SWAP, count--);
6316 : : }
6317 : 974 : return 1;
6318 : : }
6319 : :
6320 : : static int
6321 : 791 : pattern_helper_store_name(struct compiler *c, identifier n, pattern_context *pc)
6322 : : {
6323 [ + + ]: 791 : if (n == NULL) {
6324 [ - + ]: 63 : ADDOP(c, POP_TOP);
6325 : 63 : return 1;
6326 : : }
6327 [ - + ]: 728 : if (forbidden_name(c, n, Store)) {
6328 : 0 : return 0;
6329 : : }
6330 : : // Can't assign to the same name twice:
6331 : 728 : int duplicate = PySequence_Contains(pc->stores, n);
6332 [ - + ]: 728 : if (duplicate < 0) {
6333 : 0 : return 0;
6334 : : }
6335 [ + + ]: 728 : if (duplicate) {
6336 : 6 : return compiler_error_duplicate_store(c, n);
6337 : : }
6338 : : // Rotate this object underneath any items we need to preserve:
6339 : 722 : Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
6340 [ - + ]: 722 : RETURN_IF_FALSE(pattern_helper_rotate(c, rotations));
6341 : 722 : return !PyList_Append(pc->stores, n);
6342 : : }
6343 : :
6344 : :
6345 : : static int
6346 : 355 : pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts)
6347 : : {
6348 [ + - ]: 355 : Py_ssize_t n = asdl_seq_LEN(elts);
6349 : 355 : int seen_star = 0;
6350 [ + + ]: 1124 : for (Py_ssize_t i = 0; i < n; i++) {
6351 : 769 : pattern_ty elt = asdl_seq_GET(elts, i);
6352 [ + + + - ]: 769 : if (elt->kind == MatchStar_kind && !seen_star) {
6353 [ + - ]: 64 : if ((i >= (1 << 8)) ||
6354 [ - + ]: 64 : (n-i-1 >= (INT_MAX >> 8)))
6355 : 0 : return compiler_error(c,
6356 : : "too many expressions in "
6357 : : "star-unpacking sequence pattern");
6358 [ - + ]: 64 : ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
6359 : 64 : seen_star = 1;
6360 : : }
6361 [ - + ]: 705 : else if (elt->kind == MatchStar_kind) {
6362 : 0 : return compiler_error(c,
6363 : : "multiple starred expressions in sequence pattern");
6364 : : }
6365 : : }
6366 [ + + ]: 355 : if (!seen_star) {
6367 [ - + ]: 291 : ADDOP_I(c, UNPACK_SEQUENCE, n);
6368 : : }
6369 : 355 : return 1;
6370 : : }
6371 : :
6372 : : static int
6373 : 355 : pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns,
6374 : : Py_ssize_t star, pattern_context *pc)
6375 : : {
6376 [ - + ]: 355 : RETURN_IF_FALSE(pattern_unpack_helper(c, patterns));
6377 [ + - ]: 355 : Py_ssize_t size = asdl_seq_LEN(patterns);
6378 : : // We've now got a bunch of new subjects on the stack. They need to remain
6379 : : // there after each subpattern match:
6380 : 355 : pc->on_top += size;
6381 [ + + ]: 1122 : for (Py_ssize_t i = 0; i < size; i++) {
6382 : : // One less item to keep track of each time we loop through:
6383 : 769 : pc->on_top--;
6384 : 769 : pattern_ty pattern = asdl_seq_GET(patterns, i);
6385 [ + + ]: 769 : RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
6386 : : }
6387 : 353 : return 1;
6388 : : }
6389 : :
6390 : : // Like pattern_helper_sequence_unpack, but uses BINARY_SUBSCR instead of
6391 : : // UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a
6392 : : // starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc.
6393 : : static int
6394 : 23 : pattern_helper_sequence_subscr(struct compiler *c, asdl_pattern_seq *patterns,
6395 : : Py_ssize_t star, pattern_context *pc)
6396 : : {
6397 : : // We need to keep the subject around for extracting elements:
6398 : 23 : pc->on_top++;
6399 [ + - ]: 23 : Py_ssize_t size = asdl_seq_LEN(patterns);
6400 [ + + ]: 90 : for (Py_ssize_t i = 0; i < size; i++) {
6401 : 67 : pattern_ty pattern = asdl_seq_GET(patterns, i);
6402 [ + + + + ]: 67 : if (WILDCARD_CHECK(pattern)) {
6403 : 8 : continue;
6404 : : }
6405 [ + + ]: 59 : if (i == star) {
6406 : : assert(WILDCARD_STAR_CHECK(pattern));
6407 : 23 : continue;
6408 : : }
6409 [ - + ]: 36 : ADDOP_I(c, COPY, 1);
6410 [ + + ]: 36 : if (i < star) {
6411 [ - + - + ]: 22 : ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i));
6412 : : }
6413 : : else {
6414 : : // The subject may not support negative indexing! Compute a
6415 : : // nonnegative index:
6416 [ - + ]: 14 : ADDOP(c, GET_LEN);
6417 [ - + - + ]: 14 : ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - i));
6418 [ - + ]: 14 : ADDOP_BINARY(c, Sub);
6419 : : }
6420 [ - + ]: 36 : ADDOP(c, BINARY_SUBSCR);
6421 [ - + ]: 36 : RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
6422 : : }
6423 : : // Pop the subject, we're done with it:
6424 : 23 : pc->on_top--;
6425 [ - + ]: 23 : ADDOP(c, POP_TOP);
6426 : 23 : return 1;
6427 : : }
6428 : :
6429 : : // Like compiler_pattern, but turn off checks for irrefutability.
6430 : : static int
6431 : 1283 : compiler_pattern_subpattern(struct compiler *c, pattern_ty p, pattern_context *pc)
6432 : : {
6433 : 1283 : int allow_irrefutable = pc->allow_irrefutable;
6434 : 1283 : pc->allow_irrefutable = 1;
6435 [ + + ]: 1283 : RETURN_IF_FALSE(compiler_pattern(c, p, pc));
6436 : 1277 : pc->allow_irrefutable = allow_irrefutable;
6437 : 1277 : return 1;
6438 : : }
6439 : :
6440 : : static int
6441 : 723 : compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc)
6442 : : {
6443 : : assert(p->kind == MatchAs_kind);
6444 [ + + ]: 723 : if (p->v.MatchAs.pattern == NULL) {
6445 : : // An irrefutable match:
6446 [ + + ]: 631 : if (!pc->allow_irrefutable) {
6447 [ + + ]: 11 : if (p->v.MatchAs.name) {
6448 : 5 : const char *e = "name capture %R makes remaining patterns unreachable";
6449 : 5 : return compiler_error(c, e, p->v.MatchAs.name);
6450 : : }
6451 : 6 : const char *e = "wildcard makes remaining patterns unreachable";
6452 : 6 : return compiler_error(c, e);
6453 : : }
6454 : 620 : return pattern_helper_store_name(c, p->v.MatchAs.name, pc);
6455 : : }
6456 : : // Need to make a copy for (possibly) storing later:
6457 : 92 : pc->on_top++;
6458 [ - + ]: 92 : ADDOP_I(c, COPY, 1);
6459 [ + + ]: 92 : RETURN_IF_FALSE(compiler_pattern(c, p->v.MatchAs.pattern, pc));
6460 : : // Success! Store it:
6461 : 91 : pc->on_top--;
6462 [ + + ]: 91 : RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchAs.name, pc));
6463 : 90 : return 1;
6464 : : }
6465 : :
6466 : : static int
6467 : 64 : compiler_pattern_star(struct compiler *c, pattern_ty p, pattern_context *pc)
6468 : : {
6469 : : assert(p->kind == MatchStar_kind);
6470 [ - + ]: 64 : RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchStar.name, pc));
6471 : 64 : return 1;
6472 : : }
6473 : :
6474 : : static int
6475 : 47 : validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns)
6476 : : {
6477 : : // Any errors will point to the pattern rather than the arg name as the
6478 : : // parser is only supplying identifiers rather than Name or keyword nodes
6479 [ + - ]: 47 : Py_ssize_t nattrs = asdl_seq_LEN(attrs);
6480 [ + + ]: 124 : for (Py_ssize_t i = 0; i < nattrs; i++) {
6481 : 78 : identifier attr = ((identifier)asdl_seq_GET(attrs, i));
6482 : 78 : SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i)));
6483 [ - + ]: 78 : if (forbidden_name(c, attr, Store)) {
6484 : 0 : return -1;
6485 : : }
6486 [ + + ]: 117 : for (Py_ssize_t j = i + 1; j < nattrs; j++) {
6487 : 40 : identifier other = ((identifier)asdl_seq_GET(attrs, j));
6488 [ + + ]: 40 : if (!PyUnicode_Compare(attr, other)) {
6489 : 1 : SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, j)));
6490 : 1 : compiler_error(c, "attribute name repeated in class pattern: %U", attr);
6491 : 1 : return -1;
6492 : : }
6493 : : }
6494 : : }
6495 : 46 : return 0;
6496 : : }
6497 : :
6498 : : static int
6499 : 186 : compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
6500 : : {
6501 : : assert(p->kind == MatchClass_kind);
6502 : 186 : asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
6503 : 186 : asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs;
6504 : 186 : asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns;
6505 [ + + ]: 186 : Py_ssize_t nargs = asdl_seq_LEN(patterns);
6506 [ + + ]: 186 : Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs);
6507 [ + + ]: 186 : Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns);
6508 [ - + ]: 186 : if (nattrs != nkwd_patterns) {
6509 : : // AST validator shouldn't let this happen, but if it does,
6510 : : // just fail, don't crash out of the interpreter
6511 : 0 : const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern";
6512 : 0 : return compiler_error(c, e, nattrs, nkwd_patterns);
6513 : : }
6514 [ + - - + ]: 186 : if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) {
6515 : 0 : const char *e = "too many sub-patterns in class pattern %R";
6516 : 0 : return compiler_error(c, e, p->v.MatchClass.cls);
6517 : : }
6518 [ + + ]: 186 : if (nattrs) {
6519 [ + + ]: 47 : RETURN_IF_FALSE(!validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
6520 : 46 : SET_LOC(c, p);
6521 : : }
6522 [ - + ]: 185 : VISIT(c, expr, p->v.MatchClass.cls);
6523 : : PyObject *attr_names;
6524 [ - + ]: 185 : RETURN_IF_FALSE(attr_names = PyTuple_New(nattrs));
6525 : : Py_ssize_t i;
6526 [ + + ]: 262 : for (i = 0; i < nattrs; i++) {
6527 : 77 : PyObject *name = asdl_seq_GET(kwd_attrs, i);
6528 : 77 : Py_INCREF(name);
6529 : 77 : PyTuple_SET_ITEM(attr_names, i, name);
6530 : : }
6531 [ - + - + ]: 185 : ADDOP_LOAD_CONST_NEW(c, attr_names);
6532 [ - + ]: 185 : ADDOP_I(c, MATCH_CLASS, nargs);
6533 [ - + ]: 185 : ADDOP_I(c, COPY, 1);
6534 [ - + ]: 185 : ADDOP_LOAD_CONST(c, Py_None);
6535 [ - + ]: 185 : ADDOP_I(c, IS_OP, 1);
6536 : : // TOS is now a tuple of (nargs + nattrs) attributes (or None):
6537 : 185 : pc->on_top++;
6538 [ - + ]: 185 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6539 [ - + ]: 185 : ADDOP_I(c, UNPACK_SEQUENCE, nargs + nattrs);
6540 : 185 : pc->on_top += nargs + nattrs - 1;
6541 [ + + ]: 454 : for (i = 0; i < nargs + nattrs; i++) {
6542 : 272 : pc->on_top--;
6543 : : pattern_ty pattern;
6544 [ + + ]: 272 : if (i < nargs) {
6545 : : // Positional:
6546 : 195 : pattern = asdl_seq_GET(patterns, i);
6547 : : }
6548 : : else {
6549 : : // Keyword:
6550 : 77 : pattern = asdl_seq_GET(kwd_patterns, i - nargs);
6551 : : }
6552 [ + + + + ]: 272 : if (WILDCARD_CHECK(pattern)) {
6553 [ - + ]: 48 : ADDOP(c, POP_TOP);
6554 : 48 : continue;
6555 : : }
6556 [ + + ]: 224 : RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
6557 : : }
6558 : : // Success! Pop the tuple of attributes:
6559 : 182 : return 1;
6560 : : }
6561 : :
6562 : : static int
6563 : 271 : compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
6564 : : {
6565 : : assert(p->kind == MatchMapping_kind);
6566 : 271 : asdl_expr_seq *keys = p->v.MatchMapping.keys;
6567 : 271 : asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
6568 [ + + ]: 271 : Py_ssize_t size = asdl_seq_LEN(keys);
6569 [ + + ]: 271 : Py_ssize_t npatterns = asdl_seq_LEN(patterns);
6570 [ - + ]: 271 : if (size != npatterns) {
6571 : : // AST validator shouldn't let this happen, but if it does,
6572 : : // just fail, don't crash out of the interpreter
6573 : 0 : const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern";
6574 : 0 : return compiler_error(c, e, size, npatterns);
6575 : : }
6576 : : // We have a double-star target if "rest" is set
6577 : 271 : PyObject *star_target = p->v.MatchMapping.rest;
6578 : : // We need to keep the subject on top during the mapping and length checks:
6579 : 271 : pc->on_top++;
6580 [ - + ]: 271 : ADDOP(c, MATCH_MAPPING);
6581 [ - + ]: 271 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6582 [ + + + + ]: 271 : if (!size && !star_target) {
6583 : : // If the pattern is just "{}", we're done! Pop the subject:
6584 : 48 : pc->on_top--;
6585 [ - + ]: 48 : ADDOP(c, POP_TOP);
6586 : 48 : return 1;
6587 : : }
6588 [ + + ]: 223 : if (size) {
6589 : : // If the pattern has any keys in it, perform a length check:
6590 [ - + ]: 217 : ADDOP(c, GET_LEN);
6591 [ - + - + ]: 217 : ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size));
6592 [ - + ]: 217 : ADDOP_COMPARE(c, GtE);
6593 [ - + ]: 217 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6594 : : }
6595 [ - + ]: 223 : if (INT_MAX < size - 1) {
6596 : 0 : return compiler_error(c, "too many sub-patterns in mapping pattern");
6597 : : }
6598 : : // Collect all of the keys into a tuple for MATCH_KEYS and
6599 : : // **rest. They can either be dotted names or literals:
6600 : :
6601 : : // Maintaining a set of Constant_kind kind keys allows us to raise a
6602 : : // SyntaxError in the case of duplicates.
6603 : 223 : PyObject *seen = PySet_New(NULL);
6604 [ - + ]: 223 : if (seen == NULL) {
6605 : 0 : return 0;
6606 : : }
6607 : :
6608 : : // NOTE: goto error on failure in the loop below to avoid leaking `seen`
6609 [ + + ]: 482 : for (Py_ssize_t i = 0; i < size; i++) {
6610 : 265 : expr_ty key = asdl_seq_GET(keys, i);
6611 [ - + ]: 265 : if (key == NULL) {
6612 : 0 : const char *e = "can't use NULL keys in MatchMapping "
6613 : : "(set 'rest' parameter instead)";
6614 : 0 : SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i)));
6615 : 0 : compiler_error(c, e);
6616 : 0 : goto error;
6617 : : }
6618 : :
6619 [ + + ]: 265 : if (key->kind == Constant_kind) {
6620 : 262 : int in_seen = PySet_Contains(seen, key->v.Constant.value);
6621 [ - + ]: 262 : if (in_seen < 0) {
6622 : 0 : goto error;
6623 : : }
6624 [ + + ]: 262 : if (in_seen) {
6625 : 5 : const char *e = "mapping pattern checks duplicate key (%R)";
6626 : 5 : compiler_error(c, e, key->v.Constant.value);
6627 : 5 : goto error;
6628 : : }
6629 [ - + ]: 257 : if (PySet_Add(seen, key->v.Constant.value)) {
6630 : 0 : goto error;
6631 : : }
6632 : : }
6633 : :
6634 [ + + ]: 3 : else if (key->kind != Attribute_kind) {
6635 : 1 : const char *e = "mapping pattern keys may only match literals and attribute lookups";
6636 : 1 : compiler_error(c, e);
6637 : 1 : goto error;
6638 : : }
6639 [ - + ]: 259 : if (!compiler_visit_expr(c, key)) {
6640 : 0 : goto error;
6641 : : }
6642 : : }
6643 : :
6644 : : // all keys have been checked; there are no duplicates
6645 : 217 : Py_DECREF(seen);
6646 : :
6647 [ - + ]: 217 : ADDOP_I(c, BUILD_TUPLE, size);
6648 [ - + ]: 217 : ADDOP(c, MATCH_KEYS);
6649 : : // There's now a tuple of keys and a tuple of values on top of the subject:
6650 : 217 : pc->on_top += 2;
6651 [ - + ]: 217 : ADDOP_I(c, COPY, 1);
6652 [ - + ]: 217 : ADDOP_LOAD_CONST(c, Py_None);
6653 [ - + ]: 217 : ADDOP_I(c, IS_OP, 1);
6654 [ - + ]: 217 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6655 : : // So far so good. Use that tuple of values on the stack to match
6656 : : // sub-patterns against:
6657 [ - + ]: 217 : ADDOP_I(c, UNPACK_SEQUENCE, size);
6658 : 217 : pc->on_top += size - 1;
6659 [ + + ]: 470 : for (Py_ssize_t i = 0; i < size; i++) {
6660 : 254 : pc->on_top--;
6661 : 254 : pattern_ty pattern = asdl_seq_GET(patterns, i);
6662 [ + + ]: 254 : RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
6663 : : }
6664 : : // If we get this far, it's a match! Whatever happens next should consume
6665 : : // the tuple of keys and the subject:
6666 : 216 : pc->on_top -= 2;
6667 [ + + ]: 216 : if (star_target) {
6668 : : // If we have a starred name, bind a dict of remaining items to it (this may
6669 : : // seem a bit inefficient, but keys is rarely big enough to actually impact
6670 : : // runtime):
6671 : : // rest = dict(TOS1)
6672 : : // for key in TOS:
6673 : : // del rest[key]
6674 [ - + ]: 16 : ADDOP_I(c, BUILD_MAP, 0); // [subject, keys, empty]
6675 [ - + ]: 16 : ADDOP_I(c, SWAP, 3); // [empty, keys, subject]
6676 [ - + ]: 16 : ADDOP_I(c, DICT_UPDATE, 2); // [copy, keys]
6677 [ - + ]: 16 : ADDOP_I(c, UNPACK_SEQUENCE, size); // [copy, keys...]
6678 [ + + ]: 30 : while (size) {
6679 [ - + ]: 14 : ADDOP_I(c, COPY, 1 + size--); // [copy, keys..., copy]
6680 [ - + ]: 14 : ADDOP_I(c, SWAP, 2); // [copy, keys..., copy, key]
6681 [ - + ]: 14 : ADDOP(c, DELETE_SUBSCR); // [copy, keys...]
6682 : : }
6683 [ - + ]: 16 : RETURN_IF_FALSE(pattern_helper_store_name(c, star_target, pc));
6684 : : }
6685 : : else {
6686 [ - + ]: 200 : ADDOP(c, POP_TOP); // Tuple of keys.
6687 [ - + ]: 200 : ADDOP(c, POP_TOP); // Subject.
6688 : : }
6689 : 216 : return 1;
6690 : :
6691 : 6 : error:
6692 : 6 : Py_DECREF(seen);
6693 : 6 : return 0;
6694 : : }
6695 : :
6696 : : static int
6697 : 110 : compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
6698 : : {
6699 : : assert(p->kind == MatchOr_kind);
6700 : : basicblock *end;
6701 [ - + ]: 110 : RETURN_IF_FALSE(end = compiler_new_block(c));
6702 [ + - ]: 110 : Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns);
6703 : : assert(size > 1);
6704 : : // We're going to be messing with pc. Keep the original info handy:
6705 : 110 : pattern_context old_pc = *pc;
6706 : 110 : Py_INCREF(pc->stores);
6707 : : // control is the list of names bound by the first alternative. It is used
6708 : : // for checking different name bindings in alternatives, and for correcting
6709 : : // the order in which extracted elements are placed on the stack.
6710 : 110 : PyObject *control = NULL;
6711 : : // NOTE: We can't use returning macros anymore! goto error on error.
6712 [ + + ]: 389 : for (Py_ssize_t i = 0; i < size; i++) {
6713 : 289 : pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i);
6714 : 289 : SET_LOC(c, alt);
6715 : 289 : PyObject *pc_stores = PyList_New(0);
6716 [ - + ]: 289 : if (pc_stores == NULL) {
6717 : 0 : goto error;
6718 : : }
6719 : 289 : Py_SETREF(pc->stores, pc_stores);
6720 : : // An irrefutable sub-pattern must be last, if it is allowed at all:
6721 [ + + + + ]: 289 : pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable;
6722 : 289 : pc->fail_pop = NULL;
6723 : 289 : pc->fail_pop_size = 0;
6724 : 289 : pc->on_top = 0;
6725 [ + - + + ]: 289 : if (!compiler_addop_i(c, COPY, 1, true) || !compiler_pattern(c, alt, pc)) {
6726 : 8 : goto error;
6727 : : }
6728 : : // Success!
6729 : 281 : Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6730 [ + + ]: 281 : if (!i) {
6731 : : // This is the first alternative, so save its stores as a "control"
6732 : : // for the others (they can't bind a different set of names, and
6733 : : // might need to be reordered):
6734 : : assert(control == NULL);
6735 : 103 : control = pc->stores;
6736 : 103 : Py_INCREF(control);
6737 : : }
6738 [ + + ]: 178 : else if (nstores != PyList_GET_SIZE(control)) {
6739 : 1 : goto diff;
6740 : : }
6741 [ + + ]: 177 : else if (nstores) {
6742 : : // There were captures. Check to see if we differ from control:
6743 : 35 : Py_ssize_t icontrol = nstores;
6744 [ + + ]: 165 : while (icontrol--) {
6745 : 131 : PyObject *name = PyList_GET_ITEM(control, icontrol);
6746 : 131 : Py_ssize_t istores = PySequence_Index(pc->stores, name);
6747 [ + + ]: 131 : if (istores < 0) {
6748 : 1 : PyErr_Clear();
6749 : 1 : goto diff;
6750 : : }
6751 [ + + ]: 130 : if (icontrol != istores) {
6752 : : // Reorder the names on the stack to match the order of the
6753 : : // names in control. There's probably a better way of doing
6754 : : // this; the current solution is potentially very
6755 : : // inefficient when each alternative subpattern binds lots
6756 : : // of names in different orders. It's fine for reasonable
6757 : : // cases, though, and the peephole optimizer will ensure
6758 : : // that the final code is as efficient as possible.
6759 : : assert(istores < icontrol);
6760 : 60 : Py_ssize_t rotations = istores + 1;
6761 : : // Perform the same rotation on pc->stores:
6762 : 60 : PyObject *rotated = PyList_GetSlice(pc->stores, 0,
6763 : : rotations);
6764 [ + - + - ]: 120 : if (rotated == NULL ||
6765 [ - + ]: 120 : PyList_SetSlice(pc->stores, 0, rotations, NULL) ||
6766 : 60 : PyList_SetSlice(pc->stores, icontrol - istores,
6767 : : icontrol - istores, rotated))
6768 : : {
6769 : 0 : Py_XDECREF(rotated);
6770 : 0 : goto error;
6771 : : }
6772 : 60 : Py_DECREF(rotated);
6773 : : // That just did:
6774 : : // rotated = pc_stores[:rotations]
6775 : : // del pc_stores[:rotations]
6776 : : // pc_stores[icontrol-istores:icontrol-istores] = rotated
6777 : : // Do the same thing to the stack, using several
6778 : : // rotations:
6779 [ + + ]: 264 : while (rotations--) {
6780 [ - + ]: 204 : if (!pattern_helper_rotate(c, icontrol + 1)){
6781 : 0 : goto error;
6782 : : }
6783 : : }
6784 : : }
6785 : : }
6786 : : }
6787 : : assert(control);
6788 [ + - - + ]: 558 : if (!compiler_addop_j(c, JUMP, end, true) ||
6789 : 279 : !emit_and_reset_fail_pop(c, pc))
6790 : : {
6791 : 0 : goto error;
6792 : : }
6793 : : }
6794 : 100 : Py_DECREF(pc->stores);
6795 : 100 : *pc = old_pc;
6796 : 100 : Py_INCREF(pc->stores);
6797 : : // Need to NULL this for the PyObject_Free call in the error block.
6798 : 100 : old_pc.fail_pop = NULL;
6799 : : // No match. Pop the remaining copy of the subject and fail:
6800 [ + - - + ]: 100 : if (!compiler_addop(c, POP_TOP, true) || !jump_to_fail_pop(c, pc, JUMP)) {
6801 : 0 : goto error;
6802 : : }
6803 : 100 : compiler_use_next_block(c, end);
6804 : 100 : Py_ssize_t nstores = PyList_GET_SIZE(control);
6805 : : // There's a bunch of stuff on the stack between where the new stores
6806 : : // are and where they need to be:
6807 : : // - The other stores.
6808 : : // - A copy of the subject.
6809 : : // - Anything else that may be on top of the stack.
6810 : : // - Any previous stores we've already stashed away on the stack.
6811 : 100 : Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
6812 [ + + ]: 148 : for (Py_ssize_t i = 0; i < nstores; i++) {
6813 : : // Rotate this capture to its proper place on the stack:
6814 [ - + ]: 48 : if (!pattern_helper_rotate(c, nrots)) {
6815 : 0 : goto error;
6816 : : }
6817 : : // Update the list of previous stores with this new name, checking for
6818 : : // duplicates:
6819 : 48 : PyObject *name = PyList_GET_ITEM(control, i);
6820 : 48 : int dupe = PySequence_Contains(pc->stores, name);
6821 [ - + ]: 48 : if (dupe < 0) {
6822 : 0 : goto error;
6823 : : }
6824 [ - + ]: 48 : if (dupe) {
6825 : 0 : compiler_error_duplicate_store(c, name);
6826 : 0 : goto error;
6827 : : }
6828 [ - + ]: 48 : if (PyList_Append(pc->stores, name)) {
6829 : 0 : goto error;
6830 : : }
6831 : : }
6832 : 100 : Py_DECREF(old_pc.stores);
6833 : 100 : Py_DECREF(control);
6834 : : // NOTE: Returning macros are safe again.
6835 : : // Pop the copy of the subject:
6836 [ - + ]: 100 : ADDOP(c, POP_TOP);
6837 : 100 : return 1;
6838 : 2 : diff:
6839 : 2 : compiler_error(c, "alternative patterns bind different names");
6840 : 10 : error:
6841 : 10 : PyObject_Free(old_pc.fail_pop);
6842 : 10 : Py_DECREF(old_pc.stores);
6843 : 10 : Py_XDECREF(control);
6844 : 10 : return 0;
6845 : : }
6846 : :
6847 : :
6848 : : static int
6849 : 451 : compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc)
6850 : : {
6851 : : assert(p->kind == MatchSequence_kind);
6852 : 451 : asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
6853 [ + + ]: 451 : Py_ssize_t size = asdl_seq_LEN(patterns);
6854 : 451 : Py_ssize_t star = -1;
6855 : 451 : int only_wildcard = 1;
6856 : 451 : int star_wildcard = 0;
6857 : : // Find a starred name, if it exists. There may be at most one:
6858 [ + + ]: 1314 : for (Py_ssize_t i = 0; i < size; i++) {
6859 : 865 : pattern_ty pattern = asdl_seq_GET(patterns, i);
6860 [ + + ]: 865 : if (pattern->kind == MatchStar_kind) {
6861 [ + + ]: 102 : if (star >= 0) {
6862 : 2 : const char *e = "multiple starred names in sequence pattern";
6863 : 2 : return compiler_error(c, e);
6864 : : }
6865 [ + - + + ]: 100 : star_wildcard = WILDCARD_STAR_CHECK(pattern);
6866 : 100 : only_wildcard &= star_wildcard;
6867 : 100 : star = i;
6868 : 100 : continue;
6869 : : }
6870 [ + + + + ]: 763 : only_wildcard &= WILDCARD_CHECK(pattern);
6871 : : }
6872 : : // We need to keep the subject on top during the sequence and length checks:
6873 : 449 : pc->on_top++;
6874 [ - + ]: 449 : ADDOP(c, MATCH_SEQUENCE);
6875 [ - + ]: 449 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6876 [ + + ]: 449 : if (star < 0) {
6877 : : // No star: len(subject) == size
6878 [ - + ]: 351 : ADDOP(c, GET_LEN);
6879 [ - + - + ]: 351 : ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size));
6880 [ - + ]: 351 : ADDOP_COMPARE(c, Eq);
6881 [ - + ]: 351 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6882 : : }
6883 [ + + ]: 98 : else if (size > 1) {
6884 : : // Star: len(subject) >= size - 1
6885 [ - + ]: 82 : ADDOP(c, GET_LEN);
6886 [ - + - + ]: 82 : ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - 1));
6887 [ - + ]: 82 : ADDOP_COMPARE(c, GtE);
6888 [ - + ]: 82 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6889 : : }
6890 : : // Whatever comes next should consume the subject:
6891 : 449 : pc->on_top--;
6892 [ + + ]: 449 : if (only_wildcard) {
6893 : : // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
6894 [ - + ]: 71 : ADDOP(c, POP_TOP);
6895 : : }
6896 [ + + ]: 378 : else if (star_wildcard) {
6897 [ - + ]: 23 : RETURN_IF_FALSE(pattern_helper_sequence_subscr(c, patterns, star, pc));
6898 : : }
6899 : : else {
6900 [ + + ]: 355 : RETURN_IF_FALSE(pattern_helper_sequence_unpack(c, patterns, star, pc));
6901 : : }
6902 : 447 : return 1;
6903 : : }
6904 : :
6905 : : static int
6906 : 773 : compiler_pattern_value(struct compiler *c, pattern_ty p, pattern_context *pc)
6907 : : {
6908 : : assert(p->kind == MatchValue_kind);
6909 : 773 : expr_ty value = p->v.MatchValue.value;
6910 [ + + + + ]: 773 : if (!MATCH_VALUE_EXPR(value)) {
6911 : 2 : const char *e = "patterns may only match literals and attribute lookups";
6912 : 2 : return compiler_error(c, e);
6913 : : }
6914 [ - + ]: 771 : VISIT(c, expr, value);
6915 [ - + ]: 771 : ADDOP_COMPARE(c, Eq);
6916 [ - + ]: 771 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6917 : 771 : return 1;
6918 : : }
6919 : :
6920 : : static int
6921 : 36 : compiler_pattern_singleton(struct compiler *c, pattern_ty p, pattern_context *pc)
6922 : : {
6923 : : assert(p->kind == MatchSingleton_kind);
6924 [ - + ]: 36 : ADDOP_LOAD_CONST(c, p->v.MatchSingleton.value);
6925 [ - + ]: 36 : ADDOP_COMPARE(c, Is);
6926 [ - + ]: 36 : RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
6927 : 36 : return 1;
6928 : : }
6929 : :
6930 : : static int
6931 : 2614 : compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc)
6932 : : {
6933 : 2614 : SET_LOC(c, p);
6934 [ + + + + : 2614 : switch (p->kind) {
+ + + +
- ]
6935 : 773 : case MatchValue_kind:
6936 : 773 : return compiler_pattern_value(c, p, pc);
6937 : 36 : case MatchSingleton_kind:
6938 : 36 : return compiler_pattern_singleton(c, p, pc);
6939 : 451 : case MatchSequence_kind:
6940 : 451 : return compiler_pattern_sequence(c, p, pc);
6941 : 271 : case MatchMapping_kind:
6942 : 271 : return compiler_pattern_mapping(c, p, pc);
6943 : 186 : case MatchClass_kind:
6944 : 186 : return compiler_pattern_class(c, p, pc);
6945 : 64 : case MatchStar_kind:
6946 : 64 : return compiler_pattern_star(c, p, pc);
6947 : 723 : case MatchAs_kind:
6948 : 723 : return compiler_pattern_as(c, p, pc);
6949 : 110 : case MatchOr_kind:
6950 : 110 : return compiler_pattern_or(c, p, pc);
6951 : : }
6952 : : // AST validator shouldn't let this happen, but if it does,
6953 : : // just fail, don't crash out of the interpreter
6954 : 0 : const char *e = "invalid match pattern node in AST (kind=%d)";
6955 : 0 : return compiler_error(c, e, p->kind);
6956 : : }
6957 : :
6958 : : static int
6959 : 682 : compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc)
6960 : : {
6961 [ - + ]: 682 : VISIT(c, expr, s->v.Match.subject);
6962 : : basicblock *end;
6963 [ - + ]: 682 : RETURN_IF_FALSE(end = compiler_new_block(c));
6964 [ + - ]: 682 : Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases);
6965 : : assert(cases > 0);
6966 : 682 : match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6967 [ + + + + : 682 : int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases;
+ + ]
6968 [ + + ]: 1602 : for (Py_ssize_t i = 0; i < cases - has_default; i++) {
6969 : 950 : m = asdl_seq_GET(s->v.Match.cases, i);
6970 : 950 : SET_LOC(c, m->pattern);
6971 : : // Only copy the subject if we're *not* on the last case:
6972 [ + + ]: 950 : if (i != cases - has_default - 1) {
6973 [ - + ]: 271 : ADDOP_I(c, COPY, 1);
6974 : : }
6975 [ - + ]: 950 : RETURN_IF_FALSE(pc->stores = PyList_New(0));
6976 : : // Irrefutable cases must be either guarded, last, or both:
6977 [ + + + + ]: 950 : pc->allow_irrefutable = m->guard != NULL || i == cases - 1;
6978 : 950 : pc->fail_pop = NULL;
6979 : 950 : pc->fail_pop_size = 0;
6980 : 950 : pc->on_top = 0;
6981 : : // NOTE: Can't use returning macros here (they'll leak pc->stores)!
6982 [ + + ]: 950 : if (!compiler_pattern(c, m->pattern, pc)) {
6983 : 30 : Py_DECREF(pc->stores);
6984 : 30 : return 0;
6985 : : }
6986 : : assert(!pc->on_top);
6987 : : // It's a match! Store all of the captured names (they're on the stack).
6988 : 920 : Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6989 [ + + ]: 1502 : for (Py_ssize_t n = 0; n < nstores; n++) {
6990 : 582 : PyObject *name = PyList_GET_ITEM(pc->stores, n);
6991 [ - + ]: 582 : if (!compiler_nameop(c, name, Store)) {
6992 : 0 : Py_DECREF(pc->stores);
6993 : 0 : return 0;
6994 : : }
6995 : : }
6996 : 920 : Py_DECREF(pc->stores);
6997 : : // NOTE: Returning macros are safe again.
6998 [ + + ]: 920 : if (m->guard) {
6999 [ - + ]: 105 : RETURN_IF_FALSE(ensure_fail_pop(c, pc, 0));
7000 [ - + ]: 105 : RETURN_IF_FALSE(compiler_jump_if(c, m->guard, pc->fail_pop[0], 0));
7001 : : }
7002 : : // Success! Pop the subject off, we're done with it:
7003 [ + + ]: 920 : if (i != cases - has_default - 1) {
7004 [ - + ]: 268 : ADDOP(c, POP_TOP);
7005 : : }
7006 [ - + + - : 1950 : VISIT_SEQ(c, stmt, m->body);
+ + ]
7007 [ - + ]: 920 : ADDOP_JUMP(c, JUMP, end);
7008 : : // If the pattern fails to match, we want the line number of the
7009 : : // cleanup to be associated with the failed pattern, not the last line
7010 : : // of the body
7011 : 920 : SET_LOC(c, m->pattern);
7012 [ - + ]: 920 : RETURN_IF_FALSE(emit_and_reset_fail_pop(c, pc));
7013 : : }
7014 [ + + ]: 652 : if (has_default) {
7015 : : // A trailing "case _" is common, and lets us save a bit of redundant
7016 : : // pushing and popping in the loop above:
7017 : 37 : m = asdl_seq_GET(s->v.Match.cases, cases - 1);
7018 : 37 : SET_LOC(c, m->pattern);
7019 [ - + ]: 37 : if (cases == 1) {
7020 : : // No matches. Done with the subject:
7021 [ # # ]: 0 : ADDOP(c, POP_TOP);
7022 : : }
7023 : : else {
7024 : : // Show line coverage for default case (it doesn't create bytecode)
7025 [ - + ]: 37 : ADDOP(c, NOP);
7026 : : }
7027 [ + + ]: 37 : if (m->guard) {
7028 [ - + ]: 2 : RETURN_IF_FALSE(compiler_jump_if(c, m->guard, end, 0));
7029 : : }
7030 [ - + + - : 74 : VISIT_SEQ(c, stmt, m->body);
+ + ]
7031 : : }
7032 : 652 : compiler_use_next_block(c, end);
7033 : 652 : return 1;
7034 : : }
7035 : :
7036 : : static int
7037 : 682 : compiler_match(struct compiler *c, stmt_ty s)
7038 : : {
7039 : : pattern_context pc;
7040 : 682 : pc.fail_pop = NULL;
7041 : 682 : int result = compiler_match_inner(c, s, &pc);
7042 : 682 : PyObject_Free(pc.fail_pop);
7043 : 682 : return result;
7044 : : }
7045 : :
7046 : : #undef WILDCARD_CHECK
7047 : : #undef WILDCARD_STAR_CHECK
7048 : :
7049 : :
7050 : : /* End of the compiler section, beginning of the assembler section */
7051 : :
7052 : :
7053 : : struct assembler {
7054 : : PyObject *a_bytecode; /* bytes containing bytecode */
7055 : : int a_offset; /* offset into bytecode */
7056 : : PyObject *a_except_table; /* bytes containing exception table */
7057 : : int a_except_table_off; /* offset into exception table */
7058 : : /* Location Info */
7059 : : int a_lineno; /* lineno of last emitted instruction */
7060 : : PyObject* a_linetable; /* bytes containing location info */
7061 : : int a_location_off; /* offset of last written location info frame */
7062 : : };
7063 : :
7064 : : static basicblock**
7065 : 2140102 : make_cfg_traversal_stack(basicblock *entryblock) {
7066 : 2140102 : int nblocks = 0;
7067 [ + + ]: 15097976 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7068 : 12957874 : b->b_visited = 0;
7069 : 12957874 : nblocks++;
7070 : : }
7071 : 2140102 : basicblock **stack = (basicblock **)PyMem_Malloc(sizeof(basicblock *) * nblocks);
7072 [ - + ]: 2140102 : if (!stack) {
7073 : : PyErr_NoMemory();
7074 : : }
7075 : 2140102 : return stack;
7076 : : }
7077 : :
7078 : : Py_LOCAL_INLINE(void)
7079 : 2790137 : stackdepth_push(basicblock ***sp, basicblock *b, int depth)
7080 : : {
7081 : : assert(b->b_startdepth < 0 || b->b_startdepth == depth);
7082 [ + + + - ]: 2790137 : if (b->b_startdepth < depth && b->b_startdepth < 100) {
7083 : : assert(b->b_startdepth < 0);
7084 : 2227863 : b->b_startdepth = depth;
7085 : 2227863 : *(*sp)++ = b;
7086 : : }
7087 : 2790137 : }
7088 : :
7089 : : /* Find the flow path that needs the largest stack. We assume that
7090 : : * cycles in the flow graph have no net effect on the stack depth.
7091 : : */
7092 : : static int
7093 : 461212 : stackdepth(basicblock *entryblock, int code_flags)
7094 : : {
7095 [ + + ]: 2689078 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7096 : 2227866 : b->b_startdepth = INT_MIN;
7097 : : }
7098 : 461212 : basicblock **stack = make_cfg_traversal_stack(entryblock);
7099 [ - + ]: 461212 : if (!stack) {
7100 : 0 : return -1;
7101 : : }
7102 : :
7103 : 461212 : int maxdepth = 0;
7104 : 461212 : basicblock **sp = stack;
7105 [ + + ]: 461212 : if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
7106 : 16436 : stackdepth_push(&sp, entryblock, 1);
7107 : : } else {
7108 : 444776 : stackdepth_push(&sp, entryblock, 0);
7109 : : }
7110 : :
7111 [ + + ]: 2689075 : while (sp != stack) {
7112 : 2227863 : basicblock *b = *--sp;
7113 : 2227863 : int depth = b->b_startdepth;
7114 : : assert(depth >= 0);
7115 : 2227863 : basicblock *next = b->b_next;
7116 [ + + ]: 18790545 : for (int i = 0; i < b->b_iused; i++) {
7117 : 17525012 : struct instr *instr = &b->b_instr[i];
7118 : 17525012 : int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0);
7119 [ - + ]: 17525012 : if (effect == PY_INVALID_STACK_EFFECT) {
7120 : 0 : PyErr_Format(PyExc_SystemError,
7121 : : "compiler stack_effect(opcode=%d, arg=%i) failed",
7122 : : instr->i_opcode, instr->i_oparg);
7123 : 0 : return -1;
7124 : : }
7125 : 17525012 : int new_depth = depth + effect;
7126 [ + + ]: 17525012 : if (new_depth > maxdepth) {
7127 : 1682743 : maxdepth = new_depth;
7128 : : }
7129 : : assert(depth >= 0); /* invalid code or bug in stackdepth() */
7130 [ + + + + ]: 17525012 : if (is_jump(instr) || is_block_push(instr)) {
7131 : 1063392 : effect = stack_effect(instr->i_opcode, instr->i_oparg, 1);
7132 : : assert(effect != PY_INVALID_STACK_EFFECT);
7133 : 1063392 : int target_depth = depth + effect;
7134 [ + + ]: 1063392 : if (target_depth > maxdepth) {
7135 : 15477 : maxdepth = target_depth;
7136 : : }
7137 : : assert(target_depth >= 0); /* invalid code or bug in stackdepth() */
7138 : 1063392 : stackdepth_push(&sp, instr->i_target, target_depth);
7139 : : }
7140 : 17525012 : depth = new_depth;
7141 : : assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode));
7142 [ + + + + : 17525012 : if (IS_UNCONDITIONAL_JUMP_OPCODE(instr->i_opcode) ||
+ - + - +
- ]
7143 [ + + + + : 17307028 : IS_SCOPE_EXIT_OPCODE(instr->i_opcode))
+ + ]
7144 : : {
7145 : : /* remaining code is dead */
7146 : 962330 : next = NULL;
7147 : 962330 : break;
7148 : : }
7149 [ + + ]: 16562682 : if (instr->i_opcode == YIELD_VALUE) {
7150 : 23563 : instr->i_oparg = depth;
7151 : : }
7152 : : }
7153 [ + + ]: 2227863 : if (next != NULL) {
7154 : : assert(BB_HAS_FALLTHROUGH(b));
7155 : 1265533 : stackdepth_push(&sp, next, depth);
7156 : : }
7157 : : }
7158 : 461212 : PyMem_Free(stack);
7159 : 461212 : return maxdepth;
7160 : : }
7161 : :
7162 : : static int
7163 : 461212 : assemble_init(struct assembler *a, int firstlineno)
7164 : : {
7165 : 461212 : memset(a, 0, sizeof(struct assembler));
7166 : 461212 : a->a_lineno = firstlineno;
7167 : 461212 : a->a_linetable = NULL;
7168 : 461212 : a->a_location_off = 0;
7169 : 461212 : a->a_except_table = NULL;
7170 : 461212 : a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
7171 [ - + ]: 461212 : if (a->a_bytecode == NULL) {
7172 : 0 : goto error;
7173 : : }
7174 : 461212 : a->a_linetable = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE);
7175 [ - + ]: 461212 : if (a->a_linetable == NULL) {
7176 : 0 : goto error;
7177 : : }
7178 : 461212 : a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
7179 [ - + ]: 461212 : if (a->a_except_table == NULL) {
7180 : 0 : goto error;
7181 : : }
7182 : 461212 : return 1;
7183 : 0 : error:
7184 : 0 : Py_XDECREF(a->a_bytecode);
7185 : 0 : Py_XDECREF(a->a_linetable);
7186 : 0 : Py_XDECREF(a->a_except_table);
7187 : 0 : return 0;
7188 : : }
7189 : :
7190 : : static void
7191 : 461212 : assemble_free(struct assembler *a)
7192 : : {
7193 : 461212 : Py_XDECREF(a->a_bytecode);
7194 : 461212 : Py_XDECREF(a->a_linetable);
7195 : 461212 : Py_XDECREF(a->a_except_table);
7196 : 461212 : }
7197 : :
7198 : : static int
7199 : 2529966 : blocksize(basicblock *b)
7200 : : {
7201 : : int i;
7202 : 2529966 : int size = 0;
7203 : :
7204 [ + + ]: 22190916 : for (i = 0; i < b->b_iused; i++) {
7205 : 19660950 : size += instr_size(&b->b_instr[i]);
7206 : : }
7207 : 2529966 : return size;
7208 : : }
7209 : :
7210 : : static basicblock *
7211 : 130313 : push_except_block(ExceptStack *stack, struct instr *setup) {
7212 : : assert(is_block_push(setup));
7213 : 130313 : int opcode = setup->i_opcode;
7214 : 130313 : basicblock * target = setup->i_target;
7215 [ + + + + ]: 130313 : if (opcode == SETUP_WITH || opcode == SETUP_CLEANUP) {
7216 : 89944 : target->b_preserve_lasti = 1;
7217 : : }
7218 : 130313 : stack->handlers[++stack->depth] = target;
7219 : 130313 : return target;
7220 : : }
7221 : :
7222 : : static basicblock *
7223 : 120022 : pop_except_block(ExceptStack *stack) {
7224 : : assert(stack->depth > 0);
7225 : 120022 : return stack->handlers[--stack->depth];
7226 : : }
7227 : :
7228 : : static basicblock *
7229 : 2227863 : except_stack_top(ExceptStack *stack) {
7230 : 2227863 : return stack->handlers[stack->depth];
7231 : : }
7232 : :
7233 : : static ExceptStack *
7234 : 461212 : make_except_stack(void) {
7235 : 461212 : ExceptStack *new = PyMem_Malloc(sizeof(ExceptStack));
7236 [ - + ]: 461212 : if (new == NULL) {
7237 : : PyErr_NoMemory();
7238 : 0 : return NULL;
7239 : : }
7240 : 461212 : new->depth = 0;
7241 : 461212 : new->handlers[0] = NULL;
7242 : 461212 : return new;
7243 : : }
7244 : :
7245 : : static ExceptStack *
7246 : 763811 : copy_except_stack(ExceptStack *stack) {
7247 : 763811 : ExceptStack *copy = PyMem_Malloc(sizeof(ExceptStack));
7248 [ - + ]: 763811 : if (copy == NULL) {
7249 : : PyErr_NoMemory();
7250 : 0 : return NULL;
7251 : : }
7252 : 763811 : memcpy(copy, stack, sizeof(ExceptStack));
7253 : 763811 : return copy;
7254 : : }
7255 : :
7256 : : static int
7257 : 461212 : label_exception_targets(basicblock *entryblock) {
7258 : 461212 : basicblock **todo_stack = make_cfg_traversal_stack(entryblock);
7259 [ - + ]: 461212 : if (todo_stack == NULL) {
7260 : 0 : return -1;
7261 : : }
7262 : 461212 : ExceptStack *except_stack = make_except_stack();
7263 [ - + ]: 461212 : if (except_stack == NULL) {
7264 : 0 : PyMem_Free(todo_stack);
7265 : : PyErr_NoMemory();
7266 : 0 : return -1;
7267 : : }
7268 : 461212 : except_stack->depth = 0;
7269 : 461212 : todo_stack[0] = entryblock;
7270 : 461212 : entryblock->b_visited = 1;
7271 : 461212 : entryblock->b_exceptstack = except_stack;
7272 : 461212 : basicblock **todo = &todo_stack[1];
7273 : 461212 : basicblock *handler = NULL;
7274 [ + + ]: 2689075 : while (todo > todo_stack) {
7275 : 2227863 : todo--;
7276 : 2227863 : basicblock *b = todo[0];
7277 : : assert(b->b_visited == 1);
7278 : 2227863 : except_stack = b->b_exceptstack;
7279 : : assert(except_stack != NULL);
7280 : 2227863 : b->b_exceptstack = NULL;
7281 : 2227863 : handler = except_stack_top(except_stack);
7282 [ + + ]: 19752875 : for (int i = 0; i < b->b_iused; i++) {
7283 : 17525012 : struct instr *instr = &b->b_instr[i];
7284 [ + + ]: 17525012 : if (is_block_push(instr)) {
7285 [ + - ]: 130313 : if (!instr->i_target->b_visited) {
7286 : 130313 : ExceptStack *copy = copy_except_stack(except_stack);
7287 [ - + ]: 130313 : if (copy == NULL) {
7288 : 0 : goto error;
7289 : : }
7290 : 130313 : instr->i_target->b_exceptstack = copy;
7291 : 130313 : todo[0] = instr->i_target;
7292 : 130313 : instr->i_target->b_visited = 1;
7293 : 130313 : todo++;
7294 : : }
7295 : 130313 : handler = push_except_block(except_stack, instr);
7296 : : }
7297 [ + + ]: 17394699 : else if (instr->i_opcode == POP_BLOCK) {
7298 : 120022 : handler = pop_except_block(except_stack);
7299 : : }
7300 [ + + ]: 17274677 : else if (is_jump(instr)) {
7301 : 933079 : instr->i_except = handler;
7302 : : assert(i == b->b_iused -1);
7303 [ + + ]: 933079 : if (!instr->i_target->b_visited) {
7304 [ + + ]: 709924 : if (BB_HAS_FALLTHROUGH(b)) {
7305 : 633498 : ExceptStack *copy = copy_except_stack(except_stack);
7306 [ - + ]: 633498 : if (copy == NULL) {
7307 : 0 : goto error;
7308 : : }
7309 : 633498 : instr->i_target->b_exceptstack = copy;
7310 : : }
7311 : : else {
7312 : 76426 : instr->i_target->b_exceptstack = except_stack;
7313 : 76426 : except_stack = NULL;
7314 : : }
7315 : 709924 : todo[0] = instr->i_target;
7316 : 709924 : instr->i_target->b_visited = 1;
7317 : 709924 : todo++;
7318 : : }
7319 : : }
7320 : : else {
7321 : 16341598 : instr->i_except = handler;
7322 : : }
7323 : : }
7324 [ + + + + ]: 2227863 : if (BB_HAS_FALLTHROUGH(b) && !b->b_next->b_visited) {
7325 : : assert(except_stack != NULL);
7326 : 926414 : b->b_next->b_exceptstack = except_stack;
7327 : 926414 : todo[0] = b->b_next;
7328 : 926414 : b->b_next->b_visited = 1;
7329 : 926414 : todo++;
7330 : : }
7331 [ + + ]: 1301449 : else if (except_stack != NULL) {
7332 : 1225023 : PyMem_Free(except_stack);
7333 : : }
7334 : : }
7335 : : #ifdef Py_DEBUG
7336 : : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7337 : : assert(b->b_exceptstack == NULL);
7338 : : }
7339 : : #endif
7340 : 461212 : PyMem_Free(todo_stack);
7341 : 461212 : return 0;
7342 : 0 : error:
7343 : 0 : PyMem_Free(todo_stack);
7344 : 0 : PyMem_Free(except_stack);
7345 : 0 : return -1;
7346 : : }
7347 : :
7348 : : static int
7349 : 147627 : mark_warm(basicblock *entryblock) {
7350 : 147627 : basicblock **stack = make_cfg_traversal_stack(entryblock);
7351 [ - + ]: 147627 : if (stack == NULL) {
7352 : 0 : return -1;
7353 : : }
7354 : 147627 : basicblock **sp = stack;
7355 : :
7356 : 147627 : *sp++ = entryblock;
7357 : 147627 : entryblock->b_visited = 1;
7358 [ + + ]: 1755597 : while (sp > stack) {
7359 : 1607970 : basicblock *b = *(--sp);
7360 : : assert(!b->b_except_predecessors);
7361 : 1607970 : b->b_warm = 1;
7362 : 1607970 : basicblock *next = b->b_next;
7363 [ + + + + : 1607970 : if (next && BB_HAS_FALLTHROUGH(b) && !next->b_visited) {
+ + ]
7364 : 854297 : *sp++ = next;
7365 : 854297 : next->b_visited = 1;
7366 : : }
7367 [ + + ]: 11322436 : for (int i=0; i < b->b_iused; i++) {
7368 : 9714466 : struct instr *instr = &b->b_instr[i];
7369 [ + + + + ]: 9714466 : if (is_jump(instr) && !instr->i_target->b_visited) {
7370 : 606046 : *sp++ = instr->i_target;
7371 : 606046 : instr->i_target->b_visited = 1;
7372 : : }
7373 : : }
7374 : : }
7375 : 147627 : PyMem_Free(stack);
7376 : 147627 : return 0;
7377 : : }
7378 : :
7379 : : static int
7380 : 147627 : mark_cold(basicblock *entryblock) {
7381 [ + + ]: 2061908 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7382 : : assert(!b->b_cold && !b->b_warm);
7383 : : }
7384 [ - + ]: 147627 : if (mark_warm(entryblock) < 0) {
7385 : 0 : return -1;
7386 : : }
7387 : :
7388 : 147627 : basicblock **stack = make_cfg_traversal_stack(entryblock);
7389 [ - + ]: 147627 : if (stack == NULL) {
7390 : 0 : return -1;
7391 : : }
7392 : :
7393 : 147627 : basicblock **sp = stack;
7394 [ + + ]: 2061908 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7395 [ + + ]: 1914281 : if (b->b_except_predecessors) {
7396 : : assert(b->b_except_predecessors == b->b_predecessors);
7397 : : assert(!b->b_warm);
7398 : 130313 : *sp++ = b;
7399 : 130313 : b->b_visited = 1;
7400 : : }
7401 : : }
7402 : :
7403 [ + + ]: 453935 : while (sp > stack) {
7404 : 306308 : basicblock *b = *(--sp);
7405 : 306308 : b->b_cold = 1;
7406 : 306308 : basicblock *next = b->b_next;
7407 [ + + + + ]: 306308 : if (next && BB_HAS_FALLTHROUGH(b)) {
7408 [ + + + + ]: 109847 : if (!next->b_warm && !next->b_visited) {
7409 : 107328 : *sp++ = next;
7410 : 107328 : next->b_visited = 1;
7411 : : }
7412 : : }
7413 [ + + ]: 1464125 : for (int i = 0; i < b->b_iused; i++) {
7414 : 1157817 : struct instr *instr = &b->b_instr[i];
7415 [ + + ]: 1157817 : if (is_jump(instr)) {
7416 : : assert(i == b->b_iused-1);
7417 : 102351 : basicblock *target = b->b_instr[i].i_target;
7418 [ + + + + ]: 102351 : if (!target->b_warm && !target->b_visited) {
7419 : 68667 : *sp++ = target;
7420 : 68667 : target->b_visited = 1;
7421 : : }
7422 : : }
7423 : : }
7424 : : }
7425 : 147627 : PyMem_Free(stack);
7426 : 147627 : return 0;
7427 : : }
7428 : :
7429 : : static int
7430 : 461212 : push_cold_blocks_to_end(basicblock *entryblock, int code_flags) {
7431 [ + + ]: 461212 : if (entryblock->b_next == NULL) {
7432 : : /* single basicblock, no need to reorder */
7433 : 313585 : return 0;
7434 : : }
7435 [ - + ]: 147627 : if (mark_cold(entryblock) < 0) {
7436 : 0 : return -1;
7437 : : }
7438 : :
7439 : : /* If we have a cold block with fallthrough to a warm block, add */
7440 : : /* an explicit jump instead of fallthrough */
7441 [ + + ]: 2062007 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7442 [ + + + + : 1914380 : if (b->b_cold && BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_next->b_warm) {
+ - + + ]
7443 : 99 : basicblock *explicit_jump = basicblock_new_b_list_successor(b);
7444 [ - + ]: 99 : if (explicit_jump == NULL) {
7445 : 0 : return -1;
7446 : : }
7447 : 99 : basicblock_addop(explicit_jump, JUMP, 0, b->b_next, &NO_LOCATION);
7448 : :
7449 : 99 : explicit_jump->b_cold = 1;
7450 : 99 : explicit_jump->b_next = b->b_next;
7451 : 99 : b->b_next = explicit_jump;
7452 : : }
7453 : : }
7454 : :
7455 : : assert(!entryblock->b_cold); /* First block can't be cold */
7456 : 147627 : basicblock *cold_blocks = NULL;
7457 : 147627 : basicblock *cold_blocks_tail = NULL;
7458 : :
7459 : 147627 : basicblock *b = entryblock;
7460 [ + + ]: 206611 : while(b->b_next) {
7461 : : assert(!b->b_cold);
7462 [ + + + + ]: 1647986 : while (b->b_next && !b->b_next->b_cold) {
7463 : 1460346 : b = b->b_next;
7464 : : }
7465 [ + + ]: 187640 : if (b->b_next == NULL) {
7466 : : /* no more cold blocks */
7467 : 128656 : break;
7468 : : }
7469 : :
7470 : : /* b->b_next is the beginning of a cold streak */
7471 : : assert(!b->b_cold && b->b_next->b_cold);
7472 : :
7473 : 58984 : basicblock *b_end = b->b_next;
7474 [ + + + + ]: 306407 : while (b_end->b_next && b_end->b_next->b_cold) {
7475 : 247423 : b_end = b_end->b_next;
7476 : : }
7477 : :
7478 : : /* b_end is the end of the cold streak */
7479 : : assert(b_end && b_end->b_cold);
7480 : : assert(b_end->b_next == NULL || !b_end->b_next->b_cold);
7481 : :
7482 [ + + ]: 58984 : if (cold_blocks == NULL) {
7483 : 40699 : cold_blocks = b->b_next;
7484 : : }
7485 : : else {
7486 : 18285 : cold_blocks_tail->b_next = b->b_next;
7487 : : }
7488 : 58984 : cold_blocks_tail = b_end;
7489 : 58984 : b->b_next = b_end->b_next;
7490 : 58984 : b_end->b_next = NULL;
7491 : : }
7492 : : assert(b != NULL && b->b_next == NULL);
7493 : 147627 : b->b_next = cold_blocks;
7494 : 147627 : return 0;
7495 : : }
7496 : :
7497 : : static void
7498 : 461212 : convert_exception_handlers_to_nops(basicblock *entryblock) {
7499 [ + + ]: 2689078 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7500 [ + + ]: 19752884 : for (int i = 0; i < b->b_iused; i++) {
7501 : 17525018 : struct instr *instr = &b->b_instr[i];
7502 [ + + + + ]: 17525018 : if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) {
7503 : 250335 : instr->i_opcode = NOP;
7504 : : }
7505 : : }
7506 : : }
7507 : 461212 : }
7508 : :
7509 : : static inline void
7510 : 1036952 : write_except_byte(struct assembler *a, int byte) {
7511 : 1036952 : unsigned char *p = (unsigned char *) PyBytes_AS_STRING(a->a_except_table);
7512 : 1036952 : p[a->a_except_table_off++] = byte;
7513 : 1036952 : }
7514 : :
7515 : : #define CONTINUATION_BIT 64
7516 : :
7517 : : static void
7518 : 725512 : assemble_emit_exception_table_item(struct assembler *a, int value, int msb)
7519 : : {
7520 : : assert ((msb | 128) == 128);
7521 : : assert(value >= 0 && value < (1 << 30));
7522 [ - + ]: 725512 : if (value >= 1 << 24) {
7523 : 0 : write_except_byte(a, (value >> 24) | CONTINUATION_BIT | msb);
7524 : 0 : msb = 0;
7525 : : }
7526 [ - + ]: 725512 : if (value >= 1 << 18) {
7527 : 0 : write_except_byte(a, ((value >> 18)&0x3f) | CONTINUATION_BIT | msb);
7528 : 0 : msb = 0;
7529 : : }
7530 [ + + ]: 725512 : if (value >= 1 << 12) {
7531 : 385 : write_except_byte(a, ((value >> 12)&0x3f) | CONTINUATION_BIT | msb);
7532 : 385 : msb = 0;
7533 : : }
7534 [ + + ]: 725512 : if (value >= 1 << 6) {
7535 : 311055 : write_except_byte(a, ((value >> 6)&0x3f) | CONTINUATION_BIT | msb);
7536 : 311055 : msb = 0;
7537 : : }
7538 : 725512 : write_except_byte(a, (value&0x3f) | msb);
7539 : 725512 : }
7540 : :
7541 : : /* See Objects/exception_handling_notes.txt for details of layout */
7542 : : #define MAX_SIZE_OF_ENTRY 20
7543 : :
7544 : : static int
7545 : 181378 : assemble_emit_exception_table_entry(struct assembler *a, int start, int end, basicblock *handler)
7546 : : {
7547 : 181378 : Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table);
7548 [ + + ]: 181378 : if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) {
7549 [ - + ]: 64489 : if (_PyBytes_Resize(&a->a_except_table, len * 2) < 0)
7550 : 0 : return 0;
7551 : : }
7552 : 181378 : int size = end-start;
7553 : : assert(end > start);
7554 : 181378 : int target = handler->b_offset;
7555 : 181378 : int depth = handler->b_startdepth - 1;
7556 [ + + ]: 181378 : if (handler->b_preserve_lasti) {
7557 : 132938 : depth -= 1;
7558 : : }
7559 : : assert(depth >= 0);
7560 : 181378 : int depth_lasti = (depth<<1) | handler->b_preserve_lasti;
7561 : 181378 : assemble_emit_exception_table_item(a, start, (1<<7));
7562 : 181378 : assemble_emit_exception_table_item(a, size, 0);
7563 : 181378 : assemble_emit_exception_table_item(a, target, 0);
7564 : 181378 : assemble_emit_exception_table_item(a, depth_lasti, 0);
7565 : 181378 : return 1;
7566 : : }
7567 : :
7568 : : static int
7569 : 461212 : assemble_exception_table(struct assembler *a, basicblock *entryblock)
7570 : : {
7571 : : basicblock *b;
7572 : 461212 : int ioffset = 0;
7573 : 461212 : basicblock *handler = NULL;
7574 : 461212 : int start = -1;
7575 [ + + ]: 2689177 : for (b = entryblock; b != NULL; b = b->b_next) {
7576 : 2227965 : ioffset = b->b_offset;
7577 [ + + ]: 19511792 : for (int i = 0; i < b->b_iused; i++) {
7578 : 17283827 : struct instr *instr = &b->b_instr[i];
7579 [ + + ]: 17283827 : if (instr->i_except != handler) {
7580 [ + + ]: 318373 : if (handler != NULL) {
7581 [ - + ]: 181378 : RETURN_IF_FALSE(assemble_emit_exception_table_entry(a, start, ioffset, handler));
7582 : : }
7583 : 318373 : start = ioffset;
7584 : 318373 : handler = instr->i_except;
7585 : : }
7586 : 17283827 : ioffset += instr_size(instr);
7587 : : }
7588 : : }
7589 [ - + ]: 461212 : if (handler != NULL) {
7590 [ # # ]: 0 : RETURN_IF_FALSE(assemble_emit_exception_table_entry(a, start, ioffset, handler));
7591 : : }
7592 : 461212 : return 1;
7593 : : }
7594 : :
7595 : : /* Code location emitting code. See locations.md for a description of the format. */
7596 : :
7597 : : #define MSB 0x80
7598 : :
7599 : : static void
7600 : 19006326 : write_location_byte(struct assembler* a, int val)
7601 : : {
7602 : 19006326 : PyBytes_AS_STRING(a->a_linetable)[a->a_location_off] = val&255;
7603 : 19006326 : a->a_location_off++;
7604 : 19006326 : }
7605 : :
7606 : :
7607 : : static uint8_t *
7608 : 38721733 : location_pointer(struct assembler* a)
7609 : : {
7610 : 38721733 : return (uint8_t *)PyBytes_AS_STRING(a->a_linetable) +
7611 : 38721733 : a->a_location_off;
7612 : : }
7613 : :
7614 : : static void
7615 : 18490001 : write_location_first_byte(struct assembler* a, int code, int length)
7616 : : {
7617 : 18490001 : a->a_location_off += write_location_entry_start(
7618 : : location_pointer(a), code, length);
7619 : 18490001 : }
7620 : :
7621 : : static void
7622 : 15149088 : write_location_varint(struct assembler* a, unsigned int val)
7623 : : {
7624 : 15149088 : uint8_t *ptr = location_pointer(a);
7625 : 15149088 : a->a_location_off += write_varint(ptr, val);
7626 : 15149088 : }
7627 : :
7628 : :
7629 : : static void
7630 : 5082644 : write_location_signed_varint(struct assembler* a, int val)
7631 : : {
7632 : 5082644 : uint8_t *ptr = location_pointer(a);
7633 : 5082644 : a->a_location_off += write_signed_varint(ptr, val);
7634 : 5082644 : }
7635 : :
7636 : : static void
7637 : 7197964 : write_location_info_short_form(struct assembler* a, int length, int column, int end_column)
7638 : : {
7639 : : assert(length > 0 && length <= 8);
7640 : 7197964 : int column_low_bits = column & 7;
7641 : 7197964 : int column_group = column >> 3;
7642 : : assert(column < 80);
7643 : : assert(end_column >= column);
7644 : : assert(end_column - column < 16);
7645 : 7197964 : write_location_first_byte(a, PY_CODE_LOCATION_INFO_SHORT0 + column_group, length);
7646 : 7197964 : write_location_byte(a, (column_low_bits << 4) | (end_column - column));
7647 : 7197964 : }
7648 : :
7649 : : static void
7650 : 5904181 : write_location_info_oneline_form(struct assembler* a, int length, int line_delta, int column, int end_column)
7651 : : {
7652 : : assert(length > 0 && length <= 8);
7653 : : assert(line_delta >= 0 && line_delta < 3);
7654 : : assert(column < 128);
7655 : : assert(end_column < 128);
7656 : 5904181 : write_location_first_byte(a, PY_CODE_LOCATION_INFO_ONE_LINE0 + line_delta, length);
7657 : 5904181 : write_location_byte(a, column);
7658 : 5904181 : write_location_byte(a, end_column);
7659 : 5904181 : }
7660 : :
7661 : : static void
7662 : 5049696 : write_location_info_long_form(struct assembler* a, struct instr* i, int length)
7663 : : {
7664 : : assert(length > 0 && length <= 8);
7665 : 5049696 : write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length);
7666 : 5049696 : write_location_signed_varint(a, i->i_loc.lineno - a->a_lineno);
7667 : : assert(i->i_loc.end_lineno >= i->i_loc.lineno);
7668 : 5049696 : write_location_varint(a, i->i_loc.end_lineno - i->i_loc.lineno);
7669 : 5049696 : write_location_varint(a, i->i_loc.col_offset + 1);
7670 : 5049696 : write_location_varint(a, i->i_loc.end_col_offset + 1);
7671 : 5049696 : }
7672 : :
7673 : : static void
7674 : 305212 : write_location_info_none(struct assembler* a, int length)
7675 : : {
7676 : 305212 : write_location_first_byte(a, PY_CODE_LOCATION_INFO_NONE, length);
7677 : 305212 : }
7678 : :
7679 : : static void
7680 : 32948 : write_location_info_no_column(struct assembler* a, int length, int line_delta)
7681 : : {
7682 : 32948 : write_location_first_byte(a, PY_CODE_LOCATION_INFO_NO_COLUMNS, length);
7683 : 32948 : write_location_signed_varint(a, line_delta);
7684 : 32948 : }
7685 : :
7686 : : #define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */
7687 : :
7688 : : static int
7689 : 18490001 : write_location_info_entry(struct assembler* a, struct instr* i, int isize)
7690 : : {
7691 : 18490001 : Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable);
7692 [ + + ]: 18490001 : if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) {
7693 : : assert(len > THEORETICAL_MAX_ENTRY_SIZE);
7694 [ - + ]: 838552 : if (_PyBytes_Resize(&a->a_linetable, len*2) < 0) {
7695 : 0 : return 0;
7696 : : }
7697 : : }
7698 [ + + ]: 18490001 : if (i->i_loc.lineno < 0) {
7699 : 305212 : write_location_info_none(a, isize);
7700 : 305212 : return 1;
7701 : : }
7702 : 18184789 : int line_delta = i->i_loc.lineno - a->a_lineno;
7703 : 18184789 : int column = i->i_loc.col_offset;
7704 : 18184789 : int end_column = i->i_loc.end_col_offset;
7705 : : assert(column >= -1);
7706 : : assert(end_column >= -1);
7707 [ + + - + ]: 18184789 : if (column < 0 || end_column < 0) {
7708 [ + + + - ]: 32948 : if (i->i_loc.end_lineno == i->i_loc.lineno || i->i_loc.end_lineno == -1) {
7709 : 32948 : write_location_info_no_column(a, isize, line_delta);
7710 : 32948 : a->a_lineno = i->i_loc.lineno;
7711 : 32948 : return 1;
7712 : : }
7713 : : }
7714 [ + + ]: 18151841 : else if (i->i_loc.end_lineno == i->i_loc.lineno) {
7715 [ + + + + : 14735268 : if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) {
+ + + + ]
7716 : 7197964 : write_location_info_short_form(a, isize, column, end_column);
7717 : 7197964 : return 1;
7718 : : }
7719 [ + + + + : 7537304 : if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) {
+ + + + ]
7720 : 5904181 : write_location_info_oneline_form(a, isize, line_delta, column, end_column);
7721 : 5904181 : a->a_lineno = i->i_loc.lineno;
7722 : 5904181 : return 1;
7723 : : }
7724 : : }
7725 : 5049696 : write_location_info_long_form(a, i, isize);
7726 : 5049696 : a->a_lineno = i->i_loc.lineno;
7727 : 5049696 : return 1;
7728 : : }
7729 : :
7730 : : static int
7731 : 17283827 : assemble_emit_location(struct assembler* a, struct instr* i)
7732 : : {
7733 : 17283827 : int isize = instr_size(i);
7734 [ + + ]: 18490001 : while (isize > 8) {
7735 [ - + ]: 1206174 : if (!write_location_info_entry(a, i, 8)) {
7736 : 0 : return 0;
7737 : : }
7738 : 1206174 : isize -= 8;
7739 : : }
7740 : 17283827 : return write_location_info_entry(a, i, isize);
7741 : : }
7742 : :
7743 : : /* assemble_emit()
7744 : : Extend the bytecode with a new instruction.
7745 : : Update lnotab if necessary.
7746 : : */
7747 : :
7748 : : static int
7749 : 17283827 : assemble_emit(struct assembler *a, struct instr *i)
7750 : : {
7751 : 17283827 : Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
7752 : : _Py_CODEUNIT *code;
7753 : :
7754 : 17283827 : int size = instr_size(i);
7755 [ + + ]: 17283827 : if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) {
7756 [ - + ]: 253600 : if (len > PY_SSIZE_T_MAX / 2)
7757 : 0 : return 0;
7758 [ - + ]: 253600 : if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0)
7759 : 0 : return 0;
7760 : : }
7761 : 17283827 : code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
7762 : 17283827 : a->a_offset += size;
7763 : 17283827 : write_instr(code, i, size);
7764 : 17283827 : return 1;
7765 : : }
7766 : :
7767 : : static void
7768 : 461212 : normalize_jumps(basicblock *entryblock)
7769 : : {
7770 [ + + ]: 2689177 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7771 : 2227965 : b->b_visited = 0;
7772 : : }
7773 [ + + ]: 2689177 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7774 : 2227965 : b->b_visited = 1;
7775 [ + + ]: 2227965 : if (b->b_iused == 0) {
7776 : 1856 : continue;
7777 : : }
7778 : 2226109 : struct instr *last = &b->b_instr[b->b_iused-1];
7779 : : assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
7780 [ + + ]: 2226109 : if (is_jump(last)) {
7781 : 898600 : bool is_forward = last->i_target->b_visited == 0;
7782 [ + + + + : 898600 : switch(last->i_opcode) {
+ + + + ]
7783 : 179004 : case JUMP:
7784 [ + + ]: 179004 : last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
7785 : 179004 : break;
7786 : 4501 : case JUMP_NO_INTERRUPT:
7787 : 4501 : last->i_opcode = is_forward ?
7788 [ - + ]: 4501 : JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
7789 : 4501 : break;
7790 : 24450 : case POP_JUMP_IF_NOT_NONE:
7791 : 24450 : last->i_opcode = is_forward ?
7792 [ + + ]: 24450 : POP_JUMP_FORWARD_IF_NOT_NONE : POP_JUMP_BACKWARD_IF_NOT_NONE;
7793 : 24450 : break;
7794 : 22137 : case POP_JUMP_IF_NONE:
7795 : 22137 : last->i_opcode = is_forward ?
7796 [ + + ]: 22137 : POP_JUMP_FORWARD_IF_NONE : POP_JUMP_BACKWARD_IF_NONE;
7797 : 22137 : break;
7798 : 495461 : case POP_JUMP_IF_FALSE:
7799 : 495461 : last->i_opcode = is_forward ?
7800 [ + + ]: 495461 : POP_JUMP_FORWARD_IF_FALSE : POP_JUMP_BACKWARD_IF_FALSE;
7801 : 495461 : break;
7802 : 85271 : case POP_JUMP_IF_TRUE:
7803 : 85271 : last->i_opcode = is_forward ?
7804 [ + + ]: 85271 : POP_JUMP_FORWARD_IF_TRUE : POP_JUMP_BACKWARD_IF_TRUE;
7805 : 85271 : break;
7806 : 19105 : case JUMP_IF_TRUE_OR_POP:
7807 : : case JUMP_IF_FALSE_OR_POP:
7808 [ - + ]: 19105 : if (!is_forward) {
7809 : : /* As far as we can tell, the compiler never emits
7810 : : * these jumps with a backwards target. If/when this
7811 : : * exception is raised, we have found a use case for
7812 : : * a backwards version of this jump (or to replace
7813 : : * it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP)
7814 : : */
7815 : 0 : PyErr_Format(PyExc_SystemError,
7816 : : "unexpected %s jumping backwards",
7817 [ # # ]: 0 : last->i_opcode == JUMP_IF_TRUE_OR_POP ?
7818 : : "JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP");
7819 : : }
7820 : 19105 : break;
7821 : : }
7822 : : }
7823 : : }
7824 : 461212 : }
7825 : :
7826 : : static void
7827 : 461212 : assemble_jump_offsets(basicblock *entryblock)
7828 : : {
7829 : : int bsize, totsize, extended_arg_recompile;
7830 : :
7831 : : /* Compute the size of each block and fixup jump args.
7832 : : Replace block pointer with position in bytecode. */
7833 : : do {
7834 : 469441 : totsize = 0;
7835 [ + + ]: 2999407 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7836 : 2529966 : bsize = blocksize(b);
7837 : 2529966 : b->b_offset = totsize;
7838 : 2529966 : totsize += bsize;
7839 : : }
7840 : 469441 : extended_arg_recompile = 0;
7841 [ + + ]: 2999407 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7842 : 2529966 : bsize = b->b_offset;
7843 [ + + ]: 22190916 : for (int i = 0; i < b->b_iused; i++) {
7844 : 19660950 : struct instr *instr = &b->b_instr[i];
7845 : 19660950 : int isize = instr_size(instr);
7846 : : /* Relative jumps are computed relative to
7847 : : the instruction pointer after fetching
7848 : : the jump instruction.
7849 : : */
7850 : 19660950 : bsize += isize;
7851 [ + + ]: 19660950 : if (is_jump(instr)) {
7852 : 1064981 : instr->i_oparg = instr->i_target->b_offset;
7853 [ + - ]: 1064981 : if (is_relative_jump(instr)) {
7854 [ + + ]: 1064981 : if (instr->i_oparg < bsize) {
7855 : : assert(IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
7856 : 173023 : instr->i_oparg = bsize - instr->i_oparg;
7857 : : }
7858 : : else {
7859 : : assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
7860 : 891958 : instr->i_oparg -= bsize;
7861 : : }
7862 : : }
7863 : : else {
7864 : : assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
7865 : : }
7866 [ + + ]: 1064981 : if (instr_size(instr) != isize) {
7867 : 24817 : extended_arg_recompile = 1;
7868 : : }
7869 : : }
7870 : : }
7871 : : }
7872 : :
7873 : : /* XXX: This is an awful hack that could hurt performance, but
7874 : : on the bright side it should work until we come up
7875 : : with a better solution.
7876 : :
7877 : : The issue is that in the first loop blocksize() is called
7878 : : which calls instr_size() which requires i_oparg be set
7879 : : appropriately. There is a bootstrap problem because
7880 : : i_oparg is calculated in the second loop above.
7881 : :
7882 : : So we loop until we stop seeing new EXTENDED_ARGs.
7883 : : The only EXTENDED_ARGs that could be popping up are
7884 : : ones in jump instructions. So this should converge
7885 : : fairly quickly.
7886 : : */
7887 [ + + ]: 469441 : } while (extended_arg_recompile);
7888 : 461212 : }
7889 : :
7890 : :
7891 : : // Ensure each basicblock is only put onto the stack once.
7892 : : #define MAYBE_PUSH(B) do { \
7893 : : if ((B)->b_visited == 0) { \
7894 : : *(*stack_top)++ = (B); \
7895 : : (B)->b_visited = 1; \
7896 : : } \
7897 : : } while (0)
7898 : :
7899 : : static void
7900 : 15109542 : scan_block_for_local(int target, basicblock *b, bool unsafe_to_start,
7901 : : basicblock ***stack_top)
7902 : : {
7903 : 15109542 : bool unsafe = unsafe_to_start;
7904 [ + + ]: 172584748 : for (int i = 0; i < b->b_iused; i++) {
7905 : 157475206 : struct instr *instr = &b->b_instr[i];
7906 : : assert(instr->i_opcode != EXTENDED_ARG);
7907 : : assert(instr->i_opcode != EXTENDED_ARG_QUICK);
7908 : : assert(instr->i_opcode != LOAD_FAST__LOAD_FAST);
7909 : : assert(instr->i_opcode != STORE_FAST__LOAD_FAST);
7910 : : assert(instr->i_opcode != LOAD_CONST__LOAD_FAST);
7911 : : assert(instr->i_opcode != STORE_FAST__STORE_FAST);
7912 : : assert(instr->i_opcode != LOAD_FAST__LOAD_CONST);
7913 [ + + + + ]: 157475206 : if (unsafe && instr->i_except != NULL) {
7914 [ + + ]: 3771930 : MAYBE_PUSH(instr->i_except);
7915 : : }
7916 [ + + ]: 157475206 : if (instr->i_oparg != target) {
7917 : 147126183 : continue;
7918 : : }
7919 [ + + + + : 10349023 : switch (instr->i_opcode) {
+ ]
7920 : 1 : case LOAD_FAST_CHECK:
7921 : : // if this doesn't raise, then var is defined
7922 : 1 : unsafe = false;
7923 : 1 : break;
7924 : 2699759 : case LOAD_FAST:
7925 [ + + ]: 2699759 : if (unsafe) {
7926 : 7527 : instr->i_opcode = LOAD_FAST_CHECK;
7927 : : }
7928 : 2699759 : unsafe = false;
7929 : 2699759 : break;
7930 : 1012642 : case STORE_FAST:
7931 : 1012642 : unsafe = false;
7932 : 1012642 : break;
7933 : 13111 : case DELETE_FAST:
7934 : 13111 : unsafe = true;
7935 : 13111 : break;
7936 : : }
7937 : : }
7938 [ + + ]: 15109542 : if (unsafe) {
7939 : : // unsafe at end of this block,
7940 : : // so unsafe at start of next blocks
7941 [ + + + + ]: 3547155 : if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
7942 [ + + ]: 2336814 : MAYBE_PUSH(b->b_next);
7943 : : }
7944 [ + + ]: 3547155 : if (b->b_iused > 0) {
7945 : 3542056 : struct instr *last = &b->b_instr[b->b_iused-1];
7946 [ + + ]: 3542056 : if (is_jump(last)) {
7947 : : assert(last->i_target != NULL);
7948 [ + + ]: 1840859 : MAYBE_PUSH(last->i_target);
7949 : : }
7950 : : }
7951 : : }
7952 : 15109542 : }
7953 : : #undef MAYBE_PUSH
7954 : :
7955 : : static int
7956 : 461212 : add_checks_for_loads_of_unknown_variables(basicblock *entryblock,
7957 : : struct compiler *c)
7958 : : {
7959 : 461212 : basicblock **stack = make_cfg_traversal_stack(entryblock);
7960 [ - + ]: 461212 : if (stack == NULL) {
7961 : 0 : return -1;
7962 : : }
7963 : 461212 : Py_ssize_t nparams = PyList_GET_SIZE(c->u->u_ste->ste_varnames);
7964 : 461212 : int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
7965 [ + + ]: 1540971 : for (int target = 0; target < nlocals; target++) {
7966 [ + + ]: 12215686 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7967 : 11135927 : b->b_visited = 0;
7968 : : }
7969 : 1079759 : basicblock **stack_top = stack;
7970 : :
7971 : : // First pass: find the relevant DFS starting points:
7972 : : // the places where "being uninitialized" originates,
7973 : : // which are the entry block and any DELETE_FAST statements.
7974 [ + + ]: 1079759 : if (target >= nparams) {
7975 : : // only non-parameter locals start out uninitialized.
7976 : 384802 : *(stack_top++) = entryblock;
7977 : 384802 : entryblock->b_visited = 1;
7978 : : }
7979 [ + + ]: 12215686 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
7980 : 11135927 : scan_block_for_local(target, b, false, &stack_top);
7981 : : }
7982 : :
7983 : : // Second pass: Depth-first search to propagate uncertainty
7984 [ + + ]: 5053374 : while (stack_top > stack) {
7985 : 3973615 : basicblock *b = *--stack_top;
7986 : 3973615 : scan_block_for_local(target, b, true, &stack_top);
7987 : : }
7988 : : }
7989 : 461212 : PyMem_Free(stack);
7990 : 461212 : return 0;
7991 : : }
7992 : :
7993 : : static PyObject *
7994 : 461212 : dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
7995 : : {
7996 : : PyObject *tuple, *k, *v;
7997 : 461212 : Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
7998 : :
7999 : 461212 : tuple = PyTuple_New(size);
8000 [ - + ]: 461212 : if (tuple == NULL)
8001 : 0 : return NULL;
8002 [ + + ]: 2615882 : while (PyDict_Next(dict, &pos, &k, &v)) {
8003 : 2154670 : i = PyLong_AS_LONG(v);
8004 : 2154670 : Py_INCREF(k);
8005 : : assert((i - offset) < size);
8006 : : assert((i - offset) >= 0);
8007 : 2154670 : PyTuple_SET_ITEM(tuple, i - offset, k);
8008 : : }
8009 : 461212 : return tuple;
8010 : : }
8011 : :
8012 : : static PyObject *
8013 : 461212 : consts_dict_keys_inorder(PyObject *dict)
8014 : : {
8015 : : PyObject *consts, *k, *v;
8016 : 461212 : Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
8017 : :
8018 : 461212 : consts = PyList_New(size); /* PyCode_Optimize() requires a list */
8019 [ - + ]: 461212 : if (consts == NULL)
8020 : 0 : return NULL;
8021 [ + + ]: 2610240 : while (PyDict_Next(dict, &pos, &k, &v)) {
8022 : 2149028 : i = PyLong_AS_LONG(v);
8023 : : /* The keys of the dictionary can be tuples wrapping a constant.
8024 : : * (see compiler_add_o and _PyCode_ConstantKey). In that case
8025 : : * the object we want is always second. */
8026 [ + + ]: 2149028 : if (PyTuple_CheckExact(k)) {
8027 : 234840 : k = PyTuple_GET_ITEM(k, 1);
8028 : : }
8029 : 2149028 : Py_INCREF(k);
8030 : : assert(i < size);
8031 : : assert(i >= 0);
8032 : 2149028 : PyList_SET_ITEM(consts, i, k);
8033 : : }
8034 : 461212 : return consts;
8035 : : }
8036 : :
8037 : : static int
8038 : 461212 : compute_code_flags(struct compiler *c)
8039 : : {
8040 : 461212 : PySTEntryObject *ste = c->u->u_ste;
8041 : 461212 : int flags = 0;
8042 [ + + ]: 461212 : if (ste->ste_type == FunctionBlock) {
8043 : 310646 : flags |= CO_NEWLOCALS | CO_OPTIMIZED;
8044 [ + + ]: 310646 : if (ste->ste_nested)
8045 : 41925 : flags |= CO_NESTED;
8046 [ + + + + ]: 310646 : if (ste->ste_generator && !ste->ste_coroutine)
8047 : 14067 : flags |= CO_GENERATOR;
8048 [ + + + + ]: 310646 : if (!ste->ste_generator && ste->ste_coroutine)
8049 : 2198 : flags |= CO_COROUTINE;
8050 [ + + + + ]: 310646 : if (ste->ste_generator && ste->ste_coroutine)
8051 : 151 : flags |= CO_ASYNC_GENERATOR;
8052 [ + + ]: 310646 : if (ste->ste_varargs)
8053 : 24333 : flags |= CO_VARARGS;
8054 [ + + ]: 310646 : if (ste->ste_varkeywords)
8055 : 23274 : flags |= CO_VARKEYWORDS;
8056 : : }
8057 : :
8058 : : /* (Only) inherit compilerflags in PyCF_MASK */
8059 : 461212 : flags |= (c->c_flags->cf_flags & PyCF_MASK);
8060 : :
8061 [ + + + + : 461212 : if ((IS_TOP_LEVEL_AWAIT(c)) &&
+ + ]
8062 : 20 : ste->ste_coroutine &&
8063 [ + - ]: 20 : !ste->ste_generator) {
8064 : 20 : flags |= CO_COROUTINE;
8065 : : }
8066 : :
8067 : 461212 : return flags;
8068 : : }
8069 : :
8070 : : // Merge *obj* with constant cache.
8071 : : // Unlike merge_consts_recursive(), this function doesn't work recursively.
8072 : : static int
8073 : 2803255 : merge_const_one(PyObject *const_cache, PyObject **obj)
8074 : : {
8075 : 2803255 : PyDict_CheckExact(const_cache);
8076 : 2803255 : PyObject *key = _PyCode_ConstantKey(*obj);
8077 [ - + ]: 2803255 : if (key == NULL) {
8078 : 0 : return 0;
8079 : : }
8080 : :
8081 : : // t is borrowed reference
8082 : 2803255 : PyObject *t = PyDict_SetDefault(const_cache, key, key);
8083 : 2803255 : Py_DECREF(key);
8084 [ - + ]: 2803255 : if (t == NULL) {
8085 : 0 : return 0;
8086 : : }
8087 [ + + ]: 2803255 : if (t == key) { // obj is new constant.
8088 : 2063484 : return 1;
8089 : : }
8090 : :
8091 [ + - ]: 739771 : if (PyTuple_CheckExact(t)) {
8092 : : // t is still borrowed reference
8093 : 739771 : t = PyTuple_GET_ITEM(t, 1);
8094 : : }
8095 : :
8096 : 739771 : Py_INCREF(t);
8097 : 739771 : Py_DECREF(*obj);
8098 : 739771 : *obj = t;
8099 : 739771 : return 1;
8100 : : }
8101 : :
8102 : : // This is in codeobject.c.
8103 : : extern void _Py_set_localsplus_info(int, PyObject *, unsigned char,
8104 : : PyObject *, PyObject *);
8105 : :
8106 : : static void
8107 : 461212 : compute_localsplus_info(struct compiler *c, int nlocalsplus,
8108 : : PyObject *names, PyObject *kinds)
8109 : : {
8110 : : PyObject *k, *v;
8111 : 461212 : Py_ssize_t pos = 0;
8112 [ + + ]: 1540971 : while (PyDict_Next(c->u->u_varnames, &pos, &k, &v)) {
8113 : 1079759 : int offset = (int)PyLong_AS_LONG(v);
8114 : : assert(offset >= 0);
8115 : : assert(offset < nlocalsplus);
8116 : : // For now we do not distinguish arg kinds.
8117 : 1079759 : _PyLocals_Kind kind = CO_FAST_LOCAL;
8118 [ + + ]: 1079759 : if (PyDict_GetItem(c->u->u_cellvars, k) != NULL) {
8119 : 9893 : kind |= CO_FAST_CELL;
8120 : : }
8121 : 1079759 : _Py_set_localsplus_info(offset, k, kind, names, kinds);
8122 : : }
8123 : 461212 : int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
8124 : :
8125 : : // This counter mirrors the fix done in fix_cell_offsets().
8126 : 461212 : int numdropped = 0;
8127 : 461212 : pos = 0;
8128 [ + + ]: 487503 : while (PyDict_Next(c->u->u_cellvars, &pos, &k, &v)) {
8129 [ + + ]: 26291 : if (PyDict_GetItem(c->u->u_varnames, k) != NULL) {
8130 : : // Skip cells that are already covered by locals.
8131 : 9893 : numdropped += 1;
8132 : 9893 : continue;
8133 : : }
8134 : 16398 : int offset = (int)PyLong_AS_LONG(v);
8135 : : assert(offset >= 0);
8136 : 16398 : offset += nlocals - numdropped;
8137 : : assert(offset < nlocalsplus);
8138 : 16398 : _Py_set_localsplus_info(offset, k, CO_FAST_CELL, names, kinds);
8139 : : }
8140 : :
8141 : 461212 : pos = 0;
8142 [ + + ]: 496119 : while (PyDict_Next(c->u->u_freevars, &pos, &k, &v)) {
8143 : 34907 : int offset = (int)PyLong_AS_LONG(v);
8144 : : assert(offset >= 0);
8145 : 34907 : offset += nlocals - numdropped;
8146 : : assert(offset < nlocalsplus);
8147 : 34907 : _Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds);
8148 : : }
8149 : 461212 : }
8150 : :
8151 : : static PyCodeObject *
8152 : 461212 : makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
8153 : : int maxdepth, int nlocalsplus, int code_flags)
8154 : : {
8155 : 461212 : PyCodeObject *co = NULL;
8156 : 461212 : PyObject *names = NULL;
8157 : 461212 : PyObject *consts = NULL;
8158 : 461212 : PyObject *localsplusnames = NULL;
8159 : 461212 : PyObject *localspluskinds = NULL;
8160 : :
8161 : 461212 : names = dict_keys_inorder(c->u->u_names, 0);
8162 [ - + ]: 461212 : if (!names) {
8163 : 0 : goto error;
8164 : : }
8165 [ - + ]: 461212 : if (!merge_const_one(c->c_const_cache, &names)) {
8166 : 0 : goto error;
8167 : : }
8168 : :
8169 : 461212 : consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */
8170 [ - + ]: 461212 : if (consts == NULL) {
8171 : 0 : goto error;
8172 : : }
8173 [ - + ]: 461212 : if (!merge_const_one(c->c_const_cache, &consts)) {
8174 : 0 : goto error;
8175 : : }
8176 : :
8177 : : assert(c->u->u_posonlyargcount < INT_MAX);
8178 : : assert(c->u->u_argcount < INT_MAX);
8179 : : assert(c->u->u_kwonlyargcount < INT_MAX);
8180 : 461212 : int posonlyargcount = (int)c->u->u_posonlyargcount;
8181 : 461212 : int posorkwargcount = (int)c->u->u_argcount;
8182 : : assert(INT_MAX - posonlyargcount - posorkwargcount > 0);
8183 : 461212 : int kwonlyargcount = (int)c->u->u_kwonlyargcount;
8184 : :
8185 : 461212 : localsplusnames = PyTuple_New(nlocalsplus);
8186 [ - + ]: 461212 : if (localsplusnames == NULL) {
8187 : 0 : goto error;
8188 : : }
8189 : 461212 : localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
8190 [ - + ]: 461212 : if (localspluskinds == NULL) {
8191 : 0 : goto error;
8192 : : }
8193 : 461212 : compute_localsplus_info(c, nlocalsplus, localsplusnames, localspluskinds);
8194 : :
8195 : 922424 : struct _PyCodeConstructor con = {
8196 : 461212 : .filename = c->c_filename,
8197 : 461212 : .name = c->u->u_name,
8198 [ + + ]: 461212 : .qualname = c->u->u_qualname ? c->u->u_qualname : c->u->u_name,
8199 : : .flags = code_flags,
8200 : :
8201 : 461212 : .code = a->a_bytecode,
8202 : 461212 : .firstlineno = c->u->u_firstlineno,
8203 : 461212 : .linetable = a->a_linetable,
8204 : :
8205 : : .consts = consts,
8206 : : .names = names,
8207 : :
8208 : : .localsplusnames = localsplusnames,
8209 : : .localspluskinds = localspluskinds,
8210 : :
8211 : 461212 : .argcount = posonlyargcount + posorkwargcount,
8212 : : .posonlyargcount = posonlyargcount,
8213 : : .kwonlyargcount = kwonlyargcount,
8214 : :
8215 : : .stacksize = maxdepth,
8216 : :
8217 : 461212 : .exceptiontable = a->a_except_table,
8218 : : };
8219 : :
8220 [ - + ]: 461212 : if (_PyCode_Validate(&con) < 0) {
8221 : 0 : goto error;
8222 : : }
8223 : :
8224 [ - + ]: 461212 : if (!merge_const_one(c->c_const_cache, &localsplusnames)) {
8225 : 0 : goto error;
8226 : : }
8227 : 461212 : con.localsplusnames = localsplusnames;
8228 : :
8229 : 461212 : co = _PyCode_New(&con);
8230 [ + - ]: 461212 : if (co == NULL) {
8231 : 0 : goto error;
8232 : : }
8233 : :
8234 : 461212 : error:
8235 : 461212 : Py_XDECREF(names);
8236 : 461212 : Py_XDECREF(consts);
8237 : 461212 : Py_XDECREF(localsplusnames);
8238 : 461212 : Py_XDECREF(localspluskinds);
8239 : 461212 : return co;
8240 : : }
8241 : :
8242 : :
8243 : : /* For debugging purposes only */
8244 : : #if 0
8245 : : static void
8246 : : dump_instr(struct instr *i)
8247 : : {
8248 : : const char *jrel = (is_relative_jump(i)) ? "jrel " : "";
8249 : : const char *jabs = (is_jump(i) && !is_relative_jump(i))? "jabs " : "";
8250 : :
8251 : : char arg[128];
8252 : :
8253 : : *arg = '\0';
8254 : : if (HAS_ARG(i->i_opcode)) {
8255 : : sprintf(arg, "arg: %d ", i->i_oparg);
8256 : : }
8257 : : if (is_jump(i)) {
8258 : : sprintf(arg, "target: %p ", i->i_target);
8259 : : }
8260 : : if (is_block_push(i)) {
8261 : : sprintf(arg, "except_target: %p ", i->i_target);
8262 : : }
8263 : : fprintf(stderr, "line: %d, opcode: %d %s%s%s\n",
8264 : : i->i_loc.lineno, i->i_opcode, arg, jabs, jrel);
8265 : : }
8266 : :
8267 : : static void
8268 : : dump_basicblock(const basicblock *b)
8269 : : {
8270 : : const char *b_return = basicblock_returns(b) ? "return " : "";
8271 : : fprintf(stderr, "[%d %d %d %p] used: %d, depth: %d, offset: %d %s\n",
8272 : : b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused,
8273 : : b->b_startdepth, b->b_offset, b_return);
8274 : : if (b->b_instr) {
8275 : : int i;
8276 : : for (i = 0; i < b->b_iused; i++) {
8277 : : fprintf(stderr, " [%02d] ", i);
8278 : : dump_instr(b->b_instr + i);
8279 : : }
8280 : : }
8281 : : }
8282 : : #endif
8283 : :
8284 : :
8285 : : static int
8286 : : normalize_basic_block(basicblock *bb);
8287 : :
8288 : : static int
8289 : : optimize_cfg(basicblock *entryblock, PyObject *consts, PyObject *const_cache);
8290 : :
8291 : : static int
8292 : : trim_unused_consts(basicblock *entryblock, PyObject *consts);
8293 : :
8294 : : /* Duplicates exit BBs, so that line numbers can be propagated to them */
8295 : : static int
8296 : : duplicate_exits_without_lineno(basicblock *entryblock);
8297 : :
8298 : : static int
8299 : : extend_block(basicblock *bb);
8300 : :
8301 : : static int *
8302 : 461212 : build_cellfixedoffsets(struct compiler *c)
8303 : : {
8304 : 461212 : int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
8305 : 461212 : int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars);
8306 : 461212 : int nfreevars = (int)PyDict_GET_SIZE(c->u->u_freevars);
8307 : :
8308 : 461212 : int noffsets = ncellvars + nfreevars;
8309 [ + - ]: 461212 : int *fixed = PyMem_New(int, noffsets);
8310 [ - + ]: 461212 : if (fixed == NULL) {
8311 : : PyErr_NoMemory();
8312 : 0 : return NULL;
8313 : : }
8314 [ + + ]: 522410 : for (int i = 0; i < noffsets; i++) {
8315 : 61198 : fixed[i] = nlocals + i;
8316 : : }
8317 : :
8318 : : PyObject *varname, *cellindex;
8319 : 461212 : Py_ssize_t pos = 0;
8320 [ + + ]: 948715 : while (PyDict_Next(c->u->u_cellvars, &pos, &varname, &cellindex)) {
8321 : 26291 : PyObject *varindex = PyDict_GetItem(c->u->u_varnames, varname);
8322 [ + + ]: 26291 : if (varindex != NULL) {
8323 : : assert(PyLong_AS_LONG(cellindex) < INT_MAX);
8324 : : assert(PyLong_AS_LONG(varindex) < INT_MAX);
8325 : 9893 : int oldindex = (int)PyLong_AS_LONG(cellindex);
8326 : 9893 : int argoffset = (int)PyLong_AS_LONG(varindex);
8327 : 9893 : fixed[oldindex] = argoffset;
8328 : : }
8329 : : }
8330 : :
8331 : 461212 : return fixed;
8332 : : }
8333 : :
8334 : : static inline int
8335 : 83508 : insert_instruction(basicblock *block, int pos, struct instr *instr) {
8336 [ - + ]: 83508 : if (basicblock_next_instr(block) < 0) {
8337 : 0 : return -1;
8338 : : }
8339 [ + + ]: 1367418 : for (int i = block->b_iused-1; i > pos; i--) {
8340 : 1283910 : block->b_instr[i] = block->b_instr[i-1];
8341 : : }
8342 : 83508 : block->b_instr[pos] = *instr;
8343 : 83508 : return 0;
8344 : : }
8345 : :
8346 : : static int
8347 : 461212 : insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
8348 : : int *fixed, int nfreevars, int code_flags)
8349 : : {
8350 : : assert(c->u->u_firstlineno > 0);
8351 : :
8352 : : /* Add the generator prefix instructions. */
8353 [ + + ]: 461212 : if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
8354 : 16436 : struct instr make_gen = {
8355 : : .i_opcode = RETURN_GENERATOR,
8356 : : .i_oparg = 0,
8357 : 16436 : .i_loc = LOCATION(c->u->u_firstlineno, c->u->u_firstlineno, -1, -1),
8358 : : .i_target = NULL,
8359 : : };
8360 [ - + ]: 16436 : if (insert_instruction(entryblock, 0, &make_gen) < 0) {
8361 : 0 : return -1;
8362 : : }
8363 : 16436 : struct instr pop_top = {
8364 : : .i_opcode = POP_TOP,
8365 : : .i_oparg = 0,
8366 : : .i_loc = NO_LOCATION,
8367 : : .i_target = NULL,
8368 : : };
8369 [ - + ]: 16436 : if (insert_instruction(entryblock, 1, &pop_top) < 0) {
8370 : 0 : return -1;
8371 : : }
8372 : : }
8373 : :
8374 : : /* Set up cells for any variable that escapes, to be put in a closure. */
8375 : 461212 : const int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars);
8376 [ + + ]: 461212 : if (ncellvars) {
8377 : : // c->u->u_cellvars has the cells out of order so we sort them
8378 : : // before adding the MAKE_CELL instructions. Note that we
8379 : : // adjust for arg cells, which come first.
8380 : 16391 : const int nvars = ncellvars + (int)PyDict_GET_SIZE(c->u->u_varnames);
8381 : 16391 : int *sorted = PyMem_RawCalloc(nvars, sizeof(int));
8382 [ - + ]: 16391 : if (sorted == NULL) {
8383 : : PyErr_NoMemory();
8384 : 0 : return -1;
8385 : : }
8386 [ + + ]: 42682 : for (int i = 0; i < ncellvars; i++) {
8387 : 26291 : sorted[fixed[i]] = i + 1;
8388 : : }
8389 [ + + ]: 87335 : for (int i = 0, ncellsused = 0; ncellsused < ncellvars; i++) {
8390 : 70944 : int oldindex = sorted[i] - 1;
8391 [ + + ]: 70944 : if (oldindex == -1) {
8392 : 44653 : continue;
8393 : : }
8394 : 26291 : struct instr make_cell = {
8395 : : .i_opcode = MAKE_CELL,
8396 : : // This will get fixed in offset_derefs().
8397 : : .i_oparg = oldindex,
8398 : : .i_loc = NO_LOCATION,
8399 : : .i_target = NULL,
8400 : : };
8401 [ - + ]: 26291 : if (insert_instruction(entryblock, ncellsused, &make_cell) < 0) {
8402 : 0 : return -1;
8403 : : }
8404 : 26291 : ncellsused += 1;
8405 : : }
8406 : 16391 : PyMem_RawFree(sorted);
8407 : : }
8408 : :
8409 [ + + ]: 461212 : if (nfreevars) {
8410 : 24345 : struct instr copy_frees = {
8411 : : .i_opcode = COPY_FREE_VARS,
8412 : : .i_oparg = nfreevars,
8413 : : .i_loc = NO_LOCATION,
8414 : : .i_target = NULL,
8415 : : };
8416 [ - + ]: 24345 : if (insert_instruction(entryblock, 0, ©_frees) < 0) {
8417 : 0 : return -1;
8418 : : }
8419 : :
8420 : : }
8421 : :
8422 : 461212 : return 0;
8423 : : }
8424 : :
8425 : : /* Make sure that all returns have a line number, even if early passes
8426 : : * have failed to propagate a correct line number.
8427 : : * The resulting line number may not be correct according to PEP 626,
8428 : : * but should be "good enough", and no worse than in older versions. */
8429 : : static void
8430 : 461212 : guarantee_lineno_for_exits(basicblock *entryblock, int firstlineno) {
8431 : 461212 : int lineno = firstlineno;
8432 : : assert(lineno > 0);
8433 [ + + ]: 2689078 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
8434 [ - + ]: 2227866 : if (b->b_iused == 0) {
8435 : 0 : continue;
8436 : : }
8437 : 2227866 : struct instr *last = &b->b_instr[b->b_iused-1];
8438 [ + + ]: 2227866 : if (last->i_loc.lineno < 0) {
8439 [ + + ]: 70488 : if (last->i_opcode == RETURN_VALUE) {
8440 [ + + ]: 107 : for (int i = 0; i < b->b_iused; i++) {
8441 : : assert(b->b_instr[i].i_loc.lineno < 0);
8442 : :
8443 : 88 : b->b_instr[i].i_loc.lineno = lineno;
8444 : : }
8445 : : }
8446 : : }
8447 : : else {
8448 : 2157378 : lineno = last->i_loc.lineno;
8449 : : }
8450 : : }
8451 : 461212 : }
8452 : :
8453 : : static int
8454 : 461212 : fix_cell_offsets(struct compiler *c, basicblock *entryblock, int *fixedmap)
8455 : : {
8456 : 461212 : int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
8457 : 461212 : int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars);
8458 : 461212 : int nfreevars = (int)PyDict_GET_SIZE(c->u->u_freevars);
8459 : 461212 : int noffsets = ncellvars + nfreevars;
8460 : :
8461 : : // First deal with duplicates (arg cells).
8462 : 461212 : int numdropped = 0;
8463 [ + + ]: 522410 : for (int i = 0; i < noffsets ; i++) {
8464 [ + + ]: 61198 : if (fixedmap[i] == i + nlocals) {
8465 : 51305 : fixedmap[i] -= numdropped;
8466 : : }
8467 : : else {
8468 : : // It was a duplicate (cell/arg).
8469 : 9893 : numdropped += 1;
8470 : : }
8471 : : }
8472 : :
8473 : : // Then update offsets, either relative to locals or by cell2arg.
8474 [ + + ]: 2906827 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
8475 [ + + ]: 20799420 : for (int i = 0; i < b->b_iused; i++) {
8476 : 18353805 : struct instr *inst = &b->b_instr[i];
8477 : : // This is called before extended args are generated.
8478 : : assert(inst->i_opcode != EXTENDED_ARG);
8479 : : assert(inst->i_opcode != EXTENDED_ARG_QUICK);
8480 : 18353805 : int oldoffset = inst->i_oparg;
8481 [ + + ]: 18353805 : switch(inst->i_opcode) {
8482 : 156438 : case MAKE_CELL:
8483 : : case LOAD_CLOSURE:
8484 : : case LOAD_DEREF:
8485 : : case STORE_DEREF:
8486 : : case DELETE_DEREF:
8487 : : case LOAD_CLASSDEREF:
8488 : : assert(oldoffset >= 0);
8489 : : assert(oldoffset < noffsets);
8490 : : assert(fixedmap[oldoffset] >= 0);
8491 : 156438 : inst->i_oparg = fixedmap[oldoffset];
8492 : : }
8493 : : }
8494 : : }
8495 : :
8496 : 461212 : return numdropped;
8497 : : }
8498 : :
8499 : : static void
8500 : : propagate_line_numbers(basicblock *entryblock);
8501 : :
8502 : : static void
8503 : : eliminate_empty_basic_blocks(basicblock *entryblock);
8504 : :
8505 : :
8506 : : static void
8507 : 461212 : remove_redundant_jumps(basicblock *entryblock) {
8508 : : /* If a non-empty block ends with a jump instruction, check if the next
8509 : : * non-empty block reached through normal flow control is the target
8510 : : * of that jump. If it is, then the jump instruction is redundant and
8511 : : * can be deleted.
8512 : : */
8513 : 461212 : int removed = 0;
8514 [ + + ]: 2689177 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
8515 [ + - ]: 2227965 : if (b->b_iused > 0) {
8516 : 2227965 : struct instr *b_last_instr = &b->b_instr[b->b_iused - 1];
8517 : : assert(!IS_ASSEMBLER_OPCODE(b_last_instr->i_opcode));
8518 [ + + ]: 2227965 : if (b_last_instr->i_opcode == JUMP ||
8519 [ + + ]: 2014383 : b_last_instr->i_opcode == JUMP_NO_INTERRUPT) {
8520 [ + + ]: 218083 : if (b_last_instr->i_target == b->b_next) {
8521 : : assert(b->b_next->b_iused);
8522 : 34578 : b_last_instr->i_opcode = NOP;
8523 : 34578 : removed++;
8524 : : }
8525 : : }
8526 : : }
8527 : : }
8528 [ + + ]: 461212 : if (removed) {
8529 : 23056 : eliminate_empty_basic_blocks(entryblock);
8530 : : }
8531 : 461212 : }
8532 : :
8533 : : static PyCodeObject *
8534 : 461212 : assemble(struct compiler *c, int addNone)
8535 : : {
8536 : 461212 : PyCodeObject *co = NULL;
8537 : 461212 : PyObject *consts = NULL;
8538 : : struct assembler a;
8539 : 461212 : memset(&a, 0, sizeof(struct assembler));
8540 : :
8541 : 461212 : int code_flags = compute_code_flags(c);
8542 [ - + ]: 461212 : if (code_flags < 0) {
8543 : 0 : return NULL;
8544 : : }
8545 : :
8546 : : /* Make sure every block that falls off the end returns None. */
8547 [ + + ]: 461212 : if (!basicblock_returns(c->u->u_curblock)) {
8548 : 247600 : UNSET_LOC(c);
8549 [ + + ]: 247600 : if (addNone)
8550 [ - + ]: 176238 : ADDOP_LOAD_CONST(c, Py_None);
8551 [ - + ]: 247600 : ADDOP(c, RETURN_VALUE);
8552 : : }
8553 : :
8554 : : assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX);
8555 : : assert(PyDict_GET_SIZE(c->u->u_cellvars) < INT_MAX);
8556 : : assert(PyDict_GET_SIZE(c->u->u_freevars) < INT_MAX);
8557 : 461212 : int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
8558 : 461212 : int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars);
8559 : 461212 : int nfreevars = (int)PyDict_GET_SIZE(c->u->u_freevars);
8560 : : assert(INT_MAX - nlocals - ncellvars > 0);
8561 : : assert(INT_MAX - nlocals - ncellvars - nfreevars > 0);
8562 : 461212 : int nlocalsplus = nlocals + ncellvars + nfreevars;
8563 : 461212 : int *cellfixedoffsets = build_cellfixedoffsets(c);
8564 [ - + ]: 461212 : if (cellfixedoffsets == NULL) {
8565 : 0 : goto error;
8566 : : }
8567 : :
8568 : 461212 : int nblocks = 0;
8569 : 461212 : basicblock *entryblock = NULL;
8570 [ + + ]: 2906869 : for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) {
8571 : 2445657 : nblocks++;
8572 : 2445657 : entryblock = b;
8573 : : }
8574 : : assert(entryblock != NULL);
8575 [ - + ]: 461212 : if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) {
8576 : : PyErr_NoMemory();
8577 : 0 : goto error;
8578 : : }
8579 : :
8580 : : /* Set firstlineno if it wasn't explicitly set. */
8581 [ - + ]: 461212 : if (!c->u->u_firstlineno) {
8582 [ # # # # ]: 0 : if (entryblock->b_instr && entryblock->b_instr->i_loc.lineno) {
8583 : 0 : c->u->u_firstlineno = entryblock->b_instr->i_loc.lineno;
8584 : : }
8585 : : else {
8586 : 0 : c->u->u_firstlineno = 1;
8587 : : }
8588 : : }
8589 : :
8590 : : // This must be called before fix_cell_offsets().
8591 [ - + ]: 461212 : if (insert_prefix_instructions(c, entryblock, cellfixedoffsets, nfreevars, code_flags)) {
8592 : 0 : goto error;
8593 : : }
8594 : :
8595 : 461212 : int numdropped = fix_cell_offsets(c, entryblock, cellfixedoffsets);
8596 : 461212 : PyMem_Free(cellfixedoffsets); // At this point we're done with it.
8597 : 461212 : cellfixedoffsets = NULL;
8598 [ - + ]: 461212 : if (numdropped < 0) {
8599 : 0 : goto error;
8600 : : }
8601 : 461212 : nlocalsplus -= numdropped;
8602 : :
8603 : 461212 : consts = consts_dict_keys_inorder(c->u->u_consts);
8604 [ - + ]: 461212 : if (consts == NULL) {
8605 : 0 : goto error;
8606 : : }
8607 : :
8608 [ - + ]: 461212 : if (optimize_cfg(entryblock, consts, c->c_const_cache)) {
8609 : 0 : goto error;
8610 : : }
8611 [ - + ]: 461212 : if (trim_unused_consts(entryblock, consts)) {
8612 : 0 : goto error;
8613 : : }
8614 [ - + ]: 461212 : if (duplicate_exits_without_lineno(entryblock)) {
8615 : 0 : return NULL;
8616 : : }
8617 : 461212 : propagate_line_numbers(entryblock);
8618 : 461212 : guarantee_lineno_for_exits(entryblock, c->u->u_firstlineno);
8619 : :
8620 : 461212 : int maxdepth = stackdepth(entryblock, code_flags);
8621 [ - + ]: 461212 : if (maxdepth < 0) {
8622 : 0 : goto error;
8623 : : }
8624 : : /* TO DO -- For 3.12, make sure that `maxdepth <= MAX_ALLOWED_STACK_USE` */
8625 : :
8626 [ - + ]: 461212 : if (label_exception_targets(entryblock)) {
8627 : 0 : goto error;
8628 : : }
8629 : 461212 : convert_exception_handlers_to_nops(entryblock);
8630 : :
8631 [ - + ]: 461212 : if (push_cold_blocks_to_end(entryblock, code_flags) < 0) {
8632 : 0 : goto error;
8633 : : }
8634 : :
8635 : 461212 : remove_redundant_jumps(entryblock);
8636 [ + + ]: 2689177 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
8637 : 2227965 : clean_basic_block(b);
8638 : : }
8639 : :
8640 : : /* Order of basic blocks must have been determined by now */
8641 : 461212 : normalize_jumps(entryblock);
8642 : :
8643 [ - + ]: 461212 : if (add_checks_for_loads_of_unknown_variables(entryblock, c) < 0) {
8644 : 0 : goto error;
8645 : : }
8646 : :
8647 : : /* Can't modify the bytecode after computing jump offsets. */
8648 : 461212 : assemble_jump_offsets(entryblock);
8649 : :
8650 : :
8651 : : /* Create assembler */
8652 [ - + ]: 461212 : if (!assemble_init(&a, c->u->u_firstlineno))
8653 : 0 : goto error;
8654 : :
8655 : : /* Emit code. */
8656 [ + + ]: 2689177 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
8657 [ + + ]: 19511792 : for (int j = 0; j < b->b_iused; j++)
8658 [ - + ]: 17283827 : if (!assemble_emit(&a, &b->b_instr[j]))
8659 : 0 : goto error;
8660 : : }
8661 : :
8662 : : /* Emit location info */
8663 : 461212 : a.a_lineno = c->u->u_firstlineno;
8664 [ + + ]: 2689177 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
8665 [ + + ]: 19511792 : for (int j = 0; j < b->b_iused; j++)
8666 [ - + ]: 17283827 : if (!assemble_emit_location(&a, &b->b_instr[j]))
8667 : 0 : goto error;
8668 : : }
8669 : :
8670 [ - + ]: 461212 : if (!assemble_exception_table(&a, entryblock)) {
8671 : 0 : goto error;
8672 : : }
8673 [ - + ]: 461212 : if (_PyBytes_Resize(&a.a_except_table, a.a_except_table_off) < 0) {
8674 : 0 : goto error;
8675 : : }
8676 [ - + ]: 461212 : if (!merge_const_one(c->c_const_cache, &a.a_except_table)) {
8677 : 0 : goto error;
8678 : : }
8679 : :
8680 [ - + ]: 461212 : if (_PyBytes_Resize(&a.a_linetable, a.a_location_off) < 0) {
8681 : 0 : goto error;
8682 : : }
8683 [ - + ]: 461212 : if (!merge_const_one(c->c_const_cache, &a.a_linetable)) {
8684 : 0 : goto error;
8685 : : }
8686 : :
8687 [ - + ]: 461212 : if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) {
8688 : 0 : goto error;
8689 : : }
8690 [ - + ]: 461212 : if (!merge_const_one(c->c_const_cache, &a.a_bytecode)) {
8691 : 0 : goto error;
8692 : : }
8693 : :
8694 : 461212 : co = makecode(c, &a, consts, maxdepth, nlocalsplus, code_flags);
8695 : 461212 : error:
8696 : 461212 : Py_XDECREF(consts);
8697 : 461212 : assemble_free(&a);
8698 [ - + ]: 461212 : if (cellfixedoffsets != NULL) {
8699 : 0 : PyMem_Free(cellfixedoffsets);
8700 : : }
8701 : 461212 : return co;
8702 : : }
8703 : :
8704 : : static PyObject*
8705 : 124196 : get_const_value(int opcode, int oparg, PyObject *co_consts)
8706 : : {
8707 : 124196 : PyObject *constant = NULL;
8708 : : assert(HAS_CONST(opcode));
8709 [ + - ]: 124196 : if (opcode == LOAD_CONST) {
8710 : 124196 : constant = PyList_GET_ITEM(co_consts, oparg);
8711 : : }
8712 : :
8713 [ - + ]: 124196 : if (constant == NULL) {
8714 : 0 : PyErr_SetString(PyExc_SystemError,
8715 : : "Internal error: failed to get value of a constant");
8716 : 0 : return NULL;
8717 : : }
8718 : 124196 : Py_INCREF(constant);
8719 : 124196 : return constant;
8720 : : }
8721 : :
8722 : : /* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n
8723 : : with LOAD_CONST (c1, c2, ... cn).
8724 : : The consts table must still be in list form so that the
8725 : : new constant (c1, c2, ... cn) can be appended.
8726 : : Called with codestr pointing to the first LOAD_CONST.
8727 : : */
8728 : : static int
8729 : 216372 : fold_tuple_on_constants(PyObject *const_cache,
8730 : : struct instr *inst,
8731 : : int n, PyObject *consts)
8732 : : {
8733 : : /* Pre-conditions */
8734 : : assert(PyDict_CheckExact(const_cache));
8735 : : assert(PyList_CheckExact(consts));
8736 : : assert(inst[n].i_opcode == BUILD_TUPLE);
8737 : : assert(inst[n].i_oparg == n);
8738 : :
8739 [ + + ]: 324618 : for (int i = 0; i < n; i++) {
8740 [ + + + + ]: 288635 : if (!HAS_CONST(inst[i].i_opcode)) {
8741 : 180389 : return 0;
8742 : : }
8743 : : }
8744 : :
8745 : : /* Buildup new tuple of constants */
8746 : 35983 : PyObject *newconst = PyTuple_New(n);
8747 [ - + ]: 35983 : if (newconst == NULL) {
8748 : 0 : return -1;
8749 : : }
8750 [ + + ]: 102872 : for (int i = 0; i < n; i++) {
8751 : 66889 : int op = inst[i].i_opcode;
8752 : 66889 : int arg = inst[i].i_oparg;
8753 : 66889 : PyObject *constant = get_const_value(op, arg, consts);
8754 [ - + ]: 66889 : if (constant == NULL) {
8755 : 0 : return -1;
8756 : : }
8757 : 66889 : PyTuple_SET_ITEM(newconst, i, constant);
8758 : : }
8759 [ - + ]: 35983 : if (merge_const_one(const_cache, &newconst) == 0) {
8760 : 0 : Py_DECREF(newconst);
8761 : 0 : return -1;
8762 : : }
8763 : :
8764 : : Py_ssize_t index;
8765 [ + + ]: 1750379 : for (index = 0; index < PyList_GET_SIZE(consts); index++) {
8766 [ + + ]: 1724696 : if (PyList_GET_ITEM(consts, index) == newconst) {
8767 : 10300 : break;
8768 : : }
8769 : : }
8770 [ + + ]: 35983 : if (index == PyList_GET_SIZE(consts)) {
8771 [ - + ]: 25683 : if ((size_t)index >= (size_t)INT_MAX - 1) {
8772 : 0 : Py_DECREF(newconst);
8773 : 0 : PyErr_SetString(PyExc_OverflowError, "too many constants");
8774 : 0 : return -1;
8775 : : }
8776 [ - + ]: 25683 : if (PyList_Append(consts, newconst)) {
8777 : 0 : Py_DECREF(newconst);
8778 : 0 : return -1;
8779 : : }
8780 : : }
8781 : 35983 : Py_DECREF(newconst);
8782 [ + + ]: 102872 : for (int i = 0; i < n; i++) {
8783 : 66889 : inst[i].i_opcode = NOP;
8784 : : }
8785 : 35983 : inst[n].i_opcode = LOAD_CONST;
8786 : 35983 : inst[n].i_oparg = (int)index;
8787 : 35983 : return 0;
8788 : : }
8789 : :
8790 : : #define VISITED (-1)
8791 : :
8792 : : // Replace an arbitrary run of SWAPs and NOPs with an optimal one that has the
8793 : : // same effect.
8794 : : static int
8795 : 19081 : swaptimize(basicblock *block, int *ix)
8796 : : {
8797 : : // NOTE: "./python -m test test_patma" serves as a good, quick stress test
8798 : : // for this function. Make sure to blow away cached *.pyc files first!
8799 : : assert(*ix < block->b_iused);
8800 : 19081 : struct instr *instructions = &block->b_instr[*ix];
8801 : : // Find the length of the current sequence of SWAPs and NOPs, and record the
8802 : : // maximum depth of the stack manipulations:
8803 : : assert(instructions[0].i_opcode == SWAP);
8804 : 19081 : int depth = instructions[0].i_oparg;
8805 : 19081 : int len = 0;
8806 : 19081 : int more = false;
8807 : 19081 : int limit = block->b_iused - *ix;
8808 [ + - ]: 23657 : while (++len < limit) {
8809 : 23657 : int opcode = instructions[len].i_opcode;
8810 [ + + ]: 23657 : if (opcode == SWAP) {
8811 : 4576 : depth = Py_MAX(depth, instructions[len].i_oparg);
8812 : 4576 : more = true;
8813 : : }
8814 [ + - ]: 19081 : else if (opcode != NOP) {
8815 : 19081 : break;
8816 : : }
8817 : : }
8818 : : // It's already optimal if there's only one SWAP:
8819 [ + + ]: 19081 : if (!more) {
8820 : 17665 : return 0;
8821 : : }
8822 : : // Create an array with elements {0, 1, 2, ..., depth - 1}:
8823 : 1416 : int *stack = PyMem_Malloc(depth * sizeof(int));
8824 [ - + ]: 1416 : if (stack == NULL) {
8825 : : PyErr_NoMemory();
8826 : 0 : return -1;
8827 : : }
8828 [ + + ]: 5900 : for (int i = 0; i < depth; i++) {
8829 : 4484 : stack[i] = i;
8830 : : }
8831 : : // Simulate the combined effect of these instructions by "running" them on
8832 : : // our "stack":
8833 [ + + ]: 7408 : for (int i = 0; i < len; i++) {
8834 [ + - ]: 5992 : if (instructions[i].i_opcode == SWAP) {
8835 : 5992 : int oparg = instructions[i].i_oparg;
8836 : 5992 : int top = stack[0];
8837 : : // SWAPs are 1-indexed:
8838 : 5992 : stack[0] = stack[oparg - 1];
8839 : 5992 : stack[oparg - 1] = top;
8840 : : }
8841 : : }
8842 : : // Now we can begin! Our approach here is based on a solution to a closely
8843 : : // related problem (https://cs.stackexchange.com/a/13938). It's easiest to
8844 : : // think of this algorithm as determining the steps needed to efficiently
8845 : : // "un-shuffle" our stack. By performing the moves in *reverse* order,
8846 : : // though, we can efficiently *shuffle* it! For this reason, we will be
8847 : : // replacing instructions starting from the *end* of the run. Since the
8848 : : // solution is optimal, we don't need to worry about running out of space:
8849 : 1416 : int current = len - 1;
8850 [ + + ]: 5900 : for (int i = 0; i < depth; i++) {
8851 : : // Skip items that have already been visited, or just happen to be in
8852 : : // the correct location:
8853 [ + + + + ]: 4484 : if (stack[i] == VISITED || stack[i] == i) {
8854 : 3084 : continue;
8855 : : }
8856 : : // Okay, we've found an item that hasn't been visited. It forms a cycle
8857 : : // with other items; traversing the cycle and swapping each item with
8858 : : // the next will put them all in the correct place. The weird
8859 : : // loop-and-a-half is necessary to insert 0 into every cycle, since we
8860 : : // can only swap from that position:
8861 : 1400 : int j = i;
8862 : 4332 : while (true) {
8863 : : // Skip the actual swap if our item is zero, since swapping the top
8864 : : // item with itself is pointless:
8865 [ + + ]: 5732 : if (j) {
8866 : : assert(0 <= current);
8867 : : // SWAPs are 1-indexed:
8868 : 3026 : instructions[current].i_opcode = SWAP;
8869 : 3026 : instructions[current--].i_oparg = j + 1;
8870 : : }
8871 [ + + ]: 5732 : if (stack[j] == VISITED) {
8872 : : // Completed the cycle:
8873 : : assert(j == i);
8874 : 1400 : break;
8875 : : }
8876 : 4332 : int next_j = stack[j];
8877 : 4332 : stack[j] = VISITED;
8878 : 4332 : j = next_j;
8879 : : }
8880 : : }
8881 : : // NOP out any unused instructions:
8882 [ + + ]: 4382 : while (0 <= current) {
8883 : 2966 : instructions[current--].i_opcode = NOP;
8884 : : }
8885 : 1416 : PyMem_Free(stack);
8886 : 1416 : *ix += len - 1;
8887 : 1416 : return 0;
8888 : : }
8889 : :
8890 : : // This list is pretty small, since it's only okay to reorder opcodes that:
8891 : : // - can't affect control flow (like jumping or raising exceptions)
8892 : : // - can't invoke arbitrary code (besides finalizers)
8893 : : // - only touch the TOS (and pop it when finished)
8894 : : #define SWAPPABLE(opcode) \
8895 : : ((opcode) == STORE_FAST || (opcode) == POP_TOP)
8896 : :
8897 : : static int
8898 : 26028 : next_swappable_instruction(basicblock *block, int i, int lineno)
8899 : : {
8900 [ + + ]: 26880 : while (++i < block->b_iused) {
8901 : 26595 : struct instr *instruction = &block->b_instr[i];
8902 [ + + + + ]: 26595 : if (0 <= lineno && instruction->i_loc.lineno != lineno) {
8903 : : // Optimizing across this instruction could cause user-visible
8904 : : // changes in the names bound between line tracing events!
8905 : 43 : return -1;
8906 : : }
8907 [ + + ]: 26552 : if (instruction->i_opcode == NOP) {
8908 : 852 : continue;
8909 : : }
8910 [ + + + + ]: 25700 : if (SWAPPABLE(instruction->i_opcode)) {
8911 : 9831 : return i;
8912 : : }
8913 : 15869 : return -1;
8914 : : }
8915 : 285 : return -1;
8916 : : }
8917 : :
8918 : : // Attempt to apply SWAPs statically by swapping *instructions* rather than
8919 : : // stack items. For example, we can replace SWAP(2), POP_TOP, STORE_FAST(42)
8920 : : // with the more efficient NOP, STORE_FAST(42), POP_TOP.
8921 : : static void
8922 : 19081 : apply_static_swaps(basicblock *block, int i)
8923 : : {
8924 : : // SWAPs are to our left, and potential swaperands are to our right:
8925 [ + + ]: 25503 : for (; 0 <= i; i--) {
8926 : : assert(i < block->b_iused);
8927 : 25466 : struct instr *swap = &block->b_instr[i];
8928 [ + + ]: 25466 : if (swap->i_opcode != SWAP) {
8929 [ + + + - : 6255 : if (swap->i_opcode == NOP || SWAPPABLE(swap->i_opcode)) {
+ + ]
8930 : : // Nope, but we know how to handle these. Keep looking:
8931 : 3408 : continue;
8932 : : }
8933 : : // We can't reason about what this instruction does. Bail:
8934 : 19044 : return;
8935 : : }
8936 : 19211 : int j = next_swappable_instruction(block, i, -1);
8937 [ + + ]: 19211 : if (j < 0) {
8938 : 13209 : return;
8939 : : }
8940 : 6002 : int k = j;
8941 : 6002 : int lineno = block->b_instr[j].i_loc.lineno;
8942 [ + + ]: 9831 : for (int count = swap->i_oparg - 1; 0 < count; count--) {
8943 : 6817 : k = next_swappable_instruction(block, k, lineno);
8944 [ + + ]: 6817 : if (k < 0) {
8945 : 2988 : return;
8946 : : }
8947 : : }
8948 : : // Success!
8949 : 3014 : swap->i_opcode = NOP;
8950 : 3014 : struct instr temp = block->b_instr[j];
8951 : 3014 : block->b_instr[j] = block->b_instr[k];
8952 : 3014 : block->b_instr[k] = temp;
8953 : : }
8954 : : }
8955 : :
8956 : : // Attempt to eliminate jumps to jumps by updating inst to jump to
8957 : : // target->i_target using the provided opcode. Return whether or not the
8958 : : // optimization was successful.
8959 : : static bool
8960 : 55357 : jump_thread(struct instr *inst, struct instr *target, int opcode)
8961 : : {
8962 : : assert(is_jump(inst));
8963 : : assert(is_jump(target));
8964 : : // bpo-45773: If inst->i_target == target->i_target, then nothing actually
8965 : : // changes (and we fall into an infinite loop):
8966 [ + + + + ]: 55357 : if ((inst->i_loc.lineno == target->i_loc.lineno || target->i_loc.lineno == -1) &&
8967 [ + + ]: 55303 : inst->i_target != target->i_target)
8968 : : {
8969 : 55301 : inst->i_target = target->i_target;
8970 : 55301 : inst->i_opcode = opcode;
8971 : 55301 : return true;
8972 : : }
8973 : 56 : return false;
8974 : : }
8975 : :
8976 : : /* Maximum size of basic block that should be copied in optimizer */
8977 : : #define MAX_COPY_SIZE 4
8978 : :
8979 : : /* Optimization */
8980 : : static int
8981 : 2445615 : optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
8982 : : {
8983 : : assert(PyDict_CheckExact(const_cache));
8984 : : assert(PyList_CheckExact(consts));
8985 : : struct instr nop;
8986 : 2445615 : nop.i_opcode = NOP;
8987 : : struct instr *target;
8988 [ + + ]: 20953684 : for (int i = 0; i < bb->b_iused; i++) {
8989 : 18508069 : struct instr *inst = &bb->b_instr[i];
8990 : 18508069 : int oparg = inst->i_oparg;
8991 [ + + ]: 18508069 : int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
8992 [ + + + + ]: 18508069 : if (is_jump(inst) || is_block_push(inst)) {
8993 : : /* Skip over empty basic blocks. */
8994 [ - + ]: 1157841 : while (inst->i_target->b_iused == 0) {
8995 : 0 : inst->i_target = inst->i_target->b_next;
8996 : : }
8997 : 1157841 : target = &inst->i_target->b_instr[0];
8998 : 1157841 : assert(!IS_ASSEMBLER_OPCODE(target->i_opcode));
8999 : : }
9000 : : else {
9001 : 17350228 : target = &nop;
9002 : : }
9003 : : assert(!IS_ASSEMBLER_OPCODE(inst->i_opcode));
9004 [ + + + + : 18508069 : switch (inst->i_opcode) {
+ + + + +
+ + + + ]
9005 : : /* Remove LOAD_CONST const; conditional jump */
9006 [ + + + + ]: 3453515 : case LOAD_CONST:
9007 : : {
9008 : : PyObject* cnt;
9009 : : int is_true;
9010 : : int jump_if_true;
9011 : : switch(nextop) {
9012 : 8386 : case POP_JUMP_IF_FALSE:
9013 : : case POP_JUMP_IF_TRUE:
9014 : 8386 : cnt = get_const_value(inst->i_opcode, oparg, consts);
9015 [ - + ]: 8386 : if (cnt == NULL) {
9016 : 0 : goto error;
9017 : : }
9018 : 8386 : is_true = PyObject_IsTrue(cnt);
9019 : 8386 : Py_DECREF(cnt);
9020 [ - + ]: 8386 : if (is_true == -1) {
9021 : 0 : goto error;
9022 : : }
9023 : 8386 : inst->i_opcode = NOP;
9024 : 8386 : jump_if_true = nextop == POP_JUMP_IF_TRUE;
9025 [ + + ]: 8386 : if (is_true == jump_if_true) {
9026 : 3853 : bb->b_instr[i+1].i_opcode = JUMP;
9027 : : }
9028 : : else {
9029 : 4533 : bb->b_instr[i+1].i_opcode = NOP;
9030 : : }
9031 : 8386 : break;
9032 : 79 : case JUMP_IF_FALSE_OR_POP:
9033 : : case JUMP_IF_TRUE_OR_POP:
9034 : 79 : cnt = get_const_value(inst->i_opcode, oparg, consts);
9035 [ - + ]: 79 : if (cnt == NULL) {
9036 : 0 : goto error;
9037 : : }
9038 : 79 : is_true = PyObject_IsTrue(cnt);
9039 : 79 : Py_DECREF(cnt);
9040 [ - + ]: 79 : if (is_true == -1) {
9041 : 0 : goto error;
9042 : : }
9043 : 79 : jump_if_true = nextop == JUMP_IF_TRUE_OR_POP;
9044 [ + + ]: 79 : if (is_true == jump_if_true) {
9045 : 43 : bb->b_instr[i+1].i_opcode = JUMP;
9046 : : }
9047 : : else {
9048 : 36 : inst->i_opcode = NOP;
9049 : 36 : bb->b_instr[i+1].i_opcode = NOP;
9050 : : }
9051 : 79 : break;
9052 : 48842 : case IS_OP:
9053 : 48842 : cnt = get_const_value(inst->i_opcode, oparg, consts);
9054 [ - + ]: 48842 : if (cnt == NULL) {
9055 : 0 : goto error;
9056 : : }
9057 [ + + ]: 48842 : int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0;
9058 [ + + + + : 48842 : if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) {
+ + ]
9059 : 46387 : unsigned char nextarg = bb->b_instr[i+1].i_oparg;
9060 : 46387 : inst->i_opcode = NOP;
9061 : 46387 : bb->b_instr[i+1].i_opcode = NOP;
9062 : 46387 : bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ?
9063 [ + + ]: 46387 : POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE;
9064 : : }
9065 : 48842 : Py_DECREF(cnt);
9066 : 48842 : break;
9067 : : }
9068 : 3453515 : break;
9069 : : }
9070 : :
9071 : : /* Try to fold tuples of constants.
9072 : : Skip over BUILD_TUPLE(1) UNPACK_SEQUENCE(1).
9073 : : Replace BUILD_TUPLE(2) UNPACK_SEQUENCE(2) with SWAP(2).
9074 : : Replace BUILD_TUPLE(3) UNPACK_SEQUENCE(3) with SWAP(3). */
9075 : 220169 : case BUILD_TUPLE:
9076 [ + + + - ]: 220169 : if (nextop == UNPACK_SEQUENCE && oparg == bb->b_instr[i+1].i_oparg) {
9077 : 3195 : switch(oparg) {
9078 : 1 : case 1:
9079 : 1 : inst->i_opcode = NOP;
9080 : 1 : bb->b_instr[i+1].i_opcode = NOP;
9081 : 1 : continue;
9082 : 3194 : case 2:
9083 : : case 3:
9084 : 3194 : inst->i_opcode = NOP;
9085 : 3194 : bb->b_instr[i+1].i_opcode = SWAP;
9086 : 3194 : continue;
9087 : : }
9088 : : }
9089 [ + + ]: 216974 : if (i >= oparg) {
9090 [ - + ]: 216372 : if (fold_tuple_on_constants(const_cache, inst-oparg, oparg, consts)) {
9091 : 0 : goto error;
9092 : : }
9093 : : }
9094 : 216974 : break;
9095 : :
9096 : : /* Simplify conditional jump to conditional jump where the
9097 : : result of the first test implies the success of a similar
9098 : : test or the failure of the opposite test.
9099 : : Arises in code like:
9100 : : "a and b or c"
9101 : : "(a and b) and c"
9102 : : "(a or b) or c"
9103 : : "(a or b) and c"
9104 : : x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z
9105 : : --> x:JUMP_IF_FALSE_OR_POP z
9106 : : x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z
9107 : : --> x:POP_JUMP_IF_FALSE y+1
9108 : : where y+1 is the instruction following the second test.
9109 : : */
9110 : 8002 : case JUMP_IF_FALSE_OR_POP:
9111 [ - + + + ]: 8002 : switch (target->i_opcode) {
9112 : 0 : case POP_JUMP_IF_FALSE:
9113 : 0 : i -= jump_thread(inst, target, POP_JUMP_IF_FALSE);
9114 : 0 : break;
9115 : 38 : case JUMP:
9116 : : case JUMP_IF_FALSE_OR_POP:
9117 : 38 : i -= jump_thread(inst, target, JUMP_IF_FALSE_OR_POP);
9118 : 38 : break;
9119 : 1102 : case JUMP_IF_TRUE_OR_POP:
9120 : : case POP_JUMP_IF_TRUE:
9121 [ + + ]: 1102 : if (inst->i_loc.lineno == target->i_loc.lineno) {
9122 : : // We don't need to bother checking for loops here,
9123 : : // since a block's b_next cannot point to itself:
9124 : : assert(inst->i_target != inst->i_target->b_next);
9125 : 1067 : inst->i_opcode = POP_JUMP_IF_FALSE;
9126 : 1067 : inst->i_target = inst->i_target->b_next;
9127 : 1067 : --i;
9128 : : }
9129 : 1102 : break;
9130 : : }
9131 : 8002 : break;
9132 : 12269 : case JUMP_IF_TRUE_OR_POP:
9133 [ - + + + ]: 12269 : switch (target->i_opcode) {
9134 : 0 : case POP_JUMP_IF_TRUE:
9135 : 0 : i -= jump_thread(inst, target, POP_JUMP_IF_TRUE);
9136 : 0 : break;
9137 : 29 : case JUMP:
9138 : : case JUMP_IF_TRUE_OR_POP:
9139 : 29 : i -= jump_thread(inst, target, JUMP_IF_TRUE_OR_POP);
9140 : 29 : break;
9141 : 109 : case JUMP_IF_FALSE_OR_POP:
9142 : : case POP_JUMP_IF_FALSE:
9143 [ + + ]: 109 : if (inst->i_loc.lineno == target->i_loc.lineno) {
9144 : : // We don't need to bother checking for loops here,
9145 : : // since a block's b_next cannot point to itself:
9146 : : assert(inst->i_target != inst->i_target->b_next);
9147 : 31 : inst->i_opcode = POP_JUMP_IF_TRUE;
9148 : 31 : inst->i_target = inst->i_target->b_next;
9149 : 31 : --i;
9150 : : }
9151 : 109 : break;
9152 : : }
9153 : 12269 : break;
9154 : 48709 : case POP_JUMP_IF_NOT_NONE:
9155 : : case POP_JUMP_IF_NONE:
9156 [ + + ]: 48709 : switch (target->i_opcode) {
9157 : 2102 : case JUMP:
9158 : 2102 : i -= jump_thread(inst, target, inst->i_opcode);
9159 : : }
9160 : 48709 : break;
9161 : 518881 : case POP_JUMP_IF_FALSE:
9162 [ + + ]: 518881 : switch (target->i_opcode) {
9163 : 23201 : case JUMP:
9164 : 23201 : i -= jump_thread(inst, target, POP_JUMP_IF_FALSE);
9165 : : }
9166 : 518881 : break;
9167 : 88347 : case POP_JUMP_IF_TRUE:
9168 [ + + ]: 88347 : switch (target->i_opcode) {
9169 : 2988 : case JUMP:
9170 : 2988 : i -= jump_thread(inst, target, POP_JUMP_IF_TRUE);
9171 : : }
9172 : 88347 : break;
9173 : 277954 : case JUMP:
9174 [ + + ]: 277954 : switch (target->i_opcode) {
9175 : 26999 : case JUMP:
9176 : 26999 : i -= jump_thread(inst, target, JUMP);
9177 : : }
9178 : 277954 : break;
9179 : 64194 : case FOR_ITER:
9180 : 64194 : if (target->i_opcode == JUMP) {
9181 : : /* This will not work now because the jump (at target) could
9182 : : * be forward or backward and FOR_ITER only jumps forward. We
9183 : : * can re-enable this if ever we implement a backward version
9184 : : * of FOR_ITER.
9185 : : */
9186 : : /*
9187 : : i -= jump_thread(inst, target, FOR_ITER);
9188 : : */
9189 : : }
9190 : 64194 : break;
9191 : 19081 : case SWAP:
9192 [ - + ]: 19081 : if (oparg == 1) {
9193 : 0 : inst->i_opcode = NOP;
9194 : 0 : break;
9195 : : }
9196 [ - + ]: 19081 : if (swaptimize(bb, &i)) {
9197 : 0 : goto error;
9198 : : }
9199 : 19081 : apply_static_swaps(bb, i);
9200 : 19081 : break;
9201 : 67803 : case KW_NAMES:
9202 : 67803 : break;
9203 : 627961 : case PUSH_NULL:
9204 [ + + + - ]: 627961 : if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) {
9205 : 462497 : inst->i_opcode = NOP;
9206 : 462497 : inst->i_oparg = 0;
9207 : 462497 : inst[1].i_oparg |= 1;
9208 : : }
9209 : 627961 : break;
9210 : 18508069 : default:
9211 : : /* All HAS_CONST opcodes should be handled with LOAD_CONST */
9212 : : assert (!HAS_CONST(inst->i_opcode));
9213 : : }
9214 : : }
9215 : 2445615 : return 0;
9216 : 0 : error:
9217 : 0 : return -1;
9218 : : }
9219 : :
9220 : : static bool
9221 : 90272 : basicblock_has_lineno(const basicblock *bb) {
9222 [ + + ]: 201896 : for (int i = 0; i < bb->b_iused; i++) {
9223 [ + + ]: 146651 : if (bb->b_instr[i].i_loc.lineno > 0) {
9224 : 35027 : return true;
9225 : : }
9226 : : }
9227 : 55245 : return false;
9228 : : }
9229 : :
9230 : : /* If this block ends with an unconditional jump to an exit block,
9231 : : * then remove the jump and extend this block with the target.
9232 : : */
9233 : : static int
9234 : 4891230 : extend_block(basicblock *bb) {
9235 [ + + ]: 4891230 : if (bb->b_iused == 0) {
9236 : 283815 : return 0;
9237 : : }
9238 : 4607415 : struct instr *last = &bb->b_instr[bb->b_iused-1];
9239 [ + + ]: 4607415 : if (last->i_opcode != JUMP &&
9240 [ + - ]: 4057901 : last->i_opcode != JUMP_FORWARD &&
9241 [ + - ]: 4057901 : last->i_opcode != JUMP_BACKWARD) {
9242 : 4057901 : return 0;
9243 : : }
9244 [ + + + + ]: 549514 : if (basicblock_exits_scope(last->i_target) && last->i_target->b_iused <= MAX_COPY_SIZE) {
9245 : 90272 : basicblock *to_copy = last->i_target;
9246 [ + + ]: 90272 : if (basicblock_has_lineno(to_copy)) {
9247 : : /* copy only blocks without line number (like implicit 'return None's) */
9248 : 35027 : return 0;
9249 : : }
9250 : 55245 : last->i_opcode = NOP;
9251 [ + + ]: 166854 : for (int i = 0; i < to_copy->b_iused; i++) {
9252 : 111609 : int index = basicblock_next_instr(bb);
9253 [ - + ]: 111609 : if (index < 0) {
9254 : 0 : return -1;
9255 : : }
9256 : 111609 : bb->b_instr[index] = to_copy->b_instr[i];
9257 : : }
9258 : : }
9259 : 514487 : return 0;
9260 : : }
9261 : :
9262 : : static void
9263 : 6917565 : clean_basic_block(basicblock *bb) {
9264 : : /* Remove NOPs when legal to do so. */
9265 : 6917565 : int dest = 0;
9266 : 6917565 : int prev_lineno = -1;
9267 [ + + ]: 60394460 : for (int src = 0; src < bb->b_iused; src++) {
9268 : 53476895 : int lineno = bb->b_instr[src].i_loc.lineno;
9269 [ + + ]: 53476895 : if (bb->b_instr[src].i_opcode == NOP) {
9270 : : /* Eliminate no-op if it doesn't have a line number */
9271 [ + + ]: 1108710 : if (lineno < 0) {
9272 : 93977 : continue;
9273 : : }
9274 : : /* or, if the previous instruction had the same line number. */
9275 [ + + ]: 1014733 : if (prev_lineno == lineno) {
9276 : 383559 : continue;
9277 : : }
9278 : : /* or, if the next instruction has same line number or no line number */
9279 [ + + ]: 631174 : if (src < bb->b_iused - 1) {
9280 : 575700 : int next_lineno = bb->b_instr[src+1].i_loc.lineno;
9281 [ + + + + ]: 575700 : if (next_lineno < 0 || next_lineno == lineno) {
9282 : 510621 : bb->b_instr[src+1].i_loc = bb->b_instr[src].i_loc;
9283 : 510621 : continue;
9284 : : }
9285 : : }
9286 : : else {
9287 : 55474 : basicblock* next = bb->b_next;
9288 [ + - + + ]: 55702 : while (next && next->b_iused == 0) {
9289 : 228 : next = next->b_next;
9290 : : }
9291 : : /* or if last instruction in BB and next BB has same line number */
9292 [ + - ]: 55474 : if (next) {
9293 [ + + ]: 55474 : if (lineno == next->b_instr[0].i_loc.lineno) {
9294 : 1375 : continue;
9295 : : }
9296 : : }
9297 : : }
9298 : :
9299 : : }
9300 [ + + ]: 52487363 : if (dest != src) {
9301 : 5469621 : bb->b_instr[dest] = bb->b_instr[src];
9302 : : }
9303 : 52487363 : dest++;
9304 : 52487363 : prev_lineno = lineno;
9305 : : }
9306 : : assert(dest <= bb->b_iused);
9307 : 6917565 : bb->b_iused = dest;
9308 : 6917565 : }
9309 : :
9310 : : static int
9311 : 2445615 : normalize_basic_block(basicblock *bb) {
9312 : : /* Skip over empty blocks.
9313 : : * Raise SystemError if jump or exit is not last instruction in the block. */
9314 [ + + ]: 20799420 : for (int i = 0; i < bb->b_iused; i++) {
9315 : 18353805 : int opcode = bb->b_instr[i].i_opcode;
9316 : : assert(!IS_ASSEMBLER_OPCODE(opcode));
9317 : 18353805 : int is_jump = IS_JUMP_OPCODE(opcode);
9318 [ + + + + : 18353805 : int is_exit = IS_SCOPE_EXIT_OPCODE(opcode);
+ + ]
9319 [ + + + + ]: 18353805 : if (is_exit || is_jump) {
9320 [ - + ]: 1757251 : if (i != bb->b_iused-1) {
9321 : 0 : PyErr_SetString(PyExc_SystemError, "malformed control flow graph.");
9322 : 0 : return -1;
9323 : : }
9324 : : }
9325 [ + + ]: 18353805 : if (is_jump) {
9326 : : /* Skip over empty basic blocks. */
9327 [ + + ]: 1233847 : while (bb->b_instr[i].i_target->b_iused == 0) {
9328 : 206831 : bb->b_instr[i].i_target = bb->b_instr[i].i_target->b_next;
9329 : : }
9330 : : }
9331 : : }
9332 : 2445615 : return 0;
9333 : : }
9334 : :
9335 : : static int
9336 : 461212 : mark_reachable(basicblock *entryblock) {
9337 : 461212 : basicblock **stack = make_cfg_traversal_stack(entryblock);
9338 [ - + ]: 461212 : if (stack == NULL) {
9339 : 0 : return -1;
9340 : : }
9341 : 461212 : basicblock **sp = stack;
9342 : 461212 : entryblock->b_predecessors = 1;
9343 : 461212 : *sp++ = entryblock;
9344 [ + + ]: 2712488 : while (sp > stack) {
9345 : 2251276 : basicblock *b = *(--sp);
9346 : 2251276 : b->b_visited = 1;
9347 [ + + + + ]: 2251276 : if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
9348 [ + + ]: 1304718 : if (!b->b_next->b_visited) {
9349 : : assert(b->b_next->b_predecessors == 0);
9350 : 989215 : *sp++ = b->b_next;
9351 : : }
9352 : 1304718 : b->b_next->b_predecessors++;
9353 : : }
9354 [ + + ]: 19746835 : for (int i = 0; i < b->b_iused; i++) {
9355 : : basicblock *target;
9356 : 17495559 : struct instr *instr = &b->b_instr[i];
9357 [ + + + + ]: 17495559 : if (is_jump(instr) || is_block_push(instr)) {
9358 : 1063395 : target = instr->i_target;
9359 [ + + ]: 1063395 : if (!target->b_visited) {
9360 : : assert(target->b_predecessors == 0 || target == b->b_next);
9361 : 800849 : *sp++ = target;
9362 : : }
9363 : 1063395 : target->b_predecessors++;
9364 [ + + ]: 1063395 : if (is_block_push(instr)) {
9365 : 130313 : target->b_except_predecessors++;
9366 : : }
9367 : : assert(target->b_except_predecessors == 0 ||
9368 : : target->b_except_predecessors == target->b_predecessors);
9369 : : }
9370 : : }
9371 : : }
9372 : 461212 : PyMem_Free(stack);
9373 : 461212 : return 0;
9374 : : }
9375 : :
9376 : : static void
9377 : 484268 : eliminate_empty_basic_blocks(basicblock *entryblock) {
9378 : : /* Eliminate empty blocks */
9379 [ + + ]: 3238671 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9380 : 2754403 : basicblock *next = b->b_next;
9381 [ + + ]: 2754403 : if (next) {
9382 [ + + + + ]: 2471765 : while (next->b_iused == 0 && next->b_next) {
9383 : 201630 : next = next->b_next;
9384 : : }
9385 : 2270135 : b->b_next = next;
9386 : : }
9387 : : }
9388 [ + + ]: 3238671 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9389 [ + + ]: 2754403 : if (b->b_iused == 0) {
9390 : 31894 : continue;
9391 : : }
9392 [ + + ]: 23569359 : for (int i = 0; i < b->b_iused; i++) {
9393 : 20846850 : struct instr *instr = &b->b_instr[i];
9394 [ + + + + ]: 20846850 : if (is_jump(instr) || is_block_push(instr)) {
9395 : 1273982 : basicblock *target = instr->i_target;
9396 [ + + ]: 1274178 : while (target->b_iused == 0) {
9397 : 196 : target = target->b_next;
9398 : : }
9399 : 1273982 : instr->i_target = target;
9400 : : }
9401 : : }
9402 : : }
9403 : 484268 : }
9404 : :
9405 : :
9406 : : /* If an instruction has no line number, but it's predecessor in the BB does,
9407 : : * then copy the line number. If a successor block has no line number, and only
9408 : : * one predecessor, then inherit the line number.
9409 : : * This ensures that all exit blocks (with one predecessor) receive a line number.
9410 : : * Also reduces the size of the line number table,
9411 : : * but has no impact on the generated line number events.
9412 : : */
9413 : : static void
9414 : 461212 : propagate_line_numbers(basicblock *entryblock) {
9415 [ + + ]: 2689078 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9416 [ - + ]: 2227866 : if (b->b_iused == 0) {
9417 : 0 : continue;
9418 : : }
9419 : :
9420 : 2227866 : struct location prev_location = NO_LOCATION;
9421 [ + + ]: 19752884 : for (int i = 0; i < b->b_iused; i++) {
9422 [ + + ]: 17525018 : if (b->b_instr[i].i_loc.lineno < 0) {
9423 : 1775126 : b->b_instr[i].i_loc = prev_location;
9424 : : }
9425 : : else {
9426 : 15749892 : prev_location = b->b_instr[i].i_loc;
9427 : : }
9428 : : }
9429 [ + + + + ]: 2227866 : if (BB_HAS_FALLTHROUGH(b) && b->b_next->b_predecessors == 1) {
9430 : : assert(b->b_next->b_iused);
9431 [ + + ]: 847085 : if (b->b_next->b_instr[0].i_loc.lineno < 0) {
9432 : 52087 : b->b_next->b_instr[0].i_loc = prev_location;
9433 : : }
9434 : : }
9435 [ + + ]: 2227866 : if (is_jump(&b->b_instr[b->b_iused-1])) {
9436 : 933079 : basicblock *target = b->b_instr[b->b_iused-1].i_target;
9437 [ + + ]: 933079 : if (target->b_predecessors == 1) {
9438 [ + + ]: 319160 : if (target->b_instr[0].i_loc.lineno < 0) {
9439 : 88782 : target->b_instr[0].i_loc = prev_location;
9440 : : }
9441 : : }
9442 : : }
9443 : : }
9444 : 461212 : }
9445 : :
9446 : : /* Perform optimizations on a control flow graph.
9447 : : The consts object should still be in list form to allow new constants
9448 : : to be appended.
9449 : :
9450 : : Code trasnformations that reduce code size initially fill the gaps with
9451 : : NOPs. Later those NOPs are removed.
9452 : : */
9453 : :
9454 : : static int
9455 : 461212 : optimize_cfg(basicblock *entryblock, PyObject *consts, PyObject *const_cache)
9456 : : {
9457 : : assert(PyDict_CheckExact(const_cache));
9458 [ + + ]: 2906827 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9459 [ - + ]: 2445615 : if (normalize_basic_block(b)) {
9460 : 0 : return -1;
9461 : : }
9462 : : }
9463 [ + + ]: 2906827 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9464 [ - + ]: 2445615 : if (extend_block(b)) {
9465 : 0 : return -1;
9466 : : }
9467 : : }
9468 [ + + ]: 2906827 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9469 [ - + ]: 2445615 : if (optimize_basic_block(const_cache, b, consts)) {
9470 : 0 : return -1;
9471 : : }
9472 : 2445615 : clean_basic_block(b);
9473 : : assert(b->b_predecessors == 0);
9474 : : }
9475 [ + + ]: 2906827 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9476 [ - + ]: 2445615 : if (extend_block(b)) {
9477 : 0 : return -1;
9478 : : }
9479 : : }
9480 [ - + ]: 461212 : if (mark_reachable(entryblock)) {
9481 : 0 : return -1;
9482 : : }
9483 : : /* Delete unreachable instructions */
9484 [ + + ]: 2906827 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9485 [ + + ]: 2445615 : if (b->b_predecessors == 0) {
9486 : 194342 : b->b_iused = 0;
9487 : : }
9488 : : }
9489 : 461212 : eliminate_empty_basic_blocks(entryblock);
9490 [ + + ]: 2705197 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9491 : 2243985 : clean_basic_block(b);
9492 : : }
9493 : 461212 : return 0;
9494 : : }
9495 : :
9496 : : // Remove trailing unused constants.
9497 : : static int
9498 : 461212 : trim_unused_consts(basicblock *entryblock, PyObject *consts)
9499 : : {
9500 : : assert(PyList_CheckExact(consts));
9501 : :
9502 : : // The first constant may be docstring; keep it always.
9503 : 461212 : int max_const_index = 0;
9504 [ + + ]: 2705197 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9505 [ + + ]: 19737214 : for (int i = 0; i < b->b_iused; i++) {
9506 [ + + ]: 17493229 : if ((b->b_instr[i].i_opcode == LOAD_CONST ||
9507 [ + + ]: 14186112 : b->b_instr[i].i_opcode == KW_NAMES) &&
9508 [ + + ]: 3374914 : b->b_instr[i].i_oparg > max_const_index) {
9509 : 1476178 : max_const_index = b->b_instr[i].i_oparg;
9510 : : }
9511 : : }
9512 : : }
9513 [ + + ]: 461212 : if (max_const_index+1 < PyList_GET_SIZE(consts)) {
9514 : : //fprintf(stderr, "removing trailing consts: max=%d, size=%d\n",
9515 : : // max_const_index, (int)PyList_GET_SIZE(consts));
9516 [ - + ]: 5939 : if (PyList_SetSlice(consts, max_const_index+1,
9517 : : PyList_GET_SIZE(consts), NULL) < 0) {
9518 : 0 : return 1;
9519 : : }
9520 : : }
9521 : 461212 : return 0;
9522 : : }
9523 : :
9524 : : static inline int
9525 : 2198612 : is_exit_without_lineno(basicblock *b) {
9526 [ + + ]: 2198612 : if (!basicblock_exits_scope(b)) {
9527 : 1760412 : return 0;
9528 : : }
9529 [ + + ]: 665613 : for (int i = 0; i < b->b_iused; i++) {
9530 [ + + ]: 548665 : if (b->b_instr[i].i_loc.lineno >= 0) {
9531 : 321252 : return 0;
9532 : : }
9533 : : }
9534 : 116948 : return 1;
9535 : : }
9536 : :
9537 : : /* PEP 626 mandates that the f_lineno of a frame is correct
9538 : : * after a frame terminates. It would be prohibitively expensive
9539 : : * to continuously update the f_lineno field at runtime,
9540 : : * so we make sure that all exiting instruction (raises and returns)
9541 : : * have a valid line number, allowing us to compute f_lineno lazily.
9542 : : * We can do this by duplicating the exit blocks without line number
9543 : : * so that none have more than one predecessor. We can then safely
9544 : : * copy the line number from the sole predecessor block.
9545 : : */
9546 : : static int
9547 : 461212 : duplicate_exits_without_lineno(basicblock *entryblock)
9548 : : {
9549 : : /* Copy all exit blocks without line number that are targets of a jump.
9550 : : */
9551 [ + + ]: 2720972 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9552 [ + + + + ]: 2259760 : if (b->b_iused > 0 && is_jump(&b->b_instr[b->b_iused-1])) {
9553 : 933079 : basicblock *target = b->b_instr[b->b_iused-1].i_target;
9554 [ + + + + ]: 933079 : if (is_exit_without_lineno(target) && target->b_predecessors > 1) {
9555 : 15775 : basicblock *new_target = copy_basicblock(target);
9556 [ - + ]: 15775 : if (new_target == NULL) {
9557 : 0 : return -1;
9558 : : }
9559 : 15775 : new_target->b_instr[0].i_loc = b->b_instr[b->b_iused-1].i_loc;
9560 : 15775 : b->b_instr[b->b_iused-1].i_target = new_target;
9561 : 15775 : target->b_predecessors--;
9562 : 15775 : new_target->b_predecessors = 1;
9563 : 15775 : new_target->b_next = target->b_next;
9564 : 15775 : target->b_next = new_target;
9565 : : }
9566 : : }
9567 : : }
9568 : : /* Eliminate empty blocks */
9569 [ + + ]: 2689078 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9570 [ + + + + ]: 2259760 : while (b->b_next && b->b_next->b_iused == 0) {
9571 : 31894 : b->b_next = b->b_next->b_next;
9572 : : }
9573 : : }
9574 : : /* Any remaining reachable exit blocks without line number can only be reached by
9575 : : * fall through, and thus can only have a single predecessor */
9576 [ + + ]: 2689078 : for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
9577 [ + + + - : 2227866 : if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) {
+ - ]
9578 [ + + ]: 1265533 : if (is_exit_without_lineno(b->b_next)) {
9579 : : assert(b->b_next->b_iused > 0);
9580 : 37177 : b->b_next->b_instr[0].i_loc = b->b_instr[b->b_iused-1].i_loc;
9581 : : }
9582 : : }
9583 : : }
9584 : 461212 : return 0;
9585 : : }
9586 : :
9587 : :
9588 : : /* Retained for API compatibility.
9589 : : * Optimization is now done in optimize_cfg */
9590 : :
9591 : : PyObject *
9592 : 0 : PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts),
9593 : : PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj))
9594 : : {
9595 : 0 : Py_INCREF(code);
9596 : 0 : return code;
9597 : : }
|