LCOV - code coverage report
Current view: | top level - Python - compile.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 3732 | 4990 | 74.8 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 245 | 269 | 91.1 %
|  |  | Branches: | 2719 | 4935 | 55.1 %

               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"
          33                 :            : #include "pycore_intrinsics.h"
          34                 :            : #include "pycore_long.h"          // _PyLong_GetZero()
          35                 :            : #include "pycore_opcode.h"        // _PyOpcode_Caches
          36                 :            : #include "pycore_pymem.h"         // _PyMem_IsPtrFreed()
          37                 :            : #include "pycore_symtable.h"      // PySTEntryObject, _PyFuture_FromAST()
          38                 :            :
          39                 :            : #include "opcode_metadata.h"      // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
          40                 :            :
          41                 :            :
          42                 :            : #define DEFAULT_BLOCK_SIZE 16
          43                 :            : #define DEFAULT_CODE_SIZE 128
          44                 :            : #define DEFAULT_LNOTAB_SIZE 16
          45                 :            : #define DEFAULT_CNOTAB_SIZE 32
          46                 :            :
          47                 :            : #define COMP_GENEXP   0
          48                 :            : #define COMP_LISTCOMP 1
          49                 :            : #define COMP_SETCOMP  2
          50                 :            : #define COMP_DICTCOMP 3
          51                 :            :
          52                 :            : /* A soft limit for stack use, to avoid excessive
          53                 :            :  * memory use for large constants, etc.
          54                 :            :  *
          55                 :            :  * The value 30 is plucked out of thin air.
          56                 :            :  * Code that could use more stack than this is
          57                 :            :  * rare, so the exact value is unimportant.
          58                 :            :  */
          59                 :            : #define STACK_USE_GUIDELINE 30
          60                 :            :
          61                 :            : #undef SUCCESS
          62                 :            : #undef ERROR
          63                 :            : #define SUCCESS 0
          64                 :            : #define ERROR -1
          65                 :            :
          66                 :            : #define RETURN_IF_ERROR(X)  \
          67                 :            :     if ((X) == -1) {        \
          68                 :            :         return ERROR;       \
          69                 :            :     }
          70                 :            :
          71                 :            : /* If we exceed this limit, it should
          72                 :            :  * be considered a compiler bug.
          73                 :            :  * Currently it should be impossible
          74                 :            :  * to exceed STACK_USE_GUIDELINE * 100,
          75                 :            :  * as 100 is the maximum parse depth.
          76                 :            :  * For performance reasons we will
          77                 :            :  * want to reduce this to a
          78                 :            :  * few hundred in the future.
          79                 :            :  *
          80                 :            :  * NOTE: Whatever MAX_ALLOWED_STACK_USE is
          81                 :            :  * set to, it should never restrict what Python
          82                 :            :  * we can write, just how we compile it.
          83                 :            :  */
          84                 :            : #define MAX_ALLOWED_STACK_USE (STACK_USE_GUIDELINE * 100)
          85                 :            :
          86                 :            :
          87                 :            : #define MAX_REAL_OPCODE 254
          88                 :            :
          89                 :            : #define IS_WITHIN_OPCODE_RANGE(opcode) \
          90                 :            :         (((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \
          91                 :            :          IS_PSEUDO_OPCODE(opcode))
          92                 :            :
          93                 :            : #define IS_JUMP_OPCODE(opcode) \
          94                 :            :          is_bit_set_in_table(_PyOpcode_Jump, opcode)
          95                 :            :
          96                 :            : #define IS_BLOCK_PUSH_OPCODE(opcode) \
          97                 :            :         ((opcode) == SETUP_FINALLY || \
          98                 :            :          (opcode) == SETUP_WITH || \
          99                 :            :          (opcode) == SETUP_CLEANUP)
         100                 :            :
         101                 :            : #define HAS_TARGET(opcode) \
         102                 :            :         (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode))
         103                 :            :
         104                 :            : /* opcodes that must be last in the basicblock */
         105                 :            : #define IS_TERMINATOR_OPCODE(opcode) \
         106                 :            :         (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode))
         107                 :            :
         108                 :            : /* opcodes which are not emitted in codegen stage, only by the assembler */
         109                 :            : #define IS_ASSEMBLER_OPCODE(opcode) \
         110                 :            :         ((opcode) == JUMP_FORWARD || \
         111                 :            :          (opcode) == JUMP_BACKWARD || \
         112                 :            :          (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
         113                 :            :
         114                 :            : #define IS_BACKWARDS_JUMP_OPCODE(opcode) \
         115                 :            :         ((opcode) == JUMP_BACKWARD || \
         116                 :            :          (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
         117                 :            :
         118                 :            : #define IS_UNCONDITIONAL_JUMP_OPCODE(opcode) \
         119                 :            :         ((opcode) == JUMP || \
         120                 :            :          (opcode) == JUMP_NO_INTERRUPT || \
         121                 :            :          (opcode) == JUMP_FORWARD || \
         122                 :            :          (opcode) == JUMP_BACKWARD || \
         123                 :            :          (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
         124                 :            :
         125                 :            : #define IS_SCOPE_EXIT_OPCODE(opcode) \
         126                 :            :         ((opcode) == RETURN_VALUE || \
         127                 :            :          (opcode) == RETURN_CONST || \
         128                 :            :          (opcode) == RAISE_VARARGS || \
         129                 :            :          (opcode) == RERAISE)
         130                 :            :
         131                 :            : #define IS_SUPERINSTRUCTION_OPCODE(opcode) \
         132                 :            :         ((opcode) == LOAD_FAST__LOAD_FAST || \
         133                 :            :          (opcode) == LOAD_FAST__LOAD_CONST || \
         134                 :            :          (opcode) == LOAD_CONST__LOAD_FAST || \
         135                 :            :          (opcode) == STORE_FAST__LOAD_FAST || \
         136                 :            :          (opcode) == STORE_FAST__STORE_FAST)
         137                 :            :
         138                 :            : #define IS_TOP_LEVEL_AWAIT(C) ( \
         139                 :            :         ((C)->c_flags.cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \
         140                 :            :         && ((C)->u->u_ste->ste_type == ModuleBlock))
         141                 :            :
         142                 :            : typedef _PyCompilerSrcLocation location;
         143                 :            :
         144                 :            : #define LOCATION(LNO, END_LNO, COL, END_COL) \
         145                 :            :     ((const location){(LNO), (END_LNO), (COL), (END_COL)})
         146                 :            :
         147                 :            : static location NO_LOCATION = {-1, -1, -1, -1};
         148                 :            :
         149                 :            : /* Return true if loc1 starts after loc2 ends. */
         150                 :            : static inline bool
         151                 :        524 : location_is_after(location loc1, location loc2) {
         152         [ -  + ]:        524 :     return (loc1.lineno > loc2.end_lineno) ||
         153         [ #  # ]:          0 :             ((loc1.lineno == loc2.end_lineno) &&
         154         [ #  # ]:          0 :              (loc1.col_offset > loc2.end_col_offset));
         155                 :            : }
         156                 :            :
         157                 :            : static inline bool
         158                 :     342036 : same_location(location a, location b)
         159                 :            : {
         160                 :     595006 :     return a.lineno == b.lineno &&
         161         [ +  + ]:     252970 :            a.end_lineno == b.end_lineno &&
         162   [ +  +  +  + ]:     719666 :            a.col_offset == b.col_offset &&
         163         [ +  + ]:     124660 :            a.end_col_offset == b.end_col_offset;
         164                 :            : }
         165                 :            :
         166                 :            : #define LOC(x) SRC_LOCATION_FROM_AST(x)
         167                 :            :
         168                 :            : typedef struct jump_target_label_ {
         169                 :            :     int id;
         170                 :            : } jump_target_label;
         171                 :            :
         172                 :            : static struct jump_target_label_ NO_LABEL = {-1};
         173                 :            :
         174                 :            : #define SAME_LABEL(L1, L2) ((L1).id == (L2).id)
         175                 :            : #define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL)))
         176                 :            :
         177                 :            : #define NEW_JUMP_TARGET_LABEL(C, NAME) \
         178                 :            :     jump_target_label NAME = instr_sequence_new_label(INSTR_SEQUENCE(C)); \
         179                 :            :     if (!IS_LABEL(NAME)) { \
         180                 :            :         return ERROR; \
         181                 :            :     }
         182                 :            :
         183                 :            : #define USE_LABEL(C, LBL) \
         184                 :            :     RETURN_IF_ERROR(instr_sequence_use_label(INSTR_SEQUENCE(C), (LBL).id))
         185                 :            :
         186                 :            : struct cfg_instr {
         187                 :            :     int i_opcode;
         188                 :            :     int i_oparg;
         189                 :            :     location i_loc;
         190                 :            :     struct basicblock_ *i_target; /* target block (if jump instruction) */
         191                 :            :     struct basicblock_ *i_except; /* target block when exception is raised */
         192                 :            : };
         193                 :            :
         194                 :            : /* One arg*/
         195                 :            : #define INSTR_SET_OP1(I, OP, ARG) \
         196                 :            :     do { \
         197                 :            :         assert(HAS_ARG(OP)); \
         198                 :            :         struct cfg_instr *_instr__ptr_ = (I); \
         199                 :            :         _instr__ptr_->i_opcode = (OP); \
         200                 :            :         _instr__ptr_->i_oparg = (ARG); \
         201                 :            :     } while (0);
         202                 :            :
         203                 :            : /* No args*/
         204                 :            : #define INSTR_SET_OP0(I, OP) \
         205                 :            :     do { \
         206                 :            :         assert(!HAS_ARG(OP)); \
         207                 :            :         struct cfg_instr *_instr__ptr_ = (I); \
         208                 :            :         _instr__ptr_->i_opcode = (OP); \
         209                 :            :         _instr__ptr_->i_oparg = 0; \
         210                 :            :     } while (0);
         211                 :            :
         212                 :            : typedef struct exceptstack {
         213                 :            :     struct basicblock_ *handlers[CO_MAXBLOCKS+1];
         214                 :            :     int depth;
         215                 :            : } ExceptStack;
         216                 :            :
         217                 :            : #define LOG_BITS_PER_INT 5
         218                 :            : #define MASK_LOW_LOG_BITS 31
         219                 :            :
         220                 :            : static inline int
         221                 :    4262278 : is_bit_set_in_table(const uint32_t *table, int bitindex) {
         222                 :            :     /* Is the relevant bit set in the relevant word? */
         223                 :            :     /* 512 bits fit into 9 32-bits words.
         224                 :            :      * Word is indexed by (bitindex>>ln(size of int in bits)).
         225                 :            :      * Bit within word is the low bits of bitindex.
         226                 :            :      */
         227   [ +  -  +  - ]:    4262278 :     if (bitindex >= 0 && bitindex < 512) {
         228                 :    4262278 :         uint32_t word = table[bitindex >> LOG_BITS_PER_INT];
         229                 :    4262278 :         return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1;
         230                 :            :     }
         231                 :            :     else {
         232                 :          0 :         return 0;
         233                 :            :     }
         234                 :            : }
         235                 :            :
         236                 :            : static inline int
         237                 :      26506 : is_relative_jump(struct cfg_instr *i)
         238                 :            : {
         239                 :      26506 :     return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode);
         240                 :            : }
         241                 :            :
         242                 :            : static inline int
         243                 :    1431493 : is_block_push(struct cfg_instr *i)
         244                 :            : {
         245   [ +  +  +  +  :    1431493 :     return IS_BLOCK_PUSH_OPCODE(i->i_opcode);
                       +  + ]
         246                 :            : }
         247                 :            :
         248                 :            : static inline int
         249                 :    1621642 : is_jump(struct cfg_instr *i)
         250                 :            : {
         251                 :    1621642 :     return IS_JUMP_OPCODE(i->i_opcode);
         252                 :            : }
         253                 :            :
         254                 :            : static int
         255                 :    1860948 : instr_size(struct cfg_instr *instruction)
         256                 :            : {
         257                 :    1860948 :     int opcode = instruction->i_opcode;
         258                 :            :     assert(!IS_PSEUDO_OPCODE(opcode));
         259                 :    1860948 :     int oparg = instruction->i_oparg;
         260                 :            :     assert(HAS_ARG(opcode) || oparg == 0);
         261                 :    1860948 :     int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg);
         262                 :    1860948 :     int caches = _PyOpcode_Caches[opcode];
         263                 :    1860948 :     return extended_args + 1 + caches;
         264                 :            : }
         265                 :            :
         266                 :            : static void
         267                 :     342036 : write_instr(_Py_CODEUNIT *codestr, struct cfg_instr *instruction, int ilen)
         268                 :            : {
         269                 :     342036 :     int opcode = instruction->i_opcode;
         270                 :            :     assert(!IS_PSEUDO_OPCODE(opcode));
         271                 :     342036 :     int oparg = instruction->i_oparg;
         272                 :            :     assert(HAS_ARG(opcode) || oparg == 0);
         273                 :     342036 :     int caches = _PyOpcode_Caches[opcode];
         274   [ -  -  +  +  :     342036 :     switch (ilen - caches) {
                          - ]
         275                 :          0 :         case 4:
         276                 :          0 :             codestr->op.code = EXTENDED_ARG;
         277                 :          0 :             codestr->op.arg = (oparg >> 24) & 0xFF;
         278                 :          0 :             codestr++;
         279                 :            :             /* fall through */
         280                 :          0 :         case 3:
         281                 :          0 :             codestr->op.code = EXTENDED_ARG;
         282                 :          0 :             codestr->op.arg = (oparg >> 16) & 0xFF;
         283                 :          0 :             codestr++;
         284                 :            :             /* fall through */
         285                 :       3324 :         case 2:
         286                 :       3324 :             codestr->op.code = EXTENDED_ARG;
         287                 :       3324 :             codestr->op.arg = (oparg >> 8) & 0xFF;
         288                 :       3324 :             codestr++;
         289                 :            :             /* fall through */
         290                 :     342036 :         case 1:
         291                 :     342036 :             codestr->op.code = opcode;
         292                 :     342036 :             codestr->op.arg = oparg & 0xFF;
         293                 :     342036 :             codestr++;
         294                 :     342036 :             break;
         295                 :          0 :         default:
         296                 :          0 :             Py_UNREACHABLE();
         297                 :            :     }
         298         [ +  + ]:     815594 :     while (caches--) {
         299                 :     473558 :         codestr->op.code = CACHE;
         300                 :     473558 :         codestr->op.arg = 0;
         301                 :     473558 :         codestr++;
         302                 :            :     }
         303                 :     342036 : }
         304                 :            :
         305                 :            : typedef struct basicblock_ {
         306                 :            :     /* Each basicblock in a compilation unit is linked via b_list in the
         307                 :            :        reverse order that the block are allocated.  b_list points to the next
         308                 :            :        block, not to be confused with b_next, which is next by control flow. */
         309                 :            :     struct basicblock_ *b_list;
         310                 :            :     /* The label of this block if it is a jump target, -1 otherwise */
         311                 :            :     jump_target_label b_label;
         312                 :            :     /* Exception stack at start of block, used by assembler to create the exception handling table */
         313                 :            :     ExceptStack *b_exceptstack;
         314                 :            :     /* pointer to an array of instructions, initially NULL */
         315                 :            :     struct cfg_instr *b_instr;
         316                 :            :     /* If b_next is non-NULL, it is a pointer to the next
         317                 :            :        block reached by normal control flow. */
         318                 :            :     struct basicblock_ *b_next;
         319                 :            :     /* number of instructions used */
         320                 :            :     int b_iused;
         321                 :            :     /* length of instruction array (b_instr) */
         322                 :            :     int b_ialloc;
         323                 :            :     /* Used by add_checks_for_loads_of_unknown_variables */
         324                 :            :     uint64_t b_unsafe_locals_mask;
         325                 :            :     /* Number of predecessors that a block has. */
         326                 :            :     int b_predecessors;
         327                 :            :     /* depth of stack upon entry of block, computed by stackdepth() */
         328                 :            :     int b_startdepth;
         329                 :            :     /* instruction offset for block, computed by assemble_jump_offsets() */
         330                 :            :     int b_offset;
         331                 :            :     /* Basic block is an exception handler that preserves lasti */
         332                 :            :     unsigned b_preserve_lasti : 1;
         333                 :            :     /* Used by compiler passes to mark whether they have visited a basic block. */
         334                 :            :     unsigned b_visited : 1;
         335                 :            :     /* b_except_handler is used by the cold-detection algorithm to mark exception targets */
         336                 :            :     unsigned b_except_handler : 1;
         337                 :            :     /* b_cold is true if this block is not perf critical (like an exception handler) */
         338                 :            :     unsigned b_cold : 1;
         339                 :            :     /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
         340                 :            :     unsigned b_warm : 1;
         341                 :            : } basicblock;
         342                 :            :
         343                 :            :
         344                 :            : static struct cfg_instr *
         345                 :    1316809 : basicblock_last_instr(const basicblock *b) {
         346                 :            :     assert(b->b_iused >= 0);
         347         [ +  + ]:    1316809 :     if (b->b_iused > 0) {
         348                 :            :         assert(b->b_instr != NULL);
         349                 :    1272680 :         return &b->b_instr[b->b_iused - 1];
         350                 :            :     }
         351                 :      44129 :     return NULL;
         352                 :            : }
         353                 :            :
         354                 :            : static inline int
         355                 :      65096 : basicblock_exits_scope(const basicblock *b) {
         356                 :      65096 :     struct cfg_instr *last = basicblock_last_instr(b);
         357   [ +  -  +  +  :      65096 :     return last && IS_SCOPE_EXIT_OPCODE(last->i_opcode);
              +  +  +  +  +
                          + ]
         358                 :            : }
         359                 :            :
         360                 :            : static inline int
         361                 :     347556 : basicblock_nofallthrough(const basicblock *b) {
         362                 :     347556 :     struct cfg_instr *last = basicblock_last_instr(b);
         363         [ +  + ]:     692674 :     return (last &&
         364   [ +  +  +  +  :     345118 :             (IS_SCOPE_EXIT_OPCODE(last->i_opcode) ||
                 +  +  +  + ]
         365   [ +  +  +  +  :     247926 :              IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)));
              +  -  +  -  -
                          + ]
         366                 :            : }
         367                 :            :
         368                 :            : #define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B))
         369                 :            : #define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B))
         370                 :            :
         371                 :            : /* fblockinfo tracks the current frame block.
         372                 :            :
         373                 :            : A frame block is used to handle loops, try/except, and try/finally.
         374                 :            : It's called a frame block to distinguish it from a basic block in the
         375                 :            : compiler IR.
         376                 :            : */
         377                 :            :
         378                 :            : enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END,
         379                 :            :                   WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER,
         380                 :            :                   EXCEPTION_GROUP_HANDLER, ASYNC_COMPREHENSION_GENERATOR };
         381                 :            :
         382                 :            : struct fblockinfo {
         383                 :            :     enum fblocktype fb_type;
         384                 :            :     jump_target_label fb_block;
         385                 :            :     /* (optional) type-specific exit or cleanup block */
         386                 :            :     jump_target_label fb_exit;
         387                 :            :     /* (optional) additional information required for unwinding */
         388                 :            :     void *fb_datum;
         389                 :            : };
         390                 :            :
         391                 :            : enum {
         392                 :            :     COMPILER_SCOPE_MODULE,
         393                 :            :     COMPILER_SCOPE_CLASS,
         394                 :            :     COMPILER_SCOPE_FUNCTION,
         395                 :            :     COMPILER_SCOPE_ASYNC_FUNCTION,
         396                 :            :     COMPILER_SCOPE_LAMBDA,
         397                 :            :     COMPILER_SCOPE_COMPREHENSION,
         398                 :            : };
         399                 :            :
         400                 :            : typedef struct cfg_builder_ {
         401                 :            :     /* The entryblock, at which control flow begins. All blocks of the
         402                 :            :        CFG are reachable through the b_next links */
         403                 :            :     basicblock *g_entryblock;
         404                 :            :     /* Pointer to the most recently allocated block.  By following
         405                 :            :        b_list links, you can reach all allocated blocks. */
         406                 :            :     basicblock *g_block_list;
         407                 :            :     /* pointer to the block currently being constructed */
         408                 :            :     basicblock *g_curblock;
         409                 :            :     /* label for the next instruction to be placed */
         410                 :            :     jump_target_label g_current_label;
         411                 :            : } cfg_builder;
         412                 :            :
         413                 :            : typedef struct {
         414                 :            :     int i_opcode;
         415                 :            :     int i_oparg;
         416                 :            :     location i_loc;
         417                 :            : } instruction;
         418                 :            :
         419                 :            :
         420                 :            : typedef struct instr_sequence_ {
         421                 :            :     instruction *s_instrs;
         422                 :            :     int s_allocated;
         423                 :            :     int s_used;
         424                 :            :
         425                 :            :     int *s_labelmap;       /* label id --> instr offset */
         426                 :            :     int s_labelmap_size;
         427                 :            :     int s_next_free_label; /* next free label id */
         428                 :            : } instr_sequence;
         429                 :            :
         430                 :            : #define INITIAL_INSTR_SEQUENCE_SIZE 100
         431                 :            : #define INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE 10
         432                 :            :
         433                 :            : /*
         434                 :            :  * Resize the array if index is out of range.
         435                 :            :  *
         436                 :            :  * idx: the index we want to access
         437                 :            :  * arr: pointer to the array
         438                 :            :  * alloc: pointer to the capacity of the array
         439                 :            :  * default_alloc: initial number of items
         440                 :            :  * item_size: size of each item
         441                 :            :  *
         442                 :            :  */
         443                 :            : static int
         444                 :     815334 : ensure_array_large_enough(int idx, void **arr_, int *alloc, int default_alloc, size_t item_size)
         445                 :            : {
         446                 :     815334 :     void *arr = *arr_;
         447         [ +  + ]:     815334 :     if (arr == NULL) {
         448                 :      72673 :         int new_alloc = default_alloc;
         449         [ -  + ]:      72673 :         if (idx >= new_alloc) {
         450                 :          0 :             new_alloc = idx + default_alloc;
         451                 :            :         }
         452                 :      72673 :         arr = PyObject_Calloc(new_alloc, item_size);
         453         [ -  + ]:      72673 :         if (arr == NULL) {
         454                 :          0 :             PyErr_NoMemory();
         455                 :          0 :             return ERROR;
         456                 :            :         }
         457                 :      72673 :         *alloc = new_alloc;
         458                 :            :     }
         459         [ +  + ]:     742661 :     else if (idx >= *alloc) {
         460                 :       8183 :         size_t oldsize = *alloc * item_size;
         461                 :       8183 :         int new_alloc = *alloc << 1;
         462         [ -  + ]:       8183 :         if (idx >= new_alloc) {
         463                 :          0 :             new_alloc = idx + default_alloc;
         464                 :            :         }
         465                 :       8183 :         size_t newsize = new_alloc * item_size;
         466                 :            :
         467         [ -  + ]:       8183 :         if (oldsize > (SIZE_MAX >> 1)) {
         468                 :          0 :             PyErr_NoMemory();
         469                 :          0 :             return ERROR;
         470                 :            :         }
         471                 :            :
         472                 :            :         assert(newsize > 0);
         473                 :       8183 :         void *tmp = PyObject_Realloc(arr, newsize);
         474         [ -  + ]:       8183 :         if (tmp == NULL) {
         475                 :          0 :             PyErr_NoMemory();
         476                 :          0 :             return ERROR;
         477                 :            :         }
         478                 :       8183 :         *alloc = new_alloc;
         479                 :       8183 :         arr = tmp;
         480                 :       8183 :         memset((char *)arr + oldsize, 0, newsize - oldsize);
         481                 :            :     }
         482                 :            :
         483                 :     815334 :     *arr_ = arr;
         484                 :     815334 :     return SUCCESS;
         485                 :            : }
         486                 :            :
         487                 :            : static int
         488                 :     386612 : instr_sequence_next_inst(instr_sequence *seq) {
         489                 :            :     assert(seq->s_instrs != NULL || seq->s_used == 0);
         490                 :            :
         491         [ -  + ]:     386612 :     RETURN_IF_ERROR(
         492                 :            :         ensure_array_large_enough(seq->s_used + 1,
         493                 :            :                                   (void**)&seq->s_instrs,
         494                 :            :                                   &seq->s_allocated,
         495                 :            :                                   INITIAL_INSTR_SEQUENCE_SIZE,
         496                 :            :                                   sizeof(instruction)));
         497                 :            :     assert(seq->s_used < seq->s_allocated);
         498                 :     386612 :     return seq->s_used++;
         499                 :            : }
         500                 :            :
         501                 :            : static jump_target_label
         502                 :      33597 : instr_sequence_new_label(instr_sequence *seq)
         503                 :            : {
         504                 :      33597 :     jump_target_label lbl = {++seq->s_next_free_label};
         505                 :      33597 :     return lbl;
         506                 :            : }
         507                 :            :
         508                 :            : static int
         509                 :      33597 : instr_sequence_use_label(instr_sequence *seq, int lbl) {
         510                 :      33597 :     int old_size = seq->s_labelmap_size;
         511         [ -  + ]:      33597 :     RETURN_IF_ERROR(
         512                 :            :         ensure_array_large_enough(lbl,
         513                 :            :                                   (void**)&seq->s_labelmap,
         514                 :            :                                   &seq->s_labelmap_size,
         515                 :            :                                   INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE,
         516                 :            :                                   sizeof(int)));
         517                 :            :
         518         [ +  + ]:      97907 :     for(int i = old_size; i < seq->s_labelmap_size; i++) {
         519                 :      64310 :         seq->s_labelmap[i] = -111;  /* something weird, for debugging */
         520                 :            :     }
         521                 :      33597 :     seq->s_labelmap[lbl] = seq->s_used; /* label refers to the next instruction */
         522                 :      33597 :     return SUCCESS;
         523                 :            : }
         524                 :            :
         525                 :            : static int
         526                 :     386082 : instr_sequence_addop(instr_sequence *seq, int opcode, int oparg, location loc)
         527                 :            : {
         528                 :            :     assert(IS_WITHIN_OPCODE_RANGE(opcode));
         529                 :            :     assert(!IS_ASSEMBLER_OPCODE(opcode));
         530                 :            :     assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0);
         531                 :            :     assert(0 <= oparg && oparg < (1 << 30));
         532                 :            :
         533                 :     386082 :     int idx = instr_sequence_next_inst(seq);
         534         [ -  + ]:     386082 :     RETURN_IF_ERROR(idx);
         535                 :     386082 :     instruction *ci = &seq->s_instrs[idx];
         536                 :     386082 :     ci->i_opcode = opcode;
         537                 :     386082 :     ci->i_oparg = oparg;
         538                 :     386082 :     ci->i_loc = loc;
         539                 :     386082 :     return SUCCESS;
         540                 :            : }
         541                 :            :
         542                 :            : static int
         543                 :        530 : instr_sequence_insert_instruction(instr_sequence *seq, int pos,
         544                 :            :                                   int opcode, int oparg, location loc)
         545                 :            : {
         546                 :            :     assert(pos >= 0 && pos <= seq->s_used);
         547                 :        530 :     int last_idx = instr_sequence_next_inst(seq);
         548         [ -  + ]:        530 :     RETURN_IF_ERROR(last_idx);
         549         [ +  + ]:      27294 :     for (int i=last_idx-1; i >= pos; i--) {
         550                 :      26764 :         seq->s_instrs[i+1] = seq->s_instrs[i];
         551                 :            :     }
         552                 :        530 :     instruction *ci = &seq->s_instrs[pos];
         553                 :        530 :     ci->i_opcode = opcode;
         554                 :        530 :     ci->i_oparg = oparg;
         555                 :        530 :     ci->i_loc = loc;
         556                 :            :
         557                 :            :     /* fix the labels map */
         558         [ +  + ]:       8160 :     for(int lbl=0; lbl < seq->s_labelmap_size; lbl++) {
         559         [ +  + ]:       7630 :         if (seq->s_labelmap[lbl] >= pos) {
         560                 :       4243 :             seq->s_labelmap[lbl]++;
         561                 :            :         }
         562                 :            :     }
         563                 :        530 :     return SUCCESS;
         564                 :            : }
         565                 :            :
         566                 :            : static void
         567                 :       8041 : instr_sequence_fini(instr_sequence *seq) {
         568                 :       8041 :     PyObject_Free(seq->s_labelmap);
         569                 :       8041 :     seq->s_labelmap = NULL;
         570                 :            :
         571                 :       8041 :     PyObject_Free(seq->s_instrs);
         572                 :       8041 :     seq->s_instrs = NULL;
         573                 :       8041 : }
         574                 :            :
         575                 :            : static int basicblock_addop(basicblock *b, int opcode, int oparg, location loc);
         576                 :            : static int cfg_builder_maybe_start_new_block(cfg_builder *g);
         577                 :            :
         578                 :            : static int
         579                 :      33597 : cfg_builder_use_label(cfg_builder *g, jump_target_label lbl)
         580                 :            : {
         581                 :      33597 :     g->g_current_label = lbl;
         582                 :      33597 :     return cfg_builder_maybe_start_new_block(g);
         583                 :            : }
         584                 :            :
         585                 :            : static int
         586                 :     386612 : cfg_builder_addop(cfg_builder *g, int opcode, int oparg, location loc)
         587                 :            : {
         588         [ -  + ]:     386612 :     RETURN_IF_ERROR(cfg_builder_maybe_start_new_block(g));
         589                 :     386612 :     return basicblock_addop(g->g_curblock, opcode, oparg, loc);
         590                 :            : }
         591                 :            :
         592                 :            : static int cfg_builder_init(cfg_builder *g);
         593                 :            :
         594                 :            : static int
         595                 :       8041 : instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) {
         596                 :       8041 :     memset(g, 0, sizeof(cfg_builder));
         597         [ -  + ]:       8041 :     RETURN_IF_ERROR(cfg_builder_init(g));
         598                 :            :     /* Note: there can be more than one label for the same offset */
         599         [ +  + ]:     394653 :     for (int i = 0; i < seq->s_used; i++) {
         600         [ +  + ]:   10102672 :         for (int j=0; j < seq->s_labelmap_size; j++) {
         601         [ +  + ]:    9716060 :             if (seq->s_labelmap[j] == i) {
         602                 :      33597 :                 jump_target_label lbl = {j};
         603         [ -  + ]:      33597 :                 RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
         604                 :            :             }
         605                 :            :         }
         606                 :     386612 :         instruction *instr = &seq->s_instrs[i];
         607         [ -  + ]:     386612 :         RETURN_IF_ERROR(cfg_builder_addop(g, instr->i_opcode, instr->i_oparg, instr->i_loc));
         608                 :            :     }
         609                 :       8041 :     int nblocks = 0;
         610         [ +  + ]:      69608 :     for (basicblock *b = g->g_block_list; b != NULL; b = b->b_list) {
         611                 :      61567 :         nblocks++;
         612                 :            :     }
         613         [ -  + ]:       8041 :     if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) {
         614                 :          0 :         PyErr_NoMemory();
         615                 :          0 :         return ERROR;
         616                 :            :     }
         617                 :       8041 :     return SUCCESS;
         618                 :            : }
         619                 :            :
         620                 :            :
         621                 :            : /* The following items change on entry and exit of code blocks.
         622                 :            :    They must be saved and restored when returning to a block.
         623                 :            : */
         624                 :            : struct compiler_unit {
         625                 :            :     PySTEntryObject *u_ste;
         626                 :            :
         627                 :            :     PyObject *u_name;
         628                 :            :     PyObject *u_qualname;  /* dot-separated qualified name (lazy) */
         629                 :            :     int u_scope_type;
         630                 :            :
         631                 :            :     /* The following fields are dicts that map objects to
         632                 :            :        the index of them in co_XXX.      The index is used as
         633                 :            :        the argument for opcodes that refer to those collections.
         634                 :            :     */
         635                 :            :     PyObject *u_consts;    /* all constants */
         636                 :            :     PyObject *u_names;     /* all names */
         637                 :            :     PyObject *u_varnames;  /* local variables */
         638                 :            :     PyObject *u_cellvars;  /* cell variables */
         639                 :            :     PyObject *u_freevars;  /* free variables */
         640                 :            :
         641                 :            :     PyObject *u_private;        /* for private name mangling */
         642                 :            :
         643                 :            :     Py_ssize_t u_argcount;        /* number of arguments for block */
         644                 :            :     Py_ssize_t u_posonlyargcount;        /* number of positional only arguments for block */
         645                 :            :     Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */
         646                 :            :
         647                 :            :     instr_sequence u_instr_sequence; /* codegen output */
         648                 :            :
         649                 :            :     int u_nfblocks;
         650                 :            :     struct fblockinfo u_fblock[CO_MAXBLOCKS];
         651                 :            :
         652                 :            :     int u_firstlineno; /* the first lineno of the block */
         653                 :            : };
         654                 :            :
         655                 :            : /* This struct captures the global state of a compilation.
         656                 :            :
         657                 :            : The u pointer points to the current compilation unit, while units
         658                 :            : for enclosing blocks are stored in c_stack.     The u and c_stack are
         659                 :            : managed by compiler_enter_scope() and compiler_exit_scope().
         660                 :            :
         661                 :            : Note that we don't track recursion levels during compilation - the
         662                 :            : task of detecting and rejecting excessive levels of nesting is
         663                 :            : handled by the symbol analysis pass.
         664                 :            :
         665                 :            : */
         666                 :            :
         667                 :            : struct compiler {
         668                 :            :     PyObject *c_filename;
         669                 :            :     struct symtable *c_st;
         670                 :            :     PyFutureFeatures c_future;   /* module's __future__ */
         671                 :            :     PyCompilerFlags c_flags;
         672                 :            :
         673                 :            :     int c_optimize;              /* optimization level */
         674                 :            :     int c_interactive;           /* true if in interactive mode */
         675                 :            :     int c_nestlevel;
         676                 :            :     PyObject *c_const_cache;     /* Python dict holding all constants,
         677                 :            :                                     including names tuple */
         678                 :            :     struct compiler_unit *u; /* compiler state for current block */
         679                 :            :     PyObject *c_stack;           /* Python list holding compiler_unit ptrs */
         680                 :            :     PyArena *c_arena;            /* pointer to memory allocation arena */
         681                 :            : };
         682                 :            :
         683                 :            : #define INSTR_SEQUENCE(C) (&((C)->u->u_instr_sequence))
         684                 :            :
         685                 :            :
         686                 :            : typedef struct {
         687                 :            :     // A list of strings corresponding to name captures. It is used to track:
         688                 :            :     // - Repeated name assignments in the same pattern.
         689                 :            :     // - Different name assignments in alternatives.
         690                 :            :     // - The order of name assignments in alternatives.
         691                 :            :     PyObject *stores;
         692                 :            :     // If 0, any name captures against our subject will raise.
         693                 :            :     int allow_irrefutable;
         694                 :            :     // An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop
         695                 :            :     // i items off of the stack. The end result looks like this (with each block
         696                 :            :     // falling through to the next):
         697                 :            :     // fail_pop[4]: POP_TOP
         698                 :            :     // fail_pop[3]: POP_TOP
         699                 :            :     // fail_pop[2]: POP_TOP
         700                 :            :     // fail_pop[1]: POP_TOP
         701                 :            :     // fail_pop[0]: NOP
         702                 :            :     jump_target_label *fail_pop;
         703                 :            :     // The current length of fail_pop.
         704                 :            :     Py_ssize_t fail_pop_size;
         705                 :            :     // The number of items on top of the stack that need to *stay* on top of the
         706                 :            :     // stack. Variable captures go beneath these. All of them will be popped on
         707                 :            :     // failure.
         708                 :            :     Py_ssize_t on_top;
         709                 :            : } pattern_context;
         710                 :            :
         711                 :            : static int basicblock_next_instr(basicblock *);
         712                 :            :
         713                 :            : static int codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc);
         714                 :            :
         715                 :            : static void compiler_free(struct compiler *);
         716                 :            : static int compiler_error(struct compiler *, location loc, const char *, ...);
         717                 :            : static int compiler_warn(struct compiler *, location loc, const char *, ...);
         718                 :            : static int compiler_nameop(struct compiler *, location, identifier, expr_context_ty);
         719                 :            :
         720                 :            : static PyCodeObject *compiler_mod(struct compiler *, mod_ty);
         721                 :            : static int compiler_visit_stmt(struct compiler *, stmt_ty);
         722                 :            : static int compiler_visit_keyword(struct compiler *, keyword_ty);
         723                 :            : static int compiler_visit_expr(struct compiler *, expr_ty);
         724                 :            : static int compiler_augassign(struct compiler *, stmt_ty);
         725                 :            : static int compiler_annassign(struct compiler *, stmt_ty);
         726                 :            : static int compiler_subscript(struct compiler *, expr_ty);
         727                 :            : static int compiler_slice(struct compiler *, expr_ty);
         728                 :            :
         729                 :            : static bool are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t);
         730                 :            :
         731                 :            :
         732                 :            : static int compiler_with(struct compiler *, stmt_ty, int);
         733                 :            : static int compiler_async_with(struct compiler *, stmt_ty, int);
         734                 :            : static int compiler_async_for(struct compiler *, stmt_ty);
         735                 :            : static int compiler_call_simple_kw_helper(struct compiler *c,
         736                 :            :                                           location loc,
         737                 :            :                                           asdl_keyword_seq *keywords,
         738                 :            :                                           Py_ssize_t nkwelts);
         739                 :            : static int compiler_call_helper(struct compiler *c, location loc,
         740                 :            :                                 int n, asdl_expr_seq *args,
         741                 :            :                                 asdl_keyword_seq *keywords);
         742                 :            : static int compiler_try_except(struct compiler *, stmt_ty);
         743                 :            : static int compiler_try_star_except(struct compiler *, stmt_ty);
         744                 :            : static int compiler_set_qualname(struct compiler *);
         745                 :            :
         746                 :            : static int compiler_sync_comprehension_generator(
         747                 :            :                                       struct compiler *c, location loc,
         748                 :            :                                       asdl_comprehension_seq *generators, int gen_index,
         749                 :            :                                       int depth,
         750                 :            :                                       expr_ty elt, expr_ty val, int type);
         751                 :            :
         752                 :            : static int compiler_async_comprehension_generator(
         753                 :            :                                       struct compiler *c, location loc,
         754                 :            :                                       asdl_comprehension_seq *generators, int gen_index,
         755                 :            :                                       int depth,
         756                 :            :                                       expr_ty elt, expr_ty val, int type);
         757                 :            :
         758                 :            : static int compiler_pattern(struct compiler *, pattern_ty, pattern_context *);
         759                 :            : static int compiler_match(struct compiler *, stmt_ty);
         760                 :            : static int compiler_pattern_subpattern(struct compiler *,
         761                 :            :                                        pattern_ty, pattern_context *);
         762                 :            :
         763                 :            : static int remove_redundant_nops(basicblock *bb);
         764                 :            :
         765                 :            : static PyCodeObject *assemble(struct compiler *, int addNone);
         766                 :            :
         767                 :            : #define CAPSULE_NAME "compile.c compiler unit"
         768                 :            :
         769                 :            :
         770                 :            : static int
         771                 :        319 : compiler_setup(struct compiler *c, mod_ty mod, PyObject *filename,
         772                 :            :                PyCompilerFlags flags, int optimize, PyArena *arena)
         773                 :            : {
         774                 :        319 :     c->c_const_cache = PyDict_New();
         775         [ -  + ]:        319 :     if (!c->c_const_cache) {
         776                 :          0 :         return ERROR;
         777                 :            :     }
         778                 :            :
         779                 :        319 :     c->c_stack = PyList_New(0);
         780         [ -  + ]:        319 :     if (!c->c_stack) {
         781                 :          0 :         return ERROR;
         782                 :            :     }
         783                 :            :
         784                 :        319 :     c->c_filename = Py_NewRef(filename);
         785                 :        319 :     c->c_arena = arena;
         786         [ -  + ]:        319 :     if (!_PyFuture_FromAST(mod, filename, &c->c_future)) {
         787                 :          0 :         return ERROR;
         788                 :            :     }
         789                 :        319 :     int merged = c->c_future.ff_features | flags.cf_flags;
         790                 :        319 :     c->c_future.ff_features = merged;
         791                 :        319 :     flags.cf_flags = merged;
         792                 :        319 :     c->c_flags = flags;
         793         [ +  + ]:        319 :     c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
         794                 :        319 :     c->c_nestlevel = 0;
         795                 :            :
         796                 :            :     _PyASTOptimizeState state;
         797                 :        319 :     state.optimize = c->c_optimize;
         798                 :        319 :     state.ff_features = merged;
         799                 :            :
         800         [ -  + ]:        319 :     if (!_PyAST_Optimize(mod, arena, &state)) {
         801                 :          0 :         return ERROR;
         802                 :            :     }
         803                 :        319 :     c->c_st = _PySymtable_Build(mod, filename, &c->c_future);
         804         [ -  + ]:        319 :     if (c->c_st == NULL) {
         805         [ #  # ]:          0 :         if (!PyErr_Occurred()) {
         806                 :          0 :             PyErr_SetString(PyExc_SystemError, "no symtable");
         807                 :            :         }
         808                 :          0 :         return ERROR;
         809                 :            :     }
         810                 :        319 :     return SUCCESS;
         811                 :            : }
         812                 :            :
         813                 :            : static struct compiler*
         814                 :        319 : new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
         815                 :            :              int optimize, PyArena *arena)
         816                 :            : {
         817         [ +  + ]:        319 :     PyCompilerFlags flags = pflags ? *pflags : _PyCompilerFlags_INIT;
         818                 :        319 :     struct compiler *c = PyMem_Calloc(1, sizeof(struct compiler));
         819         [ -  + ]:        319 :     if (c == NULL) {
         820                 :          0 :         return NULL;
         821                 :            :     }
         822         [ -  + ]:        319 :     if (compiler_setup(c, mod, filename, flags, optimize, arena) < 0) {
         823                 :          0 :         compiler_free(c);
         824                 :          0 :         return NULL;
         825                 :            :     }
         826                 :        319 :     return c;
         827                 :            : }
         828                 :            :
         829                 :            : PyCodeObject *
         830                 :        319 : _PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
         831                 :            :                int optimize, PyArena *arena)
         832                 :            : {
         833                 :        319 :     struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena);
         834         [ -  + ]:        319 :     if (c == NULL) {
         835                 :          0 :         return NULL;
         836                 :            :     }
         837                 :            :
         838                 :        319 :     PyCodeObject *co = compiler_mod(c, mod);
         839                 :        319 :     compiler_free(c);
         840                 :            :     assert(co || PyErr_Occurred());
         841                 :        319 :     return co;
         842                 :            : }
         843                 :            :
         844                 :            : static void
         845                 :        319 : compiler_free(struct compiler *c)
         846                 :            : {
         847         [ +  - ]:        319 :     if (c->c_st)
         848                 :        319 :         _PySymtable_Free(c->c_st);
         849                 :        319 :     Py_XDECREF(c->c_filename);
         850                 :        319 :     Py_XDECREF(c->c_const_cache);
         851                 :        319 :     Py_XDECREF(c->c_stack);
         852                 :        319 :     PyMem_Free(c);
         853                 :        319 : }
         854                 :            :
         855                 :            : static PyObject *
         856                 :       8041 : list2dict(PyObject *list)
         857                 :            : {
         858                 :            :     Py_ssize_t i, n;
         859                 :            :     PyObject *v, *k;
         860                 :       8041 :     PyObject *dict = PyDict_New();
         861         [ -  + ]:       8041 :     if (!dict) return NULL;
         862                 :            :
         863                 :       8041 :     n = PyList_Size(list);
         864         [ +  + ]:      22014 :     for (i = 0; i < n; i++) {
         865                 :      13973 :         v = PyLong_FromSsize_t(i);
         866         [ -  + ]:      13973 :         if (!v) {
         867                 :          0 :             Py_DECREF(dict);
         868                 :          0 :             return NULL;
         869                 :            :         }
         870                 :      13973 :         k = PyList_GET_ITEM(list, i);
         871         [ -  + ]:      13973 :         if (PyDict_SetItem(dict, k, v) < 0) {
         872                 :          0 :             Py_DECREF(v);
         873                 :          0 :             Py_DECREF(dict);
         874                 :          0 :             return NULL;
         875                 :            :         }
         876                 :      13973 :         Py_DECREF(v);
         877                 :            :     }
         878                 :       8041 :     return dict;
         879                 :            : }
         880                 :            :
         881                 :            : /* Return new dict containing names from src that match scope(s).
         882                 :            :
         883                 :            : src is a symbol table dictionary.  If the scope of a name matches
         884                 :            : either scope_type or flag is set, insert it into the new dict.  The
         885                 :            : values are integers, starting at offset and increasing by one for
         886                 :            : each key.
         887                 :            : */
         888                 :            :
         889                 :            : static PyObject *
         890                 :      16082 : dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
         891                 :            : {
         892                 :      16082 :     Py_ssize_t i = offset, scope, num_keys, key_i;
         893                 :      16082 :     PyObject *k, *v, *dest = PyDict_New();
         894                 :            :     PyObject *sorted_keys;
         895                 :            :
         896                 :            :     assert(offset >= 0);
         897         [ -  + ]:      16082 :     if (dest == NULL)
         898                 :          0 :         return NULL;
         899                 :            :
         900                 :            :     /* Sort the keys so that we have a deterministic order on the indexes
         901                 :            :        saved in the returned dictionary.  These indexes are used as indexes
         902                 :            :        into the free and cell var storage.  Therefore if they aren't
         903                 :            :        deterministic, then the generated bytecode is not deterministic.
         904                 :            :     */
         905                 :      16082 :     sorted_keys = PyDict_Keys(src);
         906         [ -  + ]:      16082 :     if (sorted_keys == NULL)
         907                 :          0 :         return NULL;
         908         [ -  + ]:      16082 :     if (PyList_Sort(sorted_keys) != 0) {
         909                 :          0 :         Py_DECREF(sorted_keys);
         910                 :          0 :         return NULL;
         911                 :            :     }
         912                 :      16082 :     num_keys = PyList_GET_SIZE(sorted_keys);
         913                 :            :
         914         [ +  + ]:     118292 :     for (key_i = 0; key_i < num_keys; key_i++) {
         915                 :            :         /* XXX this should probably be a macro in symtable.h */
         916                 :            :         long vi;
         917                 :     102210 :         k = PyList_GET_ITEM(sorted_keys, key_i);
         918                 :     102210 :         v = PyDict_GetItemWithError(src, k);
         919                 :            :         assert(v && PyLong_Check(v));
         920                 :     102210 :         vi = PyLong_AS_LONG(v);
         921                 :     102210 :         scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
         922                 :            :
         923   [ +  +  -  + ]:     102210 :         if (scope == scope_type || vi & flag) {
         924                 :       1525 :             PyObject *item = PyLong_FromSsize_t(i);
         925         [ -  + ]:       1525 :             if (item == NULL) {
         926                 :          0 :                 Py_DECREF(sorted_keys);
         927                 :          0 :                 Py_DECREF(dest);
         928                 :          0 :                 return NULL;
         929                 :            :             }
         930                 :       1525 :             i++;
         931         [ -  + ]:       1525 :             if (PyDict_SetItem(dest, k, item) < 0) {
         932                 :          0 :                 Py_DECREF(sorted_keys);
         933                 :          0 :                 Py_DECREF(item);
         934                 :          0 :                 Py_DECREF(dest);
         935                 :          0 :                 return NULL;
         936                 :            :             }
         937                 :       1525 :             Py_DECREF(item);
         938                 :            :         }
         939                 :            :     }
         940                 :      16082 :     Py_DECREF(sorted_keys);
         941                 :      16082 :     return dest;
         942                 :            : }
         943                 :            :
         944                 :            : #ifndef NDEBUG
         945                 :            : static bool
         946                 :            : cfg_builder_check(cfg_builder *g)
         947                 :            : {
         948                 :            :     assert(g->g_entryblock->b_iused > 0);
         949                 :            :     for (basicblock *block = g->g_block_list; block != NULL; block = block->b_list) {
         950                 :            :         assert(!_PyMem_IsPtrFreed(block));
         951                 :            :         if (block->b_instr != NULL) {
         952                 :            :             assert(block->b_ialloc > 0);
         953                 :            :             assert(block->b_iused >= 0);
         954                 :            :             assert(block->b_ialloc >= block->b_iused);
         955                 :            :         }
         956                 :            :         else {
         957                 :            :             assert (block->b_iused == 0);
         958                 :            :             assert (block->b_ialloc == 0);
         959                 :            :         }
         960                 :            :     }
         961                 :            :     return true;
         962                 :            : }
         963                 :            : #endif
         964                 :            :
         965                 :            : static basicblock *cfg_builder_new_block(cfg_builder *g);
         966                 :            :
         967                 :            : static int
         968                 :       8041 : cfg_builder_init(cfg_builder *g)
         969                 :            : {
         970                 :       8041 :     g->g_block_list = NULL;
         971                 :       8041 :     basicblock *block = cfg_builder_new_block(g);
         972         [ -  + ]:       8041 :     if (block == NULL) {
         973                 :          0 :         return ERROR;
         974                 :            :     }
         975                 :       8041 :     g->g_curblock = g->g_entryblock = block;
         976                 :       8041 :     g->g_current_label = NO_LABEL;
         977                 :       8041 :     return SUCCESS;
         978                 :            : }
         979                 :            :
         980                 :            : static void
         981                 :       8041 : cfg_builder_fini(cfg_builder* g)
         982                 :            : {
         983                 :            :     assert(cfg_builder_check(g));
         984                 :       8041 :     basicblock *b = g->g_block_list;
         985         [ +  + ]:      71160 :     while (b != NULL) {
         986         [ +  + ]:      63119 :         if (b->b_instr) {
         987                 :      60469 :             PyObject_Free((void *)b->b_instr);
         988                 :            :         }
         989                 :      63119 :         basicblock *next = b->b_list;
         990                 :      63119 :         PyObject_Free((void *)b);
         991                 :      63119 :         b = next;
         992                 :            :     }
         993                 :       8041 : }
         994                 :            :
         995                 :            : static void
         996                 :       8041 : compiler_unit_free(struct compiler_unit *u)
         997                 :            : {
         998                 :       8041 :     instr_sequence_fini(&u->u_instr_sequence);
         999         [ +  - ]:       8041 :     Py_CLEAR(u->u_ste);
        1000         [ +  - ]:       8041 :     Py_CLEAR(u->u_name);
        1001         [ +  + ]:       8041 :     Py_CLEAR(u->u_qualname);
        1002         [ +  - ]:       8041 :     Py_CLEAR(u->u_consts);
        1003         [ +  - ]:       8041 :     Py_CLEAR(u->u_names);
        1004         [ +  - ]:       8041 :     Py_CLEAR(u->u_varnames);
        1005         [ +  - ]:       8041 :     Py_CLEAR(u->u_freevars);
        1006         [ +  - ]:       8041 :     Py_CLEAR(u->u_cellvars);
        1007         [ +  + ]:       8041 :     Py_CLEAR(u->u_private);
        1008                 :       8041 :     PyObject_Free(u);
        1009                 :       8041 : }
        1010                 :            :
        1011                 :            : static int
        1012                 :       7722 : compiler_set_qualname(struct compiler *c)
        1013                 :            : {
        1014                 :            :     Py_ssize_t stack_size;
        1015                 :       7722 :     struct compiler_unit *u = c->u;
        1016                 :            :     PyObject *name, *base;
        1017                 :            :
        1018                 :       7722 :     base = NULL;
        1019                 :       7722 :     stack_size = PyList_GET_SIZE(c->c_stack);
        1020                 :            :     assert(stack_size >= 1);
        1021         [ +  + ]:       7722 :     if (stack_size > 1) {
        1022                 :       4981 :         int scope, force_global = 0;
        1023                 :            :         struct compiler_unit *parent;
        1024                 :            :         PyObject *mangled, *capsule;
        1025                 :            :
        1026                 :       4981 :         capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
        1027                 :       4981 :         parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
        1028                 :            :         assert(parent);
        1029                 :            :
        1030         [ +  + ]:       4981 :         if (u->u_scope_type == COMPILER_SCOPE_FUNCTION
        1031         [ +  + ]:        655 :             || u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
        1032         [ +  + ]:        516 :             || u->u_scope_type == COMPILER_SCOPE_CLASS) {
        1033                 :            :             assert(u->u_name);
        1034                 :       4494 :             mangled = _Py_Mangle(parent->u_private, u->u_name);
        1035         [ -  + ]:       4494 :             if (!mangled) {
        1036                 :          0 :                 return ERROR;
        1037                 :            :             }
        1038                 :            :
        1039                 :       4494 :             scope = _PyST_GetScope(parent->u_ste, mangled);
        1040                 :       4494 :             Py_DECREF(mangled);
        1041                 :            :             assert(scope != GLOBAL_IMPLICIT);
        1042         [ -  + ]:       4494 :             if (scope == GLOBAL_EXPLICIT)
        1043                 :          0 :                 force_global = 1;
        1044                 :            :         }
        1045                 :            :
        1046         [ +  - ]:       4981 :         if (!force_global) {
        1047         [ +  + ]:       4981 :             if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION
        1048         [ +  + ]:       4253 :                 || parent->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
        1049         [ -  + ]:       4229 :                 || parent->u_scope_type == COMPILER_SCOPE_LAMBDA)
        1050                 :            :             {
        1051                 :            :                 _Py_DECLARE_STR(dot_locals, ".<locals>");
        1052                 :        752 :                 base = PyUnicode_Concat(parent->u_qualname,
        1053                 :            :                                         &_Py_STR(dot_locals));
        1054         [ -  + ]:        752 :                 if (base == NULL) {
        1055                 :          0 :                     return ERROR;
        1056                 :            :                 }
        1057                 :            :             }
        1058                 :            :             else {
        1059                 :       4229 :                 base = Py_NewRef(parent->u_qualname);
        1060                 :            :             }
        1061                 :            :         }
        1062                 :            :     }
        1063                 :            :
        1064         [ +  + ]:       7722 :     if (base != NULL) {
        1065                 :            :         _Py_DECLARE_STR(dot, ".");
        1066                 :       4981 :         name = PyUnicode_Concat(base, &_Py_STR(dot));
        1067                 :       4981 :         Py_DECREF(base);
        1068         [ -  + ]:       4981 :         if (name == NULL) {
        1069                 :          0 :             return ERROR;
        1070                 :            :         }
        1071                 :       4981 :         PyUnicode_Append(&name, u->u_name);
        1072         [ -  + ]:       4981 :         if (name == NULL) {
        1073                 :          0 :             return ERROR;
        1074                 :            :         }
        1075                 :            :     }
        1076                 :            :     else {
        1077                 :       2741 :         name = Py_NewRef(u->u_name);
        1078                 :            :     }
        1079                 :       7722 :     u->u_qualname = name;
        1080                 :            :
        1081                 :       7722 :     return SUCCESS;
        1082                 :            : }
        1083                 :            :
        1084                 :            : /* Allocate a new block and return a pointer to it.
        1085                 :            :    Returns NULL on error.
        1086                 :            : */
        1087                 :            : static basicblock *
        1088                 :      63119 : cfg_builder_new_block(cfg_builder *g)
        1089                 :            : {
        1090                 :      63119 :     basicblock *b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock));
        1091         [ -  + ]:      63119 :     if (b == NULL) {
        1092                 :          0 :         PyErr_NoMemory();
        1093                 :          0 :         return NULL;
        1094                 :            :     }
        1095                 :            :     /* Extend the singly linked list of blocks with new block. */
        1096                 :      63119 :     b->b_list = g->g_block_list;
        1097                 :      63119 :     g->g_block_list = b;
        1098                 :      63119 :     b->b_label = NO_LABEL;
        1099                 :      63119 :     return b;
        1100                 :            : }
        1101                 :            :
        1102                 :            : static basicblock *
        1103                 :      53526 : cfg_builder_use_next_block(cfg_builder *g, basicblock *block)
        1104                 :            : {
        1105                 :            :     assert(block != NULL);
        1106                 :      53526 :     g->g_curblock->b_next = block;
        1107                 :      53526 :     g->g_curblock = block;
        1108                 :      53526 :     return block;
        1109                 :            : }
        1110                 :            :
        1111                 :            : static inline int
        1112                 :       2669 : basicblock_append_instructions(basicblock *target, basicblock *source)
        1113                 :            : {
        1114         [ +  + ]:       7754 :     for (int i = 0; i < source->b_iused; i++) {
        1115                 :       5085 :         int n = basicblock_next_instr(target);
        1116         [ -  + ]:       5085 :         if (n < 0) {
        1117                 :          0 :             return ERROR;
        1118                 :            :         }
        1119                 :       5085 :         target->b_instr[n] = source->b_instr[i];
        1120                 :            :     }
        1121                 :       2669 :     return SUCCESS;
        1122                 :            : }
        1123                 :            :
        1124                 :            : static basicblock *
        1125                 :        514 : copy_basicblock(cfg_builder *g, basicblock *block)
        1126                 :            : {
        1127                 :            :     /* Cannot copy a block if it has a fallthrough, since
        1128                 :            :      * a block can only have one fallthrough predecessor.
        1129                 :            :      */
        1130                 :            :     assert(BB_NO_FALLTHROUGH(block));
        1131                 :        514 :     basicblock *result = cfg_builder_new_block(g);
        1132         [ -  + ]:        514 :     if (result == NULL) {
        1133                 :          0 :         return NULL;
        1134                 :            :     }
        1135         [ -  + ]:        514 :     if (basicblock_append_instructions(result, block) < 0) {
        1136                 :          0 :         return NULL;
        1137                 :            :     }
        1138                 :        514 :     return result;
        1139                 :            : }
        1140                 :            :
        1141                 :            : /* Returns the offset of the next instruction in the current block's
        1142                 :            :    b_instr array.  Resizes the b_instr as necessary.
        1143                 :            :    Returns -1 on failure.
        1144                 :            : */
        1145                 :            :
        1146                 :            : static int
        1147                 :     395125 : basicblock_next_instr(basicblock *b)
        1148                 :            : {
        1149                 :            :     assert(b != NULL);
        1150                 :            :
        1151         [ -  + ]:     395125 :     RETURN_IF_ERROR(
        1152                 :            :         ensure_array_large_enough(
        1153                 :            :             b->b_iused + 1,
        1154                 :            :             (void**)&b->b_instr,
        1155                 :            :             &b->b_ialloc,
        1156                 :            :             DEFAULT_BLOCK_SIZE,
        1157                 :            :             sizeof(struct cfg_instr)));
        1158                 :            :
        1159                 :     395125 :     return b->b_iused++;
        1160                 :            : }
        1161                 :            :
        1162                 :            :
        1163                 :            : /* Return the stack effect of opcode with argument oparg.
        1164                 :            :
        1165                 :            :    Some opcodes have different stack effect when jump to the target and
        1166                 :            :    when not jump. The 'jump' parameter specifies the case:
        1167                 :            :
        1168                 :            :    * 0 -- when not jump
        1169                 :            :    * 1 -- when jump
        1170                 :            :    * -1 -- maximal
        1171                 :            :  */
        1172                 :            : static int
        1173                 :     374600 : stack_effect(int opcode, int oparg, int jump)
        1174                 :            : {
        1175   [ +  -  +  + ]:     374600 :     if (0 <= opcode && opcode <= MAX_REAL_OPCODE) {
        1176         [ -  + ]:     351088 :         if (_PyOpcode_Deopt[opcode] != opcode) {
        1177                 :            :             // Specialized instructions are not supported.
        1178                 :          0 :             return PY_INVALID_STACK_EFFECT;
        1179                 :            :         }
        1180                 :            :         int popped, pushed;
        1181         [ +  + ]:     351088 :         if (jump > 0) {
        1182                 :      15669 :             popped = _PyOpcode_num_popped(opcode, oparg, true);
        1183                 :      15669 :             pushed = _PyOpcode_num_pushed(opcode, oparg, true);
        1184                 :            :         }
        1185                 :            :         else {
        1186                 :     335419 :             popped = _PyOpcode_num_popped(opcode, oparg, false);
        1187                 :     335419 :             pushed = _PyOpcode_num_pushed(opcode, oparg, false);
        1188                 :            :         }
        1189   [ +  -  -  + ]:     351088 :         if (popped < 0 || pushed < 0) {
        1190                 :          0 :             return PY_INVALID_STACK_EFFECT;
        1191                 :            :         }
        1192         [ +  - ]:     351088 :         if (jump >= 0) {
        1193                 :     351088 :             return pushed - popped;
        1194                 :            :         }
        1195         [ #  # ]:          0 :         if (jump < 0) {
        1196                 :            :             // Compute max(pushed - popped, alt_pushed - alt_popped)
        1197                 :          0 :             int alt_popped = _PyOpcode_num_popped(opcode, oparg, true);
        1198                 :          0 :             int alt_pushed = _PyOpcode_num_pushed(opcode, oparg, true);
        1199   [ #  #  #  # ]:          0 :             if (alt_popped < 0 || alt_pushed < 0) {
        1200                 :          0 :                 return PY_INVALID_STACK_EFFECT;
        1201                 :            :             }
        1202                 :          0 :             int diff = pushed - popped;
        1203                 :          0 :             int alt_diff = alt_pushed - alt_popped;
        1204         [ #  # ]:          0 :             if (alt_diff > diff) {
        1205                 :          0 :                 return alt_diff;
        1206                 :            :             }
        1207                 :          0 :             return diff;
        1208                 :            :         }
        1209                 :            :     }
        1210                 :            :
        1211                 :            :     // Pseudo ops
        1212   [ +  +  +  +  :      23512 :     switch (opcode) {
                       -  - ]
        1213                 :      14050 :         case POP_BLOCK:
        1214                 :            :         case JUMP:
        1215                 :            :         case JUMP_NO_INTERRUPT:
        1216                 :      14050 :             return 0;
        1217                 :            :
        1218                 :            :         /* Exception handling pseudo-instructions */
        1219                 :       3352 :         case SETUP_FINALLY:
        1220                 :            :             /* 0 in the normal flow.
        1221                 :            :              * Restore the stack position and push 1 value before jumping to
        1222                 :            :              * the handler if an exception be raised. */
        1223                 :       3352 :             return jump ? 1 : 0;
        1224                 :       5332 :         case SETUP_CLEANUP:
        1225                 :            :             /* As SETUP_FINALLY, but pushes lasti as well */
        1226         [ +  + ]:       5332 :             return jump ? 2 : 0;
        1227                 :        778 :         case SETUP_WITH:
        1228                 :            :             /* 0 in the normal flow.
        1229                 :            :              * Restore the stack position to the position before the result
        1230                 :            :              * of __(a)enter__ and push 2 values before jumping to the handler
        1231                 :            :              * if an exception be raised. */
        1232                 :        778 :             return jump ? 1 : 0;
        1233                 :            :
        1234                 :          0 :         case LOAD_METHOD:
        1235                 :          0 :             return 1;
        1236                 :          0 :         default:
        1237                 :          0 :             return PY_INVALID_STACK_EFFECT;
        1238                 :            :     }
        1239                 :            :
        1240                 :            :     return PY_INVALID_STACK_EFFECT; /* not reachable */
        1241                 :            : }
        1242                 :            :
        1243                 :            : int
        1244                 :          0 : PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump)
        1245                 :            : {
        1246                 :          0 :     return stack_effect(opcode, oparg, jump);
        1247                 :            : }
        1248                 :            :
        1249                 :            : int
        1250                 :          0 : PyCompile_OpcodeStackEffect(int opcode, int oparg)
        1251                 :            : {
        1252                 :          0 :     return stack_effect(opcode, oparg, -1);
        1253                 :            : }
        1254                 :            :
        1255                 :            : static int
        1256                 :     387650 : basicblock_addop(basicblock *b, int opcode, int oparg, location loc)
        1257                 :            : {
        1258                 :            :     assert(IS_WITHIN_OPCODE_RANGE(opcode));
        1259                 :            :     assert(!IS_ASSEMBLER_OPCODE(opcode));
        1260                 :            :     assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0);
        1261                 :            :     assert(0 <= oparg && oparg < (1 << 30));
        1262                 :            :
        1263                 :     387650 :     int off = basicblock_next_instr(b);
        1264         [ -  + ]:     387650 :     if (off < 0) {
        1265                 :          0 :         return ERROR;
        1266                 :            :     }
        1267                 :     387650 :     struct cfg_instr *i = &b->b_instr[off];
        1268                 :     387650 :     i->i_opcode = opcode;
        1269                 :     387650 :     i->i_oparg = oparg;
        1270                 :     387650 :     i->i_target = NULL;
        1271                 :     387650 :     i->i_loc = loc;
        1272                 :            :
        1273                 :     387650 :     return SUCCESS;
        1274                 :            : }
        1275                 :            :
        1276                 :            : static bool
        1277                 :     420209 : cfg_builder_current_block_is_terminated(cfg_builder *g)
        1278                 :            : {
        1279                 :     420209 :     struct cfg_instr *last = basicblock_last_instr(g->g_curblock);
        1280   [ +  +  +  +  :     420209 :     if (last && IS_TERMINATOR_OPCODE(last->i_opcode)) {
              +  +  +  -  +
                    +  +  + ]
        1281                 :      39002 :         return true;
        1282                 :            :     }
        1283         [ +  + ]:     381207 :     if (IS_LABEL(g->g_current_label)) {
        1284   [ +  +  +  - ]:      14524 :         if (last || IS_LABEL(g->g_curblock->b_label)) {
        1285                 :      14524 :             return true;
        1286                 :            :         }
        1287                 :            :         else {
        1288                 :            :             /* current block is empty, label it */
        1289                 :          0 :             g->g_curblock->b_label = g->g_current_label;
        1290                 :          0 :             g->g_current_label = NO_LABEL;
        1291                 :            :         }
        1292                 :            :     }
        1293                 :     366683 :     return false;
        1294                 :            : }
        1295                 :            :
        1296                 :            : static int
        1297                 :     420209 : cfg_builder_maybe_start_new_block(cfg_builder *g)
        1298                 :            : {
        1299         [ +  + ]:     420209 :     if (cfg_builder_current_block_is_terminated(g)) {
        1300                 :      53526 :         basicblock *b = cfg_builder_new_block(g);
        1301         [ -  + ]:      53526 :         if (b == NULL) {
        1302                 :          0 :             return ERROR;
        1303                 :            :         }
        1304                 :      53526 :         b->b_label = g->g_current_label;
        1305                 :      53526 :         g->g_current_label = NO_LABEL;
        1306                 :      53526 :         cfg_builder_use_next_block(g, b);
        1307                 :            :     }
        1308                 :     420209 :     return SUCCESS;
        1309                 :            : }
        1310                 :            :
        1311                 :            : static int
        1312                 :      67751 : codegen_addop_noarg(instr_sequence *seq, int opcode, location loc)
        1313                 :            : {
        1314                 :            :     assert(!HAS_ARG(opcode));
        1315                 :      67751 :     return instr_sequence_addop(seq, opcode, 0, loc);
        1316                 :            : }
        1317                 :            :
        1318                 :            : static Py_ssize_t
        1319                 :     213543 : dict_add_o(PyObject *dict, PyObject *o)
        1320                 :            : {
        1321                 :            :     PyObject *v;
        1322                 :            :     Py_ssize_t arg;
        1323                 :            :
        1324                 :     213543 :     v = PyDict_GetItemWithError(dict, o);
        1325         [ +  + ]:     213543 :     if (!v) {
        1326         [ -  + ]:     102168 :         if (PyErr_Occurred()) {
        1327                 :          0 :             return ERROR;
        1328                 :            :         }
        1329                 :     102168 :         arg = PyDict_GET_SIZE(dict);
        1330                 :     102168 :         v = PyLong_FromSsize_t(arg);
        1331         [ -  + ]:     102168 :         if (!v) {
        1332                 :          0 :             return ERROR;
        1333                 :            :         }
        1334         [ -  + ]:     102168 :         if (PyDict_SetItem(dict, o, v) < 0) {
        1335                 :          0 :             Py_DECREF(v);
        1336                 :          0 :             return ERROR;
        1337                 :            :         }
        1338                 :     102168 :         Py_DECREF(v);
        1339                 :            :     }
        1340                 :            :     else
        1341                 :     111375 :         arg = PyLong_AsLong(v);
        1342                 :     213543 :     return arg;
        1343                 :            : }
        1344                 :            :
        1345                 :            : // Merge const *o* recursively and return constant key object.
        1346                 :            : static PyObject*
        1347                 :      72196 : merge_consts_recursive(PyObject *const_cache, PyObject *o)
        1348                 :            : {
        1349                 :            :     assert(PyDict_CheckExact(const_cache));
        1350                 :            :     // None and Ellipsis are singleton, and key is the singleton.
        1351                 :            :     // No need to merge object and key.
        1352   [ +  +  +  + ]:      72196 :     if (o == Py_None || o == Py_Ellipsis) {
        1353                 :      22062 :         return Py_NewRef(o);
        1354                 :            :     }
        1355                 :            :
        1356                 :      50134 :     PyObject *key = _PyCode_ConstantKey(o);
        1357         [ -  + ]:      50134 :     if (key == NULL) {
        1358                 :          0 :         return NULL;
        1359                 :            :     }
        1360                 :            :
        1361                 :            :     // t is borrowed reference
        1362                 :      50134 :     PyObject *t = PyDict_SetDefault(const_cache, key, key);
        1363         [ +  + ]:      50134 :     if (t != key) {
        1364                 :            :         // o is registered in const_cache.  Just use it.
        1365                 :       8159 :         Py_XINCREF(t);
        1366                 :       8159 :         Py_DECREF(key);
        1367                 :       8159 :         return t;
        1368                 :            :     }
        1369                 :            :
        1370                 :            :     // We registered o in const_cache.
        1371                 :            :     // When o is a tuple or frozenset, we want to merge its
        1372                 :            :     // items too.
        1373         [ +  + ]:      41975 :     if (PyTuple_CheckExact(o)) {
        1374                 :       2102 :         Py_ssize_t len = PyTuple_GET_SIZE(o);
        1375         [ +  + ]:       8890 :         for (Py_ssize_t i = 0; i < len; i++) {
        1376                 :       6788 :             PyObject *item = PyTuple_GET_ITEM(o, i);
        1377                 :       6788 :             PyObject *u = merge_consts_recursive(const_cache, item);
        1378         [ -  + ]:       6788 :             if (u == NULL) {
        1379                 :          0 :                 Py_DECREF(key);
        1380                 :          0 :                 return NULL;
        1381                 :            :             }
        1382                 :            :
        1383                 :            :             // See _PyCode_ConstantKey()
        1384                 :            :             PyObject *v;  // borrowed
        1385         [ +  + ]:       6788 :             if (PyTuple_CheckExact(u)) {
        1386                 :        416 :                 v = PyTuple_GET_ITEM(u, 1);
        1387                 :            :             }
        1388                 :            :             else {
        1389                 :       6372 :                 v = u;
        1390                 :            :             }
        1391         [ +  + ]:       6788 :             if (v != item) {
        1392                 :        830 :                 PyTuple_SET_ITEM(o, i, Py_NewRef(v));
        1393                 :        830 :                 Py_DECREF(item);
        1394                 :            :             }
        1395                 :            :
        1396                 :       6788 :             Py_DECREF(u);
        1397                 :            :         }
        1398                 :            :     }
        1399         [ +  + ]:      39873 :     else if (PyFrozenSet_CheckExact(o)) {
        1400                 :            :         // *key* is tuple. And its first item is frozenset of
        1401                 :            :         // constant keys.
        1402                 :            :         // See _PyCode_ConstantKey() for detail.
        1403                 :            :         assert(PyTuple_CheckExact(key));
        1404                 :            :         assert(PyTuple_GET_SIZE(key) == 2);
        1405                 :            :
        1406                 :         36 :         Py_ssize_t len = PySet_GET_SIZE(o);
        1407         [ -  + ]:         36 :         if (len == 0) {  // empty frozenset should not be re-created.
        1408                 :          0 :             return key;
        1409                 :            :         }
        1410                 :         36 :         PyObject *tuple = PyTuple_New(len);
        1411         [ -  + ]:         36 :         if (tuple == NULL) {
        1412                 :          0 :             Py_DECREF(key);
        1413                 :          0 :             return NULL;
        1414                 :            :         }
        1415                 :         36 :         Py_ssize_t i = 0, pos = 0;
        1416                 :            :         PyObject *item;
        1417                 :            :         Py_hash_t hash;
        1418         [ +  + ]:        160 :         while (_PySet_NextEntry(o, &pos, &item, &hash)) {
        1419                 :        124 :             PyObject *k = merge_consts_recursive(const_cache, item);
        1420         [ -  + ]:        124 :             if (k == NULL) {
        1421                 :          0 :                 Py_DECREF(tuple);
        1422                 :          0 :                 Py_DECREF(key);
        1423                 :          0 :                 return NULL;
        1424                 :            :             }
        1425                 :            :             PyObject *u;
        1426         [ -  + ]:        124 :             if (PyTuple_CheckExact(k)) {
        1427                 :          0 :                 u = Py_NewRef(PyTuple_GET_ITEM(k, 1));
        1428                 :          0 :                 Py_DECREF(k);
        1429                 :            :             }
        1430                 :            :             else {
        1431                 :        124 :                 u = k;
        1432                 :            :             }
        1433                 :        124 :             PyTuple_SET_ITEM(tuple, i, u);  // Steals reference of u.
        1434                 :        124 :             i++;
        1435                 :            :         }
        1436                 :            :
        1437                 :            :         // Instead of rewriting o, we create new frozenset and embed in the
        1438                 :            :         // key tuple.  Caller should get merged frozenset from the key tuple.
        1439                 :         36 :         PyObject *new = PyFrozenSet_New(tuple);
        1440                 :         36 :         Py_DECREF(tuple);
        1441         [ -  + ]:         36 :         if (new == NULL) {
        1442                 :          0 :             Py_DECREF(key);
        1443                 :          0 :             return NULL;
        1444                 :            :         }
        1445                 :            :         assert(PyTuple_GET_ITEM(key, 1) == o);
        1446                 :         36 :         Py_DECREF(o);
        1447                 :         36 :         PyTuple_SET_ITEM(key, 1, new);
        1448                 :            :     }
        1449                 :            :
        1450                 :      41975 :     return key;
        1451                 :            : }
        1452                 :            :
        1453                 :            : static Py_ssize_t
        1454                 :      65284 : compiler_add_const(PyObject *const_cache, struct compiler_unit *u, PyObject *o)
        1455                 :            : {
        1456                 :            :     assert(PyDict_CheckExact(const_cache));
        1457                 :      65284 :     PyObject *key = merge_consts_recursive(const_cache, o);
        1458         [ -  + ]:      65284 :     if (key == NULL) {
        1459                 :          0 :         return ERROR;
        1460                 :            :     }
        1461                 :            :
        1462                 :      65284 :     Py_ssize_t arg = dict_add_o(u->u_consts, key);
        1463                 :      65284 :     Py_DECREF(key);
        1464                 :      65284 :     return arg;
        1465                 :            : }
        1466                 :            :
        1467                 :            : static int
        1468                 :      57553 : compiler_addop_load_const(PyObject *const_cache, struct compiler_unit *u, location loc, PyObject *o)
        1469                 :            : {
        1470                 :      57553 :     Py_ssize_t arg = compiler_add_const(const_cache, u, o);
        1471         [ -  + ]:      57553 :     if (arg < 0) {
        1472                 :          0 :         return ERROR;
        1473                 :            :     }
        1474                 :      57553 :     return codegen_addop_i(&u->u_instr_sequence, LOAD_CONST, arg, loc);
        1475                 :            : }
        1476                 :            :
        1477                 :            : static int
        1478                 :      71669 : compiler_addop_o(struct compiler_unit *u, location loc,
        1479                 :            :                  int opcode, PyObject *dict, PyObject *o)
        1480                 :            : {
        1481                 :      71669 :     Py_ssize_t arg = dict_add_o(dict, o);
        1482         [ -  + ]:      71669 :     if (arg < 0) {
        1483                 :          0 :         return ERROR;
        1484                 :            :     }
        1485                 :      71669 :     return codegen_addop_i(&u->u_instr_sequence, opcode, arg, loc);
        1486                 :            : }
        1487                 :            :
        1488                 :            : static int
        1489                 :      32372 : compiler_addop_name(struct compiler_unit *u, location loc,
        1490                 :            :                     int opcode, PyObject *dict, PyObject *o)
        1491                 :            : {
        1492                 :      32372 :     PyObject *mangled = _Py_Mangle(u->u_private, o);
        1493         [ -  + ]:      32372 :     if (!mangled) {
        1494                 :          0 :         return ERROR;
        1495                 :            :     }
        1496                 :      32372 :     Py_ssize_t arg = dict_add_o(dict, mangled);
        1497                 :      32372 :     Py_DECREF(mangled);
        1498         [ -  + ]:      32372 :     if (arg < 0) {
        1499                 :          0 :         return ERROR;
        1500                 :            :     }
        1501         [ +  + ]:      32372 :     if (opcode == LOAD_ATTR) {
        1502                 :      16077 :         arg <<= 1;
        1503                 :            :     }
        1504         [ +  + ]:      32372 :     if (opcode == LOAD_METHOD) {
        1505                 :      11010 :         opcode = LOAD_ATTR;
        1506                 :      11010 :         arg <<= 1;
        1507                 :      11010 :         arg |= 1;
        1508                 :            :     }
        1509                 :      32372 :     return codegen_addop_i(&u->u_instr_sequence, opcode, arg, loc);
        1510                 :            : }
        1511                 :            :
        1512                 :            : /* Add an opcode with an integer argument */
        1513                 :            : static int
        1514                 :     289336 : codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc)
        1515                 :            : {
        1516                 :            :     /* oparg value is unsigned, but a signed C int is usually used to store
        1517                 :            :        it in the C code (like Python/ceval.c).
        1518                 :            :
        1519                 :            :        Limit to 32-bit signed C int (rather than INT_MAX) for portability.
        1520                 :            :
        1521                 :            :        The argument of a concrete bytecode instruction is limited to 8-bit.
        1522                 :            :        EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */
        1523                 :            :
        1524                 :     289336 :     int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
        1525                 :     289336 :     return instr_sequence_addop(seq, opcode, oparg_, loc);
        1526                 :            : }
        1527                 :            :
        1528                 :            : static int
        1529                 :      28995 : codegen_addop_j(instr_sequence *seq, location loc,
        1530                 :            :                 int opcode, jump_target_label target)
        1531                 :            : {
        1532                 :            :     assert(IS_LABEL(target));
        1533                 :            :     assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode));
        1534                 :      28995 :     return instr_sequence_addop(seq, opcode, target.id, loc);
        1535                 :            : }
        1536                 :            :
        1537                 :            : #define ADDOP(C, LOC, OP) \
        1538                 :            :     RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
        1539                 :            :
        1540                 :            : #define ADDOP_IN_SCOPE(C, LOC, OP) { \
        1541                 :            :     if (codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)) < 0) { \
        1542                 :            :         compiler_exit_scope(C); \
        1543                 :            :         return ERROR; \
        1544                 :            :     } \
        1545                 :            : }
        1546                 :            :
        1547                 :            : #define ADDOP_LOAD_CONST(C, LOC, O) \
        1548                 :            :     RETURN_IF_ERROR(compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), (O)))
        1549                 :            :
        1550                 :            : /* Same as ADDOP_LOAD_CONST, but steals a reference. */
        1551                 :            : #define ADDOP_LOAD_CONST_NEW(C, LOC, O) { \
        1552                 :            :     PyObject *__new_const = (O); \
        1553                 :            :     if (__new_const == NULL) { \
        1554                 :            :         return ERROR; \
        1555                 :            :     } \
        1556                 :            :     if (compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), __new_const) < 0) { \
        1557                 :            :         Py_DECREF(__new_const); \
        1558                 :            :         return ERROR; \
        1559                 :            :     } \
        1560                 :            :     Py_DECREF(__new_const); \
        1561                 :            : }
        1562                 :            :
        1563                 :            : #define ADDOP_N(C, LOC, OP, O, TYPE) { \
        1564                 :            :     assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */ \
        1565                 :            :     if (compiler_addop_o((C)->u, (LOC), (OP), (C)->u->u_ ## TYPE, (O)) < 0) { \
        1566                 :            :         Py_DECREF((O)); \
        1567                 :            :         return ERROR; \
        1568                 :            :     } \
        1569                 :            :     Py_DECREF((O)); \
        1570                 :            : }
        1571                 :            :
        1572                 :            : #define ADDOP_NAME(C, LOC, OP, O, TYPE) \
        1573                 :            :     RETURN_IF_ERROR(compiler_addop_name((C)->u, (LOC), (OP), (C)->u->u_ ## TYPE, (O)))
        1574                 :            :
        1575                 :            : #define ADDOP_I(C, LOC, OP, O) \
        1576                 :            :     RETURN_IF_ERROR(codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
        1577                 :            :
        1578                 :            : #define ADDOP_JUMP(C, LOC, OP, O) \
        1579                 :            :     RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O)))
        1580                 :            :
        1581                 :            : #define ADDOP_COMPARE(C, LOC, CMP) \
        1582                 :            :     RETURN_IF_ERROR(compiler_addcompare((C), (LOC), (cmpop_ty)(CMP)))
        1583                 :            :
        1584                 :            : #define ADDOP_BINARY(C, LOC, BINOP) \
        1585                 :            :     RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false))
        1586                 :            :
        1587                 :            : #define ADDOP_INPLACE(C, LOC, BINOP) \
        1588                 :            :     RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true))
        1589                 :            :
        1590                 :            : #define ADD_YIELD_FROM(C, LOC, await) \
        1591                 :            :     RETURN_IF_ERROR(compiler_add_yield_from((C), (LOC), (await)))
        1592                 :            :
        1593                 :            : #define POP_EXCEPT_AND_RERAISE(C, LOC) \
        1594                 :            :     RETURN_IF_ERROR(compiler_pop_except_and_reraise((C), (LOC)))
        1595                 :            :
        1596                 :            : #define ADDOP_YIELD(C, LOC) \
        1597                 :            :     RETURN_IF_ERROR(addop_yield((C), (LOC)))
        1598                 :            :
        1599                 :            : /* VISIT and VISIT_SEQ takes an ASDL type as their second argument.  They use
        1600                 :            :    the ASDL name to synthesize the name of the C type and the visit function.
        1601                 :            : */
        1602                 :            :
        1603                 :            : #define VISIT(C, TYPE, V) \
        1604                 :            :     RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), (V)));
        1605                 :            :
        1606                 :            : #define VISIT_IN_SCOPE(C, TYPE, V) {\
        1607                 :            :     if (compiler_visit_ ## TYPE((C), (V)) < 0) { \
        1608                 :            :         compiler_exit_scope(C); \
        1609                 :            :         return ERROR; \
        1610                 :            :     } \
        1611                 :            : }
        1612                 :            :
        1613                 :            : #define VISIT_SEQ(C, TYPE, SEQ) { \
        1614                 :            :     int _i; \
        1615                 :            :     asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \
        1616                 :            :     for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
        1617                 :            :         TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
        1618                 :            :         RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), elt)); \
        1619                 :            :     } \
        1620                 :            : }
        1621                 :            :
        1622                 :            : #define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \
        1623                 :            :     int _i; \
        1624                 :            :     asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \
        1625                 :            :     for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
        1626                 :            :         TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
        1627                 :            :         if (compiler_visit_ ## TYPE((C), elt) < 0) { \
        1628                 :            :             compiler_exit_scope(C); \
        1629                 :            :             return ERROR; \
        1630                 :            :         } \
        1631                 :            :     } \
        1632                 :            : }
        1633                 :            :
        1634                 :            :
        1635                 :            : static int
        1636                 :       8041 : compiler_enter_scope(struct compiler *c, identifier name,
        1637                 :            :                      int scope_type, void *key, int lineno)
        1638                 :            : {
        1639                 :       8041 :     location loc = LOCATION(lineno, lineno, 0, 0);
        1640                 :            :
        1641                 :            :     struct compiler_unit *u;
        1642                 :            :
        1643                 :       8041 :     u = (struct compiler_unit *)PyObject_Calloc(1, sizeof(
        1644                 :            :                                             struct compiler_unit));
        1645         [ -  + ]:       8041 :     if (!u) {
        1646                 :          0 :         PyErr_NoMemory();
        1647                 :          0 :         return ERROR;
        1648                 :            :     }
        1649                 :       8041 :     u->u_scope_type = scope_type;
        1650                 :       8041 :     u->u_argcount = 0;
        1651                 :       8041 :     u->u_posonlyargcount = 0;
        1652                 :       8041 :     u->u_kwonlyargcount = 0;
        1653                 :       8041 :     u->u_ste = PySymtable_Lookup(c->c_st, key);
        1654         [ -  + ]:       8041 :     if (!u->u_ste) {
        1655                 :          0 :         compiler_unit_free(u);
        1656                 :          0 :         return ERROR;
        1657                 :            :     }
        1658                 :       8041 :     u->u_name = Py_NewRef(name);
        1659                 :       8041 :     u->u_varnames = list2dict(u->u_ste->ste_varnames);
        1660                 :       8041 :     u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0);
        1661   [ +  -  -  + ]:       8041 :     if (!u->u_varnames || !u->u_cellvars) {
        1662                 :          0 :         compiler_unit_free(u);
        1663                 :          0 :         return ERROR;
        1664                 :            :     }
        1665         [ +  + ]:       8041 :     if (u->u_ste->ste_needs_class_closure) {
        1666                 :            :         /* Cook up an implicit __class__ cell. */
        1667                 :            :         int res;
        1668                 :            :         assert(u->u_scope_type == COMPILER_SCOPE_CLASS);
        1669                 :            :         assert(PyDict_GET_SIZE(u->u_cellvars) == 0);
        1670                 :        112 :         res = PyDict_SetItem(u->u_cellvars, &_Py_ID(__class__),
        1671                 :            :                              _PyLong_GetZero());
        1672         [ -  + ]:        112 :         if (res < 0) {
        1673                 :          0 :             compiler_unit_free(u);
        1674                 :          0 :             return ERROR;
        1675                 :            :         }
        1676                 :            :     }
        1677                 :            :
        1678                 :       8041 :     u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
        1679                 :            :                                PyDict_GET_SIZE(u->u_cellvars));
        1680         [ -  + ]:       8041 :     if (!u->u_freevars) {
        1681                 :          0 :         compiler_unit_free(u);
        1682                 :          0 :         return ERROR;
        1683                 :            :     }
        1684                 :            :
        1685                 :       8041 :     u->u_nfblocks = 0;
        1686                 :       8041 :     u->u_firstlineno = lineno;
        1687                 :       8041 :     u->u_consts = PyDict_New();
        1688         [ -  + ]:       8041 :     if (!u->u_consts) {
        1689                 :          0 :         compiler_unit_free(u);
        1690                 :          0 :         return ERROR;
        1691                 :            :     }
        1692                 :       8041 :     u->u_names = PyDict_New();
        1693         [ -  + ]:       8041 :     if (!u->u_names) {
        1694                 :          0 :         compiler_unit_free(u);
        1695                 :          0 :         return ERROR;
        1696                 :            :     }
        1697                 :            :
        1698                 :       8041 :     u->u_private = NULL;
        1699                 :            :
        1700                 :            :     /* Push the old compiler_unit on the stack. */
        1701         [ +  + ]:       8041 :     if (c->u) {
        1702                 :       7722 :         PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL);
        1703   [ +  -  -  + ]:       7722 :         if (!capsule || PyList_Append(c->c_stack, capsule) < 0) {
        1704                 :          0 :             Py_XDECREF(capsule);
        1705                 :          0 :             compiler_unit_free(u);
        1706                 :          0 :             return ERROR;
        1707                 :            :         }
        1708                 :       7722 :         Py_DECREF(capsule);
        1709                 :       7722 :         u->u_private = Py_XNewRef(c->u->u_private);
        1710                 :            :     }
        1711                 :       8041 :     c->u = u;
        1712                 :            :
        1713                 :       8041 :     c->c_nestlevel++;
        1714                 :            :
        1715         [ +  + ]:       8041 :     if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
        1716                 :        319 :         loc.lineno = 0;
        1717                 :            :     }
        1718                 :            :     else {
        1719         [ -  + ]:       7722 :         RETURN_IF_ERROR(compiler_set_qualname(c));
        1720                 :            :     }
        1721         [ -  + ]:       8041 :     ADDOP_I(c, loc, RESUME, 0);
        1722                 :            :
        1723         [ +  + ]:       8041 :     if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
        1724                 :        319 :         loc.lineno = -1;
        1725                 :            :     }
        1726                 :       8041 :     return SUCCESS;
        1727                 :            : }
        1728                 :            :
        1729                 :            : static void
        1730                 :       8041 : compiler_exit_scope(struct compiler *c)
        1731                 :            : {
        1732                 :            :     // Don't call PySequence_DelItem() with an exception raised
        1733                 :       8041 :     PyObject *exc = PyErr_GetRaisedException();
        1734                 :            :
        1735                 :       8041 :     c->c_nestlevel--;
        1736                 :       8041 :     compiler_unit_free(c->u);
        1737                 :            :     /* Restore c->u to the parent unit. */
        1738                 :       8041 :     Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1;
        1739         [ +  + ]:       8041 :     if (n >= 0) {
        1740                 :       7722 :         PyObject *capsule = PyList_GET_ITEM(c->c_stack, n);
        1741                 :       7722 :         c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
        1742                 :            :         assert(c->u);
        1743                 :            :         /* we are deleting from a list so this really shouldn't fail */
        1744         [ -  + ]:       7722 :         if (PySequence_DelItem(c->c_stack, n) < 0) {
        1745                 :          0 :             _PyErr_WriteUnraisableMsg("on removing the last compiler "
        1746                 :            :                                       "stack item", NULL);
        1747                 :            :         }
        1748                 :            :     }
        1749                 :            :     else {
        1750                 :        319 :         c->u = NULL;
        1751                 :            :     }
        1752                 :            :
        1753                 :       8041 :     PyErr_SetRaisedException(exc);
        1754                 :       8041 : }
        1755                 :            :
        1756                 :            : /* Search if variable annotations are present statically in a block. */
        1757                 :            :
        1758                 :            : static bool
        1759                 :       2106 : find_ann(asdl_stmt_seq *stmts)
        1760                 :            : {
        1761                 :       2106 :     int i, j, res = 0;
        1762                 :            :     stmt_ty st;
        1763                 :            :
        1764   [ +  +  +  + ]:      14783 :     for (i = 0; i < asdl_seq_LEN(stmts); i++) {
        1765                 :      12678 :         st = (stmt_ty)asdl_seq_GET(stmts, i);
        1766   [ +  +  -  +  :      12678 :         switch (st->kind) {
              +  +  -  +  -
                          + ]
        1767                 :          1 :         case AnnAssign_kind:
        1768                 :          1 :             return true;
        1769                 :         34 :         case For_kind:
        1770   [ +  -  -  + ]:         68 :             res = find_ann(st->v.For.body) ||
        1771                 :         34 :                   find_ann(st->v.For.orelse);
        1772                 :         34 :             break;
        1773                 :          0 :         case AsyncFor_kind:
        1774   [ #  #  #  # ]:          0 :             res = find_ann(st->v.AsyncFor.body) ||
        1775                 :          0 :                   find_ann(st->v.AsyncFor.orelse);
        1776                 :          0 :             break;
        1777                 :          1 :         case While_kind:
        1778   [ +  -  -  + ]:          2 :             res = find_ann(st->v.While.body) ||
        1779                 :          1 :                   find_ann(st->v.While.orelse);
        1780                 :          1 :             break;
        1781                 :        310 :         case If_kind:
        1782   [ +  -  -  + ]:        620 :             res = find_ann(st->v.If.body) ||
        1783                 :        310 :                   find_ann(st->v.If.orelse);
        1784                 :        310 :             break;
        1785                 :          1 :         case With_kind:
        1786                 :          1 :             res = find_ann(st->v.With.body);
        1787                 :          1 :             break;
        1788                 :          0 :         case AsyncWith_kind:
        1789                 :          0 :             res = find_ann(st->v.AsyncWith.body);
        1790                 :          0 :             break;
        1791                 :        105 :         case Try_kind:
        1792   [ +  +  +  + ]:        210 :             for (j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) {
        1793                 :        105 :                 excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
        1794                 :            :                     st->v.Try.handlers, j);
        1795         [ -  + ]:        105 :                 if (find_ann(handler->v.ExceptHandler.body)) {
        1796                 :          0 :                     return true;
        1797                 :            :                 }
        1798                 :            :             }
        1799         [ +  - ]:        210 :             res = find_ann(st->v.Try.body) ||
        1800   [ +  -  -  + ]:        210 :                   find_ann(st->v.Try.finalbody) ||
        1801                 :        105 :                   find_ann(st->v.Try.orelse);
        1802                 :        105 :             break;
        1803                 :          0 :         case TryStar_kind:
        1804   [ #  #  #  # ]:          0 :             for (j = 0; j < asdl_seq_LEN(st->v.TryStar.handlers); j++) {
        1805                 :          0 :                 excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
        1806                 :            :                     st->v.TryStar.handlers, j);
        1807         [ #  # ]:          0 :                 if (find_ann(handler->v.ExceptHandler.body)) {
        1808                 :          0 :                     return true;
        1809                 :            :                 }
        1810                 :            :             }
        1811         [ #  # ]:          0 :             res = find_ann(st->v.TryStar.body) ||
        1812   [ #  #  #  # ]:          0 :                   find_ann(st->v.TryStar.finalbody) ||
        1813                 :          0 :                   find_ann(st->v.TryStar.orelse);
        1814                 :          0 :             break;
        1815                 :      12226 :         default:
        1816                 :      12226 :             res = false;
        1817                 :            :         }
        1818         [ -  + ]:      12677 :         if (res) {
        1819                 :          0 :             break;
        1820                 :            :         }
        1821                 :            :     }
        1822                 :       2105 :     return res;
        1823                 :            : }
        1824                 :            :
        1825                 :            : /*
        1826                 :            :  * Frame block handling functions
        1827                 :            :  */
        1828                 :            :
        1829                 :            : static int
        1830                 :       6394 : compiler_push_fblock(struct compiler *c, location loc,
        1831                 :            :                      enum fblocktype t, jump_target_label block_label,
        1832                 :            :                      jump_target_label exit, void *datum)
        1833                 :            : {
        1834                 :            :     struct fblockinfo *f;
        1835         [ -  + ]:       6394 :     if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
        1836                 :          0 :         return compiler_error(c, loc, "too many statically nested blocks");
        1837                 :            :     }
        1838                 :       6394 :     f = &c->u->u_fblock[c->u->u_nfblocks++];
        1839                 :       6394 :     f->fb_type = t;
        1840                 :       6394 :     f->fb_block = block_label;
        1841                 :       6394 :     f->fb_exit = exit;
        1842                 :       6394 :     f->fb_datum = datum;
        1843                 :       6394 :     return SUCCESS;
        1844                 :            : }
        1845                 :            :
        1846                 :            : static void
        1847                 :       6394 : compiler_pop_fblock(struct compiler *c, enum fblocktype t, jump_target_label block_label)
        1848                 :            : {
        1849                 :       6394 :     struct compiler_unit *u = c->u;
        1850                 :            :     assert(u->u_nfblocks > 0);
        1851                 :       6394 :     u->u_nfblocks--;
        1852                 :            :     assert(u->u_fblock[u->u_nfblocks].fb_type == t);
        1853                 :            :     assert(SAME_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label));
        1854                 :       6394 : }
        1855                 :            :
        1856                 :            : static int
        1857                 :        481 : compiler_call_exit_with_nones(struct compiler *c, location loc)
        1858                 :            : {
        1859         [ -  + ]:        481 :     ADDOP_LOAD_CONST(c, loc, Py_None);
        1860         [ -  + ]:        481 :     ADDOP_LOAD_CONST(c, loc, Py_None);
        1861         [ -  + ]:        481 :     ADDOP_LOAD_CONST(c, loc, Py_None);
        1862         [ -  + ]:        481 :     ADDOP_I(c, loc, CALL, 2);
        1863                 :        481 :     return SUCCESS;
        1864                 :            : }
        1865                 :            :
        1866                 :            : static int
        1867                 :        195 : compiler_add_yield_from(struct compiler *c, location loc, int await)
        1868                 :            : {
        1869         [ -  + ]:        195 :     NEW_JUMP_TARGET_LABEL(c, send);
        1870         [ -  + ]:        195 :     NEW_JUMP_TARGET_LABEL(c, fail);
        1871         [ -  + ]:        195 :     NEW_JUMP_TARGET_LABEL(c, exit);
        1872                 :            :
        1873         [ -  + ]:        195 :     USE_LABEL(c, send);
        1874         [ -  + ]:        195 :     ADDOP_JUMP(c, loc, SEND, exit);
        1875                 :            :     // Set up a virtual try/except to handle when StopIteration is raised during
        1876                 :            :     // a close or throw call. The only way YIELD_VALUE raises if they do!
        1877         [ -  + ]:        195 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
        1878         [ -  + ]:        195 :     ADDOP_I(c, loc, YIELD_VALUE, 0);
        1879         [ -  + ]:        195 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        1880   [ +  +  -  + ]:        195 :     ADDOP_I(c, loc, RESUME, await ? 3 : 2);
        1881         [ -  + ]:        195 :     ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
        1882                 :            :
        1883         [ -  + ]:        195 :     USE_LABEL(c, fail);
        1884         [ -  + ]:        195 :     ADDOP(c, loc, CLEANUP_THROW);
        1885                 :            :
        1886         [ -  + ]:        195 :     USE_LABEL(c, exit);
        1887         [ -  + ]:        195 :     ADDOP_I(c, loc, SWAP, 2);
        1888         [ -  + ]:        195 :     ADDOP(c, loc, POP_TOP);
        1889                 :        195 :     return SUCCESS;
        1890                 :            : }
        1891                 :            :
        1892                 :            : static int
        1893                 :       1878 : compiler_pop_except_and_reraise(struct compiler *c, location loc)
        1894                 :            : {
        1895                 :            :     /* Stack contents
        1896                 :            :      * [exc_info, lasti, exc]            COPY        3
        1897                 :            :      * [exc_info, lasti, exc, exc_info]  POP_EXCEPT
        1898                 :            :      * [exc_info, lasti, exc]            RERAISE      1
        1899                 :            :      * (exception_unwind clears the stack)
        1900                 :            :      */
        1901                 :            :
        1902         [ -  + ]:       1878 :     ADDOP_I(c, loc, COPY, 3);
        1903         [ -  + ]:       1878 :     ADDOP(c, loc, POP_EXCEPT);
        1904         [ -  + ]:       1878 :     ADDOP_I(c, loc, RERAISE, 1);
        1905                 :       1878 :     return SUCCESS;
        1906                 :            : }
        1907                 :            :
        1908                 :            : /* Unwind a frame block.  If preserve_tos is true, the TOS before
        1909                 :            :  * popping the blocks will be restored afterwards, unless another
        1910                 :            :  * return, break or continue is found. In which case, the TOS will
        1911                 :            :  * be popped.
        1912                 :            :  */
        1913                 :            : static int
        1914                 :       1586 : compiler_unwind_fblock(struct compiler *c, location *ploc,
        1915                 :            :                        struct fblockinfo *info, int preserve_tos)
        1916                 :            : {
        1917   [ +  +  +  +  :       1586 :     switch (info->fb_type) {
                 +  +  +  -
                          - ]
        1918                 :        606 :         case WHILE_LOOP:
        1919                 :            :         case EXCEPTION_HANDLER:
        1920                 :            :         case EXCEPTION_GROUP_HANDLER:
        1921                 :            :         case ASYNC_COMPREHENSION_GENERATOR:
        1922                 :        606 :             return SUCCESS;
        1923                 :            :
        1924                 :        224 :         case FOR_LOOP:
        1925                 :            :             /* Pop the iterator */
        1926         [ +  + ]:        224 :             if (preserve_tos) {
        1927         [ -  + ]:         71 :                 ADDOP_I(c, *ploc, SWAP, 2);
        1928                 :            :             }
        1929         [ -  + ]:        224 :             ADDOP(c, *ploc, POP_TOP);
        1930                 :        224 :             return SUCCESS;
        1931                 :            :
        1932                 :        223 :         case TRY_EXCEPT:
        1933         [ -  + ]:        223 :             ADDOP(c, *ploc, POP_BLOCK);
        1934                 :        223 :             return SUCCESS;
        1935                 :            :
        1936                 :         49 :         case FINALLY_TRY:
        1937                 :            :             /* This POP_BLOCK gets the line number of the unwinding statement */
        1938         [ -  + ]:         49 :             ADDOP(c, *ploc, POP_BLOCK);
        1939         [ +  + ]:         49 :             if (preserve_tos) {
        1940         [ -  + ]:         44 :                 RETURN_IF_ERROR(
        1941                 :            :                     compiler_push_fblock(c, *ploc, POP_VALUE, NO_LABEL, NO_LABEL, NULL));
        1942                 :            :             }
        1943                 :            :             /* Emit the finally block */
        1944   [ -  +  +  -  :        122 :             VISIT_SEQ(c, stmt, info->fb_datum);
                       +  + ]
        1945         [ +  + ]:         49 :             if (preserve_tos) {
        1946                 :         44 :                 compiler_pop_fblock(c, POP_VALUE, NO_LABEL);
        1947                 :            :             }
        1948                 :            :             /* The finally block should appear to execute after the
        1949                 :            :              * statement causing the unwinding, so make the unwinding
        1950                 :            :              * instruction artificial */
        1951                 :         49 :             *ploc = NO_LOCATION;
        1952                 :         49 :             return SUCCESS;
        1953                 :            :
        1954                 :          1 :         case FINALLY_END:
        1955         [ -  + ]:          1 :             if (preserve_tos) {
        1956         [ #  # ]:          0 :                 ADDOP_I(c, *ploc, SWAP, 2);
        1957                 :            :             }
        1958         [ -  + ]:          1 :             ADDOP(c, *ploc, POP_TOP); /* exc_value */
        1959         [ -  + ]:          1 :             if (preserve_tos) {
        1960         [ #  # ]:          0 :                 ADDOP_I(c, *ploc, SWAP, 2);
        1961                 :            :             }
        1962         [ -  + ]:          1 :             ADDOP(c, *ploc, POP_BLOCK);
        1963         [ -  + ]:          1 :             ADDOP(c, *ploc, POP_EXCEPT);
        1964                 :          1 :             return SUCCESS;
        1965                 :            :
        1966                 :         92 :         case WITH:
        1967                 :            :         case ASYNC_WITH:
        1968                 :         92 :             *ploc = LOC((stmt_ty)info->fb_datum);
        1969         [ -  + ]:         92 :             ADDOP(c, *ploc, POP_BLOCK);
        1970         [ +  + ]:         92 :             if (preserve_tos) {
        1971         [ -  + ]:         76 :                 ADDOP_I(c, *ploc, SWAP, 2);
        1972                 :            :             }
        1973         [ -  + ]:         92 :             RETURN_IF_ERROR(compiler_call_exit_with_nones(c, *ploc));
        1974         [ +  + ]:         92 :             if (info->fb_type == ASYNC_WITH) {
        1975         [ -  + ]:          3 :                 ADDOP_I(c, *ploc, GET_AWAITABLE, 2);
        1976         [ -  + ]:          3 :                 ADDOP_LOAD_CONST(c, *ploc, Py_None);
        1977         [ -  + ]:          3 :                 ADD_YIELD_FROM(c, *ploc, 1);
        1978                 :            :             }
        1979         [ -  + ]:         92 :             ADDOP(c, *ploc, POP_TOP);
        1980                 :            :             /* The exit block should appear to execute after the
        1981                 :            :              * statement causing the unwinding, so make the unwinding
        1982                 :            :              * instruction artificial */
        1983                 :         92 :             *ploc = NO_LOCATION;
        1984                 :         92 :             return SUCCESS;
        1985                 :            :
        1986                 :        391 :         case HANDLER_CLEANUP: {
        1987         [ +  + ]:        391 :             if (info->fb_datum) {
        1988         [ -  + ]:         74 :                 ADDOP(c, *ploc, POP_BLOCK);
        1989                 :            :             }
        1990         [ +  + ]:        391 :             if (preserve_tos) {
        1991         [ -  + ]:        121 :                 ADDOP_I(c, *ploc, SWAP, 2);
        1992                 :            :             }
        1993         [ -  + ]:        391 :             ADDOP(c, *ploc, POP_BLOCK);
        1994         [ -  + ]:        391 :             ADDOP(c, *ploc, POP_EXCEPT);
        1995         [ +  + ]:        391 :             if (info->fb_datum) {
        1996         [ -  + ]:         74 :                 ADDOP_LOAD_CONST(c, *ploc, Py_None);
        1997         [ -  + ]:         74 :                 RETURN_IF_ERROR(compiler_nameop(c, *ploc, info->fb_datum, Store));
        1998         [ -  + ]:         74 :                 RETURN_IF_ERROR(compiler_nameop(c, *ploc, info->fb_datum, Del));
        1999                 :            :             }
        2000                 :        391 :             return SUCCESS;
        2001                 :            :         }
        2002                 :          0 :         case POP_VALUE: {
        2003         [ #  # ]:          0 :             if (preserve_tos) {
        2004         [ #  # ]:          0 :                 ADDOP_I(c, *ploc, SWAP, 2);
        2005                 :            :             }
        2006         [ #  # ]:          0 :             ADDOP(c, *ploc, POP_TOP);
        2007                 :          0 :             return SUCCESS;
        2008                 :            :         }
        2009                 :            :     }
        2010                 :          0 :     Py_UNREACHABLE();
        2011                 :            : }
        2012                 :            :
        2013                 :            : /** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */
        2014                 :            : static int
        2015                 :       7659 : compiler_unwind_fblock_stack(struct compiler *c, location *ploc,
        2016                 :            :                              int preserve_tos, struct fblockinfo **loop)
        2017                 :            : {
        2018         [ +  + ]:       7659 :     if (c->u->u_nfblocks == 0) {
        2019                 :       5842 :         return SUCCESS;
        2020                 :            :     }
        2021                 :       1817 :     struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1];
        2022         [ -  + ]:       1817 :     if (top->fb_type == EXCEPTION_GROUP_HANDLER) {
        2023                 :          0 :         return compiler_error(
        2024                 :            :             c, *ploc, "'break', 'continue' and 'return' cannot appear in an except* block");
        2025                 :            :     }
        2026   [ +  +  +  +  :       1817 :     if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) {
                       +  + ]
        2027                 :        506 :         *loop = top;
        2028                 :        506 :         return SUCCESS;
        2029                 :            :     }
        2030                 :       1311 :     struct fblockinfo copy = *top;
        2031                 :       1311 :     c->u->u_nfblocks--;
        2032         [ -  + ]:       1311 :     RETURN_IF_ERROR(compiler_unwind_fblock(c, ploc, &copy, preserve_tos));
        2033         [ -  + ]:       1311 :     RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, ploc, preserve_tos, loop));
        2034                 :       1311 :     c->u->u_fblock[c->u->u_nfblocks] = copy;
        2035                 :       1311 :     c->u->u_nfblocks++;
        2036                 :       1311 :     return SUCCESS;
        2037                 :            : }
        2038                 :            :
        2039                 :            : /* Compile a sequence of statements, checking for a docstring
        2040                 :            :    and for annotations. */
        2041                 :            :
        2042                 :            : static int
        2043                 :        939 : compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
        2044                 :            : {
        2045                 :        939 :     int i = 0;
        2046                 :            :     stmt_ty st;
        2047                 :            :     PyObject *docstring;
        2048                 :            :
        2049                 :            :     /* Set current line number to the line number of first statement.
        2050                 :            :        This way line number for SETUP_ANNOTATIONS will always
        2051                 :            :        coincide with the line number of first "real" statement in module.
        2052                 :            :        If body is empty, then lineno will be set later in assemble. */
        2053   [ +  +  +  +  :        939 :     if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) {
                       +  - ]
        2054                 :        200 :         st = (stmt_ty)asdl_seq_GET(stmts, 0);
        2055                 :        200 :         loc = LOC(st);
        2056                 :            :     }
        2057                 :            :     /* Every annotated class and module should have __annotations__. */
        2058         [ +  + ]:        939 :     if (find_ann(stmts)) {
        2059         [ -  + ]:          1 :         ADDOP(c, loc, SETUP_ANNOTATIONS);
        2060                 :            :     }
        2061   [ +  +  -  + ]:        939 :     if (!asdl_seq_LEN(stmts)) {
        2062                 :          6 :         return SUCCESS;
        2063                 :            :     }
        2064                 :            :     /* if not -OO mode, set docstring */
        2065         [ +  - ]:        933 :     if (c->c_optimize < 2) {
        2066                 :        933 :         docstring = _PyAST_GetDocString(stmts);
        2067         [ +  + ]:        933 :         if (docstring) {
        2068                 :        564 :             i = 1;
        2069                 :        564 :             st = (stmt_ty)asdl_seq_GET(stmts, 0);
        2070                 :            :             assert(st->kind == Expr_kind);
        2071         [ -  + ]:        564 :             VISIT(c, expr, st->v.Expr.value);
        2072         [ -  + ]:        564 :             RETURN_IF_ERROR(compiler_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
        2073                 :            :         }
        2074                 :            :     }
        2075   [ +  -  +  + ]:      11662 :     for (; i < asdl_seq_LEN(stmts); i++) {
        2076         [ -  + ]:      10729 :         VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
        2077                 :            :     }
        2078                 :        933 :     return SUCCESS;
        2079                 :            : }
        2080                 :            :
        2081                 :            : static int
        2082                 :        319 : compiler_codegen(struct compiler *c, mod_ty mod)
        2083                 :            : {
        2084                 :            :     _Py_DECLARE_STR(anon_module, "<module>");
        2085         [ -  + ]:        319 :     RETURN_IF_ERROR(
        2086                 :            :         compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE,
        2087                 :            :                              mod, 1));
        2088                 :            :
        2089                 :        319 :     location loc = LOCATION(1, 1, 0, 0);
        2090   [ +  +  +  - ]:        319 :     switch (mod->kind) {
        2091                 :        206 :     case Module_kind:
        2092         [ -  + ]:        206 :         if (compiler_body(c, loc, mod->v.Module.body) < 0) {
        2093                 :          0 :             compiler_exit_scope(c);
        2094                 :          0 :             return ERROR;
        2095                 :            :         }
        2096                 :        206 :         break;
        2097                 :         56 :     case Interactive_kind:
        2098         [ -  + ]:         56 :         if (find_ann(mod->v.Interactive.body)) {
        2099         [ #  # ]:          0 :             ADDOP(c, loc, SETUP_ANNOTATIONS);
        2100                 :            :         }
        2101                 :         56 :         c->c_interactive = 1;
        2102   [ -  +  +  -  :        112 :         VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body);
                       +  + ]
        2103                 :         56 :         break;
        2104                 :         57 :     case Expression_kind:
        2105         [ -  + ]:         57 :         VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
        2106                 :         57 :         break;
        2107                 :          0 :     default:
        2108                 :          0 :         PyErr_Format(PyExc_SystemError,
        2109                 :            :                      "module kind %d should not be possible",
        2110                 :          0 :                      mod->kind);
        2111                 :          0 :         return ERROR;
        2112                 :            :     }
        2113                 :        319 :     return SUCCESS;
        2114                 :            : }
        2115                 :            :
        2116                 :            : static PyCodeObject *
        2117                 :        319 : compiler_mod(struct compiler *c, mod_ty mod)
        2118                 :            : {
        2119                 :        319 :     int addNone = mod->kind != Expression_kind;
        2120         [ -  + ]:        319 :     if (compiler_codegen(c, mod) < 0) {
        2121                 :          0 :         return NULL;
        2122                 :            :     }
        2123                 :        319 :     PyCodeObject *co = assemble(c, addNone);
        2124                 :        319 :     compiler_exit_scope(c);
        2125                 :        319 :     return co;
        2126                 :            : }
        2127                 :            :
        2128                 :            : /* The test for LOCAL must come before the test for FREE in order to
        2129                 :            :    handle classes where name is both local and free.  The local var is
        2130                 :            :    a method and the free var is a free var referenced within a method.
        2131                 :            : */
        2132                 :            :
        2133                 :            : static int
        2134                 :        938 : get_ref_type(struct compiler *c, PyObject *name)
        2135                 :            : {
        2136                 :            :     int scope;
        2137   [ +  +  +  + ]:       1160 :     if (c->u->u_scope_type == COMPILER_SCOPE_CLASS &&
        2138                 :        222 :         _PyUnicode_EqualToASCIIString(name, "__class__"))
        2139                 :        208 :         return CELL;
        2140                 :        730 :     scope = _PyST_GetScope(c->u->u_ste, name);
        2141         [ -  + ]:        730 :     if (scope == 0) {
        2142                 :          0 :         PyErr_Format(PyExc_SystemError,
        2143                 :            :                      "_PyST_GetScope(name=%R) failed: "
        2144                 :            :                      "unknown scope in unit %S (%R); "
        2145                 :            :                      "symbols: %R; locals: %R; globals: %R",
        2146                 :            :                      name,
        2147                 :          0 :                      c->u->u_name, c->u->u_ste->ste_id,
        2148                 :          0 :                      c->u->u_ste->ste_symbols, c->u->u_varnames, c->u->u_names);
        2149                 :          0 :         return ERROR;
        2150                 :            :     }
        2151                 :        730 :     return scope;
        2152                 :            : }
        2153                 :            :
        2154                 :            : static int
        2155                 :       1050 : compiler_lookup_arg(PyObject *dict, PyObject *name)
        2156                 :            : {
        2157                 :       1050 :     PyObject *v = PyDict_GetItemWithError(dict, name);
        2158         [ -  + ]:       1050 :     if (v == NULL) {
        2159                 :          0 :         return ERROR;
        2160                 :            :     }
        2161                 :       1050 :     return PyLong_AS_LONG(v);
        2162                 :            : }
        2163                 :            :
        2164                 :            : static int
        2165                 :       7722 : compiler_make_closure(struct compiler *c, location loc,
        2166                 :            :                       PyCodeObject *co, Py_ssize_t flags)
        2167                 :            : {
        2168         [ +  + ]:       7722 :     if (co->co_nfreevars) {
        2169                 :        627 :         int i = PyCode_GetFirstFree(co);
        2170         [ +  + ]:       1565 :         for (; i < co->co_nlocalsplus; ++i) {
        2171                 :            :             /* Bypass com_addop_varname because it will generate
        2172                 :            :                LOAD_DEREF but LOAD_CLOSURE is needed.
        2173                 :            :             */
        2174                 :        938 :             PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
        2175                 :            :
        2176                 :            :             /* Special case: If a class contains a method with a
        2177                 :            :                free variable that has the same name as a method,
        2178                 :            :                the name will be considered free *and* local in the
        2179                 :            :                class.  It should be handled by the closure, as
        2180                 :            :                well as by the normal name lookup logic.
        2181                 :            :             */
        2182                 :        938 :             int reftype = get_ref_type(c, name);
        2183         [ -  + ]:        938 :             if (reftype == -1) {
        2184                 :          0 :                 return ERROR;
        2185                 :            :             }
        2186                 :            :             int arg;
        2187         [ +  + ]:        938 :             if (reftype == CELL) {
        2188                 :        902 :                 arg = compiler_lookup_arg(c->u->u_cellvars, name);
        2189                 :            :             }
        2190                 :            :             else {
        2191                 :         36 :                 arg = compiler_lookup_arg(c->u->u_freevars, name);
        2192                 :            :             }
        2193         [ -  + ]:        938 :             if (arg == -1) {
        2194                 :          0 :                 PyObject *freevars = _PyCode_GetFreevars(co);
        2195         [ #  # ]:          0 :                 if (freevars == NULL) {
        2196                 :          0 :                     PyErr_Clear();
        2197                 :            :                 }
        2198                 :          0 :                 PyErr_Format(PyExc_SystemError,
        2199                 :            :                     "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
        2200                 :            :                     "freevars of code %S: %R",
        2201                 :            :                     name,
        2202                 :            :                     reftype,
        2203                 :          0 :                     c->u->u_name,
        2204                 :            :                     co->co_name,
        2205                 :            :                     freevars);
        2206                 :          0 :                 Py_DECREF(freevars);
        2207                 :          0 :                 return ERROR;
        2208                 :            :             }
        2209         [ -  + ]:        938 :             ADDOP_I(c, loc, LOAD_CLOSURE, arg);
        2210                 :            :         }
        2211                 :        627 :         flags |= 0x08;
        2212         [ -  + ]:        627 :         ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
        2213                 :            :     }
        2214         [ -  + ]:       7722 :     ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
        2215         [ -  + ]:       7722 :     ADDOP_I(c, loc, MAKE_FUNCTION, flags);
        2216                 :       7722 :     return SUCCESS;
        2217                 :            : }
        2218                 :            :
        2219                 :            : static int
        2220                 :       7134 : compiler_decorators(struct compiler *c, asdl_expr_seq* decos)
        2221                 :            : {
        2222         [ +  + ]:       7134 :     if (!decos) {
        2223                 :       6544 :         return SUCCESS;
        2224                 :            :     }
        2225                 :            :
        2226   [ +  -  +  + ]:       1211 :     for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) {
        2227         [ -  + ]:        621 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
        2228                 :            :     }
        2229                 :        590 :     return SUCCESS;
        2230                 :            : }
        2231                 :            :
        2232                 :            : static int
        2233                 :       7134 : compiler_apply_decorators(struct compiler *c, asdl_expr_seq* decos)
        2234                 :            : {
        2235         [ +  + ]:       7134 :     if (!decos) {
        2236                 :       6544 :         return SUCCESS;
        2237                 :            :     }
        2238                 :            :
        2239   [ +  -  +  + ]:       1211 :     for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
        2240                 :        621 :         location loc = LOC((expr_ty)asdl_seq_GET(decos, i));
        2241         [ -  + ]:        621 :         ADDOP_I(c, loc, CALL, 0);
        2242                 :            :     }
        2243                 :        590 :     return SUCCESS;
        2244                 :            : }
        2245                 :            :
        2246                 :            : static int
        2247                 :       6536 : compiler_visit_kwonlydefaults(struct compiler *c, location loc,
        2248                 :            :                               asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
        2249                 :            : {
        2250                 :            :     /* Push a dict of keyword-only default values.
        2251                 :            :
        2252                 :            :        Return -1 on error, 0 if no dict pushed, 1 if a dict is pushed.
        2253                 :            :        */
        2254                 :            :     int i;
        2255                 :       6536 :     PyObject *keys = NULL;
        2256                 :            :
        2257   [ +  -  +  + ]:       7109 :     for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
        2258                 :        573 :         arg_ty arg = asdl_seq_GET(kwonlyargs, i);
        2259                 :        573 :         expr_ty default_ = asdl_seq_GET(kw_defaults, i);
        2260         [ +  + ]:        573 :         if (default_) {
        2261                 :        563 :             PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
        2262         [ -  + ]:        563 :             if (!mangled) {
        2263                 :          0 :                 goto error;
        2264                 :            :             }
        2265         [ +  + ]:        563 :             if (keys == NULL) {
        2266                 :        221 :                 keys = PyList_New(1);
        2267         [ -  + ]:        221 :                 if (keys == NULL) {
        2268                 :          0 :                     Py_DECREF(mangled);
        2269                 :          0 :                     return ERROR;
        2270                 :            :                 }
        2271                 :        221 :                 PyList_SET_ITEM(keys, 0, mangled);
        2272                 :            :             }
        2273                 :            :             else {
        2274                 :        342 :                 int res = PyList_Append(keys, mangled);
        2275                 :        342 :                 Py_DECREF(mangled);
        2276         [ -  + ]:        342 :                 if (res == -1) {
        2277                 :          0 :                     goto error;
        2278                 :            :                 }
        2279                 :            :             }
        2280         [ -  + ]:        563 :             if (compiler_visit_expr(c, default_) < 0) {
        2281                 :          0 :                 goto error;
        2282                 :            :             }
        2283                 :            :         }
        2284                 :            :     }
        2285         [ +  + ]:       6536 :     if (keys != NULL) {
        2286                 :        221 :         Py_ssize_t default_count = PyList_GET_SIZE(keys);
        2287                 :        221 :         PyObject *keys_tuple = PyList_AsTuple(keys);
        2288                 :        221 :         Py_DECREF(keys);
        2289   [ -  +  -  + ]:        221 :         ADDOP_LOAD_CONST_NEW(c, loc, keys_tuple);
        2290         [ -  + ]:        221 :         ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, default_count);
        2291                 :            :         assert(default_count > 0);
        2292                 :        221 :         return 1;
        2293                 :            :     }
        2294                 :            :     else {
        2295                 :       6315 :         return 0;
        2296                 :            :     }
        2297                 :            :
        2298                 :          0 : error:
        2299                 :          0 :     Py_XDECREF(keys);
        2300                 :          0 :     return ERROR;
        2301                 :            : }
        2302                 :            :
        2303                 :            : static int
        2304                 :          0 : compiler_visit_annexpr(struct compiler *c, expr_ty annotation)
        2305                 :            : {
        2306                 :          0 :     location loc = LOC(annotation);
        2307   [ #  #  #  # ]:          0 :     ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation));
        2308                 :          0 :     return SUCCESS;
        2309                 :            : }
        2310                 :            :
        2311                 :            : static int
        2312                 :      19050 : compiler_visit_argannotation(struct compiler *c, identifier id,
        2313                 :            :     expr_ty annotation, Py_ssize_t *annotations_len, location loc)
        2314                 :            : {
        2315         [ +  + ]:      19050 :     if (!annotation) {
        2316                 :      18453 :         return SUCCESS;
        2317                 :            :     }
        2318                 :        597 :     PyObject *mangled = _Py_Mangle(c->u->u_private, id);
        2319         [ -  + ]:        597 :     if (!mangled) {
        2320                 :          0 :         return ERROR;
        2321                 :            :     }
        2322         [ -  + ]:        597 :     ADDOP_LOAD_CONST(c, loc, mangled);
        2323                 :        597 :     Py_DECREF(mangled);
        2324                 :            :
        2325         [ -  + ]:        597 :     if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
        2326         [ #  # ]:          0 :         VISIT(c, annexpr, annotation);
        2327                 :            :     }
        2328                 :            :     else {
        2329         [ -  + ]:        597 :         if (annotation->kind == Starred_kind) {
        2330                 :            :             // *args: *Ts (where Ts is a TypeVarTuple).
        2331                 :            :             // Do [annotation_value] = [*Ts].
        2332                 :            :             // (Note that in theory we could end up here even for an argument
        2333                 :            :             // other than *args, but in practice the grammar doesn't allow it.)
        2334         [ #  # ]:          0 :             VISIT(c, expr, annotation->v.Starred.value);
        2335         [ #  # ]:          0 :             ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1);
        2336                 :            :         }
        2337                 :            :         else {
        2338         [ -  + ]:        597 :             VISIT(c, expr, annotation);
        2339                 :            :         }
        2340                 :            :     }
        2341                 :        597 :     *annotations_len += 2;
        2342                 :        597 :     return SUCCESS;
        2343                 :            : }
        2344                 :            :
        2345                 :            : static int
        2346                 :      19203 : compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args,
        2347                 :            :                               Py_ssize_t *annotations_len, location loc)
        2348                 :            : {
        2349                 :            :     int i;
        2350   [ +  -  +  + ]:      31849 :     for (i = 0; i < asdl_seq_LEN(args); i++) {
        2351                 :      12646 :         arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
        2352         [ -  + ]:      12646 :         RETURN_IF_ERROR(
        2353                 :            :             compiler_visit_argannotation(
        2354                 :            :                         c,
        2355                 :            :                         arg->arg,
        2356                 :            :                         arg->annotation,
        2357                 :            :                         annotations_len,
        2358                 :            :                         loc));
        2359                 :            :     }
        2360                 :      19203 :     return SUCCESS;
        2361                 :            : }
        2362                 :            :
        2363                 :            : static int
        2364                 :       6401 : compiler_visit_annotations(struct compiler *c, location loc,
        2365                 :            :                            arguments_ty args, expr_ty returns)
        2366                 :            : {
        2367                 :            :     /* Push arg annotation names and values.
        2368                 :            :        The expressions are evaluated out-of-order wrt the source code.
        2369                 :            :
        2370                 :            :        Return -1 on error, 0 if no annotations pushed, 1 if a annotations is pushed.
        2371                 :            :        */
        2372                 :       6401 :     Py_ssize_t annotations_len = 0;
        2373                 :            :
        2374         [ -  + ]:       6401 :     RETURN_IF_ERROR(
        2375                 :            :         compiler_visit_argannotations(c, args->args, &annotations_len, loc));
        2376                 :            :
        2377         [ -  + ]:       6401 :     RETURN_IF_ERROR(
        2378                 :            :         compiler_visit_argannotations(c, args->posonlyargs, &annotations_len, loc));
        2379                 :            :
        2380   [ +  +  +  + ]:       6401 :     if (args->vararg && args->vararg->annotation) {
        2381         [ -  + ]:          1 :         RETURN_IF_ERROR(
        2382                 :            :             compiler_visit_argannotation(c, args->vararg->arg,
        2383                 :            :                                          args->vararg->annotation, &annotations_len, loc));
        2384                 :            :     }
        2385                 :            :
        2386         [ -  + ]:       6401 :     RETURN_IF_ERROR(
        2387                 :            :         compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len, loc));
        2388                 :            :
        2389   [ +  +  +  + ]:       6401 :     if (args->kwarg && args->kwarg->annotation) {
        2390         [ -  + ]:          2 :         RETURN_IF_ERROR(
        2391                 :            :             compiler_visit_argannotation(c, args->kwarg->arg,
        2392                 :            :                                          args->kwarg->annotation, &annotations_len, loc));
        2393                 :            :     }
        2394                 :            :
        2395         [ -  + ]:       6401 :     RETURN_IF_ERROR(
        2396                 :            :         compiler_visit_argannotation(c, &_Py_ID(return), returns, &annotations_len, loc));
        2397                 :            :
        2398         [ +  + ]:       6401 :     if (annotations_len) {
        2399         [ -  + ]:        254 :         ADDOP_I(c, loc, BUILD_TUPLE, annotations_len);
        2400                 :        254 :         return 1;
        2401                 :            :     }
        2402                 :            :
        2403                 :       6147 :     return 0;
        2404                 :            : }
        2405                 :            :
        2406                 :            : static int
        2407                 :        998 : compiler_visit_defaults(struct compiler *c, arguments_ty args,
        2408                 :            :                         location loc)
        2409                 :            : {
        2410   [ -  +  +  -  :       2774 :     VISIT_SEQ(c, expr, args->defaults);
                       +  + ]
        2411   [ +  -  -  + ]:        998 :     ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
        2412                 :        998 :     return SUCCESS;
        2413                 :            : }
        2414                 :            :
        2415                 :            : static Py_ssize_t
        2416                 :       6536 : compiler_default_arguments(struct compiler *c, location loc,
        2417                 :            :                            arguments_ty args)
        2418                 :            : {
        2419                 :       6536 :     Py_ssize_t funcflags = 0;
        2420   [ +  -  +  -  :       6536 :     if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
                       +  + ]
        2421         [ -  + ]:        998 :         RETURN_IF_ERROR(compiler_visit_defaults(c, args, loc));
        2422                 :        998 :         funcflags |= 0x01;
        2423                 :            :     }
        2424         [ +  - ]:       6536 :     if (args->kwonlyargs) {
        2425                 :       6536 :         int res = compiler_visit_kwonlydefaults(c, loc,
        2426                 :            :                                                 args->kwonlyargs,
        2427                 :            :                                                 args->kw_defaults);
        2428         [ -  + ]:       6536 :         RETURN_IF_ERROR(res);
        2429         [ +  + ]:       6536 :         if (res > 0) {
        2430                 :        221 :             funcflags |= 0x02;
        2431                 :            :         }
        2432                 :            :     }
        2433                 :       6536 :     return funcflags;
        2434                 :            : }
        2435                 :            :
        2436                 :            : static bool
        2437                 :     135505 : forbidden_name(struct compiler *c, location loc, identifier name,
        2438                 :            :                expr_context_ty ctx)
        2439                 :            : {
        2440   [ +  +  -  + ]:     135505 :     if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
        2441                 :          0 :         compiler_error(c, loc, "cannot assign to __debug__");
        2442                 :          0 :         return true;
        2443                 :            :     }
        2444   [ +  +  -  + ]:     135505 :     if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
        2445                 :          0 :         compiler_error(c, loc, "cannot delete __debug__");
        2446                 :          0 :         return true;
        2447                 :            :     }
        2448                 :     135505 :     return false;
        2449                 :            : }
        2450                 :            :
        2451                 :            : static int
        2452                 :      26067 : compiler_check_debug_one_arg(struct compiler *c, arg_ty arg)
        2453                 :            : {
        2454         [ +  + ]:      26067 :     if (arg != NULL) {
        2455         [ -  + ]:      13520 :         if (forbidden_name(c, LOC(arg), arg->arg, Store)) {
        2456                 :          0 :             return ERROR;
        2457                 :            :         }
        2458                 :            :     }
        2459                 :      26067 :     return SUCCESS;
        2460                 :            : }
        2461                 :            :
        2462                 :            : static int
        2463                 :      19608 : compiler_check_debug_args_seq(struct compiler *c, asdl_arg_seq *args)
        2464                 :            : {
        2465         [ +  - ]:      19608 :     if (args != NULL) {
        2466   [ +  -  +  + ]:      32603 :         for (Py_ssize_t i = 0, n = asdl_seq_LEN(args); i < n; i++) {
        2467         [ -  + ]:      12995 :             RETURN_IF_ERROR(
        2468                 :            :                 compiler_check_debug_one_arg(c, asdl_seq_GET(args, i)));
        2469                 :            :         }
        2470                 :            :     }
        2471                 :      19608 :     return SUCCESS;
        2472                 :            : }
        2473                 :            :
        2474                 :            : static int
        2475                 :       6536 : compiler_check_debug_args(struct compiler *c, arguments_ty args)
        2476                 :            : {
        2477         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->posonlyargs));
        2478         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->args));
        2479         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_one_arg(c, args->vararg));
        2480         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->kwonlyargs));
        2481         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_one_arg(c, args->kwarg));
        2482                 :       6536 :     return SUCCESS;
        2483                 :            : }
        2484                 :            :
        2485                 :            : static inline int
        2486                 :       2390 : insert_instruction(basicblock *block, int pos, struct cfg_instr *instr) {
        2487         [ -  + ]:       2390 :     RETURN_IF_ERROR(basicblock_next_instr(block));
        2488         [ +  + ]:      31932 :     for (int i = block->b_iused - 1; i > pos; i--) {
        2489                 :      29542 :         block->b_instr[i] = block->b_instr[i-1];
        2490                 :            :     }
        2491                 :       2390 :     block->b_instr[pos] = *instr;
        2492                 :       2390 :     return SUCCESS;
        2493                 :            : }
        2494                 :            :
        2495                 :            : static int
        2496                 :        530 : wrap_in_stopiteration_handler(struct compiler *c)
        2497                 :            : {
        2498         [ -  + ]:        530 :     NEW_JUMP_TARGET_LABEL(c, handler);
        2499                 :            :
        2500                 :            :     /* Insert SETUP_CLEANUP at start */
        2501         [ -  + ]:        530 :     RETURN_IF_ERROR(
        2502                 :            :         instr_sequence_insert_instruction(
        2503                 :            :             INSTR_SEQUENCE(c), 0,
        2504                 :            :             SETUP_CLEANUP, handler.id, NO_LOCATION));
        2505                 :            :
        2506         [ -  + ]:        530 :     ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
        2507         [ -  + ]:        530 :     ADDOP(c, NO_LOCATION, RETURN_VALUE);
        2508         [ -  + ]:        530 :     USE_LABEL(c, handler);
        2509         [ -  + ]:        530 :     ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
        2510         [ -  + ]:        530 :     ADDOP_I(c, NO_LOCATION, RERAISE, 1);
        2511                 :        530 :     return SUCCESS;
        2512                 :            : }
        2513                 :            :
        2514                 :            : static int
        2515                 :       6401 : compiler_function(struct compiler *c, stmt_ty s, int is_async)
        2516                 :            : {
        2517                 :            :     PyCodeObject *co;
        2518                 :       6401 :     PyObject *docstring = NULL;
        2519                 :            :     arguments_ty args;
        2520                 :            :     expr_ty returns;
        2521                 :            :     identifier name;
        2522                 :            :     asdl_expr_seq* decos;
        2523                 :            :     asdl_stmt_seq *body;
        2524                 :            :     Py_ssize_t i, funcflags;
        2525                 :            :     int annotations;
        2526                 :            :     int scope_type;
        2527                 :            :     int firstlineno;
        2528                 :            :
        2529         [ +  + ]:       6401 :     if (is_async) {
        2530                 :            :         assert(s->kind == AsyncFunctionDef_kind);
        2531                 :            :
        2532                 :        158 :         args = s->v.AsyncFunctionDef.args;
        2533                 :        158 :         returns = s->v.AsyncFunctionDef.returns;
        2534                 :        158 :         decos = s->v.AsyncFunctionDef.decorator_list;
        2535                 :        158 :         name = s->v.AsyncFunctionDef.name;
        2536                 :        158 :         body = s->v.AsyncFunctionDef.body;
        2537                 :            :
        2538                 :        158 :         scope_type = COMPILER_SCOPE_ASYNC_FUNCTION;
        2539                 :            :     } else {
        2540                 :            :         assert(s->kind == FunctionDef_kind);
        2541                 :            :
        2542                 :       6243 :         args = s->v.FunctionDef.args;
        2543                 :       6243 :         returns = s->v.FunctionDef.returns;
        2544                 :       6243 :         decos = s->v.FunctionDef.decorator_list;
        2545                 :       6243 :         name = s->v.FunctionDef.name;
        2546                 :       6243 :         body = s->v.FunctionDef.body;
        2547                 :            :
        2548                 :       6243 :         scope_type = COMPILER_SCOPE_FUNCTION;
        2549                 :            :     }
        2550                 :            :
        2551         [ -  + ]:       6401 :     RETURN_IF_ERROR(compiler_check_debug_args(c, args));
        2552         [ -  + ]:       6401 :     RETURN_IF_ERROR(compiler_decorators(c, decos));
        2553                 :            :
        2554                 :       6401 :     firstlineno = s->lineno;
        2555   [ +  +  +  - ]:       6401 :     if (asdl_seq_LEN(decos)) {
        2556                 :        573 :         firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
        2557                 :            :     }
        2558                 :            :
        2559                 :       6401 :     location loc = LOC(s);
        2560                 :       6401 :     funcflags = compiler_default_arguments(c, loc, args);
        2561         [ -  + ]:       6401 :     if (funcflags == -1) {
        2562                 :          0 :         return ERROR;
        2563                 :            :     }
        2564                 :       6401 :     annotations = compiler_visit_annotations(c, loc, args, returns);
        2565         [ -  + ]:       6401 :     RETURN_IF_ERROR(annotations);
        2566         [ +  + ]:       6401 :     if (annotations > 0) {
        2567                 :        254 :         funcflags |= 0x04;
        2568                 :            :     }
        2569                 :            :
        2570         [ -  + ]:       6401 :     RETURN_IF_ERROR(
        2571                 :            :         compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno));
        2572                 :            :
        2573                 :            :     /* if not -OO mode, add docstring */
        2574         [ +  - ]:       6401 :     if (c->c_optimize < 2) {
        2575                 :       6401 :         docstring = _PyAST_GetDocString(body);
        2576                 :            :     }
        2577   [ +  +  -  + ]:       6401 :     if (compiler_add_const(c->c_const_cache, c->u, docstring ? docstring : Py_None) < 0) {
        2578                 :          0 :         compiler_exit_scope(c);
        2579                 :          0 :         return ERROR;
        2580                 :            :     }
        2581                 :            :
        2582         [ +  - ]:       6401 :     c->u->u_argcount = asdl_seq_LEN(args->args);
        2583         [ +  - ]:       6401 :     c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
        2584         [ +  - ]:       6401 :     c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
        2585   [ +  -  +  + ]:      25786 :     for (i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) {
        2586         [ -  + ]:      19385 :         VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
        2587                 :            :     }
        2588   [ +  +  +  + ]:       6401 :     if (c->u->u_ste->ste_coroutine || c->u->u_ste->ste_generator) {
        2589         [ -  + ]:        333 :         if (wrap_in_stopiteration_handler(c) < 0) {
        2590                 :          0 :             compiler_exit_scope(c);
        2591                 :          0 :             return ERROR;
        2592                 :            :         }
        2593                 :            :     }
        2594                 :       6401 :     co = assemble(c, 1);
        2595                 :       6401 :     compiler_exit_scope(c);
        2596         [ -  + ]:       6401 :     if (co == NULL) {
        2597                 :          0 :         Py_XDECREF(co);
        2598                 :          0 :         return ERROR;
        2599                 :            :     }
        2600         [ -  + ]:       6401 :     if (compiler_make_closure(c, loc, co, funcflags) < 0) {
        2601                 :          0 :         Py_DECREF(co);
        2602                 :          0 :         return ERROR;
        2603                 :            :     }
        2604                 :       6401 :     Py_DECREF(co);
        2605                 :            :
        2606         [ -  + ]:       6401 :     RETURN_IF_ERROR(compiler_apply_decorators(c, decos));
        2607                 :       6401 :     return compiler_nameop(c, loc, name, Store);
        2608                 :            : }
        2609                 :            :
        2610                 :            : static int
        2611                 :        733 : compiler_class(struct compiler *c, stmt_ty s)
        2612                 :            : {
        2613                 :            :     PyCodeObject *co;
        2614                 :            :     int i, firstlineno;
        2615                 :        733 :     asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
        2616                 :            :
        2617         [ -  + ]:        733 :     RETURN_IF_ERROR(compiler_decorators(c, decos));
        2618                 :            :
        2619                 :        733 :     firstlineno = s->lineno;
        2620   [ +  +  +  - ]:        733 :     if (asdl_seq_LEN(decos)) {
        2621                 :         17 :         firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
        2622                 :            :     }
        2623                 :            :
        2624                 :            :     /* ultimately generate code for:
        2625                 :            :          <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>)
        2626                 :            :        where:
        2627                 :            :          <func> is a zero arg function/closure created from the class body.
        2628                 :            :             It mutates its locals to build the class namespace.
        2629                 :            :          <name> is the class name
        2630                 :            :          <bases> is the positional arguments and *varargs argument
        2631                 :            :          <keywords> is the keyword arguments and **kwds argument
        2632                 :            :        This borrows from compiler_call.
        2633                 :            :     */
        2634                 :            :     /* 1. compile the class body into a code object */
        2635         [ -  + ]:        733 :     RETURN_IF_ERROR(
        2636                 :            :         compiler_enter_scope(c, s->v.ClassDef.name,
        2637                 :            :                              COMPILER_SCOPE_CLASS, (void *)s, firstlineno));
        2638                 :            :
        2639                 :            :     /* this block represents what we do in the new scope */
        2640                 :            :     {
        2641                 :        733 :         location loc = LOCATION(firstlineno, firstlineno, 0, 0);
        2642                 :            :         /* use the class name for name mangling */
        2643                 :        733 :         Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name));
        2644                 :            :         /* load (global) __name__ ... */
        2645         [ -  + ]:        733 :         if (compiler_nameop(c, loc, &_Py_ID(__name__), Load) < 0) {
        2646                 :          0 :             compiler_exit_scope(c);
        2647                 :          0 :             return ERROR;
        2648                 :            :         }
        2649                 :            :         /* ... and store it as __module__ */
        2650         [ -  + ]:        733 :         if (compiler_nameop(c, loc, &_Py_ID(__module__), Store) < 0) {
        2651                 :          0 :             compiler_exit_scope(c);
        2652                 :          0 :             return ERROR;
        2653                 :            :         }
        2654                 :            :         assert(c->u->u_qualname);
        2655         [ -  + ]:        733 :         ADDOP_LOAD_CONST(c, loc, c->u->u_qualname);
        2656         [ -  + ]:        733 :         if (compiler_nameop(c, loc, &_Py_ID(__qualname__), Store) < 0) {
        2657                 :          0 :             compiler_exit_scope(c);
        2658                 :          0 :             return ERROR;
        2659                 :            :         }
        2660                 :            :         /* compile the body proper */
        2661         [ -  + ]:        733 :         if (compiler_body(c, loc, s->v.ClassDef.body) < 0) {
        2662                 :          0 :             compiler_exit_scope(c);
        2663                 :          0 :             return ERROR;
        2664                 :            :         }
        2665                 :            :         /* The following code is artificial */
        2666                 :            :         /* Return __classcell__ if it is referenced, otherwise return None */
        2667         [ +  + ]:        733 :         if (c->u->u_ste->ste_needs_class_closure) {
        2668                 :            :             /* Store __classcell__ into class namespace & return it */
        2669                 :        112 :             i = compiler_lookup_arg(c->u->u_cellvars, &_Py_ID(__class__));
        2670         [ -  + ]:        112 :             if (i < 0) {
        2671                 :          0 :                 compiler_exit_scope(c);
        2672                 :          0 :                 return ERROR;
        2673                 :            :             }
        2674                 :            :             assert(i == 0);
        2675         [ -  + ]:        112 :             ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
        2676         [ -  + ]:        112 :             ADDOP_I(c, NO_LOCATION, COPY, 1);
        2677         [ -  + ]:        112 :             if (compiler_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store) < 0) {
        2678                 :          0 :                 compiler_exit_scope(c);
        2679                 :          0 :                 return ERROR;
        2680                 :            :             }
        2681                 :            :         }
        2682                 :            :         else {
        2683                 :            :             /* No methods referenced __class__, so just return None */
        2684                 :            :             assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0);
        2685         [ -  + ]:        621 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
        2686                 :            :         }
        2687         [ -  + ]:        733 :         ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
        2688                 :            :         /* create the code object */
        2689                 :        733 :         co = assemble(c, 1);
        2690                 :            :     }
        2691                 :            :     /* leave the new scope */
        2692                 :        733 :     compiler_exit_scope(c);
        2693         [ -  + ]:        733 :     if (co == NULL) {
        2694                 :          0 :         return ERROR;
        2695                 :            :     }
        2696                 :            :
        2697                 :        733 :     location loc = LOC(s);
        2698                 :            :     /* 2. load the 'build_class' function */
        2699         [ -  + ]:        733 :     ADDOP(c, loc, PUSH_NULL);
        2700         [ -  + ]:        733 :     ADDOP(c, loc, LOAD_BUILD_CLASS);
        2701                 :            :
        2702                 :            :     /* 3. load a function (or closure) made from the code object */
        2703         [ -  + ]:        733 :     if (compiler_make_closure(c, loc, co, 0) < 0) {
        2704                 :          0 :         Py_DECREF(co);
        2705                 :          0 :         return ERROR;
        2706                 :            :     }
        2707                 :        733 :     Py_DECREF(co);
        2708                 :            :
        2709                 :            :     /* 4. load class name */
        2710         [ -  + ]:        733 :     ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
        2711                 :            :
        2712                 :            :     /* 5. generate the rest of the code for the call */
        2713         [ -  + ]:        733 :     RETURN_IF_ERROR(compiler_call_helper(c, loc, 2,
        2714                 :            :                                          s->v.ClassDef.bases,
        2715                 :            :                                          s->v.ClassDef.keywords));
        2716                 :            :
        2717                 :            :     /* 6. apply decorators */
        2718         [ -  + ]:        733 :     RETURN_IF_ERROR(compiler_apply_decorators(c, decos));
        2719                 :            :
        2720                 :            :     /* 7. store into <name> */
        2721         [ -  + ]:        733 :     RETURN_IF_ERROR(compiler_nameop(c, loc, s->v.ClassDef.name, Store));
        2722                 :        733 :     return SUCCESS;
        2723                 :            : }
        2724                 :            :
        2725                 :            : /* Return false if the expression is a constant value except named singletons.
        2726                 :            :    Return true otherwise. */
        2727                 :            : static bool
        2728                 :      12784 : check_is_arg(expr_ty e)
        2729                 :            : {
        2730         [ +  + ]:      12784 :     if (e->kind != Constant_kind) {
        2731                 :       8880 :         return true;
        2732                 :            :     }
        2733                 :       3904 :     PyObject *value = e->v.Constant.value;
        2734                 :            :     return (value == Py_None
        2735         [ +  + ]:       2093 :          || value == Py_False
        2736         [ +  + ]:       2085 :          || value == Py_True
        2737   [ +  +  +  + ]:       5997 :          || value == Py_Ellipsis);
        2738                 :            : }
        2739                 :            :
        2740                 :            : /* Check operands of identity checks ("is" and "is not").
        2741                 :            :    Emit a warning if any operand is a constant except named singletons.
        2742                 :            :  */
        2743                 :            : static int
        2744                 :       6367 : check_compare(struct compiler *c, expr_ty e)
        2745                 :            : {
        2746                 :            :     Py_ssize_t i, n;
        2747                 :       6367 :     bool left = check_is_arg(e->v.Compare.left);
        2748         [ +  - ]:       6367 :     n = asdl_seq_LEN(e->v.Compare.ops);
        2749         [ +  + ]:      12784 :     for (i = 0; i < n; i++) {
        2750                 :       6417 :         cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
        2751                 :       6417 :         bool right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
        2752   [ +  +  +  + ]:       6417 :         if (op == Is || op == IsNot) {
        2753   [ +  -  -  + ]:       2359 :             if (!right || !left) {
        2754                 :          0 :                 const char *msg = (op == Is)
        2755                 :            :                         ? "\"is\" with a literal. Did you mean \"==\"?"
        2756         [ #  # ]:          0 :                         : "\"is not\" with a literal. Did you mean \"!=\"?";
        2757                 :          0 :                 return compiler_warn(c, LOC(e), msg);
        2758                 :            :             }
        2759                 :            :         }
        2760                 :       6417 :         left = right;
        2761                 :            :     }
        2762                 :       6367 :     return SUCCESS;
        2763                 :            : }
        2764                 :            :
        2765                 :       6426 : static int compiler_addcompare(struct compiler *c, location loc,
        2766                 :            :                                cmpop_ty op)
        2767                 :            : {
        2768                 :            :     int cmp;
        2769   [ +  +  +  +  :       6426 :     switch (op) {
              +  +  +  +  +
                       +  - ]
        2770                 :       1615 :     case Eq:
        2771                 :       1615 :         cmp = Py_EQ;
        2772                 :       1615 :         break;
        2773                 :        441 :     case NotEq:
        2774                 :        441 :         cmp = Py_NE;
        2775                 :        441 :         break;
        2776                 :        368 :     case Lt:
        2777                 :        368 :         cmp = Py_LT;
        2778                 :        368 :         break;
        2779                 :        187 :     case LtE:
        2780                 :        187 :         cmp = Py_LE;
        2781                 :        187 :         break;
        2782                 :        308 :     case Gt:
        2783                 :        308 :         cmp = Py_GT;
        2784                 :        308 :         break;
        2785                 :        156 :     case GtE:
        2786                 :        156 :         cmp = Py_GE;
        2787                 :        156 :         break;
        2788                 :       1337 :     case Is:
        2789         [ -  + ]:       1337 :         ADDOP_I(c, loc, IS_OP, 0);
        2790                 :       1337 :         return SUCCESS;
        2791                 :       1023 :     case IsNot:
        2792         [ -  + ]:       1023 :         ADDOP_I(c, loc, IS_OP, 1);
        2793                 :       1023 :         return SUCCESS;
        2794                 :        703 :     case In:
        2795         [ -  + ]:        703 :         ADDOP_I(c, loc, CONTAINS_OP, 0);
        2796                 :        703 :         return SUCCESS;
        2797                 :        288 :     case NotIn:
        2798         [ -  + ]:        288 :         ADDOP_I(c, loc, CONTAINS_OP, 1);
        2799                 :        288 :         return SUCCESS;
        2800                 :          0 :     default:
        2801                 :          0 :         Py_UNREACHABLE();
        2802                 :            :     }
        2803                 :            :     /* cmp goes in top bits of the oparg, while the low bits are used by quickened
        2804                 :            :      * versions of this opcode to store the comparison mask. */
        2805         [ -  + ]:       3075 :     ADDOP_I(c, loc, COMPARE_OP, cmp << 4);
        2806                 :       3075 :     return SUCCESS;
        2807                 :            : }
        2808                 :            :
        2809                 :            :
        2810                 :            :
        2811                 :            : static int
        2812                 :      14708 : compiler_jump_if(struct compiler *c, location loc,
        2813                 :            :                  expr_ty e, jump_target_label next, int cond)
        2814                 :            : {
        2815   [ +  +  +  +  :      14708 :     switch (e->kind) {
                          + ]
        2816                 :       1538 :     case UnaryOp_kind:
        2817         [ +  - ]:       1538 :         if (e->v.UnaryOp.op == Not) {
        2818                 :       1538 :             return compiler_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond);
        2819                 :            :         }
        2820                 :            :         /* fallback to general implementation */
        2821                 :          0 :         break;
        2822                 :       1429 :     case BoolOp_kind: {
        2823                 :       1429 :         asdl_expr_seq *s = e->v.BoolOp.values;
        2824         [ +  - ]:       1429 :         Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
        2825                 :            :         assert(n >= 0);
        2826                 :       1429 :         int cond2 = e->v.BoolOp.op == Or;
        2827                 :       1429 :         jump_target_label next2 = next;
        2828         [ +  + ]:       1429 :         if (!cond2 != !cond) {
        2829         [ -  + ]:        469 :             NEW_JUMP_TARGET_LABEL(c, new_next2);
        2830                 :        469 :             next2 = new_next2;
        2831                 :            :         }
        2832         [ +  + ]:       3067 :         for (i = 0; i < n; ++i) {
        2833         [ -  + ]:       1638 :             RETURN_IF_ERROR(
        2834                 :            :                 compiler_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2));
        2835                 :            :         }
        2836         [ -  + ]:       1429 :         RETURN_IF_ERROR(
        2837                 :            :             compiler_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond));
        2838         [ +  + ]:       1429 :         if (!SAME_LABEL(next2, next)) {
        2839         [ -  + ]:        469 :             USE_LABEL(c, next2);
        2840                 :            :         }
        2841                 :       1429 :         return SUCCESS;
        2842                 :            :     }
        2843                 :          2 :     case IfExp_kind: {
        2844         [ -  + ]:          2 :         NEW_JUMP_TARGET_LABEL(c, end);
        2845         [ -  + ]:          2 :         NEW_JUMP_TARGET_LABEL(c, next2);
        2846         [ -  + ]:          2 :         RETURN_IF_ERROR(
        2847                 :            :             compiler_jump_if(c, loc, e->v.IfExp.test, next2, 0));
        2848         [ -  + ]:          2 :         RETURN_IF_ERROR(
        2849                 :            :             compiler_jump_if(c, loc, e->v.IfExp.body, next, cond));
        2850         [ -  + ]:          2 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        2851                 :            :
        2852         [ -  + ]:          2 :         USE_LABEL(c, next2);
        2853         [ -  + ]:          2 :         RETURN_IF_ERROR(
        2854                 :            :             compiler_jump_if(c, loc, e->v.IfExp.orelse, next, cond));
        2855                 :            :
        2856         [ -  + ]:          2 :         USE_LABEL(c, end);
        2857                 :          2 :         return SUCCESS;
        2858                 :            :     }
        2859                 :       5835 :     case Compare_kind: {
        2860         [ +  - ]:       5835 :         Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1;
        2861         [ +  + ]:       5835 :         if (n > 0) {
        2862         [ -  + ]:         46 :             RETURN_IF_ERROR(check_compare(c, e));
        2863         [ -  + ]:         46 :             NEW_JUMP_TARGET_LABEL(c, cleanup);
        2864         [ -  + ]:         46 :             VISIT(c, expr, e->v.Compare.left);
        2865         [ +  + ]:         92 :             for (Py_ssize_t i = 0; i < n; i++) {
        2866         [ -  + ]:         46 :                 VISIT(c, expr,
        2867                 :            :                     (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
        2868         [ -  + ]:         46 :                 ADDOP_I(c, LOC(e), SWAP, 2);
        2869         [ -  + ]:         46 :                 ADDOP_I(c, LOC(e), COPY, 2);
        2870         [ -  + ]:         46 :                 ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i));
        2871         [ -  + ]:         46 :                 ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup);
        2872                 :            :             }
        2873         [ -  + ]:         46 :             VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
        2874         [ -  + ]:         46 :             ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n));
        2875   [ +  +  -  + ]:         46 :             ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
        2876         [ -  + ]:         46 :             NEW_JUMP_TARGET_LABEL(c, end);
        2877         [ -  + ]:         46 :             ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        2878                 :            :
        2879         [ -  + ]:         46 :             USE_LABEL(c, cleanup);
        2880         [ -  + ]:         46 :             ADDOP(c, LOC(e), POP_TOP);
        2881         [ +  + ]:         46 :             if (!cond) {
        2882         [ -  + ]:         15 :                 ADDOP_JUMP(c, NO_LOCATION, JUMP, next);
        2883                 :            :             }
        2884                 :            :
        2885         [ -  + ]:         46 :             USE_LABEL(c, end);
        2886                 :         46 :             return SUCCESS;
        2887                 :            :         }
        2888                 :            :         /* fallback to general implementation */
        2889                 :       5789 :         break;
        2890                 :            :     }
        2891                 :       5904 :     default:
        2892                 :            :         /* fallback to general implementation */
        2893                 :       5904 :         break;
        2894                 :            :     }
        2895                 :            :
        2896                 :            :     /* general implementation */
        2897         [ -  + ]:      11693 :     VISIT(c, expr, e);
        2898   [ +  +  -  + ]:      11693 :     ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
        2899                 :      11693 :     return SUCCESS;
        2900                 :            : }
        2901                 :            :
        2902                 :            : static int
        2903                 :        231 : compiler_ifexp(struct compiler *c, expr_ty e)
        2904                 :            : {
        2905                 :            :     assert(e->kind == IfExp_kind);
        2906         [ -  + ]:        231 :     NEW_JUMP_TARGET_LABEL(c, end);
        2907         [ -  + ]:        231 :     NEW_JUMP_TARGET_LABEL(c, next);
        2908                 :            :
        2909         [ -  + ]:        231 :     RETURN_IF_ERROR(
        2910                 :            :         compiler_jump_if(c, LOC(e), e->v.IfExp.test, next, 0));
        2911                 :            :
        2912         [ -  + ]:        231 :     VISIT(c, expr, e->v.IfExp.body);
        2913         [ -  + ]:        231 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        2914                 :            :
        2915         [ -  + ]:        231 :     USE_LABEL(c, next);
        2916         [ -  + ]:        231 :     VISIT(c, expr, e->v.IfExp.orelse);
        2917                 :            :
        2918         [ -  + ]:        231 :     USE_LABEL(c, end);
        2919                 :        231 :     return SUCCESS;
        2920                 :            : }
        2921                 :            :
        2922                 :            : static int
        2923                 :        135 : compiler_lambda(struct compiler *c, expr_ty e)
        2924                 :            : {
        2925                 :            :     PyCodeObject *co;
        2926                 :            :     Py_ssize_t funcflags;
        2927                 :        135 :     arguments_ty args = e->v.Lambda.args;
        2928                 :            :     assert(e->kind == Lambda_kind);
        2929                 :            :
        2930         [ -  + ]:        135 :     RETURN_IF_ERROR(compiler_check_debug_args(c, args));
        2931                 :            :
        2932                 :        135 :     location loc = LOC(e);
        2933                 :        135 :     funcflags = compiler_default_arguments(c, loc, args);
        2934         [ -  + ]:        135 :     if (funcflags == -1) {
        2935                 :          0 :         return ERROR;
        2936                 :            :     }
        2937                 :            :
        2938                 :            :     _Py_DECLARE_STR(anon_lambda, "<lambda>");
        2939         [ -  + ]:        135 :     RETURN_IF_ERROR(
        2940                 :            :         compiler_enter_scope(c, &_Py_STR(anon_lambda), COMPILER_SCOPE_LAMBDA,
        2941                 :            :                              (void *)e, e->lineno));
        2942                 :            :
        2943                 :            :     /* Make None the first constant, so the lambda can't have a
        2944                 :            :        docstring. */
        2945         [ -  + ]:        135 :     RETURN_IF_ERROR(compiler_add_const(c->c_const_cache, c->u, Py_None));
        2946                 :            :
        2947         [ +  - ]:        135 :     c->u->u_argcount = asdl_seq_LEN(args->args);
        2948         [ +  - ]:        135 :     c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
        2949         [ +  - ]:        135 :     c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
        2950         [ -  + ]:        135 :     VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
        2951         [ +  + ]:        135 :     if (c->u->u_ste->ste_generator) {
        2952                 :          2 :         co = assemble(c, 0);
        2953                 :            :     }
        2954                 :            :     else {
        2955                 :        133 :         location loc = LOCATION(e->lineno, e->lineno, 0, 0);
        2956         [ -  + ]:        133 :         ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
        2957                 :        133 :         co = assemble(c, 1);
        2958                 :            :     }
        2959                 :        135 :     compiler_exit_scope(c);
        2960         [ -  + ]:        135 :     if (co == NULL) {
        2961                 :          0 :         return ERROR;
        2962                 :            :     }
        2963                 :            :
        2964         [ -  + ]:        135 :     if (compiler_make_closure(c, loc, co, funcflags) < 0) {
        2965                 :          0 :         Py_DECREF(co);
        2966                 :          0 :         return ERROR;
        2967                 :            :     }
        2968                 :        135 :     Py_DECREF(co);
        2969                 :            :
        2970                 :        135 :     return SUCCESS;
        2971                 :            : }
        2972                 :            :
        2973                 :            : static int
        2974                 :       8896 : compiler_if(struct compiler *c, stmt_ty s)
        2975                 :            : {
        2976                 :            :     jump_target_label next;
        2977                 :            :     assert(s->kind == If_kind);
        2978         [ -  + ]:       8896 :     NEW_JUMP_TARGET_LABEL(c, end);
        2979   [ +  +  +  - ]:       8896 :     if (asdl_seq_LEN(s->v.If.orelse)) {
        2980         [ -  + ]:       2430 :         NEW_JUMP_TARGET_LABEL(c, orelse);
        2981                 :       2430 :         next = orelse;
        2982                 :            :     }
        2983                 :            :     else {
        2984                 :       6466 :         next = end;
        2985                 :            :     }
        2986         [ -  + ]:       8896 :     RETURN_IF_ERROR(
        2987                 :            :         compiler_jump_if(c, LOC(s), s->v.If.test, next, 0));
        2988                 :            :
        2989   [ -  +  +  -  :      22071 :     VISIT_SEQ(c, stmt, s->v.If.body);
                       +  + ]
        2990   [ +  +  +  - ]:       8896 :     if (asdl_seq_LEN(s->v.If.orelse)) {
        2991         [ -  + ]:       2430 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        2992                 :            :
        2993         [ -  + ]:       2430 :         USE_LABEL(c, next);
        2994   [ -  +  +  -  :       5605 :         VISIT_SEQ(c, stmt, s->v.If.orelse);
                       +  + ]
        2995                 :            :     }
        2996                 :            :
        2997         [ -  + ]:       8896 :     USE_LABEL(c, end);
        2998                 :       8896 :     return SUCCESS;
        2999                 :            : }
        3000                 :            :
        3001                 :            : static int
        3002                 :       1236 : compiler_for(struct compiler *c, stmt_ty s)
        3003                 :            : {
        3004                 :       1236 :     location loc = LOC(s);
        3005         [ -  + ]:       1236 :     NEW_JUMP_TARGET_LABEL(c, start);
        3006         [ -  + ]:       1236 :     NEW_JUMP_TARGET_LABEL(c, body);
        3007         [ -  + ]:       1236 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
        3008         [ -  + ]:       1236 :     NEW_JUMP_TARGET_LABEL(c, end);
        3009                 :            :
        3010         [ -  + ]:       1236 :     RETURN_IF_ERROR(compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL));
        3011                 :            :
        3012         [ -  + ]:       1236 :     VISIT(c, expr, s->v.For.iter);
        3013         [ -  + ]:       1236 :     ADDOP(c, loc, GET_ITER);
        3014                 :            :
        3015         [ -  + ]:       1236 :     USE_LABEL(c, start);
        3016         [ -  + ]:       1236 :     ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
        3017                 :            :
        3018         [ -  + ]:       1236 :     USE_LABEL(c, body);
        3019         [ -  + ]:       1236 :     VISIT(c, expr, s->v.For.target);
        3020   [ -  +  +  -  :       3601 :     VISIT_SEQ(c, stmt, s->v.For.body);
                       +  + ]
        3021                 :            :     /* Mark jump as artificial */
        3022         [ -  + ]:       1236 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
        3023                 :            :
        3024         [ -  + ]:       1236 :     USE_LABEL(c, cleanup);
        3025         [ -  + ]:       1236 :     ADDOP(c, NO_LOCATION, END_FOR);
        3026                 :            :
        3027                 :       1236 :     compiler_pop_fblock(c, FOR_LOOP, start);
        3028                 :            :
        3029   [ -  +  +  +  :       1299 :     VISIT_SEQ(c, stmt, s->v.For.orelse);
                       +  + ]
        3030                 :            :
        3031         [ -  + ]:       1236 :     USE_LABEL(c, end);
        3032                 :       1236 :     return SUCCESS;
        3033                 :            : }
        3034                 :            :
        3035                 :            :
        3036                 :            : static int
        3037                 :          0 : compiler_async_for(struct compiler *c, stmt_ty s)
        3038                 :            : {
        3039                 :          0 :     location loc = LOC(s);
        3040   [ #  #  #  # ]:          0 :     if (IS_TOP_LEVEL_AWAIT(c)){
        3041                 :          0 :         c->u->u_ste->ste_coroutine = 1;
        3042         [ #  # ]:          0 :     } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) {
        3043                 :          0 :         return compiler_error(c, loc, "'async for' outside async function");
        3044                 :            :     }
        3045                 :            :
        3046         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, start);
        3047         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, except);
        3048         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, end);
        3049                 :            :
        3050         [ #  # ]:          0 :     VISIT(c, expr, s->v.AsyncFor.iter);
        3051         [ #  # ]:          0 :     ADDOP(c, loc, GET_AITER);
        3052                 :            :
        3053         [ #  # ]:          0 :     USE_LABEL(c, start);
        3054         [ #  # ]:          0 :     RETURN_IF_ERROR(compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL));
        3055                 :            :
        3056                 :            :     /* SETUP_FINALLY to guard the __anext__ call */
        3057         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
        3058         [ #  # ]:          0 :     ADDOP(c, loc, GET_ANEXT);
        3059         [ #  # ]:          0 :     ADDOP_LOAD_CONST(c, loc, Py_None);
        3060         [ #  # ]:          0 :     ADD_YIELD_FROM(c, loc, 1);
        3061         [ #  # ]:          0 :     ADDOP(c, loc, POP_BLOCK);  /* for SETUP_FINALLY */
        3062                 :            :
        3063                 :            :     /* Success block for __anext__ */
        3064         [ #  # ]:          0 :     VISIT(c, expr, s->v.AsyncFor.target);
        3065   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
                       #  # ]
        3066                 :            :     /* Mark jump as artificial */
        3067         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
        3068                 :            :
        3069                 :          0 :     compiler_pop_fblock(c, FOR_LOOP, start);
        3070                 :            :
        3071                 :            :     /* Except block for __anext__ */
        3072         [ #  # ]:          0 :     USE_LABEL(c, except);
        3073                 :            :
        3074                 :            :     /* Use same line number as the iterator,
        3075                 :            :      * as the END_ASYNC_FOR succeeds the `for`, not the body. */
        3076                 :          0 :     loc = LOC(s->v.AsyncFor.iter);
        3077         [ #  # ]:          0 :     ADDOP(c, loc, END_ASYNC_FOR);
        3078                 :            :
        3079                 :            :     /* `else` block */
        3080   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.For.orelse);
                       #  # ]
        3081                 :            :
        3082         [ #  # ]:          0 :     USE_LABEL(c, end);
        3083                 :          0 :     return SUCCESS;
        3084                 :            : }
        3085                 :            :
        3086                 :            : static int
        3087                 :        305 : compiler_while(struct compiler *c, stmt_ty s)
        3088                 :            : {
        3089         [ -  + ]:        305 :     NEW_JUMP_TARGET_LABEL(c, loop);
        3090         [ -  + ]:        305 :     NEW_JUMP_TARGET_LABEL(c, body);
        3091         [ -  + ]:        305 :     NEW_JUMP_TARGET_LABEL(c, end);
        3092         [ -  + ]:        305 :     NEW_JUMP_TARGET_LABEL(c, anchor);
        3093                 :            :
        3094         [ -  + ]:        305 :     USE_LABEL(c, loop);
        3095                 :            :
        3096         [ -  + ]:        305 :     RETURN_IF_ERROR(compiler_push_fblock(c, LOC(s), WHILE_LOOP, loop, end, NULL));
        3097         [ -  + ]:        305 :     RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.While.test, anchor, 0));
        3098                 :            :
        3099         [ -  + ]:        305 :     USE_LABEL(c, body);
        3100   [ -  +  +  -  :       1214 :     VISIT_SEQ(c, stmt, s->v.While.body);
                       +  + ]
        3101         [ -  + ]:        305 :     RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.While.test, body, 1));
        3102                 :            :
        3103                 :        305 :     compiler_pop_fblock(c, WHILE_LOOP, loop);
        3104                 :            :
        3105         [ -  + ]:        305 :     USE_LABEL(c, anchor);
        3106         [ +  + ]:        305 :     if (s->v.While.orelse) {
        3107   [ -  +  +  -  :         10 :         VISIT_SEQ(c, stmt, s->v.While.orelse);
                       +  + ]
        3108                 :            :     }
        3109                 :            :
        3110         [ -  + ]:        305 :     USE_LABEL(c, end);
        3111                 :        305 :     return SUCCESS;
        3112                 :            : }
        3113                 :            :
        3114                 :            : static int
        3115                 :       5842 : compiler_return(struct compiler *c, stmt_ty s)
        3116                 :            : {
        3117                 :       5842 :     location loc = LOC(s);
        3118         [ +  + ]:      11356 :     int preserve_tos = ((s->v.Return.value != NULL) &&
        3119         [ +  + ]:       5514 :                         (s->v.Return.value->kind != Constant_kind));
        3120         [ -  + ]:       5842 :     if (c->u->u_ste->ste_type != FunctionBlock) {
        3121                 :          0 :         return compiler_error(c, loc, "'return' outside function");
        3122                 :            :     }
        3123         [ +  + ]:       5842 :     if (s->v.Return.value != NULL &&
        3124   [ +  +  -  + ]:       5514 :         c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator)
        3125                 :            :     {
        3126                 :          0 :         return compiler_error(c, loc, "'return' with value in async generator");
        3127                 :            :     }
        3128                 :            :
        3129         [ +  + ]:       5842 :     if (preserve_tos) {
        3130         [ -  + ]:       4825 :         VISIT(c, expr, s->v.Return.value);
        3131                 :            :     } else {
        3132                 :            :         /* Emit instruction with line number for return value */
        3133         [ +  + ]:       1017 :         if (s->v.Return.value != NULL) {
        3134                 :        689 :             loc = LOC(s->v.Return.value);
        3135         [ -  + ]:        689 :             ADDOP(c, loc, NOP);
        3136                 :            :         }
        3137                 :            :     }
        3138   [ +  +  +  + ]:       5842 :     if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
        3139                 :        338 :         loc = LOC(s);
        3140         [ -  + ]:        338 :         ADDOP(c, loc, NOP);
        3141                 :            :     }
        3142                 :            :
        3143         [ -  + ]:       5842 :     RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, preserve_tos, NULL));
        3144         [ +  + ]:       5842 :     if (s->v.Return.value == NULL) {
        3145         [ -  + ]:        328 :         ADDOP_LOAD_CONST(c, loc, Py_None);
        3146                 :            :     }
        3147         [ +  + ]:       5514 :     else if (!preserve_tos) {
        3148         [ -  + ]:        689 :         ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value);
        3149                 :            :     }
        3150         [ -  + ]:       5842 :     ADDOP(c, loc, RETURN_VALUE);
        3151                 :            :
        3152                 :       5842 :     return SUCCESS;
        3153                 :            : }
        3154                 :            :
        3155                 :            : static int
        3156                 :        275 : compiler_break(struct compiler *c, location loc)
        3157                 :            : {
        3158                 :        275 :     struct fblockinfo *loop = NULL;
        3159                 :        275 :     location origin_loc = loc;
        3160                 :            :     /* Emit instruction with line number */
        3161         [ -  + ]:        275 :     ADDOP(c, loc, NOP);
        3162         [ -  + ]:        275 :     RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, 0, &loop));
        3163         [ -  + ]:        275 :     if (loop == NULL) {
        3164                 :          0 :         return compiler_error(c, origin_loc, "'break' outside loop");
        3165                 :            :     }
        3166         [ -  + ]:        275 :     RETURN_IF_ERROR(compiler_unwind_fblock(c, &loc, loop, 0));
        3167         [ -  + ]:        275 :     ADDOP_JUMP(c, loc, JUMP, loop->fb_exit);
        3168                 :        275 :     return SUCCESS;
        3169                 :            : }
        3170                 :            :
        3171                 :            : static int
        3172                 :        231 : compiler_continue(struct compiler *c, location loc)
        3173                 :            : {
        3174                 :        231 :     struct fblockinfo *loop = NULL;
        3175                 :        231 :     location origin_loc = loc;
        3176                 :            :     /* Emit instruction with line number */
        3177         [ -  + ]:        231 :     ADDOP(c, loc, NOP);
        3178         [ -  + ]:        231 :     RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, 0, &loop));
        3179         [ -  + ]:        231 :     if (loop == NULL) {
        3180                 :          0 :         return compiler_error(c, origin_loc, "'continue' not properly in loop");
        3181                 :            :     }
        3182         [ -  + ]:        231 :     ADDOP_JUMP(c, loc, JUMP, loop->fb_block);
        3183                 :        231 :     return SUCCESS;
        3184                 :            : }
        3185                 :            :
        3186                 :            :
        3187                 :            : static location
        3188                 :        192 : location_of_last_executing_statement(asdl_stmt_seq *stmts)
        3189                 :            : {
        3190   [ +  -  +  - ]:        192 :     for (Py_ssize_t i = asdl_seq_LEN(stmts) - 1; i >= 0; i++) {
        3191                 :        192 :         location loc = LOC((stmt_ty)asdl_seq_GET(stmts, i));
        3192         [ +  - ]:        192 :         if (loc.lineno > 0) {
        3193                 :        192 :             return loc;
        3194                 :            :         }
        3195                 :            :     }
        3196                 :          0 :     return NO_LOCATION;
        3197                 :            : }
        3198                 :            :
        3199                 :            : /* Code generated for "try: <body> finally: <finalbody>" is as follows:
        3200                 :            :
        3201                 :            :         SETUP_FINALLY           L
        3202                 :            :         <code for body>
        3203                 :            :         POP_BLOCK
        3204                 :            :         <code for finalbody>
        3205                 :            :         JUMP E
        3206                 :            :     L:
        3207                 :            :         <code for finalbody>
        3208                 :            :     E:
        3209                 :            :
        3210                 :            :    The special instructions use the block stack.  Each block
        3211                 :            :    stack entry contains the instruction that created it (here
        3212                 :            :    SETUP_FINALLY), the level of the value stack at the time the
        3213                 :            :    block stack entry was created, and a label (here L).
        3214                 :            :
        3215                 :            :    SETUP_FINALLY:
        3216                 :            :     Pushes the current value stack level and the label
        3217                 :            :     onto the block stack.
        3218                 :            :    POP_BLOCK:
        3219                 :            :     Pops en entry from the block stack.
        3220                 :            :
        3221                 :            :    The block stack is unwound when an exception is raised:
        3222                 :            :    when a SETUP_FINALLY entry is found, the raised and the caught
        3223                 :            :    exceptions are pushed onto the value stack (and the exception
        3224                 :            :    condition is cleared), and the interpreter jumps to the label
        3225                 :            :    gotten from the block stack.
        3226                 :            : */
        3227                 :            :
        3228                 :            : static int
        3229                 :        192 : compiler_try_finally(struct compiler *c, stmt_ty s)
        3230                 :            : {
        3231                 :        192 :     location loc = LOC(s);
        3232                 :            :
        3233         [ -  + ]:        192 :     NEW_JUMP_TARGET_LABEL(c, body);
        3234         [ -  + ]:        192 :     NEW_JUMP_TARGET_LABEL(c, end);
        3235         [ -  + ]:        192 :     NEW_JUMP_TARGET_LABEL(c, exit);
        3236         [ -  + ]:        192 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
        3237                 :            :
        3238                 :            :     /* `try` block */
        3239         [ -  + ]:        192 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
        3240                 :            :
        3241         [ -  + ]:        192 :     USE_LABEL(c, body);
        3242         [ -  + ]:        192 :     RETURN_IF_ERROR(
        3243                 :            :         compiler_push_fblock(c, loc, FINALLY_TRY, body, end,
        3244                 :            :                              s->v.Try.finalbody));
        3245                 :            :
        3246   [ +  +  +  -  :        192 :     if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
                       +  - ]
        3247         [ -  + ]:         20 :         RETURN_IF_ERROR(compiler_try_except(c, s));
        3248                 :            :     }
        3249                 :            :     else {
        3250   [ -  +  +  -  :        511 :         VISIT_SEQ(c, stmt, s->v.Try.body);
                       +  + ]
        3251                 :            :     }
        3252         [ -  + ]:        192 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        3253                 :        192 :     compiler_pop_fblock(c, FINALLY_TRY, body);
        3254   [ -  +  +  -  :        461 :     VISIT_SEQ(c, stmt, s->v.Try.finalbody);
                       +  + ]
        3255                 :            :
        3256         [ -  + ]:        192 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
        3257                 :            :     /* `finally` block */
        3258                 :            :
        3259         [ -  + ]:        192 :     USE_LABEL(c, end);
        3260                 :            :
        3261                 :        192 :     loc = NO_LOCATION;
        3262         [ -  + ]:        192 :     ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
        3263         [ -  + ]:        192 :     ADDOP(c, loc, PUSH_EXC_INFO);
        3264         [ -  + ]:        192 :     RETURN_IF_ERROR(
        3265                 :            :         compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL));
        3266   [ -  +  +  -  :        461 :     VISIT_SEQ(c, stmt, s->v.Try.finalbody);
                       +  + ]
        3267                 :        192 :     loc = location_of_last_executing_statement(s->v.Try.finalbody);
        3268                 :        192 :     compiler_pop_fblock(c, FINALLY_END, end);
        3269                 :            :
        3270         [ -  + ]:        192 :     ADDOP_I(c, loc, RERAISE, 0);
        3271                 :            :
        3272         [ -  + ]:        192 :     USE_LABEL(c, cleanup);
        3273         [ -  + ]:        192 :     POP_EXCEPT_AND_RERAISE(c, loc);
        3274                 :            :
        3275         [ -  + ]:        192 :     USE_LABEL(c, exit);
        3276                 :        192 :     return SUCCESS;
        3277                 :            : }
        3278                 :            :
        3279                 :            : static int
        3280                 :          0 : compiler_try_star_finally(struct compiler *c, stmt_ty s)
        3281                 :            : {
        3282                 :          0 :     location loc = LOC(s);
        3283                 :            :
        3284         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, body);
        3285         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, end);
        3286         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, exit);
        3287         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
        3288                 :            :     /* `try` block */
        3289         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
        3290                 :            :
        3291         [ #  # ]:          0 :     USE_LABEL(c, body);
        3292         [ #  # ]:          0 :     RETURN_IF_ERROR(
        3293                 :            :         compiler_push_fblock(c, loc, FINALLY_TRY, body, end,
        3294                 :            :                              s->v.TryStar.finalbody));
        3295                 :            :
        3296   [ #  #  #  #  :          0 :     if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) {
                       #  # ]
        3297         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_try_star_except(c, s));
        3298                 :            :     }
        3299                 :            :     else {
        3300   [ #  #  #  #  :          0 :         VISIT_SEQ(c, stmt, s->v.TryStar.body);
                       #  # ]
        3301                 :            :     }
        3302         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        3303                 :          0 :     compiler_pop_fblock(c, FINALLY_TRY, body);
        3304   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
                       #  # ]
        3305                 :            :
        3306         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
        3307                 :            :
        3308                 :            :     /* `finally` block */
        3309         [ #  # ]:          0 :     USE_LABEL(c, end);
        3310                 :            :
        3311                 :          0 :     loc = NO_LOCATION;
        3312         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
        3313         [ #  # ]:          0 :     ADDOP(c, loc, PUSH_EXC_INFO);
        3314         [ #  # ]:          0 :     RETURN_IF_ERROR(
        3315                 :            :         compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL));
        3316                 :            :
        3317   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
                       #  # ]
        3318                 :          0 :     loc = location_of_last_executing_statement(s->v.Try.finalbody);
        3319                 :            :
        3320                 :          0 :     compiler_pop_fblock(c, FINALLY_END, end);
        3321         [ #  # ]:          0 :     ADDOP_I(c, loc, RERAISE, 0);
        3322                 :            :
        3323         [ #  # ]:          0 :     USE_LABEL(c, cleanup);
        3324         [ #  # ]:          0 :     POP_EXCEPT_AND_RERAISE(c, loc);
        3325                 :            :
        3326         [ #  # ]:          0 :     USE_LABEL(c, exit);
        3327                 :          0 :     return SUCCESS;
        3328                 :            : }
        3329                 :            :
        3330                 :            :
        3331                 :            : /*
        3332                 :            :    Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
        3333                 :            :    (The contents of the value stack is shown in [], with the top
        3334                 :            :    at the right; 'tb' is trace-back info, 'val' the exception's
        3335                 :            :    associated value, and 'exc' the exception.)
        3336                 :            :
        3337                 :            :    Value stack          Label   Instruction     Argument
        3338                 :            :    []                           SETUP_FINALLY   L1
        3339                 :            :    []                           <code for S>
        3340                 :            :    []                           POP_BLOCK
        3341                 :            :    []                           JUMP            L0
        3342                 :            :
        3343                 :            :    [exc]                L1:     <evaluate E1>           )
        3344                 :            :    [exc, E1]                    CHECK_EXC_MATCH         )
        3345                 :            :    [exc, bool]                  POP_JUMP_IF_FALSE L2    ) only if E1
        3346                 :            :    [exc]                        <assign to V1>  (or POP if no V1)
        3347                 :            :    []                           <code for S1>
        3348                 :            :                                 JUMP            L0
        3349                 :            :
        3350                 :            :    [exc]                L2:     <evaluate E2>
        3351                 :            :    .............................etc.......................
        3352                 :            :
        3353                 :            :    [exc]                Ln+1:   RERAISE     # re-raise exception
        3354                 :            :
        3355                 :            :    []                   L0:     <next statement>
        3356                 :            :
        3357                 :            :    Of course, parts are not generated if Vi or Ei is not present.
        3358                 :            : */
        3359                 :            : static int
        3360                 :       1297 : compiler_try_except(struct compiler *c, stmt_ty s)
        3361                 :            : {
        3362                 :       1297 :     location loc = LOC(s);
        3363                 :            :     Py_ssize_t i, n;
        3364                 :            :
        3365         [ -  + ]:       1297 :     NEW_JUMP_TARGET_LABEL(c, body);
        3366         [ -  + ]:       1297 :     NEW_JUMP_TARGET_LABEL(c, except);
        3367         [ -  + ]:       1297 :     NEW_JUMP_TARGET_LABEL(c, end);
        3368         [ -  + ]:       1297 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
        3369                 :            :
        3370         [ -  + ]:       1297 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
        3371                 :            :
        3372         [ -  + ]:       1297 :     USE_LABEL(c, body);
        3373         [ -  + ]:       1297 :     RETURN_IF_ERROR(
        3374                 :            :         compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL));
        3375   [ -  +  +  -  :       3050 :     VISIT_SEQ(c, stmt, s->v.Try.body);
                       +  + ]
        3376                 :       1297 :     compiler_pop_fblock(c, TRY_EXCEPT, body);
        3377         [ -  + ]:       1297 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        3378   [ +  +  +  -  :       1297 :     if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
                       +  - ]
        3379   [ -  +  +  -  :        622 :         VISIT_SEQ(c, stmt, s->v.Try.orelse);
                       +  + ]
        3380                 :            :     }
        3381         [ -  + ]:       1297 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        3382         [ +  - ]:       1297 :     n = asdl_seq_LEN(s->v.Try.handlers);
        3383                 :            :
        3384         [ -  + ]:       1297 :     USE_LABEL(c, except);
        3385                 :            :
        3386         [ -  + ]:       1297 :     ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
        3387         [ -  + ]:       1297 :     ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
        3388                 :            :
        3389                 :            :     /* Runtime will push a block here, so we need to account for that */
        3390         [ -  + ]:       1297 :     RETURN_IF_ERROR(
        3391                 :            :         compiler_push_fblock(c, loc, EXCEPTION_HANDLER, NO_LABEL, NO_LABEL, NULL));
        3392                 :            :
        3393         [ +  + ]:       2739 :     for (i = 0; i < n; i++) {
        3394                 :       1442 :         excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
        3395                 :            :             s->v.Try.handlers, i);
        3396                 :       1442 :         location loc = LOC(handler);
        3397   [ +  +  -  + ]:       1442 :         if (!handler->v.ExceptHandler.type && i < n-1) {
        3398                 :          0 :             return compiler_error(c, loc, "default 'except:' must be last");
        3399                 :            :         }
        3400         [ -  + ]:       1442 :         NEW_JUMP_TARGET_LABEL(c, next_except);
        3401                 :       1442 :         except = next_except;
        3402         [ +  + ]:       1442 :         if (handler->v.ExceptHandler.type) {
        3403         [ -  + ]:       1375 :             VISIT(c, expr, handler->v.ExceptHandler.type);
        3404         [ -  + ]:       1375 :             ADDOP(c, loc, CHECK_EXC_MATCH);
        3405         [ -  + ]:       1375 :             ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
        3406                 :            :         }
        3407         [ +  + ]:       1442 :         if (handler->v.ExceptHandler.name) {
        3408         [ -  + ]:        261 :             NEW_JUMP_TARGET_LABEL(c, cleanup_end);
        3409         [ -  + ]:        261 :             NEW_JUMP_TARGET_LABEL(c, cleanup_body);
        3410                 :            :
        3411         [ -  + ]:        261 :             RETURN_IF_ERROR(
        3412                 :            :                 compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store));
        3413                 :            :
        3414                 :            :             /*
        3415                 :            :               try:
        3416                 :            :                   # body
        3417                 :            :               except type as name:
        3418                 :            :                   try:
        3419                 :            :                       # body
        3420                 :            :                   finally:
        3421                 :            :                       name = None # in case body contains "del name"
        3422                 :            :                       del name
        3423                 :            :             */
        3424                 :            :
        3425                 :            :             /* second try: */
        3426         [ -  + ]:        261 :             ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
        3427                 :            :
        3428         [ -  + ]:        261 :             USE_LABEL(c, cleanup_body);
        3429         [ -  + ]:        261 :             RETURN_IF_ERROR(
        3430                 :            :                 compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body,
        3431                 :            :                                      NO_LABEL, handler->v.ExceptHandler.name));
        3432                 :            :
        3433                 :            :             /* second # body */
        3434   [ -  +  +  -  :        704 :             VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
                       +  + ]
        3435                 :        261 :             compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
        3436                 :            :             /* name = None; del name; # Mark as artificial */
        3437         [ -  + ]:        261 :             ADDOP(c, NO_LOCATION, POP_BLOCK);
        3438         [ -  + ]:        261 :             ADDOP(c, NO_LOCATION, POP_BLOCK);
        3439         [ -  + ]:        261 :             ADDOP(c, NO_LOCATION, POP_EXCEPT);
        3440         [ -  + ]:        261 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
        3441         [ -  + ]:        261 :             RETURN_IF_ERROR(
        3442                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
        3443         [ -  + ]:        261 :             RETURN_IF_ERROR(
        3444                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
        3445         [ -  + ]:        261 :             ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        3446                 :            :
        3447                 :            :             /* except: */
        3448         [ -  + ]:        261 :             USE_LABEL(c, cleanup_end);
        3449                 :            :
        3450                 :            :             /* name = None; del name; # artificial */
        3451         [ -  + ]:        261 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
        3452         [ -  + ]:        261 :             RETURN_IF_ERROR(
        3453                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
        3454         [ -  + ]:        261 :             RETURN_IF_ERROR(
        3455                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
        3456                 :            :
        3457         [ -  + ]:        261 :             ADDOP_I(c, NO_LOCATION, RERAISE, 1);
        3458                 :            :         }
        3459                 :            :         else {
        3460         [ -  + ]:       1181 :             NEW_JUMP_TARGET_LABEL(c, cleanup_body);
        3461                 :            :
        3462         [ -  + ]:       1181 :             ADDOP(c, loc, POP_TOP); /* exc_value */
        3463                 :            :
        3464         [ -  + ]:       1181 :             USE_LABEL(c, cleanup_body);
        3465         [ -  + ]:       1181 :             RETURN_IF_ERROR(
        3466                 :            :                 compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body,
        3467                 :            :                                      NO_LABEL, NULL));
        3468                 :            :
        3469   [ -  +  +  -  :       2665 :             VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
                       +  + ]
        3470                 :       1181 :             compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
        3471         [ -  + ]:       1181 :             ADDOP(c, NO_LOCATION, POP_BLOCK);
        3472         [ -  + ]:       1181 :             ADDOP(c, NO_LOCATION, POP_EXCEPT);
        3473         [ -  + ]:       1181 :             ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        3474                 :            :         }
        3475                 :            :
        3476         [ -  + ]:       1442 :         USE_LABEL(c, except);
        3477                 :            :     }
        3478                 :            :     /* artificial */
        3479                 :       1297 :     compiler_pop_fblock(c, EXCEPTION_HANDLER, NO_LABEL);
        3480         [ -  + ]:       1297 :     ADDOP_I(c, NO_LOCATION, RERAISE, 0);
        3481                 :            :
        3482         [ -  + ]:       1297 :     USE_LABEL(c, cleanup);
        3483         [ -  + ]:       1297 :     POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
        3484                 :            :
        3485         [ -  + ]:       1297 :     USE_LABEL(c, end);
        3486                 :       1297 :     return SUCCESS;
        3487                 :            : }
        3488                 :            :
        3489                 :            : /*
        3490                 :            :    Code generated for "try: S except* E1 as V1: S1 except* E2 as V2: S2 ...":
        3491                 :            :    (The contents of the value stack is shown in [], with the top
        3492                 :            :    at the right; 'tb' is trace-back info, 'val' the exception instance,
        3493                 :            :    and 'typ' the exception's type.)
        3494                 :            :
        3495                 :            :    Value stack                   Label         Instruction     Argument
        3496                 :            :    []                                         SETUP_FINALLY         L1
        3497                 :            :    []                                         <code for S>
        3498                 :            :    []                                         POP_BLOCK
        3499                 :            :    []                                         JUMP                  L0
        3500                 :            :
        3501                 :            :    [exc]                            L1:       BUILD_LIST   )  list for raised/reraised excs ("result")
        3502                 :            :    [orig, res]                                COPY 2       )  make a copy of the original EG
        3503                 :            :
        3504                 :            :    [orig, res, exc]                           <evaluate E1>
        3505                 :            :    [orig, res, exc, E1]                       CHECK_EG_MATCH
        3506                 :            :    [orig, res, rest/exc, match?]              COPY 1
        3507                 :            :    [orig, res, rest/exc, match?, match?]      POP_JUMP_IF_NOT_NONE  H1
        3508                 :            :    [orig, res, exc, None]                     POP_TOP
        3509                 :            :    [orig, res, exc]                           JUMP L2
        3510                 :            :
        3511                 :            :    [orig, res, rest, match]         H1:       <assign to V1>  (or POP if no V1)
        3512                 :            :
        3513                 :            :    [orig, res, rest]                          SETUP_FINALLY         R1
        3514                 :            :    [orig, res, rest]                          <code for S1>
        3515                 :            :    [orig, res, rest]                          JUMP                  L2
        3516                 :            :
        3517                 :            :    [orig, res, rest, i, v]          R1:       LIST_APPEND   3 ) exc raised in except* body - add to res
        3518                 :            :    [orig, res, rest, i]                       POP
        3519                 :            :
        3520                 :            :    [orig, res, rest]                L2:       <evaluate E2>
        3521                 :            :    .............................etc.......................
        3522                 :            :
        3523                 :            :    [orig, res, rest]                Ln+1:     LIST_APPEND 1  ) add unhandled exc to res (could be None)
        3524                 :            :
        3525                 :            :    [orig, res]                                CALL_INTRINSIC_2 PREP_RERAISE_STAR
        3526                 :            :    [exc]                                      COPY 1
        3527                 :            :    [exc, exc]                                 POP_JUMP_IF_NOT_NONE  RER
        3528                 :            :    [exc]                                      POP_TOP
        3529                 :            :    []                                         JUMP                  L0
        3530                 :            :
        3531                 :            :    [exc]                            RER:      SWAP 2
        3532                 :            :    [exc, prev_exc_info]                       POP_EXCEPT
        3533                 :            :    [exc]                                      RERAISE               0
        3534                 :            :
        3535                 :            :    []                               L0:       <next statement>
        3536                 :            : */
        3537                 :            : static int
        3538                 :          0 : compiler_try_star_except(struct compiler *c, stmt_ty s)
        3539                 :            : {
        3540                 :          0 :     location loc = LOC(s);
        3541                 :            :
        3542         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, body);
        3543         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, except);
        3544         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, orelse);
        3545         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, end);
        3546         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
        3547         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, reraise_star);
        3548                 :            :
        3549         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
        3550                 :            :
        3551         [ #  # ]:          0 :     USE_LABEL(c, body);
        3552         [ #  # ]:          0 :     RETURN_IF_ERROR(
        3553                 :            :         compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL));
        3554   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.TryStar.body);
                       #  # ]
        3555                 :          0 :     compiler_pop_fblock(c, TRY_EXCEPT, body);
        3556         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        3557         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, orelse);
        3558         [ #  # ]:          0 :     Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers);
        3559                 :            :
        3560         [ #  # ]:          0 :     USE_LABEL(c, except);
        3561                 :            :
        3562         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
        3563         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
        3564                 :            :
        3565                 :            :     /* Runtime will push a block here, so we need to account for that */
        3566         [ #  # ]:          0 :     RETURN_IF_ERROR(
        3567                 :            :         compiler_push_fblock(c, loc, EXCEPTION_GROUP_HANDLER,
        3568                 :            :                              NO_LABEL, NO_LABEL, "except handler"));
        3569                 :            :
        3570         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < n; i++) {
        3571                 :          0 :         excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
        3572                 :            :             s->v.TryStar.handlers, i);
        3573                 :          0 :         location loc = LOC(handler);
        3574         [ #  # ]:          0 :         NEW_JUMP_TARGET_LABEL(c, next_except);
        3575                 :          0 :         except = next_except;
        3576         [ #  # ]:          0 :         NEW_JUMP_TARGET_LABEL(c, handle_match);
        3577         [ #  # ]:          0 :         if (i == 0) {
        3578                 :            :             /* create empty list for exceptions raised/reraise in the except* blocks */
        3579                 :            :             /*
        3580                 :            :                [orig]       BUILD_LIST
        3581                 :            :             */
        3582                 :            :             /* Create a copy of the original EG */
        3583                 :            :             /*
        3584                 :            :                [orig, []]   COPY 2
        3585                 :            :                [orig, [], exc]
        3586                 :            :             */
        3587         [ #  # ]:          0 :             ADDOP_I(c, loc, BUILD_LIST, 0);
        3588         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 2);
        3589                 :            :         }
        3590         [ #  # ]:          0 :         if (handler->v.ExceptHandler.type) {
        3591         [ #  # ]:          0 :             VISIT(c, expr, handler->v.ExceptHandler.type);
        3592         [ #  # ]:          0 :             ADDOP(c, loc, CHECK_EG_MATCH);
        3593         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 1);
        3594         [ #  # ]:          0 :             ADDOP_JUMP(c, loc, POP_JUMP_IF_NOT_NONE, handle_match);
        3595         [ #  # ]:          0 :             ADDOP(c, loc, POP_TOP);  // match
        3596         [ #  # ]:          0 :             ADDOP_JUMP(c, loc, JUMP, except);
        3597                 :            :         }
        3598                 :            :
        3599         [ #  # ]:          0 :         USE_LABEL(c, handle_match);
        3600                 :            :
        3601         [ #  # ]:          0 :         NEW_JUMP_TARGET_LABEL(c, cleanup_end);
        3602         [ #  # ]:          0 :         NEW_JUMP_TARGET_LABEL(c, cleanup_body);
        3603                 :            :
        3604         [ #  # ]:          0 :         if (handler->v.ExceptHandler.name) {
        3605         [ #  # ]:          0 :             RETURN_IF_ERROR(
        3606                 :            :                 compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store));
        3607                 :            :         }
        3608                 :            :         else {
        3609         [ #  # ]:          0 :             ADDOP(c, loc, POP_TOP);  // match
        3610                 :            :         }
        3611                 :            :
        3612                 :            :         /*
        3613                 :            :           try:
        3614                 :            :               # body
        3615                 :            :           except type as name:
        3616                 :            :               try:
        3617                 :            :                   # body
        3618                 :            :               finally:
        3619                 :            :                   name = None # in case body contains "del name"
        3620                 :            :                   del name
        3621                 :            :         */
        3622                 :            :         /* second try: */
        3623         [ #  # ]:          0 :         ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
        3624                 :            :
        3625         [ #  # ]:          0 :         USE_LABEL(c, cleanup_body);
        3626         [ #  # ]:          0 :         RETURN_IF_ERROR(
        3627                 :            :             compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body,
        3628                 :            :                                  NO_LABEL, handler->v.ExceptHandler.name));
        3629                 :            :
        3630                 :            :         /* second # body */
        3631   [ #  #  #  #  :          0 :         VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
                       #  # ]
        3632                 :          0 :         compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
        3633                 :            :         /* name = None; del name; # artificial */
        3634         [ #  # ]:          0 :         ADDOP(c, NO_LOCATION, POP_BLOCK);
        3635         [ #  # ]:          0 :         if (handler->v.ExceptHandler.name) {
        3636         [ #  # ]:          0 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
        3637         [ #  # ]:          0 :             RETURN_IF_ERROR(
        3638                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
        3639         [ #  # ]:          0 :             RETURN_IF_ERROR(
        3640                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
        3641                 :            :         }
        3642         [ #  # ]:          0 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, except);
        3643                 :            :
        3644                 :            :         /* except: */
        3645         [ #  # ]:          0 :         USE_LABEL(c, cleanup_end);
        3646                 :            :
        3647                 :            :         /* name = None; del name; # artificial */
        3648         [ #  # ]:          0 :         if (handler->v.ExceptHandler.name) {
        3649         [ #  # ]:          0 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
        3650         [ #  # ]:          0 :             RETURN_IF_ERROR(
        3651                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
        3652         [ #  # ]:          0 :             RETURN_IF_ERROR(
        3653                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
        3654                 :            :         }
        3655                 :            :
        3656                 :            :         /* add exception raised to the res list */
        3657         [ #  # ]:          0 :         ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc
        3658         [ #  # ]:          0 :         ADDOP(c, NO_LOCATION, POP_TOP); // lasti
        3659         [ #  # ]:          0 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, except);
        3660                 :            :
        3661         [ #  # ]:          0 :         USE_LABEL(c, except);
        3662                 :            :
        3663         [ #  # ]:          0 :         if (i == n - 1) {
        3664                 :            :             /* Add exc to the list (if not None it's the unhandled part of the EG) */
        3665         [ #  # ]:          0 :             ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1);
        3666         [ #  # ]:          0 :             ADDOP_JUMP(c, NO_LOCATION, JUMP, reraise_star);
        3667                 :            :         }
        3668                 :            :     }
        3669                 :            :     /* artificial */
        3670                 :          0 :     compiler_pop_fblock(c, EXCEPTION_GROUP_HANDLER, NO_LABEL);
        3671         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, reraise);
        3672                 :            :
        3673         [ #  # ]:          0 :     USE_LABEL(c, reraise_star);
        3674         [ #  # ]:          0 :     ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_2, INTRINSIC_PREP_RERAISE_STAR);
        3675         [ #  # ]:          0 :     ADDOP_I(c, NO_LOCATION, COPY, 1);
        3676         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise);
        3677                 :            :
        3678                 :            :     /* Nothing to reraise */
        3679         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_TOP);
        3680         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        3681         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_EXCEPT);
        3682         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        3683                 :            :
        3684         [ #  # ]:          0 :     USE_LABEL(c, reraise);
        3685         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        3686         [ #  # ]:          0 :     ADDOP_I(c, NO_LOCATION, SWAP, 2);
        3687         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_EXCEPT);
        3688         [ #  # ]:          0 :     ADDOP_I(c, NO_LOCATION, RERAISE, 0);
        3689                 :            :
        3690         [ #  # ]:          0 :     USE_LABEL(c, cleanup);
        3691         [ #  # ]:          0 :     POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
        3692                 :            :
        3693         [ #  # ]:          0 :     USE_LABEL(c, orelse);
        3694   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.TryStar.orelse);
                       #  # ]
        3695                 :            :
        3696         [ #  # ]:          0 :     USE_LABEL(c, end);
        3697                 :          0 :     return SUCCESS;
        3698                 :            : }
        3699                 :            :
        3700                 :            : static int
        3701                 :       1469 : compiler_try(struct compiler *c, stmt_ty s) {
        3702   [ +  +  +  -  :       1469 :     if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
                       +  - ]
        3703                 :        192 :         return compiler_try_finally(c, s);
        3704                 :            :     else
        3705                 :       1277 :         return compiler_try_except(c, s);
        3706                 :            : }
        3707                 :            :
        3708                 :            : static int
        3709                 :          0 : compiler_try_star(struct compiler *c, stmt_ty s)
        3710                 :            : {
        3711   [ #  #  #  #  :          0 :     if (s->v.TryStar.finalbody && asdl_seq_LEN(s->v.TryStar.finalbody)) {
                       #  # ]
        3712                 :          0 :         return compiler_try_star_finally(c, s);
        3713                 :            :     }
        3714                 :            :     else {
        3715                 :          0 :         return compiler_try_star_except(c, s);
        3716                 :            :     }
        3717                 :            : }
        3718                 :            :
        3719                 :            : static int
        3720                 :         50 : compiler_import_as(struct compiler *c, location loc,
        3721                 :            :                    identifier name, identifier asname)
        3722                 :            : {
        3723                 :            :     /* The IMPORT_NAME opcode was already generated.  This function
        3724                 :            :        merely needs to bind the result to a name.
        3725                 :            :
        3726                 :            :        If there is a dot in name, we need to split it and emit a
        3727                 :            :        IMPORT_FROM for each name.
        3728                 :            :     */
        3729                 :         50 :     Py_ssize_t len = PyUnicode_GET_LENGTH(name);
        3730                 :         50 :     Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
        3731         [ -  + ]:         50 :     if (dot == -2) {
        3732                 :          0 :         return ERROR;
        3733                 :            :     }
        3734         [ +  + ]:         50 :     if (dot != -1) {
        3735                 :            :         /* Consume the base module name to get the first attribute */
        3736                 :          4 :         while (1) {
        3737                 :          8 :             Py_ssize_t pos = dot + 1;
        3738                 :            :             PyObject *attr;
        3739                 :          8 :             dot = PyUnicode_FindChar(name, '.', pos, len, 1);
        3740         [ -  + ]:          8 :             if (dot == -2) {
        3741                 :          0 :                 return ERROR;
        3742                 :            :             }
        3743         [ +  + ]:          8 :             attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
        3744         [ -  + ]:          8 :             if (!attr) {
        3745                 :          0 :                 return ERROR;
        3746                 :            :             }
        3747         [ -  + ]:          8 :             ADDOP_N(c, loc, IMPORT_FROM, attr, names);
        3748         [ +  + ]:          8 :             if (dot == -1) {
        3749                 :          4 :                 break;
        3750                 :            :             }
        3751         [ -  + ]:          4 :             ADDOP_I(c, loc, SWAP, 2);
        3752         [ -  + ]:          4 :             ADDOP(c, loc, POP_TOP);
        3753                 :            :         }
        3754         [ -  + ]:          4 :         RETURN_IF_ERROR(compiler_nameop(c, loc, asname, Store));
        3755         [ -  + ]:          4 :         ADDOP(c, loc, POP_TOP);
        3756                 :          4 :         return SUCCESS;
        3757                 :            :     }
        3758                 :         46 :     return compiler_nameop(c, loc, asname, Store);
        3759                 :            : }
        3760                 :            :
        3761                 :            : static int
        3762                 :        899 : compiler_import(struct compiler *c, stmt_ty s)
        3763                 :            : {
        3764                 :        899 :     location loc = LOC(s);
        3765                 :            :     /* The Import node stores a module name like a.b.c as a single
        3766                 :            :        string.  This is convenient for all cases except
        3767                 :            :          import a.b.c as d
        3768                 :            :        where we need to parse that string to extract the individual
        3769                 :            :        module names.
        3770                 :            :        XXX Perhaps change the representation to make this case simpler?
        3771                 :            :      */
        3772         [ +  - ]:        899 :     Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
        3773                 :            :
        3774                 :        899 :     PyObject *zero = _PyLong_GetZero();  // borrowed reference
        3775         [ +  + ]:       1819 :     for (i = 0; i < n; i++) {
        3776                 :        920 :         alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
        3777                 :            :         int r;
        3778                 :            :
        3779         [ -  + ]:        920 :         ADDOP_LOAD_CONST(c, loc, zero);
        3780         [ -  + ]:        920 :         ADDOP_LOAD_CONST(c, loc, Py_None);
        3781         [ -  + ]:        920 :         ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names);
        3782                 :            :
        3783         [ +  + ]:        920 :         if (alias->asname) {
        3784                 :         50 :             r = compiler_import_as(c, loc, alias->name, alias->asname);
        3785         [ -  + ]:         50 :             RETURN_IF_ERROR(r);
        3786                 :            :         }
        3787                 :            :         else {
        3788                 :        870 :             identifier tmp = alias->name;
        3789                 :        870 :             Py_ssize_t dot = PyUnicode_FindChar(
        3790                 :        870 :                 alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
        3791         [ +  + ]:        870 :             if (dot != -1) {
        3792                 :         22 :                 tmp = PyUnicode_Substring(alias->name, 0, dot);
        3793         [ -  + ]:         22 :                 if (tmp == NULL) {
        3794                 :          0 :                     return ERROR;
        3795                 :            :                 }
        3796                 :            :             }
        3797                 :        870 :             r = compiler_nameop(c, loc, tmp, Store);
        3798         [ +  + ]:        870 :             if (dot != -1) {
        3799                 :         22 :                 Py_DECREF(tmp);
        3800                 :            :             }
        3801         [ -  + ]:        870 :             RETURN_IF_ERROR(r);
        3802                 :            :         }
        3803                 :            :     }
        3804                 :        899 :     return SUCCESS;
        3805                 :            : }
        3806                 :            :
        3807                 :            : static int
        3808                 :        524 : compiler_from_import(struct compiler *c, stmt_ty s)
        3809                 :            : {
        3810         [ +  - ]:        524 :     Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names);
        3811                 :            :
        3812   [ -  +  -  + ]:        524 :     ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level));
        3813                 :            :
        3814                 :        524 :     PyObject *names = PyTuple_New(n);
        3815         [ -  + ]:        524 :     if (!names) {
        3816                 :          0 :         return ERROR;
        3817                 :            :     }
        3818                 :            :
        3819                 :            :     /* build up the names */
        3820         [ +  + ]:       1347 :     for (Py_ssize_t i = 0; i < n; i++) {
        3821                 :        823 :         alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
        3822                 :        823 :         PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name));
        3823                 :            :     }
        3824                 :            :
        3825         [ +  - ]:        524 :     if (location_is_after(LOC(s), c->c_future.ff_location) &&
        3826   [ +  +  -  + ]:        953 :         s->v.ImportFrom.module &&
        3827                 :        429 :         _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__"))
        3828                 :            :     {
        3829                 :          0 :         Py_DECREF(names);
        3830                 :          0 :         return compiler_error(c, LOC(s), "from __future__ imports must occur "
        3831                 :            :                               "at the beginning of the file");
        3832                 :            :     }
        3833   [ -  +  -  + ]:        524 :     ADDOP_LOAD_CONST_NEW(c, LOC(s), names);
        3834                 :            :
        3835         [ +  + ]:        524 :     if (s->v.ImportFrom.module) {
        3836         [ -  + ]:        429 :         ADDOP_NAME(c, LOC(s), IMPORT_NAME, s->v.ImportFrom.module, names);
        3837                 :            :     }
        3838                 :            :     else {
        3839                 :            :         _Py_DECLARE_STR(empty, "");
        3840         [ -  + ]:         95 :         ADDOP_NAME(c, LOC(s), IMPORT_NAME, &_Py_STR(empty), names);
        3841                 :            :     }
        3842         [ +  + ]:       1299 :     for (Py_ssize_t i = 0; i < n; i++) {
        3843                 :        823 :         alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
        3844                 :            :         identifier store_name;
        3845                 :            :
        3846   [ +  +  +  + ]:        823 :         if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
        3847                 :            :             assert(n == 1);
        3848         [ -  + ]:         48 :             ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
        3849         [ -  + ]:         48 :             ADDOP(c, NO_LOCATION, POP_TOP);
        3850                 :         48 :             return SUCCESS;
        3851                 :            :         }
        3852                 :            :
        3853         [ -  + ]:        775 :         ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names);
        3854                 :        775 :         store_name = alias->name;
        3855         [ +  + ]:        775 :         if (alias->asname) {
        3856                 :         90 :             store_name = alias->asname;
        3857                 :            :         }
        3858                 :            :
        3859         [ -  + ]:        775 :         RETURN_IF_ERROR(compiler_nameop(c, LOC(s), store_name, Store));
        3860                 :            :     }
        3861                 :            :     /* remove imported module */
        3862         [ -  + ]:        476 :     ADDOP(c, LOC(s), POP_TOP);
        3863                 :        476 :     return SUCCESS;
        3864                 :            : }
        3865                 :            :
        3866                 :            : static int
        3867                 :        239 : compiler_assert(struct compiler *c, stmt_ty s)
        3868                 :            : {
        3869                 :            :     /* Always emit a warning if the test is a non-zero length tuple */
        3870         [ -  + ]:        239 :     if ((s->v.Assert.test->kind == Tuple_kind &&
        3871   [ #  #  #  # ]:          0 :         asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
        3872   [ +  +  -  + ]:        242 :         (s->v.Assert.test->kind == Constant_kind &&
        3873         [ -  - ]:          3 :          PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
        3874                 :          0 :          PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0))
        3875                 :            :     {
        3876         [ #  # ]:          0 :         RETURN_IF_ERROR(
        3877                 :            :             compiler_warn(c, LOC(s), "assertion is always true, "
        3878                 :            :                                      "perhaps remove parentheses?"));
        3879                 :            :     }
        3880         [ -  + ]:        239 :     if (c->c_optimize) {
        3881                 :          0 :         return SUCCESS;
        3882                 :            :     }
        3883         [ -  + ]:        239 :     NEW_JUMP_TARGET_LABEL(c, end);
        3884         [ -  + ]:        239 :     RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.Assert.test, end, 1));
        3885         [ -  + ]:        239 :     ADDOP(c, LOC(s), LOAD_ASSERTION_ERROR);
        3886         [ +  + ]:        239 :     if (s->v.Assert.msg) {
        3887         [ -  + ]:         71 :         VISIT(c, expr, s->v.Assert.msg);
        3888         [ -  + ]:         71 :         ADDOP_I(c, LOC(s), CALL, 0);
        3889                 :            :     }
        3890         [ -  + ]:        239 :     ADDOP_I(c, LOC(s), RAISE_VARARGS, 1);
        3891                 :            :
        3892         [ -  + ]:        239 :     USE_LABEL(c, end);
        3893                 :        239 :     return SUCCESS;
        3894                 :            : }
        3895                 :            :
        3896                 :            : static int
        3897                 :       8026 : compiler_stmt_expr(struct compiler *c, location loc, expr_ty value)
        3898                 :            : {
        3899   [ +  +  +  - ]:       8026 :     if (c->c_interactive && c->c_nestlevel <= 1) {
        3900         [ -  + ]:         47 :         VISIT(c, expr, value);
        3901         [ -  + ]:         47 :         ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT);
        3902         [ -  + ]:         47 :         ADDOP(c, NO_LOCATION, POP_TOP);
        3903                 :         47 :         return SUCCESS;
        3904                 :            :     }
        3905                 :            :
        3906         [ +  + ]:       7979 :     if (value->kind == Constant_kind) {
        3907                 :            :         /* ignore constant statement */
        3908         [ -  + ]:          1 :         ADDOP(c, loc, NOP);
        3909                 :          1 :         return SUCCESS;
        3910                 :            :     }
        3911                 :            :
        3912         [ -  + ]:       7978 :     VISIT(c, expr, value);
        3913         [ -  + ]:       7978 :     ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */
        3914                 :       7978 :     return SUCCESS;
        3915                 :            : }
        3916                 :            :
        3917                 :            : static int
        3918                 :      55660 : compiler_visit_stmt(struct compiler *c, stmt_ty s)
        3919                 :            : {
        3920                 :            :
        3921   [ +  +  +  +  :      55660 :     switch (s->kind) {
              +  +  +  +  +
              +  +  +  +  -
              +  +  +  +  +
              +  +  +  +  +
                    +  -  - ]
        3922                 :       6243 :     case FunctionDef_kind:
        3923                 :       6243 :         return compiler_function(c, s, 0);
        3924                 :        733 :     case ClassDef_kind:
        3925                 :        733 :         return compiler_class(c, s);
        3926                 :       5842 :     case Return_kind:
        3927                 :       5842 :         return compiler_return(c, s);
        3928                 :        201 :     case Delete_kind:
        3929   [ -  +  +  -  :        439 :         VISIT_SEQ(c, expr, s->v.Delete.targets)
                       +  + ]
        3930                 :        201 :         break;
        3931                 :      16725 :     case Assign_kind:
        3932                 :            :     {
        3933         [ +  - ]:      16725 :         Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets);
        3934         [ -  + ]:      16725 :         VISIT(c, expr, s->v.Assign.value);
        3935         [ +  + ]:      33608 :         for (Py_ssize_t i = 0; i < n; i++) {
        3936         [ +  + ]:      16883 :             if (i < n - 1) {
        3937         [ -  + ]:        158 :                 ADDOP_I(c, LOC(s), COPY, 1);
        3938                 :            :             }
        3939         [ -  + ]:      16883 :             VISIT(c, expr,
        3940                 :            :                   (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
        3941                 :            :         }
        3942                 :      16725 :         break;
        3943                 :            :     }
        3944                 :        722 :     case AugAssign_kind:
        3945                 :        722 :         return compiler_augassign(c, s);
        3946                 :         17 :     case AnnAssign_kind:
        3947                 :         17 :         return compiler_annassign(c, s);
        3948                 :       1236 :     case For_kind:
        3949                 :       1236 :         return compiler_for(c, s);
        3950                 :        305 :     case While_kind:
        3951                 :        305 :         return compiler_while(c, s);
        3952                 :       8896 :     case If_kind:
        3953                 :       8896 :         return compiler_if(c, s);
        3954                 :          4 :     case Match_kind:
        3955                 :          4 :         return compiler_match(c, s);
        3956                 :       1939 :     case Raise_kind:
        3957                 :            :     {
        3958                 :       1939 :         Py_ssize_t n = 0;
        3959         [ +  + ]:       1939 :         if (s->v.Raise.exc) {
        3960         [ -  + ]:       1739 :             VISIT(c, expr, s->v.Raise.exc);
        3961                 :       1739 :             n++;
        3962         [ +  + ]:       1739 :             if (s->v.Raise.cause) {
        3963         [ -  + ]:        102 :                 VISIT(c, expr, s->v.Raise.cause);
        3964                 :        102 :                 n++;
        3965                 :            :             }
        3966                 :            :         }
        3967         [ -  + ]:       1939 :         ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n);
        3968                 :       1939 :         break;
        3969                 :            :     }
        3970                 :       1469 :     case Try_kind:
        3971                 :       1469 :         return compiler_try(c, s);
        3972                 :          0 :     case TryStar_kind:
        3973                 :          0 :         return compiler_try_star(c, s);
        3974                 :        239 :     case Assert_kind:
        3975                 :        239 :         return compiler_assert(c, s);
        3976                 :        899 :     case Import_kind:
        3977                 :        899 :         return compiler_import(c, s);
        3978                 :        524 :     case ImportFrom_kind:
        3979                 :        524 :         return compiler_from_import(c, s);
        3980                 :         87 :     case Global_kind:
        3981                 :            :     case Nonlocal_kind:
        3982                 :         87 :         break;
        3983                 :       8026 :     case Expr_kind:
        3984                 :            :     {
        3985                 :       8026 :         return compiler_stmt_expr(c, LOC(s), s->v.Expr.value);
        3986                 :            :     }
        3987                 :        505 :     case Pass_kind:
        3988                 :            :     {
        3989         [ -  + ]:        505 :         ADDOP(c, LOC(s), NOP);
        3990                 :        505 :         break;
        3991                 :            :     }
        3992                 :        275 :     case Break_kind:
        3993                 :            :     {
        3994                 :        275 :         return compiler_break(c, LOC(s));
        3995                 :            :     }
        3996                 :        231 :     case Continue_kind:
        3997                 :            :     {
        3998                 :        231 :         return compiler_continue(c, LOC(s));
        3999                 :            :     }
        4000                 :        379 :     case With_kind:
        4001                 :        379 :         return compiler_with(c, s, 0);
        4002                 :        158 :     case AsyncFunctionDef_kind:
        4003                 :        158 :         return compiler_function(c, s, 1);
        4004                 :          5 :     case AsyncWith_kind:
        4005                 :          5 :         return compiler_async_with(c, s, 0);
        4006                 :          0 :     case AsyncFor_kind:
        4007                 :          0 :         return compiler_async_for(c, s);
        4008                 :            :     }
        4009                 :            :
        4010                 :      19457 :     return SUCCESS;
        4011                 :            : }
        4012                 :            :
        4013                 :            : static int
        4014                 :        266 : unaryop(unaryop_ty op)
        4015                 :            : {
        4016   [ +  +  +  - ]:        266 :     switch (op) {
        4017                 :         25 :     case Invert:
        4018                 :         25 :         return UNARY_INVERT;
        4019                 :         73 :     case Not:
        4020                 :         73 :         return UNARY_NOT;
        4021                 :        168 :     case USub:
        4022                 :        168 :         return UNARY_NEGATIVE;
        4023                 :          0 :     default:
        4024                 :          0 :         PyErr_Format(PyExc_SystemError,
        4025                 :            :             "unary op %d should not be possible", op);
        4026                 :          0 :         return 0;
        4027                 :            :     }
        4028                 :            : }
        4029                 :            :
        4030                 :            : static int
        4031                 :       4263 : addop_binary(struct compiler *c, location loc, operator_ty binop,
        4032                 :            :              bool inplace)
        4033                 :            : {
        4034                 :            :     int oparg;
        4035   [ +  +  +  +  :       4263 :     switch (binop) {
              +  +  +  +  +
                 +  +  +  +
                          - ]
        4036                 :       1898 :         case Add:
        4037         [ +  + ]:       1898 :             oparg = inplace ? NB_INPLACE_ADD : NB_ADD;
        4038                 :       1898 :             break;
        4039                 :        627 :         case Sub:
        4040         [ +  + ]:        627 :             oparg = inplace ? NB_INPLACE_SUBTRACT : NB_SUBTRACT;
        4041                 :        627 :             break;
        4042                 :        415 :         case Mult:
        4043         [ +  + ]:        415 :             oparg = inplace ? NB_INPLACE_MULTIPLY : NB_MULTIPLY;
        4044                 :        415 :             break;
        4045                 :          2 :         case MatMult:
        4046         [ +  + ]:          2 :             oparg = inplace ? NB_INPLACE_MATRIX_MULTIPLY : NB_MATRIX_MULTIPLY;
        4047                 :          2 :             break;
        4048                 :        111 :         case Div:
        4049         [ +  + ]:        111 :             oparg = inplace ? NB_INPLACE_TRUE_DIVIDE : NB_TRUE_DIVIDE;
        4050                 :        111 :             break;
        4051                 :        542 :         case Mod:
        4052         [ +  + ]:        542 :             oparg = inplace ? NB_INPLACE_REMAINDER : NB_REMAINDER;
        4053                 :        542 :             break;
        4054                 :         91 :         case Pow:
        4055         [ +  + ]:         91 :             oparg = inplace ? NB_INPLACE_POWER : NB_POWER;
        4056                 :         91 :             break;
        4057                 :         39 :         case LShift:
        4058         [ +  + ]:         39 :             oparg = inplace ? NB_INPLACE_LSHIFT : NB_LSHIFT;
        4059                 :         39 :             break;
        4060                 :         25 :         case RShift:
        4061         [ +  + ]:         25 :             oparg = inplace ? NB_INPLACE_RSHIFT : NB_RSHIFT;
        4062                 :         25 :             break;
        4063                 :        186 :         case BitOr:
        4064         [ +  + ]:        186 :             oparg = inplace ? NB_INPLACE_OR : NB_OR;
        4065                 :        186 :             break;
        4066                 :         22 :         case BitXor:
        4067         [ +  + ]:         22 :             oparg = inplace ? NB_INPLACE_XOR : NB_XOR;
        4068                 :         22 :             break;
        4069                 :        210 :         case BitAnd:
        4070         [ +  + ]:        210 :             oparg = inplace ? NB_INPLACE_AND : NB_AND;
        4071                 :        210 :             break;
        4072                 :         95 :         case FloorDiv:
        4073         [ +  + ]:         95 :             oparg = inplace ? NB_INPLACE_FLOOR_DIVIDE : NB_FLOOR_DIVIDE;
        4074                 :         95 :             break;
        4075                 :          0 :         default:
        4076         [ #  # ]:          0 :             PyErr_Format(PyExc_SystemError, "%s op %d should not be possible",
        4077                 :            :                          inplace ? "inplace" : "binary", binop);
        4078                 :          0 :             return ERROR;
        4079                 :            :     }
        4080         [ -  + ]:       4263 :     ADDOP_I(c, loc, BINARY_OP, oparg);
        4081                 :       4263 :     return SUCCESS;
        4082                 :            : }
        4083                 :            :
        4084                 :            :
        4085                 :            : static int
        4086                 :        449 : addop_yield(struct compiler *c, location loc) {
        4087   [ +  -  +  + ]:        449 :     if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) {
        4088         [ -  + ]:          3 :         ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
        4089                 :            :     }
        4090         [ -  + ]:        449 :     ADDOP_I(c, loc, YIELD_VALUE, 0);
        4091         [ -  + ]:        449 :     ADDOP_I(c, loc, RESUME, 1);
        4092                 :        449 :     return SUCCESS;
        4093                 :            : }
        4094                 :            :
        4095                 :            : static int
        4096                 :     115879 : compiler_nameop(struct compiler *c, location loc,
        4097                 :            :                 identifier name, expr_context_ty ctx)
        4098                 :            : {
        4099                 :            :     int op, scope;
        4100                 :            :     Py_ssize_t arg;
        4101                 :            :     enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
        4102                 :            :
        4103                 :     115879 :     PyObject *dict = c->u->u_names;
        4104                 :            :     PyObject *mangled;
        4105                 :            :
        4106                 :            :     assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
        4107                 :            :            !_PyUnicode_EqualToASCIIString(name, "True") &&
        4108                 :            :            !_PyUnicode_EqualToASCIIString(name, "False"));
        4109                 :            :
        4110         [ -  + ]:     115879 :     if (forbidden_name(c, loc, name, ctx)) {
        4111                 :          0 :         return ERROR;
        4112                 :            :     }
        4113                 :            :
        4114                 :     115879 :     mangled = _Py_Mangle(c->u->u_private, name);
        4115         [ -  + ]:     115879 :     if (!mangled) {
        4116                 :          0 :         return ERROR;
        4117                 :            :     }
        4118                 :            :
        4119                 :     115879 :     op = 0;
        4120                 :     115879 :     optype = OP_NAME;
        4121                 :     115879 :     scope = _PyST_GetScope(c->u->u_ste, mangled);
        4122   [ +  +  +  +  :     115879 :     switch (scope) {
                       +  + ]
        4123                 :        996 :     case FREE:
        4124                 :        996 :         dict = c->u->u_freevars;
        4125                 :        996 :         optype = OP_DEREF;
        4126                 :        996 :         break;
        4127                 :       1452 :     case CELL:
        4128                 :       1452 :         dict = c->u->u_cellvars;
        4129                 :       1452 :         optype = OP_DEREF;
        4130                 :       1452 :         break;
        4131                 :      86222 :     case LOCAL:
        4132         [ +  + ]:      86222 :         if (c->u->u_ste->ste_type == FunctionBlock)
        4133                 :      71661 :             optype = OP_FAST;
        4134                 :      86222 :         break;
        4135                 :      24052 :     case GLOBAL_IMPLICIT:
        4136         [ +  + ]:      24052 :         if (c->u->u_ste->ste_type == FunctionBlock)
        4137                 :      21268 :             optype = OP_GLOBAL;
        4138                 :      24052 :         break;
        4139                 :        287 :     case GLOBAL_EXPLICIT:
        4140                 :        287 :         optype = OP_GLOBAL;
        4141                 :        287 :         break;
        4142                 :       2870 :     default:
        4143                 :            :         /* scope can be 0 */
        4144                 :       2870 :         break;
        4145                 :            :     }
        4146                 :            :
        4147                 :            :     /* XXX Leave assert here, but handle __doc__ and the like better */
        4148                 :            :     assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
        4149                 :            :
        4150   [ +  +  +  +  :     115879 :     switch (optype) {
                          - ]
        4151   [ +  +  -  - ]:       2448 :     case OP_DEREF:
        4152                 :            :         switch (ctx) {
        4153                 :       2022 :         case Load:
        4154         [ +  + ]:       2022 :             op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
        4155                 :       2022 :             break;
        4156                 :        426 :         case Store: op = STORE_DEREF; break;
        4157                 :          0 :         case Del: op = DELETE_DEREF; break;
        4158                 :            :         }
        4159                 :       2448 :         break;
        4160   [ +  +  +  - ]:      71661 :     case OP_FAST:
        4161                 :            :         switch (ctx) {
        4162                 :      55671 :         case Load: op = LOAD_FAST; break;
        4163                 :      15390 :         case Store: op = STORE_FAST; break;
        4164                 :        600 :         case Del: op = DELETE_FAST; break;
        4165                 :            :         }
        4166         [ -  + ]:      71661 :         ADDOP_N(c, loc, op, mangled, varnames);
        4167                 :      71661 :         return SUCCESS;
        4168   [ +  +  -  - ]:      21555 :     case OP_GLOBAL:
        4169                 :            :         switch (ctx) {
        4170                 :      21400 :         case Load: op = LOAD_GLOBAL; break;
        4171                 :        155 :         case Store: op = STORE_GLOBAL; break;
        4172                 :          0 :         case Del: op = DELETE_GLOBAL; break;
        4173                 :            :         }
        4174                 :      21555 :         break;
        4175   [ +  +  +  - ]:      20215 :     case OP_NAME:
        4176                 :            :         switch (ctx) {
        4177                 :       6996 :         case Load: op = LOAD_NAME; break;
        4178                 :      13085 :         case Store: op = STORE_NAME; break;
        4179                 :        134 :         case Del: op = DELETE_NAME; break;
        4180                 :            :         }
        4181                 :      20215 :         break;
        4182                 :            :     }
        4183                 :            :
        4184                 :      44218 :     assert(op);
        4185                 :      44218 :     arg = dict_add_o(dict, mangled);
        4186                 :      44218 :     Py_DECREF(mangled);
        4187         [ -  + ]:      44218 :     if (arg < 0) {
        4188                 :          0 :         return ERROR;
        4189                 :            :     }
        4190         [ +  + ]:      44218 :     if (op == LOAD_GLOBAL) {
        4191                 :      21400 :         arg <<= 1;
        4192                 :            :     }
        4193                 :      44218 :     return codegen_addop_i(INSTR_SEQUENCE(c), op, arg, loc);
        4194                 :            : }
        4195                 :            :
        4196                 :            : static int
        4197                 :        392 : compiler_boolop(struct compiler *c, expr_ty e)
        4198                 :            : {
        4199                 :            :     int jumpi;
        4200                 :            :     Py_ssize_t i, n;
        4201                 :            :     asdl_expr_seq *s;
        4202                 :            :
        4203                 :        392 :     location loc = LOC(e);
        4204                 :            :     assert(e->kind == BoolOp_kind);
        4205         [ +  + ]:        392 :     if (e->v.BoolOp.op == And)
        4206                 :        152 :         jumpi = JUMP_IF_FALSE_OR_POP;
        4207                 :            :     else
        4208                 :        240 :         jumpi = JUMP_IF_TRUE_OR_POP;
        4209         [ -  + ]:        392 :     NEW_JUMP_TARGET_LABEL(c, end);
        4210                 :        392 :     s = e->v.BoolOp.values;
        4211         [ +  - ]:        392 :     n = asdl_seq_LEN(s) - 1;
        4212                 :            :     assert(n >= 0);
        4213         [ +  + ]:        846 :     for (i = 0; i < n; ++i) {
        4214         [ -  + ]:        454 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
        4215         [ -  + ]:        454 :         ADDOP_JUMP(c, loc, jumpi, end);
        4216         [ -  + ]:        454 :         NEW_JUMP_TARGET_LABEL(c, next);
        4217                 :            :
        4218         [ -  + ]:        454 :         USE_LABEL(c, next);
        4219                 :            :     }
        4220         [ -  + ]:        392 :     VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
        4221                 :            :
        4222         [ -  + ]:        392 :     USE_LABEL(c, end);
        4223                 :        392 :     return SUCCESS;
        4224                 :            : }
        4225                 :            :
        4226                 :            : static int
        4227                 :       3075 : starunpack_helper(struct compiler *c, location loc,
        4228                 :            :                   asdl_expr_seq *elts, int pushed,
        4229                 :            :                   int build, int add, int extend, int tuple)
        4230                 :            : {
        4231         [ +  + ]:       3075 :     Py_ssize_t n = asdl_seq_LEN(elts);
        4232   [ +  +  +  + ]:       3075 :     if (n > 2 && are_all_items_const(elts, 0, n)) {
        4233                 :        180 :         PyObject *folded = PyTuple_New(n);
        4234         [ -  + ]:        180 :         if (folded == NULL) {
        4235                 :          0 :             return ERROR;
        4236                 :            :         }
        4237                 :            :         PyObject *val;
        4238         [ +  + ]:       2505 :         for (Py_ssize_t i = 0; i < n; i++) {
        4239                 :       2325 :             val = ((expr_ty)asdl_seq_GET(elts, i))->v.Constant.value;
        4240                 :       2325 :             PyTuple_SET_ITEM(folded, i, Py_NewRef(val));
        4241                 :            :         }
        4242   [ +  +  +  - ]:        180 :         if (tuple && !pushed) {
        4243   [ -  +  -  + ]:          1 :             ADDOP_LOAD_CONST_NEW(c, loc, folded);
        4244                 :            :         } else {
        4245         [ +  + ]:        179 :             if (add == SET_ADD) {
        4246                 :          8 :                 Py_SETREF(folded, PyFrozenSet_New(folded));
        4247         [ -  + ]:          8 :                 if (folded == NULL) {
        4248                 :          0 :                     return ERROR;
        4249                 :            :                 }
        4250                 :            :             }
        4251         [ -  + ]:        179 :             ADDOP_I(c, loc, build, pushed);
        4252   [ -  +  -  + ]:        179 :             ADDOP_LOAD_CONST_NEW(c, loc, folded);
        4253         [ -  + ]:        179 :             ADDOP_I(c, loc, extend, 1);
        4254         [ -  + ]:        179 :             if (tuple) {
        4255         [ #  # ]:          0 :                 ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
        4256                 :            :             }
        4257                 :            :         }
        4258                 :        180 :         return SUCCESS;
        4259                 :            :     }
        4260                 :            :
        4261                 :       2895 :     int big = n+pushed > STACK_USE_GUIDELINE;
        4262                 :       2895 :     int seen_star = 0;
        4263         [ +  + ]:       8326 :     for (Py_ssize_t i = 0; i < n; i++) {
        4264                 :       5562 :         expr_ty elt = asdl_seq_GET(elts, i);
        4265         [ +  + ]:       5562 :         if (elt->kind == Starred_kind) {
        4266                 :        131 :             seen_star = 1;
        4267                 :        131 :             break;
        4268                 :            :         }
        4269                 :            :     }
        4270   [ +  +  +  - ]:       2895 :     if (!seen_star && !big) {
        4271         [ +  + ]:       8019 :         for (Py_ssize_t i = 0; i < n; i++) {
        4272                 :       5255 :             expr_ty elt = asdl_seq_GET(elts, i);
        4273         [ -  + ]:       5255 :             VISIT(c, expr, elt);
        4274                 :            :         }
        4275         [ +  + ]:       2764 :         if (tuple) {
        4276         [ -  + ]:       1877 :             ADDOP_I(c, loc, BUILD_TUPLE, n+pushed);
        4277                 :            :         } else {
        4278         [ -  + ]:        887 :             ADDOP_I(c, loc, build, n+pushed);
        4279                 :            :         }
        4280                 :       2764 :         return SUCCESS;
        4281                 :            :     }
        4282                 :        131 :     int sequence_built = 0;
        4283         [ -  + ]:        131 :     if (big) {
        4284         [ #  # ]:          0 :         ADDOP_I(c, loc, build, pushed);
        4285                 :          0 :         sequence_built = 1;
        4286                 :            :     }
        4287         [ +  + ]:        456 :     for (Py_ssize_t i = 0; i < n; i++) {
        4288                 :        325 :         expr_ty elt = asdl_seq_GET(elts, i);
        4289         [ +  + ]:        325 :         if (elt->kind == Starred_kind) {
        4290         [ +  + ]:        140 :             if (sequence_built == 0) {
        4291         [ -  + ]:        131 :                 ADDOP_I(c, loc, build, i+pushed);
        4292                 :        131 :                 sequence_built = 1;
        4293                 :            :             }
        4294         [ -  + ]:        140 :             VISIT(c, expr, elt->v.Starred.value);
        4295         [ -  + ]:        140 :             ADDOP_I(c, loc, extend, 1);
        4296                 :            :         }
        4297                 :            :         else {
        4298         [ -  + ]:        185 :             VISIT(c, expr, elt);
        4299         [ +  + ]:        185 :             if (sequence_built) {
        4300         [ -  + ]:          9 :                 ADDOP_I(c, loc, add, 1);
        4301                 :            :             }
        4302                 :            :         }
        4303                 :            :     }
        4304                 :            :     assert(sequence_built);
        4305         [ +  + ]:        131 :     if (tuple) {
        4306         [ -  + ]:        129 :         ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
        4307                 :            :     }
        4308                 :        131 :     return SUCCESS;
        4309                 :            : }
        4310                 :            :
        4311                 :            : static int
        4312                 :       1134 : unpack_helper(struct compiler *c, location loc, asdl_expr_seq *elts)
        4313                 :            : {
        4314         [ +  - ]:       1134 :     Py_ssize_t n = asdl_seq_LEN(elts);
        4315                 :       1134 :     int seen_star = 0;
        4316         [ +  + ]:       3864 :     for (Py_ssize_t i = 0; i < n; i++) {
        4317                 :       2730 :         expr_ty elt = asdl_seq_GET(elts, i);
        4318   [ +  +  +  - ]:       2730 :         if (elt->kind == Starred_kind && !seen_star) {
        4319         [ +  - ]:          7 :             if ((i >= (1 << 8)) ||
        4320         [ -  + ]:          7 :                 (n-i-1 >= (INT_MAX >> 8))) {
        4321                 :          0 :                 return compiler_error(c, loc,
        4322                 :            :                     "too many expressions in "
        4323                 :            :                     "star-unpacking assignment");
        4324                 :            :             }
        4325         [ -  + ]:          7 :             ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
        4326                 :          7 :             seen_star = 1;
        4327                 :            :         }
        4328         [ -  + ]:       2723 :         else if (elt->kind == Starred_kind) {
        4329                 :          0 :             return compiler_error(c, loc,
        4330                 :            :                 "multiple starred expressions in assignment");
        4331                 :            :         }
        4332                 :            :     }
        4333         [ +  + ]:       1134 :     if (!seen_star) {
        4334         [ -  + ]:       1127 :         ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
        4335                 :            :     }
        4336                 :       1134 :     return SUCCESS;
        4337                 :            : }
        4338                 :            :
        4339                 :            : static int
        4340                 :       1134 : assignment_helper(struct compiler *c, location loc, asdl_expr_seq *elts)
        4341                 :            : {
        4342         [ +  - ]:       1134 :     Py_ssize_t n = asdl_seq_LEN(elts);
        4343         [ -  + ]:       1134 :     RETURN_IF_ERROR(unpack_helper(c, loc, elts));
        4344         [ +  + ]:       3864 :     for (Py_ssize_t i = 0; i < n; i++) {
        4345                 :       2730 :         expr_ty elt = asdl_seq_GET(elts, i);
        4346   [ +  +  -  + ]:       2730 :         VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
        4347                 :            :     }
        4348                 :       1134 :     return SUCCESS;
        4349                 :            : }
        4350                 :            :
        4351                 :            : static int
        4352                 :       1029 : compiler_list(struct compiler *c, expr_ty e)
        4353                 :            : {
        4354                 :       1029 :     location loc = LOC(e);
        4355                 :       1029 :     asdl_expr_seq *elts = e->v.List.elts;
        4356         [ +  + ]:       1029 :     if (e->v.List.ctx == Store) {
        4357                 :          1 :         return assignment_helper(c, loc, elts);
        4358                 :            :     }
        4359         [ +  - ]:       1028 :     else if (e->v.List.ctx == Load) {
        4360                 :       1028 :         return starunpack_helper(c, loc, elts, 0,
        4361                 :            :                                  BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0);
        4362                 :            :     }
        4363                 :            :     else {
        4364   [ #  #  #  #  :          0 :         VISIT_SEQ(c, expr, elts);
                       #  # ]
        4365                 :            :     }
        4366                 :          0 :     return SUCCESS;
        4367                 :            : }
        4368                 :            :
        4369                 :            : static int
        4370                 :       2952 : compiler_tuple(struct compiler *c, expr_ty e)
        4371                 :            : {
        4372                 :       2952 :     location loc = LOC(e);
        4373                 :       2952 :     asdl_expr_seq *elts = e->v.Tuple.elts;
        4374         [ +  + ]:       2952 :     if (e->v.Tuple.ctx == Store) {
        4375                 :       1133 :         return assignment_helper(c, loc, elts);
        4376                 :            :     }
        4377         [ +  + ]:       1819 :     else if (e->v.Tuple.ctx == Load) {
        4378                 :       1818 :         return starunpack_helper(c, loc, elts, 0,
        4379                 :            :                                  BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1);
        4380                 :            :     }
        4381                 :            :     else {
        4382   [ -  +  +  -  :         43 :         VISIT_SEQ(c, expr, elts);
                       +  + ]
        4383                 :            :     }
        4384                 :          1 :     return SUCCESS;
        4385                 :            : }
        4386                 :            :
        4387                 :            : static int
        4388                 :         40 : compiler_set(struct compiler *c, expr_ty e)
        4389                 :            : {
        4390                 :         40 :     location loc = LOC(e);
        4391                 :         40 :     return starunpack_helper(c, loc, e->v.Set.elts, 0,
        4392                 :            :                              BUILD_SET, SET_ADD, SET_UPDATE, 0);
        4393                 :            : }
        4394                 :            :
        4395                 :            : static bool
        4396                 :        924 : are_all_items_const(asdl_expr_seq *seq, Py_ssize_t begin, Py_ssize_t end)
        4397                 :            : {
        4398         [ +  + ]:       3859 :     for (Py_ssize_t i = begin; i < end; i++) {
        4399                 :       3576 :         expr_ty key = (expr_ty)asdl_seq_GET(seq, i);
        4400   [ +  -  +  + ]:       3576 :         if (key == NULL || key->kind != Constant_kind) {
        4401                 :        641 :             return false;
        4402                 :            :         }
        4403                 :            :     }
        4404                 :        283 :     return true;
        4405                 :            : }
        4406                 :            :
        4407                 :            : static int
        4408                 :        282 : compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
        4409                 :            : {
        4410                 :        282 :     Py_ssize_t i, n = end - begin;
        4411                 :            :     PyObject *keys, *key;
        4412                 :        282 :     int big = n*2 > STACK_USE_GUIDELINE;
        4413                 :        282 :     location loc = LOC(e);
        4414   [ +  +  +  +  :        282 :     if (n > 1 && !big && are_all_items_const(e->v.Dict.keys, begin, end)) {
                       +  + ]
        4415         [ +  + ]:        611 :         for (i = begin; i < end; i++) {
        4416         [ -  + ]:        508 :             VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
        4417                 :            :         }
        4418                 :        103 :         keys = PyTuple_New(n);
        4419         [ -  + ]:        103 :         if (keys == NULL) {
        4420                 :          0 :             return SUCCESS;
        4421                 :            :         }
        4422         [ +  + ]:        611 :         for (i = begin; i < end; i++) {
        4423                 :        508 :             key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value;
        4424                 :        508 :             PyTuple_SET_ITEM(keys, i - begin, Py_NewRef(key));
        4425                 :            :         }
        4426   [ -  +  -  + ]:        103 :         ADDOP_LOAD_CONST_NEW(c, loc, keys);
        4427         [ -  + ]:        103 :         ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n);
        4428                 :        103 :         return SUCCESS;
        4429                 :            :     }
        4430         [ +  + ]:        179 :     if (big) {
        4431         [ -  + ]:        135 :         ADDOP_I(c, loc, BUILD_MAP, 0);
        4432                 :            :     }
        4433         [ +  + ]:       2559 :     for (i = begin; i < end; i++) {
        4434         [ -  + ]:       2380 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
        4435         [ -  + ]:       2380 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
        4436         [ +  + ]:       2380 :         if (big) {
        4437         [ -  + ]:       2292 :             ADDOP_I(c, loc, MAP_ADD, 1);
        4438                 :            :         }
        4439                 :            :     }
        4440         [ +  + ]:        179 :     if (!big) {
        4441         [ -  + ]:         44 :         ADDOP_I(c, loc, BUILD_MAP, n);
        4442                 :            :     }
        4443                 :        179 :     return SUCCESS;
        4444                 :            : }
        4445                 :            :
        4446                 :            : static int
        4447                 :        397 : compiler_dict(struct compiler *c, expr_ty e)
        4448                 :            : {
        4449                 :        397 :     location loc = LOC(e);
        4450                 :            :     Py_ssize_t i, n, elements;
        4451                 :            :     int have_dict;
        4452                 :        397 :     int is_unpacking = 0;
        4453         [ +  - ]:        397 :     n = asdl_seq_LEN(e->v.Dict.values);
        4454                 :        397 :     have_dict = 0;
        4455                 :        397 :     elements = 0;
        4456         [ +  + ]:       3297 :     for (i = 0; i < n; i++) {
        4457                 :       2900 :         is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
        4458         [ +  + ]:       2900 :         if (is_unpacking) {
        4459         [ -  + ]:         12 :             if (elements) {
        4460         [ #  # ]:          0 :                 RETURN_IF_ERROR(compiler_subdict(c, e, i - elements, i));
        4461         [ #  # ]:          0 :                 if (have_dict) {
        4462         [ #  # ]:          0 :                     ADDOP_I(c, loc, DICT_UPDATE, 1);
        4463                 :            :                 }
        4464                 :          0 :                 have_dict = 1;
        4465                 :          0 :                 elements = 0;
        4466                 :            :             }
        4467         [ +  + ]:         12 :             if (have_dict == 0) {
        4468         [ -  + ]:          6 :                 ADDOP_I(c, loc, BUILD_MAP, 0);
        4469                 :          6 :                 have_dict = 1;
        4470                 :            :             }
        4471         [ -  + ]:         12 :             VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
        4472         [ -  + ]:         12 :             ADDOP_I(c, loc, DICT_UPDATE, 1);
        4473                 :            :         }
        4474                 :            :         else {
        4475         [ +  + ]:       2888 :             if (elements*2 > STACK_USE_GUIDELINE) {
        4476         [ -  + ]:        132 :                 RETURN_IF_ERROR(compiler_subdict(c, e, i - elements, i + 1));
        4477         [ +  + ]:        132 :                 if (have_dict) {
        4478         [ -  + ]:        122 :                     ADDOP_I(c, loc, DICT_UPDATE, 1);
        4479                 :            :                 }
        4480                 :        132 :                 have_dict = 1;
        4481                 :        132 :                 elements = 0;
        4482                 :            :             }
        4483                 :            :             else {
        4484                 :       2756 :                 elements++;
        4485                 :            :             }
        4486                 :            :         }
        4487                 :            :     }
        4488         [ +  + ]:        397 :     if (elements) {
        4489         [ -  + ]:        150 :         RETURN_IF_ERROR(compiler_subdict(c, e, n - elements, n));
        4490         [ +  + ]:        150 :         if (have_dict) {
        4491         [ -  + ]:         10 :             ADDOP_I(c, loc, DICT_UPDATE, 1);
        4492                 :            :         }
        4493                 :        150 :         have_dict = 1;
        4494                 :            :     }
        4495         [ +  + ]:        397 :     if (!have_dict) {
        4496         [ -  + ]:        241 :         ADDOP_I(c, loc, BUILD_MAP, 0);
        4497                 :            :     }
        4498                 :        397 :     return SUCCESS;
        4499                 :            : }
        4500                 :            :
        4501                 :            : static int
        4502                 :       6321 : compiler_compare(struct compiler *c, expr_ty e)
        4503                 :            : {
        4504                 :       6321 :     location loc = LOC(e);
        4505                 :            :     Py_ssize_t i, n;
        4506                 :            :
        4507         [ -  + ]:       6321 :     RETURN_IF_ERROR(check_compare(c, e));
        4508         [ -  + ]:       6321 :     VISIT(c, expr, e->v.Compare.left);
        4509                 :            :     assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
        4510         [ +  - ]:       6321 :     n = asdl_seq_LEN(e->v.Compare.ops) - 1;
        4511         [ +  + ]:       6321 :     if (n == 0) {
        4512         [ -  + ]:       6317 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
        4513         [ -  + ]:       6317 :         ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0));
        4514                 :            :     }
        4515                 :            :     else {
        4516         [ -  + ]:          4 :         NEW_JUMP_TARGET_LABEL(c, cleanup);
        4517         [ +  + ]:          8 :         for (i = 0; i < n; i++) {
        4518         [ -  + ]:          4 :             VISIT(c, expr,
        4519                 :            :                 (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
        4520         [ -  + ]:          4 :             ADDOP_I(c, loc, SWAP, 2);
        4521         [ -  + ]:          4 :             ADDOP_I(c, loc, COPY, 2);
        4522         [ -  + ]:          4 :             ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i));
        4523         [ -  + ]:          4 :             ADDOP_JUMP(c, loc, JUMP_IF_FALSE_OR_POP, cleanup);
        4524                 :            :         }
        4525         [ -  + ]:          4 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
        4526         [ -  + ]:          4 :         ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
        4527         [ -  + ]:          4 :         NEW_JUMP_TARGET_LABEL(c, end);
        4528         [ -  + ]:          4 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        4529                 :            :
        4530         [ -  + ]:          4 :         USE_LABEL(c, cleanup);
        4531         [ -  + ]:          4 :         ADDOP_I(c, loc, SWAP, 2);
        4532         [ -  + ]:          4 :         ADDOP(c, loc, POP_TOP);
        4533                 :            :
        4534         [ -  + ]:          4 :         USE_LABEL(c, end);
        4535                 :            :     }
        4536                 :       6321 :     return SUCCESS;
        4537                 :            : }
        4538                 :            :
        4539                 :            : static PyTypeObject *
        4540                 :       2593 : infer_type(expr_ty e)
        4541                 :            : {
        4542   [ +  -  -  -  :       2593 :     switch (e->kind) {
                 -  -  -  +
                          + ]
        4543                 :         43 :     case Tuple_kind:
        4544                 :         43 :         return &PyTuple_Type;
        4545                 :          0 :     case List_kind:
        4546                 :            :     case ListComp_kind:
        4547                 :          0 :         return &PyList_Type;
        4548                 :          0 :     case Dict_kind:
        4549                 :            :     case DictComp_kind:
        4550                 :          0 :         return &PyDict_Type;
        4551                 :          0 :     case Set_kind:
        4552                 :            :     case SetComp_kind:
        4553                 :          0 :         return &PySet_Type;
        4554                 :          0 :     case GeneratorExp_kind:
        4555                 :          0 :         return &PyGen_Type;
        4556                 :          0 :     case Lambda_kind:
        4557                 :          0 :         return &PyFunction_Type;
        4558                 :          0 :     case JoinedStr_kind:
        4559                 :            :     case FormattedValue_kind:
        4560                 :          0 :         return &PyUnicode_Type;
        4561                 :       1070 :     case Constant_kind:
        4562                 :       1070 :         return Py_TYPE(e->v.Constant.value);
        4563                 :       1480 :     default:
        4564                 :       1480 :         return NULL;
        4565                 :            :     }
        4566                 :            : }
        4567                 :            :
        4568                 :            : static int
        4569                 :      15536 : check_caller(struct compiler *c, expr_ty e)
        4570                 :            : {
        4571         [ -  + ]:      15536 :     switch (e->kind) {
        4572                 :          0 :     case Constant_kind:
        4573                 :            :     case Tuple_kind:
        4574                 :            :     case List_kind:
        4575                 :            :     case ListComp_kind:
        4576                 :            :     case Dict_kind:
        4577                 :            :     case DictComp_kind:
        4578                 :            :     case Set_kind:
        4579                 :            :     case SetComp_kind:
        4580                 :            :     case GeneratorExp_kind:
        4581                 :            :     case JoinedStr_kind:
        4582                 :            :     case FormattedValue_kind: {
        4583                 :          0 :         location loc = LOC(e);
        4584                 :          0 :         return compiler_warn(c, loc, "'%.200s' object is not callable; "
        4585                 :            :                                      "perhaps you missed a comma?",
        4586                 :          0 :                                      infer_type(e)->tp_name);
        4587                 :            :     }
        4588                 :      15536 :     default:
        4589                 :      15536 :         return SUCCESS;
        4590                 :            :     }
        4591                 :            : }
        4592                 :            :
        4593                 :            : static int
        4594                 :       2593 : check_subscripter(struct compiler *c, expr_ty e)
        4595                 :            : {
        4596                 :            :     PyObject *v;
        4597                 :            :
        4598      [ -  -  + ]:       2593 :     switch (e->kind) {
        4599                 :          0 :     case Constant_kind:
        4600                 :          0 :         v = e->v.Constant.value;
        4601   [ #  #  #  #  :          0 :         if (!(v == Py_None || v == Py_Ellipsis ||
                 #  #  #  # ]
        4602   [ #  #  #  # ]:          0 :               PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) ||
        4603   [ #  #  #  #  :          0 :               PyAnySet_Check(v)))
                       #  # ]
        4604                 :            :         {
        4605                 :          0 :             return SUCCESS;
        4606                 :            :         }
        4607                 :            :         /* fall through */
        4608                 :            :     case Set_kind:
        4609                 :            :     case SetComp_kind:
        4610                 :            :     case GeneratorExp_kind:
        4611                 :            :     case Lambda_kind: {
        4612                 :          0 :         location loc = LOC(e);
        4613                 :          0 :         return compiler_warn(c, loc, "'%.200s' object is not subscriptable; "
        4614                 :            :                                      "perhaps you missed a comma?",
        4615                 :          0 :                                      infer_type(e)->tp_name);
        4616                 :            :     }
        4617                 :       2593 :     default:
        4618                 :       2593 :         return SUCCESS;
        4619                 :            :     }
        4620                 :            : }
        4621                 :            :
        4622                 :            : static int
        4623                 :       2593 : check_index(struct compiler *c, expr_ty e, expr_ty s)
        4624                 :            : {
        4625                 :            :     PyObject *v;
        4626                 :            :
        4627                 :       2593 :     PyTypeObject *index_type = infer_type(s);
        4628         [ +  + ]:       2593 :     if (index_type == NULL
        4629         [ +  + ]:       1113 :         || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
        4630         [ -  + ]:        153 :         || index_type == &PySlice_Type) {
        4631                 :       2440 :         return SUCCESS;
        4632                 :            :     }
        4633                 :            :
        4634      [ -  -  + ]:        153 :     switch (e->kind) {
        4635                 :          0 :     case Constant_kind:
        4636                 :          0 :         v = e->v.Constant.value;
        4637   [ #  #  #  #  :          0 :         if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
                       #  # ]
        4638                 :          0 :             return SUCCESS;
        4639                 :            :         }
        4640                 :            :         /* fall through */
        4641                 :            :     case Tuple_kind:
        4642                 :            :     case List_kind:
        4643                 :            :     case ListComp_kind:
        4644                 :            :     case JoinedStr_kind:
        4645                 :            :     case FormattedValue_kind: {
        4646                 :          0 :         location loc = LOC(e);
        4647                 :          0 :         return compiler_warn(c, loc, "%.200s indices must be integers "
        4648                 :            :                                      "or slices, not %.200s; "
        4649                 :            :                                      "perhaps you missed a comma?",
        4650                 :          0 :                                      infer_type(e)->tp_name,
        4651                 :            :                                      index_type->tp_name);
        4652                 :            :     }
        4653                 :        153 :     default:
        4654                 :        153 :         return SUCCESS;
        4655                 :            :     }
        4656                 :            : }
        4657                 :            :
        4658                 :            : static int
        4659                 :      13833 : is_import_originated(struct compiler *c, expr_ty e)
        4660                 :            : {
        4661                 :            :     /* Check whether the global scope has an import named
        4662                 :            :      e, if it is a Name object. For not traversing all the
        4663                 :            :      scope stack every time this function is called, it will
        4664                 :            :      only check the global scope to determine whether something
        4665                 :            :      is imported or not. */
        4666                 :            :
        4667         [ +  + ]:      13833 :     if (e->kind != Name_kind) {
        4668                 :       2962 :         return 0;
        4669                 :            :     }
        4670                 :            :
        4671                 :      10871 :     long flags = _PyST_GetSymbol(c->c_st->st_top, e->v.Name.id);
        4672                 :      10871 :     return flags & DEF_IMPORT;
        4673                 :            : }
        4674                 :            :
        4675                 :            : // If an attribute access spans multiple lines, update the current start
        4676                 :            : // location to point to the attribute name.
        4677                 :            : static location
        4678                 :      41161 : update_start_location_to_match_attr(struct compiler *c, location loc,
        4679                 :            :                                     expr_ty attr)
        4680                 :            : {
        4681                 :            :     assert(attr->kind == Attribute_kind);
        4682         [ +  + ]:      41161 :     if (loc.lineno != attr->end_lineno) {
        4683                 :         80 :         loc.lineno = attr->end_lineno;
        4684                 :         80 :         int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
        4685         [ +  - ]:         80 :         if (len <= attr->end_col_offset) {
        4686                 :         80 :             loc.col_offset = attr->end_col_offset - len;
        4687                 :            :         }
        4688                 :            :         else {
        4689                 :            :             // GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
        4690                 :          0 :             loc.col_offset = -1;
        4691                 :          0 :             loc.end_col_offset = -1;
        4692                 :            :         }
        4693                 :            :         // Make sure the end position still follows the start position, even for
        4694                 :            :         // weird ASTs:
        4695                 :         80 :         loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno);
        4696         [ +  + ]:         80 :         if (loc.lineno == loc.end_lineno) {
        4697                 :         75 :             loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset);
        4698                 :            :         }
        4699                 :            :     }
        4700                 :      41161 :     return loc;
        4701                 :            : }
        4702                 :            :
        4703                 :            : // Return 1 if the method call was optimized, 0 if not, and -1 on error.
        4704                 :            : static int
        4705                 :      26546 : maybe_optimize_method_call(struct compiler *c, expr_ty e)
        4706                 :            : {
        4707                 :            :     Py_ssize_t argsl, i, kwdsl;
        4708                 :      26546 :     expr_ty meth = e->v.Call.func;
        4709                 :      26546 :     asdl_expr_seq *args = e->v.Call.args;
        4710                 :      26546 :     asdl_keyword_seq *kwds = e->v.Call.keywords;
        4711                 :            :
        4712                 :            :     /* Check that the call node is an attribute access */
        4713   [ +  +  -  + ]:      26546 :     if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) {
        4714                 :      12713 :         return 0;
        4715                 :            :     }
        4716                 :            :
        4717                 :            :     /* Check that the base object is not something that is imported */
        4718         [ +  + ]:      13833 :     if (is_import_originated(c, meth->v.Attribute.value)) {
        4719                 :       2657 :         return 0;
        4720                 :            :     }
        4721                 :            :
        4722                 :            :     /* Check that there aren't too many arguments */
        4723         [ +  + ]:      11176 :     argsl = asdl_seq_LEN(args);
        4724         [ +  + ]:      11176 :     kwdsl = asdl_seq_LEN(kwds);
        4725         [ -  + ]:      11176 :     if (argsl + kwdsl + (kwdsl != 0) >= STACK_USE_GUIDELINE) {
        4726                 :          0 :         return 0;
        4727                 :            :     }
        4728                 :            :     /* Check that there are no *varargs types of arguments. */
        4729         [ +  + ]:      23164 :     for (i = 0; i < argsl; i++) {
        4730                 :      12118 :         expr_ty elt = asdl_seq_GET(args, i);
        4731         [ +  + ]:      12118 :         if (elt->kind == Starred_kind) {
        4732                 :        130 :             return 0;
        4733                 :            :         }
        4734                 :            :     }
        4735                 :            :
        4736         [ +  + ]:      11859 :     for (i = 0; i < kwdsl; i++) {
        4737                 :        849 :         keyword_ty kw = asdl_seq_GET(kwds, i);
        4738         [ +  + ]:        849 :         if (kw->arg == NULL) {
        4739                 :         36 :             return 0;
        4740                 :            :         }
        4741                 :            :     }
        4742                 :            :     /* Alright, we can optimize the code. */
        4743         [ -  + ]:      11010 :     VISIT(c, expr, meth->v.Attribute.value);
        4744                 :      11010 :     location loc = LOC(meth);
        4745                 :      11010 :     loc = update_start_location_to_match_attr(c, loc, meth);
        4746         [ -  + ]:      11010 :     ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names);
        4747   [ -  +  +  +  :      22825 :     VISIT_SEQ(c, expr, e->v.Call.args);
                       +  + ]
        4748                 :            :
        4749         [ +  + ]:      11010 :     if (kwdsl) {
        4750   [ -  +  +  -  :       1236 :         VISIT_SEQ(c, keyword, kwds);
                       +  + ]
        4751         [ -  + ]:        433 :         RETURN_IF_ERROR(
        4752                 :            :             compiler_call_simple_kw_helper(c, loc, kwds, kwdsl));
        4753                 :            :     }
        4754                 :      11010 :     loc = update_start_location_to_match_attr(c, LOC(e), meth);
        4755         [ -  + ]:      11010 :     ADDOP_I(c, loc, CALL, argsl + kwdsl);
        4756                 :      11010 :     return 1;
        4757                 :            : }
        4758                 :            :
        4759                 :            : static int
        4760                 :      42815 : validate_keywords(struct compiler *c, asdl_keyword_seq *keywords)
        4761                 :            : {
        4762         [ +  + ]:      42815 :     Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
        4763         [ +  + ]:      46334 :     for (Py_ssize_t i = 0; i < nkeywords; i++) {
        4764                 :       3519 :         keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
        4765         [ +  + ]:       3519 :         if (key->arg == NULL) {
        4766                 :        362 :             continue;
        4767                 :            :         }
        4768                 :       3157 :         location loc = LOC(key);
        4769         [ -  + ]:       3157 :         if (forbidden_name(c, loc, key->arg, Store)) {
        4770                 :          0 :             return ERROR;
        4771                 :            :         }
        4772         [ +  + ]:       5646 :         for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
        4773                 :       2489 :             keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
        4774   [ +  +  -  + ]:       2489 :             if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
        4775                 :          0 :                 compiler_error(c, LOC(other), "keyword argument repeated: %U", key->arg);
        4776                 :          0 :                 return ERROR;
        4777                 :            :             }
        4778                 :            :         }
        4779                 :            :     }
        4780                 :      42815 :     return SUCCESS;
        4781                 :            : }
        4782                 :            :
        4783                 :            : static int
        4784                 :      26546 : compiler_call(struct compiler *c, expr_ty e)
        4785                 :            : {
        4786         [ -  + ]:      26546 :     RETURN_IF_ERROR(validate_keywords(c, e->v.Call.keywords));
        4787                 :      26546 :     int ret = maybe_optimize_method_call(c, e);
        4788         [ -  + ]:      26546 :     if (ret < 0) {
        4789                 :          0 :         return ERROR;
        4790                 :            :     }
        4791         [ +  + ]:      26546 :     if (ret == 1) {
        4792                 :      11010 :         return SUCCESS;
        4793                 :            :     }
        4794         [ -  + ]:      15536 :     RETURN_IF_ERROR(check_caller(c, e->v.Call.func));
        4795                 :      15536 :     location loc = LOC(e->v.Call.func);
        4796         [ -  + ]:      15536 :     ADDOP(c, loc, PUSH_NULL);
        4797         [ -  + ]:      15536 :     VISIT(c, expr, e->v.Call.func);
        4798                 :      15536 :     loc = LOC(e);
        4799                 :      15536 :     return compiler_call_helper(c, loc, 0,
        4800                 :            :                                 e->v.Call.args,
        4801                 :            :                                 e->v.Call.keywords);
        4802                 :            : }
        4803                 :            :
        4804                 :            : static int
        4805                 :       1188 : compiler_joined_str(struct compiler *c, expr_ty e)
        4806                 :            : {
        4807                 :       1188 :     location loc = LOC(e);
        4808         [ +  - ]:       1188 :     Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
        4809         [ -  + ]:       1188 :     if (value_count > STACK_USE_GUIDELINE) {
        4810                 :            :         _Py_DECLARE_STR(empty, "");
        4811   [ #  #  #  # ]:          0 :         ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
        4812         [ #  # ]:          0 :         ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names);
        4813         [ #  # ]:          0 :         ADDOP_I(c, loc, BUILD_LIST, 0);
        4814   [ #  #  #  # ]:          0 :         for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
        4815         [ #  # ]:          0 :             VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
        4816         [ #  # ]:          0 :             ADDOP_I(c, loc, LIST_APPEND, 1);
        4817                 :            :         }
        4818         [ #  # ]:          0 :         ADDOP_I(c, loc, CALL, 1);
        4819                 :            :     }
        4820                 :            :     else {
        4821   [ -  +  +  -  :       5021 :         VISIT_SEQ(c, expr, e->v.JoinedStr.values);
                       +  + ]
        4822   [ +  -  +  + ]:       1188 :         if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) {
        4823   [ +  -  -  + ]:       1130 :             ADDOP_I(c, loc, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
        4824                 :            :         }
        4825                 :            :     }
        4826                 :       1188 :     return SUCCESS;
        4827                 :            : }
        4828                 :            :
        4829                 :            : /* Used to implement f-strings. Format a single value. */
        4830                 :            : static int
        4831                 :       1826 : compiler_formatted_value(struct compiler *c, expr_ty e)
        4832                 :            : {
        4833                 :            :     /* Our oparg encodes 2 pieces of information: the conversion
        4834                 :            :        character, and whether or not a format_spec was provided.
        4835                 :            :
        4836                 :            :        Convert the conversion char to 3 bits:
        4837                 :            :            : 000  0x0  FVC_NONE   The default if nothing specified.
        4838                 :            :        !s  : 001  0x1  FVC_STR
        4839                 :            :        !r  : 010  0x2  FVC_REPR
        4840                 :            :        !a  : 011  0x3  FVC_ASCII
        4841                 :            :
        4842                 :            :        next bit is whether or not we have a format spec:
        4843                 :            :        yes : 100  0x4
        4844                 :            :        no  : 000  0x0
        4845                 :            :     */
        4846                 :            :
        4847                 :       1826 :     int conversion = e->v.FormattedValue.conversion;
        4848                 :            :     int oparg;
        4849                 :            :
        4850                 :            :     /* The expression to be formatted. */
        4851         [ -  + ]:       1826 :     VISIT(c, expr, e->v.FormattedValue.value);
        4852                 :            :
        4853   [ +  +  -  +  :       1826 :     switch (conversion) {
                          - ]
        4854                 :        417 :     case 's': oparg = FVC_STR;   break;
        4855                 :        482 :     case 'r': oparg = FVC_REPR;  break;
        4856                 :          0 :     case 'a': oparg = FVC_ASCII; break;
        4857                 :        927 :     case -1:  oparg = FVC_NONE;  break;
        4858                 :          0 :     default:
        4859                 :          0 :         PyErr_Format(PyExc_SystemError,
        4860                 :            :                      "Unrecognized conversion character %d", conversion);
        4861                 :          0 :         return ERROR;
        4862                 :            :     }
        4863         [ +  + ]:       1826 :     if (e->v.FormattedValue.format_spec) {
        4864                 :            :         /* Evaluate the format spec, and update our opcode arg. */
        4865         [ -  + ]:         39 :         VISIT(c, expr, e->v.FormattedValue.format_spec);
        4866                 :         39 :         oparg |= FVS_HAVE_SPEC;
        4867                 :            :     }
        4868                 :            :
        4869                 :            :     /* And push our opcode and oparg */
        4870                 :       1826 :     location loc = LOC(e);
        4871         [ -  + ]:       1826 :     ADDOP_I(c, loc, FORMAT_VALUE, oparg);
        4872                 :            :
        4873                 :       1826 :     return SUCCESS;
        4874                 :            : }
        4875                 :            :
        4876                 :            : static int
        4877                 :         24 : compiler_subkwargs(struct compiler *c, location loc,
        4878                 :            :                    asdl_keyword_seq *keywords,
        4879                 :            :                    Py_ssize_t begin, Py_ssize_t end)
        4880                 :            : {
        4881                 :         24 :     Py_ssize_t i, n = end - begin;
        4882                 :            :     keyword_ty kw;
        4883                 :            :     PyObject *keys, *key;
        4884                 :            :     assert(n > 0);
        4885                 :         24 :     int big = n*2 > STACK_USE_GUIDELINE;
        4886   [ +  +  +  - ]:         24 :     if (n > 1 && !big) {
        4887         [ +  + ]:         39 :         for (i = begin; i < end; i++) {
        4888                 :         30 :             kw = asdl_seq_GET(keywords, i);
        4889         [ -  + ]:         30 :             VISIT(c, expr, kw->value);
        4890                 :            :         }
        4891                 :          9 :         keys = PyTuple_New(n);
        4892         [ -  + ]:          9 :         if (keys == NULL) {
        4893                 :          0 :             return ERROR;
        4894                 :            :         }
        4895         [ +  + ]:         39 :         for (i = begin; i < end; i++) {
        4896                 :         30 :             key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg;
        4897                 :         30 :             PyTuple_SET_ITEM(keys, i - begin, Py_NewRef(key));
        4898                 :            :         }
        4899   [ -  +  -  + ]:          9 :         ADDOP_LOAD_CONST_NEW(c, loc, keys);
        4900         [ -  + ]:          9 :         ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n);
        4901                 :          9 :         return SUCCESS;
        4902                 :            :     }
        4903         [ -  + ]:         15 :     if (big) {
        4904         [ #  # ]:          0 :         ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0);
        4905                 :            :     }
        4906         [ +  + ]:         30 :     for (i = begin; i < end; i++) {
        4907                 :         15 :         kw = asdl_seq_GET(keywords, i);
        4908         [ -  + ]:         15 :         ADDOP_LOAD_CONST(c, loc, kw->arg);
        4909         [ -  + ]:         15 :         VISIT(c, expr, kw->value);
        4910         [ -  + ]:         15 :         if (big) {
        4911         [ #  # ]:          0 :             ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
        4912                 :            :         }
        4913                 :            :     }
        4914         [ +  - ]:         15 :     if (!big) {
        4915         [ -  + ]:         15 :         ADDOP_I(c, loc, BUILD_MAP, n);
        4916                 :            :     }
        4917                 :         15 :     return SUCCESS;
        4918                 :            : }
        4919                 :            :
        4920                 :            : /* Used by compiler_call_helper and maybe_optimize_method_call to emit
        4921                 :            :  * KW_NAMES before CALL.
        4922                 :            :  */
        4923                 :            : static int
        4924                 :       1195 : compiler_call_simple_kw_helper(struct compiler *c, location loc,
        4925                 :            :                                asdl_keyword_seq *keywords, Py_ssize_t nkwelts)
        4926                 :            : {
        4927                 :            :     PyObject *names;
        4928                 :       1195 :     names = PyTuple_New(nkwelts);
        4929         [ -  + ]:       1195 :     if (names == NULL) {
        4930                 :          0 :         return ERROR;
        4931                 :            :     }
        4932         [ +  + ]:       3158 :     for (int i = 0; i < nkwelts; i++) {
        4933                 :       1963 :         keyword_ty kw = asdl_seq_GET(keywords, i);
        4934                 :       1963 :         PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
        4935                 :            :     }
        4936                 :       1195 :     Py_ssize_t arg = compiler_add_const(c->c_const_cache, c->u, names);
        4937         [ -  + ]:       1195 :     if (arg < 0) {
        4938                 :          0 :         return ERROR;
        4939                 :            :     }
        4940                 :       1195 :     Py_DECREF(names);
        4941         [ -  + ]:       1195 :     ADDOP_I(c, loc, KW_NAMES, arg);
        4942                 :       1195 :     return SUCCESS;
        4943                 :            : }
        4944                 :            :
        4945                 :            :
        4946                 :            : /* shared code between compiler_call and compiler_class */
        4947                 :            : static int
        4948                 :      16269 : compiler_call_helper(struct compiler *c, location loc,
        4949                 :            :                      int n, /* Args already pushed */
        4950                 :            :                      asdl_expr_seq *args,
        4951                 :            :                      asdl_keyword_seq *keywords)
        4952                 :            : {
        4953                 :            :     Py_ssize_t i, nseen, nelts, nkwelts;
        4954                 :            :
        4955         [ -  + ]:      16269 :     RETURN_IF_ERROR(validate_keywords(c, keywords));
        4956                 :            :
        4957         [ +  + ]:      16269 :     nelts = asdl_seq_LEN(args);
        4958         [ +  + ]:      16269 :     nkwelts = asdl_seq_LEN(keywords);
        4959                 :            :
        4960         [ +  + ]:      16269 :     if (nelts + nkwelts*2 > STACK_USE_GUIDELINE) {
        4961                 :          1 :          goto ex_call;
        4962                 :            :     }
        4963         [ +  + ]:      38166 :     for (i = 0; i < nelts; i++) {
        4964                 :      22179 :         expr_ty elt = asdl_seq_GET(args, i);
        4965         [ +  + ]:      22179 :         if (elt->kind == Starred_kind) {
        4966                 :        281 :             goto ex_call;
        4967                 :            :         }
        4968                 :            :     }
        4969         [ +  + ]:      17171 :     for (i = 0; i < nkwelts; i++) {
        4970                 :       1257 :         keyword_ty kw = asdl_seq_GET(keywords, i);
        4971         [ +  + ]:       1257 :         if (kw->arg == NULL) {
        4972                 :         73 :             goto ex_call;
        4973                 :            :         }
        4974                 :            :     }
        4975                 :            :
        4976                 :            :     /* No * or ** args, so can use faster calling sequence */
        4977         [ +  + ]:      37530 :     for (i = 0; i < nelts; i++) {
        4978                 :      21616 :         expr_ty elt = asdl_seq_GET(args, i);
        4979                 :            :         assert(elt->kind != Starred_kind);
        4980         [ -  + ]:      21616 :         VISIT(c, expr, elt);
        4981                 :            :     }
        4982         [ +  + ]:      15914 :     if (nkwelts) {
        4983   [ -  +  +  -  :       1922 :         VISIT_SEQ(c, keyword, keywords);
                       +  + ]
        4984         [ -  + ]:        762 :         RETURN_IF_ERROR(
        4985                 :            :             compiler_call_simple_kw_helper(c, loc, keywords, nkwelts));
        4986                 :            :     }
        4987         [ -  + ]:      15914 :     ADDOP_I(c, loc, CALL, n + nelts + nkwelts);
        4988                 :      15914 :     return SUCCESS;
        4989                 :            :
        4990                 :        355 : ex_call:
        4991                 :            :
        4992                 :            :     /* Do positional arguments. */
        4993   [ +  -  +  +  :        355 :     if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
                       +  + ]
        4994         [ -  + ]:        166 :         VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
        4995                 :            :     }
        4996                 :            :     else {
        4997         [ -  + ]:        189 :         RETURN_IF_ERROR(starunpack_helper(c, loc, args, n, BUILD_LIST,
        4998                 :            :                                           LIST_APPEND, LIST_EXTEND, 1));
        4999                 :            :     }
        5000                 :            :     /* Then keyword arguments */
        5001         [ +  + ]:        355 :     if (nkwelts) {
        5002                 :            :         /* Has a new dict been pushed */
        5003                 :        189 :         int have_dict = 0;
        5004                 :            :
        5005                 :        189 :         nseen = 0;  /* the number of keyword arguments on the stack following */
        5006         [ +  + ]:        415 :         for (i = 0; i < nkwelts; i++) {
        5007                 :        226 :             keyword_ty kw = asdl_seq_GET(keywords, i);
        5008         [ +  + ]:        226 :             if (kw->arg == NULL) {
        5009                 :            :                 /* A keyword argument unpacking. */
        5010         [ +  + ]:        181 :                 if (nseen) {
        5011         [ -  + ]:         16 :                     RETURN_IF_ERROR(compiler_subkwargs(c, loc, keywords, i - nseen, i));
        5012         [ -  + ]:         16 :                     if (have_dict) {
        5013         [ #  # ]:          0 :                         ADDOP_I(c, loc, DICT_MERGE, 1);
        5014                 :            :                     }
        5015                 :         16 :                     have_dict = 1;
        5016                 :         16 :                     nseen = 0;
        5017                 :            :                 }
        5018         [ +  + ]:        181 :                 if (!have_dict) {
        5019         [ -  + ]:        165 :                     ADDOP_I(c, loc, BUILD_MAP, 0);
        5020                 :        165 :                     have_dict = 1;
        5021                 :            :                 }
        5022         [ -  + ]:        181 :                 VISIT(c, expr, kw->value);
        5023         [ -  + ]:        181 :                 ADDOP_I(c, loc, DICT_MERGE, 1);
        5024                 :            :             }
        5025                 :            :             else {
        5026                 :         45 :                 nseen++;
        5027                 :            :             }
        5028                 :            :         }
        5029         [ +  + ]:        189 :         if (nseen) {
        5030                 :            :             /* Pack up any trailing keyword arguments. */
        5031         [ -  + ]:          8 :             RETURN_IF_ERROR(compiler_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts));
        5032         [ -  + ]:          8 :             if (have_dict) {
        5033         [ #  # ]:          0 :                 ADDOP_I(c, loc, DICT_MERGE, 1);
        5034                 :            :             }
        5035                 :          8 :             have_dict = 1;
        5036                 :            :         }
        5037                 :            :         assert(have_dict);
        5038                 :            :     }
        5039         [ -  + ]:        355 :     ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0);
        5040                 :        355 :     return SUCCESS;
        5041                 :            : }
        5042                 :            :
        5043                 :            :
        5044                 :            : /* List and set comprehensions and generator expressions work by creating a
        5045                 :            :   nested function to perform the actual iteration. This means that the
        5046                 :            :   iteration variables don't leak into the current scope.
        5047                 :            :   The defined function is called immediately following its definition, with the
        5048                 :            :   result of that call being the result of the expression.
        5049                 :            :   The LC/SC version returns the populated container, while the GE version is
        5050                 :            :   flagged in symtable.c as a generator, so it returns the generator object
        5051                 :            :   when the function is called.
        5052                 :            :
        5053                 :            :   Possible cleanups:
        5054                 :            :     - iterate over the generator sequence instead of using recursion
        5055                 :            : */
        5056                 :            :
        5057                 :            :
        5058                 :            : static int
        5059                 :        471 : compiler_comprehension_generator(struct compiler *c, location loc,
        5060                 :            :                                  asdl_comprehension_seq *generators, int gen_index,
        5061                 :            :                                  int depth,
        5062                 :            :                                  expr_ty elt, expr_ty val, int type)
        5063                 :            : {
        5064                 :            :     comprehension_ty gen;
        5065                 :        471 :     gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
        5066         [ -  + ]:        471 :     if (gen->is_async) {
        5067                 :          0 :         return compiler_async_comprehension_generator(
        5068                 :            :             c, loc, generators, gen_index, depth, elt, val, type);
        5069                 :            :     } else {
        5070                 :        471 :         return compiler_sync_comprehension_generator(
        5071                 :            :             c, loc, generators, gen_index, depth, elt, val, type);
        5072                 :            :     }
        5073                 :            : }
        5074                 :            :
        5075                 :            : static int
        5076                 :        471 : compiler_sync_comprehension_generator(struct compiler *c, location loc,
        5077                 :            :                                       asdl_comprehension_seq *generators,
        5078                 :            :                                       int gen_index, int depth,
        5079                 :            :                                       expr_ty elt, expr_ty val, int type)
        5080                 :            : {
        5081                 :            :     /* generate code for the iterator, then each of the ifs,
        5082                 :            :        and then write to the element */
        5083                 :            :
        5084         [ -  + ]:        471 :     NEW_JUMP_TARGET_LABEL(c, start);
        5085         [ -  + ]:        471 :     NEW_JUMP_TARGET_LABEL(c, if_cleanup);
        5086         [ -  + ]:        471 :     NEW_JUMP_TARGET_LABEL(c, anchor);
        5087                 :            :
        5088                 :        471 :     comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
        5089                 :            :                                                           gen_index);
        5090                 :            :
        5091         [ +  + ]:        471 :     if (gen_index == 0) {
        5092                 :            :         /* Receive outermost iter as an implicit argument */
        5093                 :        453 :         c->u->u_argcount = 1;
        5094         [ -  + ]:        453 :         ADDOP_I(c, loc, LOAD_FAST, 0);
        5095                 :            :     }
        5096                 :            :     else {
        5097                 :            :         /* Sub-iter - calculate on the fly */
        5098                 :            :         /* Fast path for the temporary variable assignment idiom:
        5099                 :            :              for y in [f(x)]
        5100                 :            :          */
        5101                 :            :         asdl_expr_seq *elts;
        5102      [ -  -  + ]:         18 :         switch (gen->iter->kind) {
        5103                 :          0 :             case List_kind:
        5104                 :          0 :                 elts = gen->iter->v.List.elts;
        5105                 :          0 :                 break;
        5106                 :          0 :             case Tuple_kind:
        5107                 :          0 :                 elts = gen->iter->v.Tuple.elts;
        5108                 :          0 :                 break;
        5109                 :         18 :             default:
        5110                 :         18 :                 elts = NULL;
        5111                 :            :         }
        5112   [ -  +  -  - ]:         18 :         if (asdl_seq_LEN(elts) == 1) {
        5113                 :          0 :             expr_ty elt = asdl_seq_GET(elts, 0);
        5114         [ #  # ]:          0 :             if (elt->kind != Starred_kind) {
        5115         [ #  # ]:          0 :                 VISIT(c, expr, elt);
        5116                 :          0 :                 start = NO_LABEL;
        5117                 :            :             }
        5118                 :            :         }
        5119         [ +  - ]:         18 :         if (IS_LABEL(start)) {
        5120         [ -  + ]:         18 :             VISIT(c, expr, gen->iter);
        5121         [ -  + ]:         18 :             ADDOP(c, loc, GET_ITER);
        5122                 :            :         }
        5123                 :            :     }
        5124         [ +  - ]:        471 :     if (IS_LABEL(start)) {
        5125                 :        471 :         depth++;
        5126         [ -  + ]:        471 :         USE_LABEL(c, start);
        5127         [ -  + ]:        471 :         ADDOP_JUMP(c, loc, FOR_ITER, anchor);
        5128                 :            :     }
        5129         [ -  + ]:        471 :     VISIT(c, expr, gen->target);
        5130                 :            :
        5131                 :            :     /* XXX this needs to be cleaned up...a lot! */
        5132         [ +  - ]:        471 :     Py_ssize_t n = asdl_seq_LEN(gen->ifs);
        5133         [ +  + ]:        591 :     for (Py_ssize_t i = 0; i < n; i++) {
        5134                 :        120 :         expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
        5135         [ -  + ]:        120 :         RETURN_IF_ERROR(compiler_jump_if(c, loc, e, if_cleanup, 0));
        5136                 :            :     }
        5137                 :            :
        5138   [ +  -  +  + ]:        471 :     if (++gen_index < asdl_seq_LEN(generators)) {
        5139         [ -  + ]:         18 :         RETURN_IF_ERROR(
        5140                 :            :             compiler_comprehension_generator(c, loc,
        5141                 :            :                                              generators, gen_index, depth,
        5142                 :            :                                              elt, val, type));
        5143                 :            :     }
        5144                 :            :
        5145                 :        471 :     location elt_loc = LOC(elt);
        5146                 :            :
        5147                 :            :     /* only append after the last for generator */
        5148   [ +  -  +  + ]:        471 :     if (gen_index >= asdl_seq_LEN(generators)) {
        5149                 :            :         /* comprehension specific code */
        5150   [ +  +  +  +  :        453 :         switch (type) {
                          - ]
        5151                 :        197 :         case COMP_GENEXP:
        5152         [ -  + ]:        197 :             VISIT(c, expr, elt);
        5153         [ -  + ]:        197 :             ADDOP_YIELD(c, elt_loc);
        5154         [ -  + ]:        197 :             ADDOP(c, elt_loc, POP_TOP);
        5155                 :        453 :             break;
        5156                 :        219 :         case COMP_LISTCOMP:
        5157         [ -  + ]:        219 :             VISIT(c, expr, elt);
        5158         [ -  + ]:        219 :             ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
        5159                 :        219 :             break;
        5160                 :         14 :         case COMP_SETCOMP:
        5161         [ -  + ]:         14 :             VISIT(c, expr, elt);
        5162         [ -  + ]:         14 :             ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
        5163                 :         14 :             break;
        5164                 :         23 :         case COMP_DICTCOMP:
        5165                 :            :             /* With '{k: v}', k is evaluated before v, so we do
        5166                 :            :                the same. */
        5167         [ -  + ]:         23 :             VISIT(c, expr, elt);
        5168         [ -  + ]:         23 :             VISIT(c, expr, val);
        5169                 :         23 :             elt_loc = LOCATION(elt->lineno,
        5170                 :            :                                val->end_lineno,
        5171                 :            :                                elt->col_offset,
        5172                 :            :                                val->end_col_offset);
        5173         [ -  + ]:         23 :             ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
        5174                 :         23 :             break;
        5175                 :          0 :         default:
        5176                 :          0 :             return ERROR;
        5177                 :            :         }
        5178                 :         18 :     }
        5179                 :            :
        5180         [ -  + ]:        471 :     USE_LABEL(c, if_cleanup);
        5181         [ +  - ]:        471 :     if (IS_LABEL(start)) {
        5182         [ -  + ]:        471 :         ADDOP_JUMP(c, elt_loc, JUMP, start);
        5183                 :            :
        5184         [ -  + ]:        471 :         USE_LABEL(c, anchor);
        5185         [ -  + ]:        471 :         ADDOP(c, NO_LOCATION, END_FOR);
        5186                 :            :     }
        5187                 :            :
        5188                 :        471 :     return SUCCESS;
        5189                 :            : }
        5190                 :            :
        5191                 :            : static int
        5192                 :          0 : compiler_async_comprehension_generator(struct compiler *c, location loc,
        5193                 :            :                                       asdl_comprehension_seq *generators,
        5194                 :            :                                       int gen_index, int depth,
        5195                 :            :                                       expr_ty elt, expr_ty val, int type)
        5196                 :            : {
        5197         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, start);
        5198         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, except);
        5199         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, if_cleanup);
        5200                 :            :
        5201                 :          0 :     comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
        5202                 :            :                                                           gen_index);
        5203                 :            :
        5204         [ #  # ]:          0 :     if (gen_index == 0) {
        5205                 :            :         /* Receive outermost iter as an implicit argument */
        5206                 :          0 :         c->u->u_argcount = 1;
        5207         [ #  # ]:          0 :         ADDOP_I(c, loc, LOAD_FAST, 0);
        5208                 :            :     }
        5209                 :            :     else {
        5210                 :            :         /* Sub-iter - calculate on the fly */
        5211         [ #  # ]:          0 :         VISIT(c, expr, gen->iter);
        5212         [ #  # ]:          0 :         ADDOP(c, loc, GET_AITER);
        5213                 :            :     }
        5214                 :            :
        5215         [ #  # ]:          0 :     USE_LABEL(c, start);
        5216                 :            :     /* Runtime will push a block here, so we need to account for that */
        5217         [ #  # ]:          0 :     RETURN_IF_ERROR(
        5218                 :            :         compiler_push_fblock(c, loc, ASYNC_COMPREHENSION_GENERATOR,
        5219                 :            :                              start, NO_LABEL, NULL));
        5220                 :            :
        5221         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
        5222         [ #  # ]:          0 :     ADDOP(c, loc, GET_ANEXT);
        5223         [ #  # ]:          0 :     ADDOP_LOAD_CONST(c, loc, Py_None);
        5224         [ #  # ]:          0 :     ADD_YIELD_FROM(c, loc, 1);
        5225         [ #  # ]:          0 :     ADDOP(c, loc, POP_BLOCK);
        5226         [ #  # ]:          0 :     VISIT(c, expr, gen->target);
        5227                 :            :
        5228         [ #  # ]:          0 :     Py_ssize_t n = asdl_seq_LEN(gen->ifs);
        5229         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < n; i++) {
        5230                 :          0 :         expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
        5231         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_jump_if(c, loc, e, if_cleanup, 0));
        5232                 :            :     }
        5233                 :            :
        5234                 :          0 :     depth++;
        5235   [ #  #  #  # ]:          0 :     if (++gen_index < asdl_seq_LEN(generators)) {
        5236         [ #  # ]:          0 :         RETURN_IF_ERROR(
        5237                 :            :             compiler_comprehension_generator(c, loc,
        5238                 :            :                                              generators, gen_index, depth,
        5239                 :            :                                              elt, val, type));
        5240                 :            :     }
        5241                 :            :
        5242                 :          0 :     location elt_loc = LOC(elt);
        5243                 :            :     /* only append after the last for generator */
        5244   [ #  #  #  # ]:          0 :     if (gen_index >= asdl_seq_LEN(generators)) {
        5245                 :            :         /* comprehension specific code */
        5246   [ #  #  #  #  :          0 :         switch (type) {
                          # ]
        5247                 :          0 :         case COMP_GENEXP:
        5248         [ #  # ]:          0 :             VISIT(c, expr, elt);
        5249         [ #  # ]:          0 :             ADDOP_YIELD(c, elt_loc);
        5250         [ #  # ]:          0 :             ADDOP(c, elt_loc, POP_TOP);
        5251                 :          0 :             break;
        5252                 :          0 :         case COMP_LISTCOMP:
        5253         [ #  # ]:          0 :             VISIT(c, expr, elt);
        5254         [ #  # ]:          0 :             ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
        5255                 :          0 :             break;
        5256                 :          0 :         case COMP_SETCOMP:
        5257         [ #  # ]:          0 :             VISIT(c, expr, elt);
        5258         [ #  # ]:          0 :             ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
        5259                 :          0 :             break;
        5260                 :          0 :         case COMP_DICTCOMP:
        5261                 :            :             /* With '{k: v}', k is evaluated before v, so we do
        5262                 :            :                the same. */
        5263         [ #  # ]:          0 :             VISIT(c, expr, elt);
        5264         [ #  # ]:          0 :             VISIT(c, expr, val);
        5265                 :          0 :             elt_loc = LOCATION(elt->lineno,
        5266                 :            :                                val->end_lineno,
        5267                 :            :                                elt->col_offset,
        5268                 :            :                                val->end_col_offset);
        5269         [ #  # ]:          0 :             ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
        5270                 :          0 :             break;
        5271                 :          0 :         default:
        5272                 :          0 :             return ERROR;
        5273                 :            :         }
        5274                 :          0 :     }
        5275                 :            :
        5276         [ #  # ]:          0 :     USE_LABEL(c, if_cleanup);
        5277         [ #  # ]:          0 :     ADDOP_JUMP(c, elt_loc, JUMP, start);
        5278                 :            :
        5279                 :          0 :     compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start);
        5280                 :            :
        5281         [ #  # ]:          0 :     USE_LABEL(c, except);
        5282                 :            :
        5283         [ #  # ]:          0 :     ADDOP(c, loc, END_ASYNC_FOR);
        5284                 :            :
        5285                 :          0 :     return SUCCESS;
        5286                 :            : }
        5287                 :            :
        5288                 :            : static int
        5289                 :        453 : compiler_comprehension(struct compiler *c, expr_ty e, int type,
        5290                 :            :                        identifier name, asdl_comprehension_seq *generators, expr_ty elt,
        5291                 :            :                        expr_ty val)
        5292                 :            : {
        5293                 :        453 :     PyCodeObject *co = NULL;
        5294                 :            :     comprehension_ty outermost;
        5295                 :        453 :     int scope_type = c->u->u_scope_type;
        5296                 :        453 :     int is_async_generator = 0;
        5297   [ -  +  -  - ]:        453 :     int is_top_level_await = IS_TOP_LEVEL_AWAIT(c);
        5298                 :            :
        5299                 :        453 :     outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
        5300         [ -  + ]:        453 :     if (compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION,
        5301                 :            :                              (void *)e, e->lineno) < 0)
        5302                 :            :     {
        5303                 :          0 :         goto error;
        5304                 :            :     }
        5305                 :        453 :     location loc = LOC(e);
        5306                 :            :
        5307                 :        453 :     is_async_generator = c->u->u_ste->ste_coroutine;
        5308                 :            :
        5309   [ -  +  -  -  :        453 :     if (is_async_generator && type != COMP_GENEXP &&
                       -  - ]
        5310         [ #  # ]:          0 :         scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
        5311         [ #  # ]:          0 :         scope_type != COMPILER_SCOPE_COMPREHENSION &&
        5312                 :            :         !is_top_level_await)
        5313                 :            :     {
        5314                 :          0 :         compiler_error(c, loc, "asynchronous comprehension outside of "
        5315                 :            :                                "an asynchronous function");
        5316                 :          0 :         goto error_in_scope;
        5317                 :            :     }
        5318                 :            :
        5319         [ +  + ]:        453 :     if (type != COMP_GENEXP) {
        5320                 :            :         int op;
        5321   [ +  +  +  - ]:        256 :         switch (type) {
        5322                 :        219 :         case COMP_LISTCOMP:
        5323                 :        219 :             op = BUILD_LIST;
        5324                 :        219 :             break;
        5325                 :         14 :         case COMP_SETCOMP:
        5326                 :         14 :             op = BUILD_SET;
        5327                 :         14 :             break;
        5328                 :         23 :         case COMP_DICTCOMP:
        5329                 :         23 :             op = BUILD_MAP;
        5330                 :         23 :             break;
        5331                 :          0 :         default:
        5332                 :          0 :             PyErr_Format(PyExc_SystemError,
        5333                 :            :                          "unknown comprehension type %d", type);
        5334                 :          0 :             goto error_in_scope;
        5335                 :            :         }
        5336                 :            :
        5337         [ -  + ]:        256 :         ADDOP_I(c, loc, op, 0);
        5338                 :            :     }
        5339                 :            :
        5340         [ -  + ]:        453 :     if (compiler_comprehension_generator(c, loc, generators, 0, 0,
        5341                 :            :                                          elt, val, type) < 0) {
        5342                 :          0 :         goto error_in_scope;
        5343                 :            :     }
        5344                 :            :
        5345         [ +  + ]:        453 :     if (type != COMP_GENEXP) {
        5346         [ -  + ]:        256 :         ADDOP(c, LOC(e), RETURN_VALUE);
        5347                 :            :     }
        5348         [ +  + ]:        453 :     if (type == COMP_GENEXP) {
        5349         [ -  + ]:        197 :         if (wrap_in_stopiteration_handler(c) < 0) {
        5350                 :          0 :             goto error_in_scope;
        5351                 :            :         }
        5352                 :            :     }
        5353                 :            :
        5354                 :        453 :     co = assemble(c, 1);
        5355                 :        453 :     compiler_exit_scope(c);
        5356   [ -  +  -  - ]:        453 :     if (is_top_level_await && is_async_generator){
        5357                 :          0 :         c->u->u_ste->ste_coroutine = 1;
        5358                 :            :     }
        5359         [ -  + ]:        453 :     if (co == NULL) {
        5360                 :          0 :         goto error;
        5361                 :            :     }
        5362                 :            :
        5363                 :        453 :     loc = LOC(e);
        5364         [ -  + ]:        453 :     if (compiler_make_closure(c, loc, co, 0) < 0) {
        5365                 :          0 :         goto error;
        5366                 :            :     }
        5367                 :        453 :     Py_DECREF(co);
        5368                 :            :
        5369         [ -  + ]:        453 :     VISIT(c, expr, outermost->iter);
        5370                 :            :
        5371                 :        453 :     loc = LOC(e);
        5372         [ -  + ]:        453 :     if (outermost->is_async) {
        5373         [ #  # ]:          0 :         ADDOP(c, loc, GET_AITER);
        5374                 :            :     } else {
        5375         [ -  + ]:        453 :         ADDOP(c, loc, GET_ITER);
        5376                 :            :     }
        5377                 :            :
        5378         [ -  + ]:        453 :     ADDOP_I(c, loc, CALL, 0);
        5379                 :            :
        5380   [ -  +  -  - ]:        453 :     if (is_async_generator && type != COMP_GENEXP) {
        5381         [ #  # ]:          0 :         ADDOP_I(c, loc, GET_AWAITABLE, 0);
        5382         [ #  # ]:          0 :         ADDOP_LOAD_CONST(c, loc, Py_None);
        5383         [ #  # ]:          0 :         ADD_YIELD_FROM(c, loc, 1);
        5384                 :            :     }
        5385                 :            :
        5386                 :        453 :     return SUCCESS;
        5387                 :          0 : error_in_scope:
        5388                 :          0 :     compiler_exit_scope(c);
        5389                 :          0 : error:
        5390                 :          0 :     Py_XDECREF(co);
        5391                 :          0 :     return ERROR;
        5392                 :            : }
        5393                 :            :
        5394                 :            : static int
        5395                 :        197 : compiler_genexp(struct compiler *c, expr_ty e)
        5396                 :            : {
        5397                 :            :     assert(e->kind == GeneratorExp_kind);
        5398                 :            :     _Py_DECLARE_STR(anon_genexpr, "<genexpr>");
        5399                 :        197 :     return compiler_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
        5400                 :            :                                   e->v.GeneratorExp.generators,
        5401                 :            :                                   e->v.GeneratorExp.elt, NULL);
        5402                 :            : }
        5403                 :            :
        5404                 :            : static int
        5405                 :        219 : compiler_listcomp(struct compiler *c, expr_ty e)
        5406                 :            : {
        5407                 :            :     assert(e->kind == ListComp_kind);
        5408                 :            :     _Py_DECLARE_STR(anon_listcomp, "<listcomp>");
        5409                 :        219 :     return compiler_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
        5410                 :            :                                   e->v.ListComp.generators,
        5411                 :            :                                   e->v.ListComp.elt, NULL);
        5412                 :            : }
        5413                 :            :
        5414                 :            : static int
        5415                 :         14 : compiler_setcomp(struct compiler *c, expr_ty e)
        5416                 :            : {
        5417                 :            :     assert(e->kind == SetComp_kind);
        5418                 :            :     _Py_DECLARE_STR(anon_setcomp, "<setcomp>");
        5419                 :         14 :     return compiler_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp),
        5420                 :            :                                   e->v.SetComp.generators,
        5421                 :            :                                   e->v.SetComp.elt, NULL);
        5422                 :            : }
        5423                 :            :
        5424                 :            :
        5425                 :            : static int
        5426                 :         23 : compiler_dictcomp(struct compiler *c, expr_ty e)
        5427                 :            : {
        5428                 :            :     assert(e->kind == DictComp_kind);
        5429                 :            :     _Py_DECLARE_STR(anon_dictcomp, "<dictcomp>");
        5430                 :         23 :     return compiler_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
        5431                 :            :                                   e->v.DictComp.generators,
        5432                 :            :                                   e->v.DictComp.key, e->v.DictComp.value);
        5433                 :            : }
        5434                 :            :
        5435                 :            :
        5436                 :            : static int
        5437                 :       1963 : compiler_visit_keyword(struct compiler *c, keyword_ty k)
        5438                 :            : {
        5439         [ -  + ]:       1963 :     VISIT(c, expr, k->value);
        5440                 :       1963 :     return SUCCESS;
        5441                 :            : }
        5442                 :            :
        5443                 :            :
        5444                 :            : static int
        5445                 :        389 : compiler_with_except_finish(struct compiler *c, jump_target_label cleanup) {
        5446         [ -  + ]:        389 :     NEW_JUMP_TARGET_LABEL(c, suppress);
        5447         [ -  + ]:        389 :     ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress);
        5448         [ -  + ]:        389 :     ADDOP_I(c, NO_LOCATION, RERAISE, 2);
        5449                 :            :
        5450         [ -  + ]:        389 :     USE_LABEL(c, suppress);
        5451         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */
        5452         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        5453         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_EXCEPT);
        5454         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_TOP);
        5455         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_TOP);
        5456         [ -  + ]:        389 :     NEW_JUMP_TARGET_LABEL(c, exit);
        5457         [ -  + ]:        389 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
        5458                 :            :
        5459         [ -  + ]:        389 :     USE_LABEL(c, cleanup);
        5460         [ -  + ]:        389 :     POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
        5461                 :            :
        5462         [ -  + ]:        389 :     USE_LABEL(c, exit);
        5463                 :        389 :     return SUCCESS;
        5464                 :            : }
        5465                 :            :
        5466                 :            : /*
        5467                 :            :    Implements the async with statement.
        5468                 :            :
        5469                 :            :    The semantics outlined in that PEP are as follows:
        5470                 :            :
        5471                 :            :    async with EXPR as VAR:
        5472                 :            :        BLOCK
        5473                 :            :
        5474                 :            :    It is implemented roughly as:
        5475                 :            :
        5476                 :            :    context = EXPR
        5477                 :            :    exit = context.__aexit__  # not calling it
        5478                 :            :    value = await context.__aenter__()
        5479                 :            :    try:
        5480                 :            :        VAR = value  # if VAR present in the syntax
        5481                 :            :        BLOCK
        5482                 :            :    finally:
        5483                 :            :        if an exception was raised:
        5484                 :            :            exc = copy of (exception, instance, traceback)
        5485                 :            :        else:
        5486                 :            :            exc = (None, None, None)
        5487                 :            :        if not (await exit(*exc)):
        5488                 :            :            raise
        5489                 :            :  */
        5490                 :            : static int
        5491                 :          5 : compiler_async_with(struct compiler *c, stmt_ty s, int pos)
        5492                 :            : {
        5493                 :          5 :     location loc = LOC(s);
        5494                 :          5 :     withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
        5495                 :            :
        5496                 :            :     assert(s->kind == AsyncWith_kind);
        5497   [ -  +  -  - ]:          5 :     if (IS_TOP_LEVEL_AWAIT(c)){
        5498                 :          0 :         c->u->u_ste->ste_coroutine = 1;
        5499         [ -  + ]:          5 :     } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){
        5500                 :          0 :         return compiler_error(c, loc, "'async with' outside async function");
        5501                 :            :     }
        5502                 :            :
        5503         [ -  + ]:          5 :     NEW_JUMP_TARGET_LABEL(c, block);
        5504         [ -  + ]:          5 :     NEW_JUMP_TARGET_LABEL(c, final);
        5505         [ -  + ]:          5 :     NEW_JUMP_TARGET_LABEL(c, exit);
        5506         [ -  + ]:          5 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
        5507                 :            :
        5508                 :            :     /* Evaluate EXPR */
        5509         [ -  + ]:          5 :     VISIT(c, expr, item->context_expr);
        5510                 :            :
        5511         [ -  + ]:          5 :     ADDOP(c, loc, BEFORE_ASYNC_WITH);
        5512         [ -  + ]:          5 :     ADDOP_I(c, loc, GET_AWAITABLE, 1);
        5513         [ -  + ]:          5 :     ADDOP_LOAD_CONST(c, loc, Py_None);
        5514         [ -  + ]:          5 :     ADD_YIELD_FROM(c, loc, 1);
        5515                 :            :
        5516         [ -  + ]:          5 :     ADDOP_JUMP(c, loc, SETUP_WITH, final);
        5517                 :            :
        5518                 :            :     /* SETUP_WITH pushes a finally block. */
        5519         [ -  + ]:          5 :     USE_LABEL(c, block);
        5520         [ -  + ]:          5 :     RETURN_IF_ERROR(compiler_push_fblock(c, loc, ASYNC_WITH, block, final, s));
        5521                 :            :
        5522         [ -  + ]:          5 :     if (item->optional_vars) {
        5523         [ #  # ]:          0 :         VISIT(c, expr, item->optional_vars);
        5524                 :            :     }
        5525                 :            :     else {
        5526                 :            :         /* Discard result from context.__aenter__() */
        5527         [ -  + ]:          5 :         ADDOP(c, loc, POP_TOP);
        5528                 :            :     }
        5529                 :            :
        5530                 :          5 :     pos++;
        5531   [ +  -  +  - ]:          5 :     if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) {
        5532                 :            :         /* BLOCK code */
        5533   [ -  +  +  -  :         13 :         VISIT_SEQ(c, stmt, s->v.AsyncWith.body)
                       +  + ]
        5534                 :            :     }
        5535                 :            :     else {
        5536         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_async_with(c, s, pos));
        5537                 :            :     }
        5538                 :            :
        5539                 :          5 :     compiler_pop_fblock(c, ASYNC_WITH, block);
        5540                 :            :
        5541         [ -  + ]:          5 :     ADDOP(c, loc, POP_BLOCK);
        5542                 :            :     /* End of body; start the cleanup */
        5543                 :            :
        5544                 :            :     /* For successful outcome:
        5545                 :            :      * call __exit__(None, None, None)
        5546                 :            :      */
        5547         [ -  + ]:          5 :     RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc));
        5548         [ -  + ]:          5 :     ADDOP_I(c, loc, GET_AWAITABLE, 2);
        5549         [ -  + ]:          5 :     ADDOP_LOAD_CONST(c, loc, Py_None);
        5550         [ -  + ]:          5 :     ADD_YIELD_FROM(c, loc, 1);
        5551                 :            :
        5552         [ -  + ]:          5 :     ADDOP(c, loc, POP_TOP);
        5553                 :            :
        5554         [ -  + ]:          5 :     ADDOP_JUMP(c, loc, JUMP, exit);
        5555                 :            :
        5556                 :            :     /* For exceptional outcome: */
        5557         [ -  + ]:          5 :     USE_LABEL(c, final);
        5558                 :            :
        5559         [ -  + ]:          5 :     ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
        5560         [ -  + ]:          5 :     ADDOP(c, loc, PUSH_EXC_INFO);
        5561         [ -  + ]:          5 :     ADDOP(c, loc, WITH_EXCEPT_START);
        5562         [ -  + ]:          5 :     ADDOP_I(c, loc, GET_AWAITABLE, 2);
        5563         [ -  + ]:          5 :     ADDOP_LOAD_CONST(c, loc, Py_None);
        5564         [ -  + ]:          5 :     ADD_YIELD_FROM(c, loc, 1);
        5565         [ -  + ]:          5 :     RETURN_IF_ERROR(compiler_with_except_finish(c, cleanup));
        5566                 :            :
        5567         [ -  + ]:          5 :     USE_LABEL(c, exit);
        5568                 :          5 :     return SUCCESS;
        5569                 :            : }
        5570                 :            :
        5571                 :            :
        5572                 :            : /*
        5573                 :            :    Implements the with statement from PEP 343.
        5574                 :            :    with EXPR as VAR:
        5575                 :            :        BLOCK
        5576                 :            :    is implemented as:
        5577                 :            :         <code for EXPR>
        5578                 :            :         SETUP_WITH  E
        5579                 :            :         <code to store to VAR> or POP_TOP
        5580                 :            :         <code for BLOCK>
        5581                 :            :         LOAD_CONST (None, None, None)
        5582                 :            :         CALL_FUNCTION_EX 0
        5583                 :            :         JUMP  EXIT
        5584                 :            :     E:  WITH_EXCEPT_START (calls EXPR.__exit__)
        5585                 :            :         POP_JUMP_IF_TRUE T:
        5586                 :            :         RERAISE
        5587                 :            :     T:  POP_TOP (remove exception from stack)
        5588                 :            :         POP_EXCEPT
        5589                 :            :         POP_TOP
        5590                 :            :     EXIT:
        5591                 :            :  */
        5592                 :            :
        5593                 :            : static int
        5594                 :        384 : compiler_with(struct compiler *c, stmt_ty s, int pos)
        5595                 :            : {
        5596                 :        384 :     withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
        5597                 :            :
        5598                 :            :     assert(s->kind == With_kind);
        5599                 :            :
        5600         [ -  + ]:        384 :     NEW_JUMP_TARGET_LABEL(c, block);
        5601         [ -  + ]:        384 :     NEW_JUMP_TARGET_LABEL(c, final);
        5602         [ -  + ]:        384 :     NEW_JUMP_TARGET_LABEL(c, exit);
        5603         [ -  + ]:        384 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
        5604                 :            :
        5605                 :            :     /* Evaluate EXPR */
        5606         [ -  + ]:        384 :     VISIT(c, expr, item->context_expr);
        5607                 :            :     /* Will push bound __exit__ */
        5608                 :        384 :     location loc = LOC(s);
        5609         [ -  + ]:        384 :     ADDOP(c, loc, BEFORE_WITH);
        5610         [ -  + ]:        384 :     ADDOP_JUMP(c, loc, SETUP_WITH, final);
        5611                 :            :
        5612                 :            :     /* SETUP_WITH pushes a finally block. */
        5613         [ -  + ]:        384 :     USE_LABEL(c, block);
        5614         [ -  + ]:        384 :     RETURN_IF_ERROR(compiler_push_fblock(c, loc, WITH, block, final, s));
        5615                 :            :
        5616         [ +  + ]:        384 :     if (item->optional_vars) {
        5617         [ -  + ]:        143 :         VISIT(c, expr, item->optional_vars);
        5618                 :            :     }
        5619                 :            :     else {
        5620                 :            :     /* Discard result from context.__enter__() */
        5621         [ -  + ]:        241 :         ADDOP(c, loc, POP_TOP);
        5622                 :            :     }
        5623                 :            :
        5624                 :        384 :     pos++;
        5625   [ +  -  +  + ]:        384 :     if (pos == asdl_seq_LEN(s->v.With.items)) {
        5626                 :            :         /* BLOCK code */
        5627   [ -  +  +  -  :       1131 :         VISIT_SEQ(c, stmt, s->v.With.body)
                       +  + ]
        5628                 :            :     }
        5629                 :            :     else {
        5630         [ -  + ]:          5 :         RETURN_IF_ERROR(compiler_with(c, s, pos));
        5631                 :            :     }
        5632                 :            :
        5633         [ -  + ]:        384 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
        5634                 :        384 :     compiler_pop_fblock(c, WITH, block);
        5635                 :            :
        5636                 :            :     /* End of body; start the cleanup. */
        5637                 :            :
        5638                 :            :     /* For successful outcome:
        5639                 :            :      * call __exit__(None, None, None)
        5640                 :            :      */
        5641                 :        384 :     loc = LOC(s);
        5642         [ -  + ]:        384 :     RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc));
        5643         [ -  + ]:        384 :     ADDOP(c, loc, POP_TOP);
        5644         [ -  + ]:        384 :     ADDOP_JUMP(c, loc, JUMP, exit);
        5645                 :            :
        5646                 :            :     /* For exceptional outcome: */
        5647         [ -  + ]:        384 :     USE_LABEL(c, final);
        5648                 :            :
        5649         [ -  + ]:        384 :     ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
        5650         [ -  + ]:        384 :     ADDOP(c, loc, PUSH_EXC_INFO);
        5651         [ -  + ]:        384 :     ADDOP(c, loc, WITH_EXCEPT_START);
        5652         [ -  + ]:        384 :     RETURN_IF_ERROR(compiler_with_except_finish(c, cleanup));
        5653                 :            :
        5654         [ -  + ]:        384 :     USE_LABEL(c, exit);
        5655                 :        384 :     return SUCCESS;
        5656                 :            : }
        5657                 :            :
        5658                 :            : static int
        5659                 :     201007 : compiler_visit_expr1(struct compiler *c, expr_ty e)
        5660                 :            : {
        5661                 :     201007 :     location loc = LOC(e);
        5662   [ +  +  +  +  :     201007 :     switch (e->kind) {
              +  +  +  +  +
              +  +  +  +  +
              +  +  +  +  +
              +  +  +  -  +
                 +  +  +  - ]
        5663                 :         32 :     case NamedExpr_kind:
        5664         [ -  + ]:     146610 :         VISIT(c, expr, e->v.NamedExpr.value);
        5665         [ -  + ]:         32 :         ADDOP_I(c, loc, COPY, 1);
        5666         [ -  + ]:         32 :         VISIT(c, expr, e->v.NamedExpr.target);
        5667                 :      54429 :         break;
        5668                 :        392 :     case BoolOp_kind:
        5669                 :        392 :         return compiler_boolop(c, e);
        5670                 :       3541 :     case BinOp_kind:
        5671         [ -  + ]:       3541 :         VISIT(c, expr, e->v.BinOp.left);
        5672         [ -  + ]:       3541 :         VISIT(c, expr, e->v.BinOp.right);
        5673         [ -  + ]:       3541 :         ADDOP_BINARY(c, loc, e->v.BinOp.op);
        5674                 :       3541 :         break;
        5675                 :        271 :     case UnaryOp_kind:
        5676         [ -  + ]:        271 :         VISIT(c, expr, e->v.UnaryOp.operand);
        5677         [ +  + ]:        271 :         if (e->v.UnaryOp.op == UAdd) {
        5678         [ -  + ]:          5 :             ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE);
        5679                 :            :         }
        5680                 :            :         else {
        5681         [ -  + ]:        266 :             ADDOP(c, loc, unaryop(e->v.UnaryOp.op));
        5682                 :            :         }
        5683                 :        271 :         break;
        5684                 :        135 :     case Lambda_kind:
        5685                 :        135 :         return compiler_lambda(c, e);
        5686                 :        231 :     case IfExp_kind:
        5687                 :        231 :         return compiler_ifexp(c, e);
        5688                 :        397 :     case Dict_kind:
        5689                 :        397 :         return compiler_dict(c, e);
        5690                 :         40 :     case Set_kind:
        5691                 :         40 :         return compiler_set(c, e);
        5692                 :        197 :     case GeneratorExp_kind:
        5693                 :        197 :         return compiler_genexp(c, e);
        5694                 :        219 :     case ListComp_kind:
        5695                 :        219 :         return compiler_listcomp(c, e);
        5696                 :         14 :     case SetComp_kind:
        5697                 :         14 :         return compiler_setcomp(c, e);
        5698                 :         23 :     case DictComp_kind:
        5699                 :         23 :         return compiler_dictcomp(c, e);
        5700                 :        252 :     case Yield_kind:
        5701         [ -  + ]:        252 :         if (c->u->u_ste->ste_type != FunctionBlock) {
        5702                 :          0 :             return compiler_error(c, loc, "'yield' outside function");
        5703                 :            :         }
        5704         [ +  + ]:        252 :         if (e->v.Yield.value) {
        5705         [ -  + ]:        220 :             VISIT(c, expr, e->v.Yield.value);
        5706                 :            :         }
        5707                 :            :         else {
        5708         [ -  + ]:         32 :             ADDOP_LOAD_CONST(c, loc, Py_None);
        5709                 :            :         }
        5710         [ -  + ]:        252 :         ADDOP_YIELD(c, loc);
        5711                 :        252 :         break;
        5712                 :         44 :     case YieldFrom_kind:
        5713         [ -  + ]:         44 :         if (c->u->u_ste->ste_type != FunctionBlock) {
        5714                 :          0 :             return compiler_error(c, loc, "'yield' outside function");
        5715                 :            :         }
        5716         [ -  + ]:         44 :         if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) {
        5717                 :          0 :             return compiler_error(c, loc, "'yield from' inside async function");
        5718                 :            :         }
        5719         [ -  + ]:         44 :         VISIT(c, expr, e->v.YieldFrom.value);
        5720         [ -  + ]:         44 :         ADDOP(c, loc, GET_YIELD_FROM_ITER);
        5721         [ -  + ]:         44 :         ADDOP_LOAD_CONST(c, loc, Py_None);
        5722         [ -  + ]:         44 :         ADD_YIELD_FROM(c, loc, 0);
        5723                 :         44 :         break;
        5724                 :        133 :     case Await_kind:
        5725   [ -  +  -  - ]:        133 :         if (!IS_TOP_LEVEL_AWAIT(c)){
        5726         [ -  + ]:        133 :             if (c->u->u_ste->ste_type != FunctionBlock){
        5727                 :          0 :                 return compiler_error(c, loc, "'await' outside function");
        5728                 :            :             }
        5729                 :            :
        5730         [ -  + ]:        133 :             if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
        5731         [ #  # ]:          0 :                     c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION) {
        5732                 :          0 :                 return compiler_error(c, loc, "'await' outside async function");
        5733                 :            :             }
        5734                 :            :         }
        5735                 :            :
        5736         [ -  + ]:        133 :         VISIT(c, expr, e->v.Await.value);
        5737         [ -  + ]:        133 :         ADDOP_I(c, loc, GET_AWAITABLE, 0);
        5738         [ -  + ]:        133 :         ADDOP_LOAD_CONST(c, loc, Py_None);
        5739         [ -  + ]:        133 :         ADD_YIELD_FROM(c, loc, 1);
        5740                 :        133 :         break;
        5741                 :       6321 :     case Compare_kind:
        5742                 :       6321 :         return compiler_compare(c, e);
        5743                 :      26546 :     case Call_kind:
        5744                 :      26546 :         return compiler_call(c, e);
        5745                 :      31226 :     case Constant_kind:
        5746         [ -  + ]:      31226 :         ADDOP_LOAD_CONST(c, loc, e->v.Constant.value);
        5747                 :      31226 :         break;
        5748                 :       1188 :     case JoinedStr_kind:
        5749                 :       1188 :         return compiler_joined_str(c, e);
        5750                 :       1826 :     case FormattedValue_kind:
        5751                 :       1826 :         return compiler_formatted_value(c, e);
        5752                 :            :     /* The following exprs can be assignment targets. */
        5753                 :      18909 :     case Attribute_kind:
        5754         [ -  + ]:      18909 :         VISIT(c, expr, e->v.Attribute.value);
        5755                 :      18909 :         loc = LOC(e);
        5756                 :      18909 :         loc = update_start_location_to_match_attr(c, loc, e);
        5757   [ +  +  +  - ]:      18909 :         switch (e->v.Attribute.ctx) {
        5758                 :      15961 :         case Load:
        5759         [ -  + ]:      15961 :             ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
        5760                 :      15961 :             break;
        5761                 :       2928 :         case Store:
        5762         [ -  + ]:       2928 :             if (forbidden_name(c, loc, e->v.Attribute.attr, e->v.Attribute.ctx)) {
        5763                 :          0 :                 return ERROR;
        5764                 :            :             }
        5765         [ -  + ]:       2928 :             ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
        5766                 :       2928 :             break;
        5767                 :         20 :         case Del:
        5768         [ -  + ]:         20 :             ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names);
        5769                 :         20 :             break;
        5770                 :            :         }
        5771                 :      18909 :         break;
        5772                 :       3526 :     case Subscript_kind:
        5773                 :       3526 :         return compiler_subscript(c, e);
        5774                 :          0 :     case Starred_kind:
        5775         [ #  # ]:          0 :         switch (e->v.Starred.ctx) {
        5776                 :          0 :         case Store:
        5777                 :            :             /* In all legitimate cases, the Starred node was already replaced
        5778                 :            :              * by compiler_list/compiler_tuple. XXX: is that okay? */
        5779                 :          0 :             return compiler_error(c, loc,
        5780                 :            :                 "starred assignment target must be in a list or tuple");
        5781                 :          0 :         default:
        5782                 :          0 :             return compiler_error(c, loc,
        5783                 :            :                 "can't use starred expression here");
        5784                 :            :         }
        5785                 :            :         break;
        5786                 :         21 :     case Slice_kind:
        5787                 :            :     {
        5788                 :         21 :         int n = compiler_slice(c, e);
        5789         [ -  + ]:         21 :         RETURN_IF_ERROR(n);
        5790         [ -  + ]:         21 :         ADDOP_I(c, loc, BUILD_SLICE, n);
        5791                 :         21 :         break;
        5792                 :            :     }
        5793                 :     101542 :     case Name_kind:
        5794                 :     101542 :         return compiler_nameop(c, loc, e->v.Name.id, e->v.Name.ctx);
        5795                 :            :     /* child nodes of List and Tuple will have expr_context set */
        5796                 :       1029 :     case List_kind:
        5797                 :       1029 :         return compiler_list(c, e);
        5798                 :       2952 :     case Tuple_kind:
        5799                 :       2952 :         return compiler_tuple(c, e);
        5800                 :            :     }
        5801                 :      54429 :     return SUCCESS;
        5802                 :            : }
        5803                 :            :
        5804                 :            : static int
        5805                 :     201007 : compiler_visit_expr(struct compiler *c, expr_ty e)
        5806                 :            : {
        5807                 :     201007 :     int res = compiler_visit_expr1(c, e);
        5808                 :     201007 :     return res;
        5809                 :            : }
        5810                 :            :
        5811                 :            : static bool
        5812                 :       3562 : is_two_element_slice(expr_ty s)
        5813                 :            : {
        5814         [ +  + ]:       4376 :     return s->kind == Slice_kind &&
        5815         [ +  + ]:        814 :            s->v.Slice.step == NULL;
        5816                 :            : }
        5817                 :            :
        5818                 :            : static int
        5819                 :        722 : compiler_augassign(struct compiler *c, stmt_ty s)
        5820                 :            : {
        5821                 :            :     assert(s->kind == AugAssign_kind);
        5822                 :        722 :     expr_ty e = s->v.AugAssign.target;
        5823                 :            :
        5824                 :        722 :     location loc = LOC(e);
        5825                 :            :
        5826   [ +  +  +  - ]:        722 :     switch (e->kind) {
        5827                 :        116 :     case Attribute_kind:
        5828         [ -  + ]:        116 :         VISIT(c, expr, e->v.Attribute.value);
        5829         [ -  + ]:        116 :         ADDOP_I(c, loc, COPY, 1);
        5830                 :        116 :         loc = update_start_location_to_match_attr(c, loc, e);
        5831         [ -  + ]:        116 :         ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
        5832                 :        116 :         break;
        5833                 :         18 :     case Subscript_kind:
        5834         [ -  + ]:         18 :         VISIT(c, expr, e->v.Subscript.value);
        5835         [ -  + ]:         18 :         if (is_two_element_slice(e->v.Subscript.slice)) {
        5836         [ #  # ]:          0 :             RETURN_IF_ERROR(compiler_slice(c, e->v.Subscript.slice));
        5837         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 3);
        5838         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 3);
        5839         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 3);
        5840         [ #  # ]:          0 :             ADDOP(c, loc, BINARY_SLICE);
        5841                 :            :         }
        5842                 :            :         else {
        5843         [ -  + ]:         18 :             VISIT(c, expr, e->v.Subscript.slice);
        5844         [ -  + ]:         18 :             ADDOP_I(c, loc, COPY, 2);
        5845         [ -  + ]:         18 :             ADDOP_I(c, loc, COPY, 2);
        5846         [ -  + ]:         18 :             ADDOP(c, loc, BINARY_SUBSCR);
        5847                 :            :         }
        5848                 :         18 :         break;
        5849                 :        588 :     case Name_kind:
        5850         [ -  + ]:        588 :         RETURN_IF_ERROR(compiler_nameop(c, loc, e->v.Name.id, Load));
        5851                 :        588 :         break;
        5852                 :          0 :     default:
        5853                 :          0 :         PyErr_Format(PyExc_SystemError,
        5854                 :            :             "invalid node type (%d) for augmented assignment",
        5855                 :          0 :             e->kind);
        5856                 :          0 :         return ERROR;
        5857                 :            :     }
        5858                 :            :
        5859                 :        722 :     loc = LOC(s);
        5860                 :            :
        5861         [ -  + ]:        722 :     VISIT(c, expr, s->v.AugAssign.value);
        5862         [ -  + ]:        722 :     ADDOP_INPLACE(c, loc, s->v.AugAssign.op);
        5863                 :            :
        5864                 :        722 :     loc = LOC(e);
        5865                 :            :
        5866   [ +  +  +  - ]:        722 :     switch (e->kind) {
        5867                 :        116 :     case Attribute_kind:
        5868                 :        116 :         loc = update_start_location_to_match_attr(c, loc, e);
        5869         [ -  + ]:        116 :         ADDOP_I(c, loc, SWAP, 2);
        5870         [ -  + ]:        116 :         ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
        5871                 :        116 :         break;
        5872                 :         18 :     case Subscript_kind:
        5873         [ -  + ]:         18 :         if (is_two_element_slice(e->v.Subscript.slice)) {
        5874         [ #  # ]:          0 :             ADDOP_I(c, loc, SWAP, 4);
        5875         [ #  # ]:          0 :             ADDOP_I(c, loc, SWAP, 3);
        5876         [ #  # ]:          0 :             ADDOP_I(c, loc, SWAP, 2);
        5877         [ #  # ]:          0 :             ADDOP(c, loc, STORE_SLICE);
        5878                 :            :         }
        5879                 :            :         else {
        5880         [ -  + ]:         18 :             ADDOP_I(c, loc, SWAP, 3);
        5881         [ -  + ]:         18 :             ADDOP_I(c, loc, SWAP, 2);
        5882         [ -  + ]:         18 :             ADDOP(c, loc, STORE_SUBSCR);
        5883                 :            :         }
        5884                 :         18 :         break;
        5885                 :        588 :     case Name_kind:
        5886                 :        588 :         return compiler_nameop(c, loc, e->v.Name.id, Store);
        5887                 :          0 :     default:
        5888                 :          0 :         Py_UNREACHABLE();
        5889                 :            :     }
        5890                 :        134 :     return SUCCESS;
        5891                 :            : }
        5892                 :            :
        5893                 :            : static int
        5894                 :          0 : check_ann_expr(struct compiler *c, expr_ty e)
        5895                 :            : {
        5896         [ #  # ]:          0 :     VISIT(c, expr, e);
        5897         [ #  # ]:          0 :     ADDOP(c, LOC(e), POP_TOP);
        5898                 :          0 :     return SUCCESS;
        5899                 :            : }
        5900                 :            :
        5901                 :            : static int
        5902                 :         10 : check_annotation(struct compiler *c, stmt_ty s)
        5903                 :            : {
        5904                 :            :     /* Annotations of complex targets does not produce anything
        5905                 :            :        under annotations future */
        5906         [ -  + ]:         10 :     if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
        5907                 :          0 :         return SUCCESS;
        5908                 :            :     }
        5909                 :            :
        5910                 :            :     /* Annotations are only evaluated in a module or class. */
        5911         [ +  - ]:         10 :     if (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
        5912         [ -  + ]:         10 :         c->u->u_scope_type == COMPILER_SCOPE_CLASS) {
        5913                 :          0 :         return check_ann_expr(c, s->v.AnnAssign.annotation);
        5914                 :            :     }
        5915                 :         10 :     return SUCCESS;
        5916                 :            : }
        5917                 :            :
        5918                 :            : static int
        5919                 :          0 : check_ann_subscr(struct compiler *c, expr_ty e)
        5920                 :            : {
        5921                 :            :     /* We check that everything in a subscript is defined at runtime. */
        5922      [ #  #  # ]:          0 :     switch (e->kind) {
        5923                 :          0 :     case Slice_kind:
        5924   [ #  #  #  # ]:          0 :         if (e->v.Slice.lower && check_ann_expr(c, e->v.Slice.lower) < 0) {
        5925                 :          0 :             return ERROR;
        5926                 :            :         }
        5927   [ #  #  #  # ]:          0 :         if (e->v.Slice.upper && check_ann_expr(c, e->v.Slice.upper) < 0) {
        5928                 :          0 :             return ERROR;
        5929                 :            :         }
        5930   [ #  #  #  # ]:          0 :         if (e->v.Slice.step && check_ann_expr(c, e->v.Slice.step) < 0) {
        5931                 :          0 :             return ERROR;
        5932                 :            :         }
        5933                 :          0 :         return SUCCESS;
        5934                 :          0 :     case Tuple_kind: {
        5935                 :            :         /* extended slice */
        5936                 :          0 :         asdl_expr_seq *elts = e->v.Tuple.elts;
        5937         [ #  # ]:          0 :         Py_ssize_t i, n = asdl_seq_LEN(elts);
        5938         [ #  # ]:          0 :         for (i = 0; i < n; i++) {
        5939         [ #  # ]:          0 :             RETURN_IF_ERROR(check_ann_subscr(c, asdl_seq_GET(elts, i)));
        5940                 :            :         }
        5941                 :          0 :         return SUCCESS;
        5942                 :            :     }
        5943                 :          0 :     default:
        5944                 :          0 :         return check_ann_expr(c, e);
        5945                 :            :     }
        5946                 :            : }
        5947                 :            :
        5948                 :            : static int
        5949                 :         17 : compiler_annassign(struct compiler *c, stmt_ty s)
        5950                 :            : {
        5951                 :         17 :     location loc = LOC(s);
        5952                 :         17 :     expr_ty targ = s->v.AnnAssign.target;
        5953                 :            :     PyObject* mangled;
        5954                 :            :
        5955                 :            :     assert(s->kind == AnnAssign_kind);
        5956                 :            :
        5957                 :            :     /* We perform the actual assignment first. */
        5958         [ +  + ]:         17 :     if (s->v.AnnAssign.value) {
        5959         [ -  + ]:         15 :         VISIT(c, expr, s->v.AnnAssign.value);
        5960         [ -  + ]:         15 :         VISIT(c, expr, targ);
        5961                 :            :     }
        5962   [ +  +  -  - ]:         17 :     switch (targ->kind) {
        5963                 :          7 :     case Name_kind:
        5964         [ -  + ]:          7 :         if (forbidden_name(c, loc, targ->v.Name.id, Store)) {
        5965                 :          0 :             return ERROR;
        5966                 :            :         }
        5967                 :            :         /* If we have a simple name in a module or class, store annotation. */
        5968         [ +  - ]:          7 :         if (s->v.AnnAssign.simple &&
        5969         [ +  - ]:          7 :             (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
        5970         [ +  + ]:          7 :              c->u->u_scope_type == COMPILER_SCOPE_CLASS)) {
        5971         [ -  + ]:          2 :             if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
        5972         [ #  # ]:          0 :                 VISIT(c, annexpr, s->v.AnnAssign.annotation)
        5973                 :            :             }
        5974                 :            :             else {
        5975         [ -  + ]:          2 :                 VISIT(c, expr, s->v.AnnAssign.annotation);
        5976                 :            :             }
        5977         [ -  + ]:          2 :             ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
        5978                 :          2 :             mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
        5979   [ -  +  -  + ]:          2 :             ADDOP_LOAD_CONST_NEW(c, loc, mangled);
        5980         [ -  + ]:          2 :             ADDOP(c, loc, STORE_SUBSCR);
        5981                 :            :         }
        5982                 :          7 :         break;
        5983                 :         10 :     case Attribute_kind:
        5984         [ -  + ]:         10 :         if (forbidden_name(c, loc, targ->v.Attribute.attr, Store)) {
        5985                 :          0 :             return ERROR;
        5986                 :            :         }
        5987   [ -  +  -  - ]:         10 :         if (!s->v.AnnAssign.value &&
        5988                 :          0 :             check_ann_expr(c, targ->v.Attribute.value) < 0) {
        5989                 :          0 :             return ERROR;
        5990                 :            :         }
        5991                 :         10 :         break;
        5992                 :          0 :     case Subscript_kind:
        5993   [ #  #  #  # ]:          0 :         if (!s->v.AnnAssign.value &&
        5994         [ #  # ]:          0 :             (check_ann_expr(c, targ->v.Subscript.value) < 0 ||
        5995                 :          0 :              check_ann_subscr(c, targ->v.Subscript.slice) < 0)) {
        5996                 :          0 :                 return ERROR;
        5997                 :            :         }
        5998                 :          0 :         break;
        5999                 :          0 :     default:
        6000                 :          0 :         PyErr_Format(PyExc_SystemError,
        6001                 :            :                      "invalid node type (%d) for annotated assignment",
        6002                 :          0 :                      targ->kind);
        6003                 :          0 :         return ERROR;
        6004                 :            :     }
        6005                 :            :     /* Annotation is evaluated last. */
        6006   [ +  +  -  + ]:         17 :     if (!s->v.AnnAssign.simple && check_annotation(c, s) < 0) {
        6007                 :          0 :         return ERROR;
        6008                 :            :     }
        6009                 :         17 :     return SUCCESS;
        6010                 :            : }
        6011                 :            :
        6012                 :            : /* Raises a SyntaxError and returns 0.
        6013                 :            :    If something goes wrong, a different exception may be raised.
        6014                 :            : */
        6015                 :            :
        6016                 :            : static int
        6017                 :          0 : compiler_error(struct compiler *c, location loc,
        6018                 :            :                const char *format, ...)
        6019                 :            : {
        6020                 :            :     va_list vargs;
        6021                 :          0 :     va_start(vargs, format);
        6022                 :          0 :     PyObject *msg = PyUnicode_FromFormatV(format, vargs);
        6023                 :          0 :     va_end(vargs);
        6024         [ #  # ]:          0 :     if (msg == NULL) {
        6025                 :          0 :         return ERROR;
        6026                 :            :     }
        6027                 :          0 :     PyObject *loc_obj = PyErr_ProgramTextObject(c->c_filename, loc.lineno);
        6028         [ #  # ]:          0 :     if (loc_obj == NULL) {
        6029                 :          0 :         loc_obj = Py_NewRef(Py_None);
        6030                 :            :     }
        6031                 :          0 :     PyObject *args = Py_BuildValue("O(OiiOii)", msg, c->c_filename,
        6032                 :          0 :                                    loc.lineno, loc.col_offset + 1, loc_obj,
        6033                 :          0 :                                    loc.end_lineno, loc.end_col_offset + 1);
        6034                 :          0 :     Py_DECREF(msg);
        6035         [ #  # ]:          0 :     if (args == NULL) {
        6036                 :          0 :         goto exit;
        6037                 :            :     }
        6038                 :          0 :     PyErr_SetObject(PyExc_SyntaxError, args);
        6039                 :          0 :  exit:
        6040                 :          0 :     Py_DECREF(loc_obj);
        6041                 :          0 :     Py_XDECREF(args);
        6042                 :          0 :     return ERROR;
        6043                 :            : }
        6044                 :            :
        6045                 :            : /* Emits a SyntaxWarning and returns 1 on success.
        6046                 :            :    If a SyntaxWarning raised as error, replaces it with a SyntaxError
        6047                 :            :    and returns 0.
        6048                 :            : */
        6049                 :            : static int
        6050                 :          0 : compiler_warn(struct compiler *c, location loc,
        6051                 :            :               const char *format, ...)
        6052                 :            : {
        6053                 :            :     va_list vargs;
        6054                 :          0 :     va_start(vargs, format);
        6055                 :          0 :     PyObject *msg = PyUnicode_FromFormatV(format, vargs);
        6056                 :          0 :     va_end(vargs);
        6057         [ #  # ]:          0 :     if (msg == NULL) {
        6058                 :          0 :         return ERROR;
        6059                 :            :     }
        6060         [ #  # ]:          0 :     if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename,
        6061                 :            :                                  loc.lineno, NULL, NULL) < 0)
        6062                 :            :     {
        6063         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
        6064                 :            :             /* Replace the SyntaxWarning exception with a SyntaxError
        6065                 :            :                to get a more accurate error report */
        6066                 :          0 :             PyErr_Clear();
        6067                 :            :             assert(PyUnicode_AsUTF8(msg) != NULL);
        6068                 :          0 :             compiler_error(c, loc, PyUnicode_AsUTF8(msg));
        6069                 :            :         }
        6070                 :          0 :         Py_DECREF(msg);
        6071                 :          0 :         return ERROR;
        6072                 :            :     }
        6073                 :          0 :     Py_DECREF(msg);
        6074                 :          0 :     return SUCCESS;
        6075                 :            : }
        6076                 :            :
        6077                 :            : static int
        6078                 :       3526 : compiler_subscript(struct compiler *c, expr_ty e)
        6079                 :            : {
        6080                 :       3526 :     location loc = LOC(e);
        6081                 :       3526 :     expr_context_ty ctx = e->v.Subscript.ctx;
        6082                 :       3526 :     int op = 0;
        6083                 :            :
        6084         [ +  + ]:       3526 :     if (ctx == Load) {
        6085         [ -  + ]:       2593 :         RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value));
        6086         [ -  + ]:       2593 :         RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice));
        6087                 :            :     }
        6088                 :            :
        6089         [ -  + ]:       3526 :     VISIT(c, expr, e->v.Subscript.value);
        6090   [ +  +  +  + ]:       3526 :     if (is_two_element_slice(e->v.Subscript.slice) && ctx != Del) {
        6091         [ -  + ]:        793 :         RETURN_IF_ERROR(compiler_slice(c, e->v.Subscript.slice));
        6092         [ +  + ]:        793 :         if (ctx == Load) {
        6093         [ -  + ]:        751 :             ADDOP(c, loc, BINARY_SLICE);
        6094                 :            :         }
        6095                 :            :         else {
        6096                 :            :             assert(ctx == Store);
        6097         [ -  + ]:         42 :             ADDOP(c, loc, STORE_SLICE);
        6098                 :            :         }
        6099                 :            :     }
        6100                 :            :     else {
        6101         [ -  + ]:       2733 :         VISIT(c, expr, e->v.Subscript.slice);
        6102   [ +  +  +  - ]:       2733 :         switch (ctx) {
        6103                 :       1842 :             case Load:    op = BINARY_SUBSCR; break;
        6104                 :        770 :             case Store:   op = STORE_SUBSCR; break;
        6105                 :        121 :             case Del:     op = DELETE_SUBSCR; break;
        6106                 :            :         }
        6107                 :       2733 :         assert(op);
        6108         [ -  + ]:       2733 :         ADDOP(c, loc, op);
        6109                 :            :     }
        6110                 :       3526 :     return SUCCESS;
        6111                 :            : }
        6112                 :            :
        6113                 :            : /* Returns the number of the values emitted,
        6114                 :            :  * thus are needed to build the slice, or -1 if there is an error. */
        6115                 :            : static int
        6116                 :        814 : compiler_slice(struct compiler *c, expr_ty s)
        6117                 :            : {
        6118                 :        814 :     int n = 2;
        6119                 :            :     assert(s->kind == Slice_kind);
        6120                 :            :
        6121                 :            :     /* only handles the cases where BUILD_SLICE is emitted */
        6122         [ +  + ]:        814 :     if (s->v.Slice.lower) {
        6123         [ -  + ]:        450 :         VISIT(c, expr, s->v.Slice.lower);
        6124                 :            :     }
        6125                 :            :     else {
        6126         [ -  + ]:        364 :         ADDOP_LOAD_CONST(c, LOC(s), Py_None);
        6127                 :            :     }
        6128                 :            :
        6129         [ +  + ]:        814 :     if (s->v.Slice.upper) {
        6130         [ -  + ]:        483 :         VISIT(c, expr, s->v.Slice.upper);
        6131                 :            :     }
        6132                 :            :     else {
        6133         [ -  + ]:        331 :         ADDOP_LOAD_CONST(c, LOC(s), Py_None);
        6134                 :            :     }
        6135                 :            :
        6136         [ +  + ]:        814 :     if (s->v.Slice.step) {
        6137                 :          9 :         n++;
        6138         [ -  + ]:          9 :         VISIT(c, expr, s->v.Slice.step);
        6139                 :            :     }
        6140                 :        814 :     return n;
        6141                 :            : }
        6142                 :            :
        6143                 :            :
        6144                 :            : // PEP 634: Structural Pattern Matching
        6145                 :            :
        6146                 :            : // To keep things simple, all compiler_pattern_* and pattern_helper_* routines
        6147                 :            : // follow the convention of consuming TOS (the subject for the given pattern)
        6148                 :            : // and calling jump_to_fail_pop on failure (no match).
        6149                 :            :
        6150                 :            : // When calling into these routines, it's important that pc->on_top be kept
        6151                 :            : // updated to reflect the current number of items that we are using on the top
        6152                 :            : // of the stack: they will be popped on failure, and any name captures will be
        6153                 :            : // stored *underneath* them on success. This lets us defer all names stores
        6154                 :            : // until the *entire* pattern matches.
        6155                 :            :
        6156                 :            : #define WILDCARD_CHECK(N) \
        6157                 :            :     ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name)
        6158                 :            :
        6159                 :            : #define WILDCARD_STAR_CHECK(N) \
        6160                 :            :     ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
        6161                 :            :
        6162                 :            : // Limit permitted subexpressions, even if the parser & AST validator let them through
        6163                 :            : #define MATCH_VALUE_EXPR(N) \
        6164                 :            :     ((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
        6165                 :            :
        6166                 :            : // Allocate or resize pc->fail_pop to allow for n items to be popped on failure.
        6167                 :            : static int
        6168                 :         19 : ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n)
        6169                 :            : {
        6170                 :         19 :     Py_ssize_t size = n + 1;
        6171         [ +  + ]:         19 :     if (size <= pc->fail_pop_size) {
        6172                 :          8 :         return SUCCESS;
        6173                 :            :     }
        6174                 :         11 :     Py_ssize_t needed = sizeof(jump_target_label) * size;
        6175                 :         11 :     jump_target_label *resized = PyObject_Realloc(pc->fail_pop, needed);
        6176         [ -  + ]:         11 :     if (resized == NULL) {
        6177                 :          0 :         PyErr_NoMemory();
        6178                 :          0 :         return ERROR;
        6179                 :            :     }
        6180                 :         11 :     pc->fail_pop = resized;
        6181         [ +  + ]:         31 :     while (pc->fail_pop_size < size) {
        6182         [ -  + ]:         20 :         NEW_JUMP_TARGET_LABEL(c, new_block);
        6183                 :         20 :         pc->fail_pop[pc->fail_pop_size++] = new_block;
        6184                 :            :     }
        6185                 :         11 :     return SUCCESS;
        6186                 :            : }
        6187                 :            :
        6188                 :            : // Use op to jump to the correct fail_pop block.
        6189                 :            : static int
        6190                 :         18 : jump_to_fail_pop(struct compiler *c, location loc,
        6191                 :            :                  pattern_context *pc, int op)
        6192                 :            : {
        6193                 :            :     // Pop any items on the top of the stack, plus any objects we were going to
        6194                 :            :     // capture on success:
        6195                 :         18 :     Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
        6196         [ -  + ]:         18 :     RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops));
        6197         [ -  + ]:         18 :     ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
        6198                 :         18 :     return SUCCESS;
        6199                 :            : }
        6200                 :            :
        6201                 :            : // Build all of the fail_pop blocks and reset fail_pop.
        6202                 :            : static int
        6203                 :         11 : emit_and_reset_fail_pop(struct compiler *c, location loc,
        6204                 :            :                         pattern_context *pc)
        6205                 :            : {
        6206         [ -  + ]:         11 :     if (!pc->fail_pop_size) {
        6207                 :            :         assert(pc->fail_pop == NULL);
        6208                 :          0 :         return SUCCESS;
        6209                 :            :     }
        6210         [ +  + ]:         20 :     while (--pc->fail_pop_size) {
        6211         [ -  + ]:          9 :         USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
        6212         [ -  + ]:          9 :         if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, loc) < 0) {
        6213                 :          0 :             pc->fail_pop_size = 0;
        6214                 :          0 :             PyObject_Free(pc->fail_pop);
        6215                 :          0 :             pc->fail_pop = NULL;
        6216                 :          0 :             return ERROR;
        6217                 :            :         }
        6218                 :            :     }
        6219         [ -  + ]:         11 :     USE_LABEL(c, pc->fail_pop[0]);
        6220                 :         11 :     PyObject_Free(pc->fail_pop);
        6221                 :         11 :     pc->fail_pop = NULL;
        6222                 :         11 :     return SUCCESS;
        6223                 :            : }
        6224                 :            :
        6225                 :            : static int
        6226                 :          0 : compiler_error_duplicate_store(struct compiler *c, location loc, identifier n)
        6227                 :            : {
        6228                 :          0 :     return compiler_error(c, loc,
        6229                 :            :         "multiple assignments to name %R in pattern", n);
        6230                 :            : }
        6231                 :            :
        6232                 :            : // Duplicate the effect of 3.10's ROT_* instructions using SWAPs.
        6233                 :            : static int
        6234                 :          4 : pattern_helper_rotate(struct compiler *c, location loc, Py_ssize_t count)
        6235                 :            : {
        6236         [ -  + ]:          4 :     while (1 < count) {
        6237         [ #  # ]:          0 :         ADDOP_I(c, loc, SWAP, count--);
        6238                 :            :     }
        6239                 :          4 :     return SUCCESS;
        6240                 :            : }
        6241                 :            :
        6242                 :            : static int
        6243                 :          4 : pattern_helper_store_name(struct compiler *c, location loc,
        6244                 :            :                           identifier n, pattern_context *pc)
        6245                 :            : {
        6246         [ -  + ]:          4 :     if (n == NULL) {
        6247         [ #  # ]:          0 :         ADDOP(c, loc, POP_TOP);
        6248                 :          0 :         return SUCCESS;
        6249                 :            :     }
        6250         [ -  + ]:          4 :     if (forbidden_name(c, loc, n, Store)) {
        6251                 :          0 :         return ERROR;
        6252                 :            :     }
        6253                 :            :     // Can't assign to the same name twice:
        6254                 :          4 :     int duplicate = PySequence_Contains(pc->stores, n);
        6255         [ -  + ]:          4 :     RETURN_IF_ERROR(duplicate);
        6256         [ -  + ]:          4 :     if (duplicate) {
        6257                 :          0 :         return compiler_error_duplicate_store(c, loc, n);
        6258                 :            :     }
        6259                 :            :     // Rotate this object underneath any items we need to preserve:
        6260                 :          4 :     Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
        6261         [ -  + ]:          4 :     RETURN_IF_ERROR(pattern_helper_rotate(c, loc, rotations));
        6262         [ -  + ]:          4 :     RETURN_IF_ERROR(PyList_Append(pc->stores, n));
        6263                 :          4 :     return SUCCESS;
        6264                 :            : }
        6265                 :            :
        6266                 :            :
        6267                 :            : static int
        6268                 :          5 : pattern_unpack_helper(struct compiler *c, location loc,
        6269                 :            :                       asdl_pattern_seq *elts)
        6270                 :            : {
        6271         [ +  - ]:          5 :     Py_ssize_t n = asdl_seq_LEN(elts);
        6272                 :          5 :     int seen_star = 0;
        6273         [ +  + ]:         10 :     for (Py_ssize_t i = 0; i < n; i++) {
        6274                 :          5 :         pattern_ty elt = asdl_seq_GET(elts, i);
        6275   [ +  +  +  - ]:          5 :         if (elt->kind == MatchStar_kind && !seen_star) {
        6276         [ +  - ]:          1 :             if ((i >= (1 << 8)) ||
        6277         [ -  + ]:          1 :                 (n-i-1 >= (INT_MAX >> 8))) {
        6278                 :          0 :                 return compiler_error(c, loc,
        6279                 :            :                     "too many expressions in "
        6280                 :            :                     "star-unpacking sequence pattern");
        6281                 :            :             }
        6282         [ -  + ]:          1 :             ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
        6283                 :          1 :             seen_star = 1;
        6284                 :            :         }
        6285         [ -  + ]:          4 :         else if (elt->kind == MatchStar_kind) {
        6286                 :          0 :             return compiler_error(c, loc,
        6287                 :            :                 "multiple starred expressions in sequence pattern");
        6288                 :            :         }
        6289                 :            :     }
        6290         [ +  + ]:          5 :     if (!seen_star) {
        6291         [ -  + ]:          4 :         ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
        6292                 :            :     }
        6293                 :          5 :     return SUCCESS;
        6294                 :            : }
        6295                 :            :
        6296                 :            : static int
        6297                 :          5 : pattern_helper_sequence_unpack(struct compiler *c, location loc,
        6298                 :            :                                asdl_pattern_seq *patterns, Py_ssize_t star,
        6299                 :            :                                pattern_context *pc)
        6300                 :            : {
        6301         [ -  + ]:          5 :     RETURN_IF_ERROR(pattern_unpack_helper(c, loc, patterns));
        6302         [ +  - ]:          5 :     Py_ssize_t size = asdl_seq_LEN(patterns);
        6303                 :            :     // We've now got a bunch of new subjects on the stack. They need to remain
        6304                 :            :     // there after each subpattern match:
        6305                 :          5 :     pc->on_top += size;
        6306         [ +  + ]:         10 :     for (Py_ssize_t i = 0; i < size; i++) {
        6307                 :            :         // One less item to keep track of each time we loop through:
        6308                 :          5 :         pc->on_top--;
        6309                 :          5 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
        6310         [ -  + ]:          5 :         RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc));
        6311                 :            :     }
        6312                 :          5 :     return SUCCESS;
        6313                 :            : }
        6314                 :            :
        6315                 :            : // Like pattern_helper_sequence_unpack, but uses BINARY_SUBSCR instead of
        6316                 :            : // UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a
        6317                 :            : // starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc.
        6318                 :            : static int
        6319                 :          0 : pattern_helper_sequence_subscr(struct compiler *c, location loc,
        6320                 :            :                                asdl_pattern_seq *patterns, Py_ssize_t star,
        6321                 :            :                                pattern_context *pc)
        6322                 :            : {
        6323                 :            :     // We need to keep the subject around for extracting elements:
        6324                 :          0 :     pc->on_top++;
        6325         [ #  # ]:          0 :     Py_ssize_t size = asdl_seq_LEN(patterns);
        6326         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < size; i++) {
        6327                 :          0 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
        6328   [ #  #  #  # ]:          0 :         if (WILDCARD_CHECK(pattern)) {
        6329                 :          0 :             continue;
        6330                 :            :         }
        6331         [ #  # ]:          0 :         if (i == star) {
        6332                 :            :             assert(WILDCARD_STAR_CHECK(pattern));
        6333                 :          0 :             continue;
        6334                 :            :         }
        6335         [ #  # ]:          0 :         ADDOP_I(c, loc, COPY, 1);
        6336         [ #  # ]:          0 :         if (i < star) {
        6337   [ #  #  #  # ]:          0 :             ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i));
        6338                 :            :         }
        6339                 :            :         else {
        6340                 :            :             // The subject may not support negative indexing! Compute a
        6341                 :            :             // nonnegative index:
        6342         [ #  # ]:          0 :             ADDOP(c, loc, GET_LEN);
        6343   [ #  #  #  # ]:          0 :             ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i));
        6344         [ #  # ]:          0 :             ADDOP_BINARY(c, loc, Sub);
        6345                 :            :         }
        6346         [ #  # ]:          0 :         ADDOP(c, loc, BINARY_SUBSCR);
        6347         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc));
        6348                 :            :     }
        6349                 :            :     // Pop the subject, we're done with it:
        6350                 :          0 :     pc->on_top--;
        6351         [ #  # ]:          0 :     ADDOP(c, loc, POP_TOP);
        6352                 :          0 :     return SUCCESS;
        6353                 :            : }
        6354                 :            :
        6355                 :            : // Like compiler_pattern, but turn off checks for irrefutability.
        6356                 :            : static int
        6357                 :          7 : compiler_pattern_subpattern(struct compiler *c,
        6358                 :            :                             pattern_ty p, pattern_context *pc)
        6359                 :            : {
        6360                 :          7 :     int allow_irrefutable = pc->allow_irrefutable;
        6361                 :          7 :     pc->allow_irrefutable = 1;
        6362         [ -  + ]:          7 :     RETURN_IF_ERROR(compiler_pattern(c, p, pc));
        6363                 :          7 :     pc->allow_irrefutable = allow_irrefutable;
        6364                 :          7 :     return SUCCESS;
        6365                 :            : }
        6366                 :            :
        6367                 :            : static int
        6368                 :          3 : compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc)
        6369                 :            : {
        6370                 :            :     assert(p->kind == MatchAs_kind);
        6371         [ +  - ]:          3 :     if (p->v.MatchAs.pattern == NULL) {
        6372                 :            :         // An irrefutable match:
        6373         [ -  + ]:          3 :         if (!pc->allow_irrefutable) {
        6374         [ #  # ]:          0 :             if (p->v.MatchAs.name) {
        6375                 :          0 :                 const char *e = "name capture %R makes remaining patterns unreachable";
        6376                 :          0 :                 return compiler_error(c, LOC(p), e, p->v.MatchAs.name);
        6377                 :            :             }
        6378                 :          0 :             const char *e = "wildcard makes remaining patterns unreachable";
        6379                 :          0 :             return compiler_error(c, LOC(p), e);
        6380                 :            :         }
        6381                 :          3 :         return pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc);
        6382                 :            :     }
        6383                 :            :     // Need to make a copy for (possibly) storing later:
        6384                 :          0 :     pc->on_top++;
        6385         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), COPY, 1);
        6386         [ #  # ]:          0 :     RETURN_IF_ERROR(compiler_pattern(c, p->v.MatchAs.pattern, pc));
        6387                 :            :     // Success! Store it:
        6388                 :          0 :     pc->on_top--;
        6389         [ #  # ]:          0 :     RETURN_IF_ERROR(pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc));
        6390                 :          0 :     return SUCCESS;
        6391                 :            : }
        6392                 :            :
        6393                 :            : static int
        6394                 :          1 : compiler_pattern_star(struct compiler *c, pattern_ty p, pattern_context *pc)
        6395                 :            : {
        6396                 :            :     assert(p->kind == MatchStar_kind);
        6397         [ -  + ]:          1 :     RETURN_IF_ERROR(
        6398                 :            :         pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc));
        6399                 :          1 :     return SUCCESS;
        6400                 :            : }
        6401                 :            :
        6402                 :            : static int
        6403                 :          0 : validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns)
        6404                 :            : {
        6405                 :            :     // Any errors will point to the pattern rather than the arg name as the
        6406                 :            :     // parser is only supplying identifiers rather than Name or keyword nodes
        6407         [ #  # ]:          0 :     Py_ssize_t nattrs = asdl_seq_LEN(attrs);
        6408         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < nattrs; i++) {
        6409                 :          0 :         identifier attr = ((identifier)asdl_seq_GET(attrs, i));
        6410                 :          0 :         location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
        6411         [ #  # ]:          0 :         if (forbidden_name(c, loc, attr, Store)) {
        6412                 :          0 :             return ERROR;
        6413                 :            :         }
        6414         [ #  # ]:          0 :         for (Py_ssize_t j = i + 1; j < nattrs; j++) {
        6415                 :          0 :             identifier other = ((identifier)asdl_seq_GET(attrs, j));
        6416         [ #  # ]:          0 :             if (!PyUnicode_Compare(attr, other)) {
        6417                 :          0 :                 location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j));
        6418                 :          0 :                 compiler_error(c, loc, "attribute name repeated in class pattern: %U", attr);
        6419                 :          0 :                 return ERROR;
        6420                 :            :             }
        6421                 :            :         }
        6422                 :            :     }
        6423                 :          0 :     return SUCCESS;
        6424                 :            : }
        6425                 :            :
        6426                 :            : static int
        6427                 :          4 : compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
        6428                 :            : {
        6429                 :            :     assert(p->kind == MatchClass_kind);
        6430                 :          4 :     asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
        6431                 :          4 :     asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs;
        6432                 :          4 :     asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns;
        6433         [ +  + ]:          4 :     Py_ssize_t nargs = asdl_seq_LEN(patterns);
        6434         [ -  + ]:          4 :     Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs);
        6435         [ -  + ]:          4 :     Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns);
        6436         [ -  + ]:          4 :     if (nattrs != nkwd_patterns) {
        6437                 :            :         // AST validator shouldn't let this happen, but if it does,
        6438                 :            :         // just fail, don't crash out of the interpreter
        6439                 :          0 :         const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern";
        6440                 :          0 :         return compiler_error(c, LOC(p), e, nattrs, nkwd_patterns);
        6441                 :            :     }
        6442   [ +  -  -  + ]:          4 :     if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) {
        6443                 :          0 :         const char *e = "too many sub-patterns in class pattern %R";
        6444                 :          0 :         return compiler_error(c, LOC(p), e, p->v.MatchClass.cls);
        6445                 :            :     }
        6446         [ -  + ]:          4 :     if (nattrs) {
        6447         [ #  # ]:          0 :         RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
        6448                 :            :     }
        6449         [ -  + ]:          4 :     VISIT(c, expr, p->v.MatchClass.cls);
        6450                 :          4 :     PyObject *attr_names = PyTuple_New(nattrs);
        6451         [ -  + ]:          4 :     if (attr_names == NULL) {
        6452                 :          0 :         return ERROR;
        6453                 :            :     }
        6454                 :            :     Py_ssize_t i;
        6455         [ -  + ]:          4 :     for (i = 0; i < nattrs; i++) {
        6456                 :          0 :         PyObject *name = asdl_seq_GET(kwd_attrs, i);
        6457                 :          0 :         PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name));
        6458                 :            :     }
        6459   [ -  +  -  + ]:          4 :     ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names);
        6460         [ -  + ]:          4 :     ADDOP_I(c, LOC(p), MATCH_CLASS, nargs);
        6461         [ -  + ]:          4 :     ADDOP_I(c, LOC(p), COPY, 1);
        6462         [ -  + ]:          4 :     ADDOP_LOAD_CONST(c, LOC(p), Py_None);
        6463         [ -  + ]:          4 :     ADDOP_I(c, LOC(p), IS_OP, 1);
        6464                 :            :     // TOS is now a tuple of (nargs + nattrs) attributes (or None):
        6465                 :          4 :     pc->on_top++;
        6466         [ -  + ]:          4 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6467         [ -  + ]:          4 :     ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs);
        6468                 :          4 :     pc->on_top += nargs + nattrs - 1;
        6469         [ +  + ]:          6 :     for (i = 0; i < nargs + nattrs; i++) {
        6470                 :          2 :         pc->on_top--;
        6471                 :            :         pattern_ty pattern;
        6472         [ +  - ]:          2 :         if (i < nargs) {
        6473                 :            :             // Positional:
        6474                 :          2 :             pattern = asdl_seq_GET(patterns, i);
        6475                 :            :         }
        6476                 :            :         else {
        6477                 :            :             // Keyword:
        6478                 :          0 :             pattern = asdl_seq_GET(kwd_patterns, i - nargs);
        6479                 :            :         }
        6480   [ +  -  -  + ]:          2 :         if (WILDCARD_CHECK(pattern)) {
        6481         [ #  # ]:          0 :             ADDOP(c, LOC(p), POP_TOP);
        6482                 :          0 :             continue;
        6483                 :            :         }
        6484         [ -  + ]:          2 :         RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc));
        6485                 :            :     }
        6486                 :            :     // Success! Pop the tuple of attributes:
        6487                 :          4 :     return SUCCESS;
        6488                 :            : }
        6489                 :            :
        6490                 :            : static int
        6491                 :          0 : compiler_pattern_mapping(struct compiler *c, pattern_ty p,
        6492                 :            :                          pattern_context *pc)
        6493                 :            : {
        6494                 :            :     assert(p->kind == MatchMapping_kind);
        6495                 :          0 :     asdl_expr_seq *keys = p->v.MatchMapping.keys;
        6496                 :          0 :     asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
        6497         [ #  # ]:          0 :     Py_ssize_t size = asdl_seq_LEN(keys);
        6498         [ #  # ]:          0 :     Py_ssize_t npatterns = asdl_seq_LEN(patterns);
        6499         [ #  # ]:          0 :     if (size != npatterns) {
        6500                 :            :         // AST validator shouldn't let this happen, but if it does,
        6501                 :            :         // just fail, don't crash out of the interpreter
        6502                 :          0 :         const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern";
        6503                 :          0 :         return compiler_error(c, LOC(p), e, size, npatterns);
        6504                 :            :     }
        6505                 :            :     // We have a double-star target if "rest" is set
        6506                 :          0 :     PyObject *star_target = p->v.MatchMapping.rest;
        6507                 :            :     // We need to keep the subject on top during the mapping and length checks:
        6508                 :          0 :     pc->on_top++;
        6509         [ #  # ]:          0 :     ADDOP(c, LOC(p), MATCH_MAPPING);
        6510         [ #  # ]:          0 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6511   [ #  #  #  # ]:          0 :     if (!size && !star_target) {
        6512                 :            :         // If the pattern is just "{}", we're done! Pop the subject:
        6513                 :          0 :         pc->on_top--;
        6514         [ #  # ]:          0 :         ADDOP(c, LOC(p), POP_TOP);
        6515                 :          0 :         return SUCCESS;
        6516                 :            :     }
        6517         [ #  # ]:          0 :     if (size) {
        6518                 :            :         // If the pattern has any keys in it, perform a length check:
        6519         [ #  # ]:          0 :         ADDOP(c, LOC(p), GET_LEN);
        6520   [ #  #  #  # ]:          0 :         ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
        6521         [ #  # ]:          0 :         ADDOP_COMPARE(c, LOC(p), GtE);
        6522         [ #  # ]:          0 :         RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6523                 :            :     }
        6524         [ #  # ]:          0 :     if (INT_MAX < size - 1) {
        6525                 :          0 :         return compiler_error(c, LOC(p), "too many sub-patterns in mapping pattern");
        6526                 :            :     }
        6527                 :            :     // Collect all of the keys into a tuple for MATCH_KEYS and
        6528                 :            :     // **rest. They can either be dotted names or literals:
        6529                 :            :
        6530                 :            :     // Maintaining a set of Constant_kind kind keys allows us to raise a
        6531                 :            :     // SyntaxError in the case of duplicates.
        6532                 :          0 :     PyObject *seen = PySet_New(NULL);
        6533         [ #  # ]:          0 :     if (seen == NULL) {
        6534                 :          0 :         return ERROR;
        6535                 :            :     }
        6536                 :            :
        6537                 :            :     // NOTE: goto error on failure in the loop below to avoid leaking `seen`
        6538         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < size; i++) {
        6539                 :          0 :         expr_ty key = asdl_seq_GET(keys, i);
        6540         [ #  # ]:          0 :         if (key == NULL) {
        6541                 :          0 :             const char *e = "can't use NULL keys in MatchMapping "
        6542                 :            :                             "(set 'rest' parameter instead)";
        6543                 :          0 :             location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
        6544                 :          0 :             compiler_error(c, loc, e);
        6545                 :          0 :             goto error;
        6546                 :            :         }
        6547                 :            :
        6548         [ #  # ]:          0 :         if (key->kind == Constant_kind) {
        6549                 :          0 :             int in_seen = PySet_Contains(seen, key->v.Constant.value);
        6550         [ #  # ]:          0 :             if (in_seen < 0) {
        6551                 :          0 :                 goto error;
        6552                 :            :             }
        6553         [ #  # ]:          0 :             if (in_seen) {
        6554                 :          0 :                 const char *e = "mapping pattern checks duplicate key (%R)";
        6555                 :          0 :                 compiler_error(c, LOC(p), e, key->v.Constant.value);
        6556                 :          0 :                 goto error;
        6557                 :            :             }
        6558         [ #  # ]:          0 :             if (PySet_Add(seen, key->v.Constant.value)) {
        6559                 :          0 :                 goto error;
        6560                 :            :             }
        6561                 :            :         }
        6562                 :            :
        6563         [ #  # ]:          0 :         else if (key->kind != Attribute_kind) {
        6564                 :          0 :             const char *e = "mapping pattern keys may only match literals and attribute lookups";
        6565                 :          0 :             compiler_error(c, LOC(p), e);
        6566                 :          0 :             goto error;
        6567                 :            :         }
        6568         [ #  # ]:          0 :         if (compiler_visit_expr(c, key) < 0) {
        6569                 :          0 :             goto error;
        6570                 :            :         }
        6571                 :            :     }
        6572                 :            :
        6573                 :            :     // all keys have been checked; there are no duplicates
        6574                 :          0 :     Py_DECREF(seen);
        6575                 :            :
        6576         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), BUILD_TUPLE, size);
        6577         [ #  # ]:          0 :     ADDOP(c, LOC(p), MATCH_KEYS);
        6578                 :            :     // There's now a tuple of keys and a tuple of values on top of the subject:
        6579                 :          0 :     pc->on_top += 2;
        6580         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), COPY, 1);
        6581         [ #  # ]:          0 :     ADDOP_LOAD_CONST(c, LOC(p), Py_None);
        6582         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), IS_OP, 1);
        6583         [ #  # ]:          0 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6584                 :            :     // So far so good. Use that tuple of values on the stack to match
        6585                 :            :     // sub-patterns against:
        6586         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);
        6587                 :          0 :     pc->on_top += size - 1;
        6588         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < size; i++) {
        6589                 :          0 :         pc->on_top--;
        6590                 :          0 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
        6591         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc));
        6592                 :            :     }
        6593                 :            :     // If we get this far, it's a match! Whatever happens next should consume
        6594                 :            :     // the tuple of keys and the subject:
        6595                 :          0 :     pc->on_top -= 2;
        6596         [ #  # ]:          0 :     if (star_target) {
        6597                 :            :         // If we have a starred name, bind a dict of remaining items to it (this may
        6598                 :            :         // seem a bit inefficient, but keys is rarely big enough to actually impact
        6599                 :            :         // runtime):
        6600                 :            :         // rest = dict(TOS1)
        6601                 :            :         // for key in TOS:
        6602                 :            :         //     del rest[key]
        6603         [ #  # ]:          0 :         ADDOP_I(c, LOC(p), BUILD_MAP, 0);           // [subject, keys, empty]
        6604         [ #  # ]:          0 :         ADDOP_I(c, LOC(p), SWAP, 3);                // [empty, keys, subject]
        6605         [ #  # ]:          0 :         ADDOP_I(c, LOC(p), DICT_UPDATE, 2);         // [copy, keys]
        6606         [ #  # ]:          0 :         ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);  // [copy, keys...]
        6607         [ #  # ]:          0 :         while (size) {
        6608         [ #  # ]:          0 :             ADDOP_I(c, LOC(p), COPY, 1 + size--);   // [copy, keys..., copy]
        6609         [ #  # ]:          0 :             ADDOP_I(c, LOC(p), SWAP, 2);            // [copy, keys..., copy, key]
        6610         [ #  # ]:          0 :             ADDOP(c, LOC(p), DELETE_SUBSCR);        // [copy, keys...]
        6611                 :            :         }
        6612         [ #  # ]:          0 :         RETURN_IF_ERROR(pattern_helper_store_name(c, LOC(p), star_target, pc));
        6613                 :            :     }
        6614                 :            :     else {
        6615         [ #  # ]:          0 :         ADDOP(c, LOC(p), POP_TOP);  // Tuple of keys.
        6616         [ #  # ]:          0 :         ADDOP(c, LOC(p), POP_TOP);  // Subject.
        6617                 :            :     }
        6618                 :          0 :     return SUCCESS;
        6619                 :            :
        6620                 :          0 : error:
        6621                 :          0 :     Py_DECREF(seen);
        6622                 :          0 :     return ERROR;
        6623                 :            : }
        6624                 :            :
        6625                 :            : static int
        6626                 :          0 : compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
        6627                 :            : {
        6628                 :            :     assert(p->kind == MatchOr_kind);
        6629         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, end);
        6630         [ #  # ]:          0 :     Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns);
        6631                 :            :     assert(size > 1);
        6632                 :            :     // We're going to be messing with pc. Keep the original info handy:
        6633                 :          0 :     pattern_context old_pc = *pc;
        6634                 :          0 :     Py_INCREF(pc->stores);
        6635                 :            :     // control is the list of names bound by the first alternative. It is used
        6636                 :            :     // for checking different name bindings in alternatives, and for correcting
        6637                 :            :     // the order in which extracted elements are placed on the stack.
        6638                 :          0 :     PyObject *control = NULL;
        6639                 :            :     // NOTE: We can't use returning macros anymore! goto error on error.
        6640         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < size; i++) {
        6641                 :          0 :         pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i);
        6642                 :          0 :         PyObject *pc_stores = PyList_New(0);
        6643         [ #  # ]:          0 :         if (pc_stores == NULL) {
        6644                 :          0 :             goto error;
        6645                 :            :         }
        6646                 :          0 :         Py_SETREF(pc->stores, pc_stores);
        6647                 :            :         // An irrefutable sub-pattern must be last, if it is allowed at all:
        6648   [ #  #  #  # ]:          0 :         pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable;
        6649                 :          0 :         pc->fail_pop = NULL;
        6650                 :          0 :         pc->fail_pop_size = 0;
        6651                 :          0 :         pc->on_top = 0;
        6652   [ #  #  #  # ]:          0 :         if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 ||
        6653                 :          0 :             compiler_pattern(c, alt, pc) < 0) {
        6654                 :          0 :             goto error;
        6655                 :            :         }
        6656                 :            :         // Success!
        6657                 :          0 :         Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
        6658         [ #  # ]:          0 :         if (!i) {
        6659                 :            :             // This is the first alternative, so save its stores as a "control"
        6660                 :            :             // for the others (they can't bind a different set of names, and
        6661                 :            :             // might need to be reordered):
        6662                 :            :             assert(control == NULL);
        6663                 :          0 :             control = Py_NewRef(pc->stores);
        6664                 :            :         }
        6665         [ #  # ]:          0 :         else if (nstores != PyList_GET_SIZE(control)) {
        6666                 :          0 :             goto diff;
        6667                 :            :         }
        6668         [ #  # ]:          0 :         else if (nstores) {
        6669                 :            :             // There were captures. Check to see if we differ from control:
        6670                 :          0 :             Py_ssize_t icontrol = nstores;
        6671         [ #  # ]:          0 :             while (icontrol--) {
        6672                 :          0 :                 PyObject *name = PyList_GET_ITEM(control, icontrol);
        6673                 :          0 :                 Py_ssize_t istores = PySequence_Index(pc->stores, name);
        6674         [ #  # ]:          0 :                 if (istores < 0) {
        6675                 :          0 :                     PyErr_Clear();
        6676                 :          0 :                     goto diff;
        6677                 :            :                 }
        6678         [ #  # ]:          0 :                 if (icontrol != istores) {
        6679                 :            :                     // Reorder the names on the stack to match the order of the
        6680                 :            :                     // names in control. There's probably a better way of doing
        6681                 :            :                     // this; the current solution is potentially very
        6682                 :            :                     // inefficient when each alternative subpattern binds lots
        6683                 :            :                     // of names in different orders. It's fine for reasonable
        6684                 :            :                     // cases, though, and the peephole optimizer will ensure
        6685                 :            :                     // that the final code is as efficient as possible.
        6686                 :            :                     assert(istores < icontrol);
        6687                 :          0 :                     Py_ssize_t rotations = istores + 1;
        6688                 :            :                     // Perform the same rotation on pc->stores:
        6689                 :          0 :                     PyObject *rotated = PyList_GetSlice(pc->stores, 0,
        6690                 :            :                                                         rotations);
        6691   [ #  #  #  # ]:          0 :                     if (rotated == NULL ||
        6692         [ #  # ]:          0 :                         PyList_SetSlice(pc->stores, 0, rotations, NULL) ||
        6693                 :          0 :                         PyList_SetSlice(pc->stores, icontrol - istores,
        6694                 :            :                                         icontrol - istores, rotated))
        6695                 :            :                     {
        6696                 :          0 :                         Py_XDECREF(rotated);
        6697                 :          0 :                         goto error;
        6698                 :            :                     }
        6699                 :          0 :                     Py_DECREF(rotated);
        6700                 :            :                     // That just did:
        6701                 :            :                     // rotated = pc_stores[:rotations]
        6702                 :            :                     // del pc_stores[:rotations]
        6703                 :            :                     // pc_stores[icontrol-istores:icontrol-istores] = rotated
        6704                 :            :                     // Do the same thing to the stack, using several
        6705                 :            :                     // rotations:
        6706         [ #  # ]:          0 :                     while (rotations--) {
        6707         [ #  # ]:          0 :                         if (pattern_helper_rotate(c, LOC(alt), icontrol + 1) < 0) {
        6708                 :          0 :                             goto error;
        6709                 :            :                         }
        6710                 :            :                     }
        6711                 :            :                 }
        6712                 :            :             }
        6713                 :            :         }
        6714                 :            :         assert(control);
        6715   [ #  #  #  # ]:          0 :         if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 ||
        6716                 :          0 :             emit_and_reset_fail_pop(c, LOC(alt), pc) < 0)
        6717                 :            :         {
        6718                 :          0 :             goto error;
        6719                 :            :         }
        6720                 :            :     }
        6721                 :          0 :     Py_DECREF(pc->stores);
        6722                 :          0 :     *pc = old_pc;
        6723                 :          0 :     Py_INCREF(pc->stores);
        6724                 :            :     // Need to NULL this for the PyObject_Free call in the error block.
        6725                 :          0 :     old_pc.fail_pop = NULL;
        6726                 :            :     // No match. Pop the remaining copy of the subject and fail:
        6727   [ #  #  #  # ]:          0 :     if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 ||
        6728                 :          0 :         jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) {
        6729                 :          0 :         goto error;
        6730                 :            :     }
        6731                 :            :
        6732         [ #  # ]:          0 :     USE_LABEL(c, end);
        6733                 :          0 :     Py_ssize_t nstores = PyList_GET_SIZE(control);
        6734                 :            :     // There's a bunch of stuff on the stack between where the new stores
        6735                 :            :     // are and where they need to be:
        6736                 :            :     // - The other stores.
        6737                 :            :     // - A copy of the subject.
        6738                 :            :     // - Anything else that may be on top of the stack.
        6739                 :            :     // - Any previous stores we've already stashed away on the stack.
        6740                 :          0 :     Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
        6741         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < nstores; i++) {
        6742                 :            :         // Rotate this capture to its proper place on the stack:
        6743         [ #  # ]:          0 :         if (pattern_helper_rotate(c, LOC(p), nrots) < 0) {
        6744                 :          0 :             goto error;
        6745                 :            :         }
        6746                 :            :         // Update the list of previous stores with this new name, checking for
        6747                 :            :         // duplicates:
        6748                 :          0 :         PyObject *name = PyList_GET_ITEM(control, i);
        6749                 :          0 :         int dupe = PySequence_Contains(pc->stores, name);
        6750         [ #  # ]:          0 :         if (dupe < 0) {
        6751                 :          0 :             goto error;
        6752                 :            :         }
        6753         [ #  # ]:          0 :         if (dupe) {
        6754                 :          0 :             compiler_error_duplicate_store(c, LOC(p), name);
        6755                 :          0 :             goto error;
        6756                 :            :         }
        6757         [ #  # ]:          0 :         if (PyList_Append(pc->stores, name)) {
        6758                 :          0 :             goto error;
        6759                 :            :         }
        6760                 :            :     }
        6761                 :          0 :     Py_DECREF(old_pc.stores);
        6762                 :          0 :     Py_DECREF(control);
        6763                 :            :     // NOTE: Returning macros are safe again.
        6764                 :            :     // Pop the copy of the subject:
        6765         [ #  # ]:          0 :     ADDOP(c, LOC(p), POP_TOP);
        6766                 :          0 :     return SUCCESS;
        6767                 :          0 : diff:
        6768                 :          0 :     compiler_error(c, LOC(p), "alternative patterns bind different names");
        6769                 :          0 : error:
        6770                 :          0 :     PyObject_Free(old_pc.fail_pop);
        6771                 :          0 :     Py_DECREF(old_pc.stores);
        6772                 :          0 :     Py_XDECREF(control);
        6773                 :          0 :     return ERROR;
        6774                 :            : }
        6775                 :            :
        6776                 :            :
        6777                 :            : static int
        6778                 :          5 : compiler_pattern_sequence(struct compiler *c, pattern_ty p,
        6779                 :            :                           pattern_context *pc)
        6780                 :            : {
        6781                 :            :     assert(p->kind == MatchSequence_kind);
        6782                 :          5 :     asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
        6783         [ +  - ]:          5 :     Py_ssize_t size = asdl_seq_LEN(patterns);
        6784                 :          5 :     Py_ssize_t star = -1;
        6785                 :          5 :     int only_wildcard = 1;
        6786                 :          5 :     int star_wildcard = 0;
        6787                 :            :     // Find a starred name, if it exists. There may be at most one:
        6788         [ +  + ]:         10 :     for (Py_ssize_t i = 0; i < size; i++) {
        6789                 :          5 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
        6790         [ +  + ]:          5 :         if (pattern->kind == MatchStar_kind) {
        6791         [ -  + ]:          1 :             if (star >= 0) {
        6792                 :          0 :                 const char *e = "multiple starred names in sequence pattern";
        6793                 :          0 :                 return compiler_error(c, LOC(p), e);
        6794                 :            :             }
        6795   [ +  -  -  + ]:          1 :             star_wildcard = WILDCARD_STAR_CHECK(pattern);
        6796                 :          1 :             only_wildcard &= star_wildcard;
        6797                 :          1 :             star = i;
        6798                 :          1 :             continue;
        6799                 :            :         }
        6800   [ -  +  -  - ]:          4 :         only_wildcard &= WILDCARD_CHECK(pattern);
        6801                 :            :     }
        6802                 :            :     // We need to keep the subject on top during the sequence and length checks:
        6803                 :          5 :     pc->on_top++;
        6804         [ -  + ]:          5 :     ADDOP(c, LOC(p), MATCH_SEQUENCE);
        6805         [ -  + ]:          5 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6806         [ +  + ]:          5 :     if (star < 0) {
        6807                 :            :         // No star: len(subject) == size
        6808         [ -  + ]:          4 :         ADDOP(c, LOC(p), GET_LEN);
        6809   [ -  +  -  + ]:          4 :         ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
        6810         [ -  + ]:          4 :         ADDOP_COMPARE(c, LOC(p), Eq);
        6811         [ -  + ]:          4 :         RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6812                 :            :     }
        6813         [ -  + ]:          1 :     else if (size > 1) {
        6814                 :            :         // Star: len(subject) >= size - 1
        6815         [ #  # ]:          0 :         ADDOP(c, LOC(p), GET_LEN);
        6816   [ #  #  #  # ]:          0 :         ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1));
        6817         [ #  # ]:          0 :         ADDOP_COMPARE(c, LOC(p), GtE);
        6818         [ #  # ]:          0 :         RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6819                 :            :     }
        6820                 :            :     // Whatever comes next should consume the subject:
        6821                 :          5 :     pc->on_top--;
        6822         [ -  + ]:          5 :     if (only_wildcard) {
        6823                 :            :         // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
        6824         [ #  # ]:          0 :         ADDOP(c, LOC(p), POP_TOP);
        6825                 :            :     }
        6826         [ -  + ]:          5 :     else if (star_wildcard) {
        6827         [ #  # ]:          0 :         RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc));
        6828                 :            :     }
        6829                 :            :     else {
        6830         [ -  + ]:          5 :         RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc));
        6831                 :            :     }
        6832                 :          5 :     return SUCCESS;
        6833                 :            : }
        6834                 :            :
        6835                 :            : static int
        6836                 :          4 : compiler_pattern_value(struct compiler *c, pattern_ty p, pattern_context *pc)
        6837                 :            : {
        6838                 :            :     assert(p->kind == MatchValue_kind);
        6839                 :          4 :     expr_ty value = p->v.MatchValue.value;
        6840   [ -  +  -  - ]:          4 :     if (!MATCH_VALUE_EXPR(value)) {
        6841                 :          0 :         const char *e = "patterns may only match literals and attribute lookups";
        6842                 :          0 :         return compiler_error(c, LOC(p), e);
        6843                 :            :     }
        6844         [ -  + ]:          4 :     VISIT(c, expr, value);
        6845         [ -  + ]:          4 :     ADDOP_COMPARE(c, LOC(p), Eq);
        6846         [ -  + ]:          4 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6847                 :          4 :     return SUCCESS;
        6848                 :            : }
        6849                 :            :
        6850                 :            : static int
        6851                 :          1 : compiler_pattern_singleton(struct compiler *c, pattern_ty p, pattern_context *pc)
        6852                 :            : {
        6853                 :            :     assert(p->kind == MatchSingleton_kind);
        6854         [ -  + ]:          1 :     ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value);
        6855         [ -  + ]:          1 :     ADDOP_COMPARE(c, LOC(p), Is);
        6856         [ -  + ]:          1 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
        6857                 :          1 :     return SUCCESS;
        6858                 :            : }
        6859                 :            :
        6860                 :            : static int
        6861                 :         18 : compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc)
        6862                 :            : {
        6863   [ +  +  +  -  :         18 :     switch (p->kind) {
                 +  +  +  -
                          - ]
        6864                 :          4 :         case MatchValue_kind:
        6865                 :          4 :             return compiler_pattern_value(c, p, pc);
        6866                 :          1 :         case MatchSingleton_kind:
        6867                 :          1 :             return compiler_pattern_singleton(c, p, pc);
        6868                 :          5 :         case MatchSequence_kind:
        6869                 :          5 :             return compiler_pattern_sequence(c, p, pc);
        6870                 :          0 :         case MatchMapping_kind:
        6871                 :          0 :             return compiler_pattern_mapping(c, p, pc);
        6872                 :          4 :         case MatchClass_kind:
        6873                 :          4 :             return compiler_pattern_class(c, p, pc);
        6874                 :          1 :         case MatchStar_kind:
        6875                 :          1 :             return compiler_pattern_star(c, p, pc);
        6876                 :          3 :         case MatchAs_kind:
        6877                 :          3 :             return compiler_pattern_as(c, p, pc);
        6878                 :          0 :         case MatchOr_kind:
        6879                 :          0 :             return compiler_pattern_or(c, p, pc);
        6880                 :            :     }
        6881                 :            :     // AST validator shouldn't let this happen, but if it does,
        6882                 :            :     // just fail, don't crash out of the interpreter
        6883                 :          0 :     const char *e = "invalid match pattern node in AST (kind=%d)";
        6884                 :          0 :     return compiler_error(c, LOC(p), e, p->kind);
        6885                 :            : }
        6886                 :            :
        6887                 :            : static int
        6888                 :          4 : compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc)
        6889                 :            : {
        6890         [ -  + ]:          4 :     VISIT(c, expr, s->v.Match.subject);
        6891         [ -  + ]:          4 :     NEW_JUMP_TARGET_LABEL(c, end);
        6892         [ +  - ]:          4 :     Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases);
        6893                 :            :     assert(cases > 0);
        6894                 :          4 :     match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1);
        6895   [ +  +  +  -  :          4 :     int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases;
                       +  - ]
        6896         [ +  + ]:         15 :     for (Py_ssize_t i = 0; i < cases - has_default; i++) {
        6897                 :         11 :         m = asdl_seq_GET(s->v.Match.cases, i);
        6898                 :            :         // Only copy the subject if we're *not* on the last case:
        6899         [ +  + ]:         11 :         if (i != cases - has_default - 1) {
        6900         [ -  + ]:          7 :             ADDOP_I(c, LOC(m->pattern), COPY, 1);
        6901                 :            :         }
        6902                 :         11 :         pc->stores = PyList_New(0);
        6903         [ -  + ]:         11 :         if (pc->stores == NULL) {
        6904                 :          0 :             return ERROR;
        6905                 :            :         }
        6906                 :            :         // Irrefutable cases must be either guarded, last, or both:
        6907   [ +  +  +  + ]:         11 :         pc->allow_irrefutable = m->guard != NULL || i == cases - 1;
        6908                 :         11 :         pc->fail_pop = NULL;
        6909                 :         11 :         pc->fail_pop_size = 0;
        6910                 :         11 :         pc->on_top = 0;
        6911                 :            :         // NOTE: Can't use returning macros here (they'll leak pc->stores)!
        6912         [ -  + ]:         11 :         if (compiler_pattern(c, m->pattern, pc) < 0) {
        6913                 :          0 :             Py_DECREF(pc->stores);
        6914                 :          0 :             return ERROR;
        6915                 :            :         }
        6916                 :            :         assert(!pc->on_top);
        6917                 :            :         // It's a match! Store all of the captured names (they're on the stack).
        6918                 :         11 :         Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
        6919         [ +  + ]:         15 :         for (Py_ssize_t n = 0; n < nstores; n++) {
        6920                 :          4 :             PyObject *name = PyList_GET_ITEM(pc->stores, n);
        6921         [ -  + ]:          4 :             if (compiler_nameop(c, LOC(m->pattern), name, Store) < 0) {
        6922                 :          0 :                 Py_DECREF(pc->stores);
        6923                 :          0 :                 return ERROR;
        6924                 :            :             }
        6925                 :            :         }
        6926                 :         11 :         Py_DECREF(pc->stores);
        6927                 :            :         // NOTE: Returning macros are safe again.
        6928         [ +  + ]:         11 :         if (m->guard) {
        6929         [ -  + ]:          1 :             RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0));
        6930         [ -  + ]:          1 :             RETURN_IF_ERROR(compiler_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0));
        6931                 :            :         }
        6932                 :            :         // Success! Pop the subject off, we're done with it:
        6933         [ +  + ]:         11 :         if (i != cases - has_default - 1) {
        6934         [ -  + ]:          7 :             ADDOP(c, LOC(m->pattern), POP_TOP);
        6935                 :            :         }
        6936   [ -  +  +  -  :         31 :         VISIT_SEQ(c, stmt, m->body);
                       +  + ]
        6937         [ -  + ]:         11 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
        6938                 :            :         // If the pattern fails to match, we want the line number of the
        6939                 :            :         // cleanup to be associated with the failed pattern, not the last line
        6940                 :            :         // of the body
        6941         [ -  + ]:         11 :         RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc));
        6942                 :            :     }
        6943         [ +  + ]:          4 :     if (has_default) {
        6944                 :            :         // A trailing "case _" is common, and lets us save a bit of redundant
        6945                 :            :         // pushing and popping in the loop above:
        6946                 :          1 :         m = asdl_seq_GET(s->v.Match.cases, cases - 1);
        6947         [ -  + ]:          1 :         if (cases == 1) {
        6948                 :            :             // No matches. Done with the subject:
        6949         [ #  # ]:          0 :             ADDOP(c, LOC(m->pattern), POP_TOP);
        6950                 :            :         }
        6951                 :            :         else {
        6952                 :            :             // Show line coverage for default case (it doesn't create bytecode)
        6953         [ -  + ]:          1 :             ADDOP(c, LOC(m->pattern), NOP);
        6954                 :            :         }
        6955         [ -  + ]:          1 :         if (m->guard) {
        6956         [ #  # ]:          0 :             RETURN_IF_ERROR(compiler_jump_if(c, LOC(m->pattern), m->guard, end, 0));
        6957                 :            :         }
        6958   [ -  +  +  -  :          2 :         VISIT_SEQ(c, stmt, m->body);
                       +  + ]
        6959                 :            :     }
        6960         [ -  + ]:          4 :     USE_LABEL(c, end);
        6961                 :          4 :     return SUCCESS;
        6962                 :            : }
        6963                 :            :
        6964                 :            : static int
        6965                 :          4 : compiler_match(struct compiler *c, stmt_ty s)
        6966                 :            : {
        6967                 :            :     pattern_context pc;
        6968                 :          4 :     pc.fail_pop = NULL;
        6969                 :          4 :     int result = compiler_match_inner(c, s, &pc);
        6970                 :          4 :     PyObject_Free(pc.fail_pop);
        6971                 :          4 :     return result;
        6972                 :            : }
        6973                 :            :
        6974                 :            : #undef WILDCARD_CHECK
        6975                 :            : #undef WILDCARD_STAR_CHECK
        6976                 :            :
        6977                 :            :
        6978                 :            : /* End of the compiler section, beginning of the assembler section */
        6979                 :            :
        6980                 :            :
        6981                 :            : struct assembler {
        6982                 :            :     PyObject *a_bytecode;  /* bytes containing bytecode */
        6983                 :            :     int a_offset;              /* offset into bytecode */
        6984                 :            :     PyObject *a_except_table;  /* bytes containing exception table */
        6985                 :            :     int a_except_table_off;    /* offset into exception table */
        6986                 :            :     /* Location Info */
        6987                 :            :     int a_lineno;          /* lineno of last emitted instruction */
        6988                 :            :     PyObject* a_linetable; /* bytes containing location info */
        6989                 :            :     int a_location_off;    /* offset of last written location info frame */
        6990                 :            : };
        6991                 :            :
        6992                 :            : static basicblock**
        6993                 :      39288 : make_cfg_traversal_stack(basicblock *entryblock) {
        6994                 :      39288 :     int nblocks = 0;
        6995         [ +  + ]:     352190 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        6996                 :     312902 :         b->b_visited = 0;
        6997                 :     312902 :         nblocks++;
        6998                 :            :     }
        6999                 :      39288 :     basicblock **stack = (basicblock **)PyMem_Malloc(sizeof(basicblock *) * nblocks);
        7000         [ -  + ]:      39288 :     if (!stack) {
        7001                 :          0 :         PyErr_NoMemory();
        7002                 :            :     }
        7003                 :      39288 :     return stack;
        7004                 :            : }
        7005                 :            :
        7006                 :            : Py_LOCAL_INLINE(void)
        7007                 :      61955 : stackdepth_push(basicblock ***sp, basicblock *b, int depth)
        7008                 :            : {
        7009                 :            :     assert(b->b_startdepth < 0 || b->b_startdepth == depth);
        7010   [ +  +  +  - ]:      61955 :     if (b->b_startdepth < depth && b->b_startdepth < 100) {
        7011                 :            :         assert(b->b_startdepth < 0);
        7012                 :      51311 :         b->b_startdepth = depth;
        7013                 :      51311 :         *(*sp)++ = b;
        7014                 :            :     }
        7015                 :      61955 : }
        7016                 :            :
        7017                 :            : /* Find the flow path that needs the largest stack.  We assume that
        7018                 :            :  * cycles in the flow graph have no net effect on the stack depth.
        7019                 :            :  */
        7020                 :            : static int
        7021                 :       8041 : stackdepth(basicblock *entryblock, int code_flags)
        7022                 :            : {
        7023         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7024                 :      51311 :         b->b_startdepth = INT_MIN;
        7025                 :            :     }
        7026                 :       8041 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
        7027         [ -  + ]:       8041 :     if (!stack) {
        7028                 :          0 :         return ERROR;
        7029                 :            :     }
        7030                 :            :
        7031                 :       8041 :     int maxdepth = 0;
        7032                 :       8041 :     basicblock **sp = stack;
        7033         [ +  + ]:       8041 :     if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
        7034                 :        532 :         stackdepth_push(&sp, entryblock, 1);
        7035                 :            :     } else {
        7036                 :       7509 :         stackdepth_push(&sp, entryblock, 0);
        7037                 :            :     }
        7038                 :            :
        7039         [ +  + ]:      59352 :     while (sp != stack) {
        7040                 :      51311 :         basicblock *b = *--sp;
        7041                 :      51311 :         int depth = b->b_startdepth;
        7042                 :            :         assert(depth >= 0);
        7043                 :      51311 :         basicblock *next = b->b_next;
        7044         [ +  + ]:     377664 :         for (int i = 0; i < b->b_iused; i++) {
        7045                 :     349175 :             struct cfg_instr *instr = &b->b_instr[i];
        7046                 :     349175 :             int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0);
        7047         [ -  + ]:     349175 :             if (effect == PY_INVALID_STACK_EFFECT) {
        7048                 :          0 :                 PyErr_Format(PyExc_SystemError,
        7049                 :            :                              "compiler stack_effect(opcode=%d, arg=%i) failed",
        7050                 :            :                              instr->i_opcode, instr->i_oparg);
        7051                 :          0 :                 return ERROR;
        7052                 :            :             }
        7053                 :     349175 :             int new_depth = depth + effect;
        7054                 :            :             assert(new_depth >= 0); /* invalid code or bug in stackdepth() */
        7055         [ +  + ]:     349175 :             if (new_depth > maxdepth) {
        7056                 :      30259 :                 maxdepth = new_depth;
        7057                 :            :             }
        7058   [ +  +  +  +  :     349175 :             if (HAS_TARGET(instr->i_opcode)) {
                 +  +  +  + ]
        7059                 :      25425 :                 effect = stack_effect(instr->i_opcode, instr->i_oparg, 1);
        7060                 :            :                 assert(effect != PY_INVALID_STACK_EFFECT);
        7061                 :      25425 :                 int target_depth = depth + effect;
        7062                 :            :                 assert(target_depth >= 0); /* invalid code or bug in stackdepth() */
        7063         [ +  + ]:      25425 :                 if (target_depth > maxdepth) {
        7064                 :        994 :                     maxdepth = target_depth;
        7065                 :            :                 }
        7066                 :      25425 :                 stackdepth_push(&sp, instr->i_target, target_depth);
        7067                 :            :             }
        7068                 :     349175 :             depth = new_depth;
        7069                 :            :             assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode));
        7070   [ +  +  +  +  :     349175 :             if (IS_UNCONDITIONAL_JUMP_OPCODE(instr->i_opcode) ||
              +  -  +  -  +
                          - ]
        7071   [ +  +  +  +  :     344150 :                 IS_SCOPE_EXIT_OPCODE(instr->i_opcode))
                 +  +  +  + ]
        7072                 :            :             {
        7073                 :            :                 /* remaining code is dead */
        7074                 :      22822 :                 next = NULL;
        7075                 :      22822 :                 break;
        7076                 :            :             }
        7077                 :            :         }
        7078         [ +  + ]:      51311 :         if (next != NULL) {
        7079                 :            :             assert(BB_HAS_FALLTHROUGH(b));
        7080                 :      28489 :             stackdepth_push(&sp, next, depth);
        7081                 :            :         }
        7082                 :            :     }
        7083                 :       8041 :     PyMem_Free(stack);
        7084                 :       8041 :     return maxdepth;
        7085                 :            : }
        7086                 :            :
        7087                 :            : static int
        7088                 :       8041 : assemble_init(struct assembler *a, int firstlineno)
        7089                 :            : {
        7090                 :       8041 :     memset(a, 0, sizeof(struct assembler));
        7091                 :       8041 :     a->a_lineno = firstlineno;
        7092                 :       8041 :     a->a_linetable = NULL;
        7093                 :       8041 :     a->a_location_off = 0;
        7094                 :       8041 :     a->a_except_table = NULL;
        7095                 :       8041 :     a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
        7096         [ -  + ]:       8041 :     if (a->a_bytecode == NULL) {
        7097                 :          0 :         goto error;
        7098                 :            :     }
        7099                 :       8041 :     a->a_linetable = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE);
        7100         [ -  + ]:       8041 :     if (a->a_linetable == NULL) {
        7101                 :          0 :         goto error;
        7102                 :            :     }
        7103                 :       8041 :     a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
        7104         [ -  + ]:       8041 :     if (a->a_except_table == NULL) {
        7105                 :          0 :         goto error;
        7106                 :            :     }
        7107                 :       8041 :     return SUCCESS;
        7108                 :          0 : error:
        7109                 :          0 :     Py_XDECREF(a->a_bytecode);
        7110                 :          0 :     Py_XDECREF(a->a_linetable);
        7111                 :          0 :     Py_XDECREF(a->a_except_table);
        7112                 :          0 :     return ERROR;
        7113                 :            : }
        7114                 :            :
        7115                 :            : static void
        7116                 :       8041 : assemble_free(struct assembler *a)
        7117                 :            : {
        7118                 :       8041 :     Py_XDECREF(a->a_bytecode);
        7119                 :       8041 :     Py_XDECREF(a->a_linetable);
        7120                 :       8041 :     Py_XDECREF(a->a_except_table);
        7121                 :       8041 : }
        7122                 :            :
        7123                 :            : static int
        7124                 :      61502 : blocksize(basicblock *b)
        7125                 :            : {
        7126                 :      61502 :     int size = 0;
        7127         [ +  + ]:     465669 :     for (int i = 0; i < b->b_iused; i++) {
        7128                 :     404167 :         size += instr_size(&b->b_instr[i]);
        7129                 :            :     }
        7130                 :      61502 :     return size;
        7131                 :            : }
        7132                 :            :
        7133                 :            : static basicblock *
        7134                 :       4732 : push_except_block(ExceptStack *stack, struct cfg_instr *setup) {
        7135                 :            :     assert(is_block_push(setup));
        7136                 :       4732 :     int opcode = setup->i_opcode;
        7137                 :       4732 :     basicblock * target = setup->i_target;
        7138   [ +  +  +  + ]:       4732 :     if (opcode == SETUP_WITH || opcode == SETUP_CLEANUP) {
        7139                 :       3055 :         target->b_preserve_lasti = 1;
        7140                 :            :     }
        7141                 :       4732 :     stack->handlers[++stack->depth] = target;
        7142                 :       4732 :     return target;
        7143                 :            : }
        7144                 :            :
        7145                 :            : static basicblock *
        7146                 :       3949 : pop_except_block(ExceptStack *stack) {
        7147                 :            :     assert(stack->depth > 0);
        7148                 :       3949 :     return stack->handlers[--stack->depth];
        7149                 :            : }
        7150                 :            :
        7151                 :            : static basicblock *
        7152                 :      54053 : except_stack_top(ExceptStack *stack) {
        7153                 :      54053 :     return stack->handlers[stack->depth];
        7154                 :            : }
        7155                 :            :
        7156                 :            : static ExceptStack *
        7157                 :       8041 : make_except_stack(void) {
        7158                 :       8041 :     ExceptStack *new = PyMem_Malloc(sizeof(ExceptStack));
        7159         [ -  + ]:       8041 :     if (new == NULL) {
        7160                 :          0 :         PyErr_NoMemory();
        7161                 :          0 :         return NULL;
        7162                 :            :     }
        7163                 :       8041 :     new->depth = 0;
        7164                 :       8041 :     new->handlers[0] = NULL;
        7165                 :       8041 :     return new;
        7166                 :            : }
        7167                 :            :
        7168                 :            : static ExceptStack *
        7169                 :      18779 : copy_except_stack(ExceptStack *stack) {
        7170                 :      18779 :     ExceptStack *copy = PyMem_Malloc(sizeof(ExceptStack));
        7171         [ -  + ]:      18779 :     if (copy == NULL) {
        7172                 :          0 :         PyErr_NoMemory();
        7173                 :          0 :         return NULL;
        7174                 :            :     }
        7175                 :      18779 :     memcpy(copy, stack, sizeof(ExceptStack));
        7176                 :      18779 :     return copy;
        7177                 :            : }
        7178                 :            :
        7179                 :            : static int
        7180                 :       8041 : label_exception_targets(basicblock *entryblock) {
        7181                 :       8041 :     basicblock **todo_stack = make_cfg_traversal_stack(entryblock);
        7182         [ -  + ]:       8041 :     if (todo_stack == NULL) {
        7183                 :          0 :         return ERROR;
        7184                 :            :     }
        7185                 :       8041 :     ExceptStack *except_stack = make_except_stack();
        7186         [ -  + ]:       8041 :     if (except_stack == NULL) {
        7187                 :          0 :         PyMem_Free(todo_stack);
        7188                 :          0 :         PyErr_NoMemory();
        7189                 :          0 :         return ERROR;
        7190                 :            :     }
        7191                 :       8041 :     except_stack->depth = 0;
        7192                 :       8041 :     todo_stack[0] = entryblock;
        7193                 :       8041 :     entryblock->b_visited = 1;
        7194                 :       8041 :     entryblock->b_exceptstack = except_stack;
        7195                 :       8041 :     basicblock **todo = &todo_stack[1];
        7196                 :       8041 :     basicblock *handler = NULL;
        7197         [ +  + ]:      62094 :     while (todo > todo_stack) {
        7198                 :      54053 :         todo--;
        7199                 :      54053 :         basicblock *b = todo[0];
        7200                 :            :         assert(b->b_visited == 1);
        7201                 :      54053 :         except_stack = b->b_exceptstack;
        7202                 :            :         assert(except_stack != NULL);
        7203                 :      54053 :         b->b_exceptstack = NULL;
        7204                 :      54053 :         handler = except_stack_top(except_stack);
        7205         [ +  + ]:     424982 :         for (int i = 0; i < b->b_iused; i++) {
        7206                 :     370929 :             struct cfg_instr *instr = &b->b_instr[i];
        7207         [ +  + ]:     370929 :             if (is_block_push(instr)) {
        7208         [ +  - ]:       4732 :                 if (!instr->i_target->b_visited) {
        7209                 :       4732 :                     ExceptStack *copy = copy_except_stack(except_stack);
        7210         [ -  + ]:       4732 :                     if (copy == NULL) {
        7211                 :          0 :                         goto error;
        7212                 :            :                     }
        7213                 :       4732 :                     instr->i_target->b_exceptstack = copy;
        7214                 :       4732 :                     todo[0] = instr->i_target;
        7215                 :       4732 :                     instr->i_target->b_visited = 1;
        7216                 :       4732 :                     todo++;
        7217                 :            :                 }
        7218                 :       4732 :                 handler = push_except_block(except_stack, instr);
        7219                 :            :             }
        7220         [ +  + ]:     366197 :             else if (instr->i_opcode == POP_BLOCK) {
        7221                 :       3949 :                 handler = pop_except_block(except_stack);
        7222                 :            :             }
        7223         [ +  + ]:     362248 :             else if (is_jump(instr)) {
        7224                 :      23254 :                 instr->i_except = handler;
        7225                 :            :                 assert(i == b->b_iused -1);
        7226         [ +  + ]:      23254 :                 if (!instr->i_target->b_visited) {
        7227         [ +  + ]:      17544 :                     if (BB_HAS_FALLTHROUGH(b)) {
        7228                 :      14047 :                         ExceptStack *copy = copy_except_stack(except_stack);
        7229         [ -  + ]:      14047 :                         if (copy == NULL) {
        7230                 :          0 :                             goto error;
        7231                 :            :                         }
        7232                 :      14047 :                         instr->i_target->b_exceptstack = copy;
        7233                 :            :                     }
        7234                 :            :                     else {
        7235                 :       3497 :                         instr->i_target->b_exceptstack = except_stack;
        7236                 :       3497 :                         except_stack = NULL;
        7237                 :            :                     }
        7238                 :      17544 :                     todo[0] = instr->i_target;
        7239                 :      17544 :                     instr->i_target->b_visited = 1;
        7240                 :      17544 :                     todo++;
        7241                 :            :                 }
        7242                 :            :             }
        7243                 :            :             else {
        7244         [ +  + ]:     338994 :                 if (instr->i_opcode == YIELD_VALUE) {
        7245                 :        640 :                     instr->i_oparg = except_stack->depth;
        7246                 :            :                 }
        7247                 :     338994 :                 instr->i_except = handler;
        7248                 :            :             }
        7249                 :            :         }
        7250   [ +  +  +  + ]:      54053 :         if (BB_HAS_FALLTHROUGH(b) && !b->b_next->b_visited) {
        7251                 :            :             assert(except_stack != NULL);
        7252                 :      23736 :             b->b_next->b_exceptstack = except_stack;
        7253                 :      23736 :             todo[0] = b->b_next;
        7254                 :      23736 :             b->b_next->b_visited = 1;
        7255                 :      23736 :             todo++;
        7256                 :            :         }
        7257         [ +  + ]:      30317 :         else if (except_stack != NULL) {
        7258                 :      26820 :            PyMem_Free(except_stack);
        7259                 :            :         }
        7260                 :            :     }
        7261                 :            : #ifdef Py_DEBUG
        7262                 :            :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7263                 :            :         assert(b->b_exceptstack == NULL);
        7264                 :            :     }
        7265                 :            : #endif
        7266                 :       8041 :     PyMem_Free(todo_stack);
        7267                 :       8041 :     return SUCCESS;
        7268                 :          0 : error:
        7269                 :          0 :     PyMem_Free(todo_stack);
        7270                 :          0 :     PyMem_Free(except_stack);
        7271                 :          0 :     return ERROR;
        7272                 :            : }
        7273                 :            :
        7274                 :            :
        7275                 :            : static int
        7276                 :       8041 : mark_except_handlers(basicblock *entryblock) {
        7277                 :            : #ifndef NDEBUG
        7278                 :            :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7279                 :            :         assert(!b->b_except_handler);
        7280                 :            :     }
        7281                 :            : #endif
        7282         [ +  + ]:      69608 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7283         [ +  + ]:     448179 :         for (int i=0; i < b->b_iused; i++) {
        7284                 :     386612 :             struct cfg_instr *instr = &b->b_instr[i];
        7285         [ +  + ]:     386612 :             if (is_block_push(instr)) {
        7286                 :       4742 :                 instr->i_target->b_except_handler = 1;
        7287                 :            :             }
        7288                 :            :         }
        7289                 :            :     }
        7290                 :       8041 :     return SUCCESS;
        7291                 :            : }
        7292                 :            :
        7293                 :            : static int
        7294                 :       4163 : mark_warm(basicblock *entryblock) {
        7295                 :       4163 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
        7296         [ -  + ]:       4163 :     if (stack == NULL) {
        7297                 :          0 :         return ERROR;
        7298                 :            :     }
        7299                 :       4163 :     basicblock **sp = stack;
        7300                 :            :
        7301                 :       4163 :     *sp++ = entryblock;
        7302                 :       4163 :     entryblock->b_visited = 1;
        7303         [ +  + ]:      40123 :     while (sp > stack) {
        7304                 :      35960 :         basicblock *b = *(--sp);
        7305                 :            :         assert(!b->b_except_handler);
        7306                 :      35960 :         b->b_warm = 1;
        7307                 :      35960 :         basicblock *next = b->b_next;
        7308   [ +  +  +  +  :      35960 :         if (next && BB_HAS_FALLTHROUGH(b) && !next->b_visited) {
                       +  + ]
        7309                 :      19933 :             *sp++ = next;
        7310                 :      19933 :             next->b_visited = 1;
        7311                 :            :         }
        7312         [ +  + ]:     270596 :         for (int i=0; i < b->b_iused; i++) {
        7313                 :     234636 :             struct cfg_instr *instr = &b->b_instr[i];
        7314   [ +  +  +  + ]:     234636 :             if (is_jump(instr) && !instr->i_target->b_visited) {
        7315                 :      11864 :                 *sp++ = instr->i_target;
        7316                 :      11864 :                 instr->i_target->b_visited = 1;
        7317                 :            :             }
        7318                 :            :         }
        7319                 :            :     }
        7320                 :       4163 :     PyMem_Free(stack);
        7321                 :       4163 :     return SUCCESS;
        7322                 :            : }
        7323                 :            :
        7324                 :            : static int
        7325                 :       4163 : mark_cold(basicblock *entryblock) {
        7326         [ +  + ]:      50901 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7327                 :            :         assert(!b->b_cold && !b->b_warm);
        7328                 :            :     }
        7329         [ -  + ]:       4163 :     if (mark_warm(entryblock) < 0) {
        7330                 :          0 :         return ERROR;
        7331                 :            :     }
        7332                 :            :
        7333                 :       4163 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
        7334         [ -  + ]:       4163 :     if (stack == NULL) {
        7335                 :          0 :         return ERROR;
        7336                 :            :     }
        7337                 :            :
        7338                 :       4163 :     basicblock **sp = stack;
        7339         [ +  + ]:      50901 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7340         [ +  + ]:      46738 :         if (b->b_except_handler) {
        7341                 :            :             assert(!b->b_warm);
        7342                 :       4731 :             *sp++ = b;
        7343                 :       4731 :             b->b_visited = 1;
        7344                 :            :         }
        7345                 :            :     }
        7346                 :            :
        7347         [ +  + ]:      14941 :     while (sp > stack) {
        7348                 :      10778 :         basicblock *b = *(--sp);
        7349                 :      10778 :         b->b_cold = 1;
        7350                 :      10778 :         basicblock *next = b->b_next;
        7351   [ +  +  +  + ]:      10778 :         if (next && BB_HAS_FALLTHROUGH(b)) {
        7352   [ +  +  +  + ]:       4154 :             if (!next->b_warm && !next->b_visited) {
        7353                 :       3828 :                 *sp++ = next;
        7354                 :       3828 :                 next->b_visited = 1;
        7355                 :            :             }
        7356                 :            :         }
        7357         [ +  + ]:      49664 :         for (int i = 0; i < b->b_iused; i++) {
        7358                 :      38886 :             struct cfg_instr *instr = &b->b_instr[i];
        7359         [ +  + ]:      38886 :             if (is_jump(instr)) {
        7360                 :            :                 assert(i == b->b_iused - 1);
        7361                 :       3191 :                 basicblock *target = b->b_instr[i].i_target;
        7362   [ +  +  +  + ]:       3191 :                 if (!target->b_warm && !target->b_visited) {
        7363                 :       2219 :                     *sp++ = target;
        7364                 :       2219 :                     target->b_visited = 1;
        7365                 :            :                 }
        7366                 :            :             }
        7367                 :            :         }
        7368                 :            :     }
        7369                 :       4163 :     PyMem_Free(stack);
        7370                 :       4163 :     return SUCCESS;
        7371                 :            : }
        7372                 :            :
        7373                 :            : static int
        7374                 :            : remove_redundant_jumps(cfg_builder *g);
        7375                 :            :
        7376                 :            : static int
        7377                 :       8041 : push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
        7378                 :       8041 :     basicblock *entryblock = g->g_entryblock;
        7379         [ +  + ]:       8041 :     if (entryblock->b_next == NULL) {
        7380                 :            :         /* single basicblock, no need to reorder */
        7381                 :       3878 :         return SUCCESS;
        7382                 :            :     }
        7383         [ -  + ]:       4163 :     RETURN_IF_ERROR(mark_cold(entryblock));
        7384                 :            :
        7385                 :            :     /* If we have a cold block with fallthrough to a warm block, add */
        7386                 :            :     /* an explicit jump instead of fallthrough */
        7387         [ +  + ]:      51082 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7388   [ +  +  +  +  :      46919 :         if (b->b_cold && BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_next->b_warm) {
                 +  -  +  + ]
        7389                 :        181 :             basicblock *explicit_jump = cfg_builder_new_block(g);
        7390         [ -  + ]:        181 :             if (explicit_jump == NULL) {
        7391                 :          0 :                 return ERROR;
        7392                 :            :             }
        7393                 :        181 :             basicblock_addop(explicit_jump, JUMP, b->b_next->b_label.id, NO_LOCATION);
        7394                 :        181 :             explicit_jump->b_cold = 1;
        7395                 :        181 :             explicit_jump->b_next = b->b_next;
        7396                 :        181 :             b->b_next = explicit_jump;
        7397                 :            :
        7398                 :            :             /* set target */
        7399                 :        181 :             struct cfg_instr *last = basicblock_last_instr(explicit_jump);
        7400                 :        181 :             last->i_target = explicit_jump->b_next;
        7401                 :            :         }
        7402                 :            :     }
        7403                 :            :
        7404                 :            :     assert(!entryblock->b_cold);  /* First block can't be cold */
        7405                 :       4163 :     basicblock *cold_blocks = NULL;
        7406                 :       4163 :     basicblock *cold_blocks_tail = NULL;
        7407                 :            :
        7408                 :       4163 :     basicblock *b = entryblock;
        7409         [ +  + ]:       6539 :     while(b->b_next) {
        7410                 :            :         assert(!b->b_cold);
        7411   [ +  +  +  + ]:      37263 :         while (b->b_next && !b->b_next->b_cold) {
        7412                 :      31797 :             b = b->b_next;
        7413                 :            :         }
        7414         [ +  + ]:       5466 :         if (b->b_next == NULL) {
        7415                 :            :             /* no more cold blocks */
        7416                 :       3090 :             break;
        7417                 :            :         }
        7418                 :            :
        7419                 :            :         /* b->b_next is the beginning of a cold streak */
        7420                 :            :         assert(!b->b_cold && b->b_next->b_cold);
        7421                 :            :
        7422                 :       2376 :         basicblock *b_end = b->b_next;
        7423   [ +  +  +  + ]:      10959 :         while (b_end->b_next && b_end->b_next->b_cold) {
        7424                 :       8583 :             b_end = b_end->b_next;
        7425                 :            :         }
        7426                 :            :
        7427                 :            :         /* b_end is the end of the cold streak */
        7428                 :            :         assert(b_end && b_end->b_cold);
        7429                 :            :         assert(b_end->b_next == NULL || !b_end->b_next->b_cold);
        7430                 :            :
        7431         [ +  + ]:       2376 :         if (cold_blocks == NULL) {
        7432                 :       1599 :             cold_blocks = b->b_next;
        7433                 :            :         }
        7434                 :            :         else {
        7435                 :        777 :             cold_blocks_tail->b_next = b->b_next;
        7436                 :            :         }
        7437                 :       2376 :         cold_blocks_tail = b_end;
        7438                 :       2376 :         b->b_next = b_end->b_next;
        7439                 :       2376 :         b_end->b_next = NULL;
        7440                 :            :     }
        7441                 :            :     assert(b != NULL && b->b_next == NULL);
        7442                 :       4163 :     b->b_next = cold_blocks;
        7443                 :            :
        7444         [ +  + ]:       4163 :     if (cold_blocks != NULL) {
        7445         [ -  + ]:       1599 :         RETURN_IF_ERROR(remove_redundant_jumps(g));
        7446                 :            :     }
        7447                 :       4163 :     return SUCCESS;
        7448                 :            : }
        7449                 :            :
        7450                 :            : static void
        7451                 :       8041 : convert_exception_handlers_to_nops(basicblock *entryblock) {
        7452         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7453         [ +  + ]:     400486 :         for (int i = 0; i < b->b_iused; i++) {
        7454                 :     349175 :             struct cfg_instr *instr = &b->b_instr[i];
        7455   [ +  +  +  + ]:     349175 :             if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) {
        7456                 :       8731 :                 INSTR_SET_OP0(instr, NOP);
        7457                 :            :             }
        7458                 :            :         }
        7459                 :            :     }
        7460         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7461                 :      51311 :         remove_redundant_nops(b);
        7462                 :            :     }
        7463                 :       8041 : }
        7464                 :            :
        7465                 :            : static inline void
        7466                 :      41949 : write_except_byte(struct assembler *a, int byte) {
        7467                 :      41949 :     unsigned char *p = (unsigned char *) PyBytes_AS_STRING(a->a_except_table);
        7468                 :      41949 :     p[a->a_except_table_off++] = byte;
        7469                 :      41949 : }
        7470                 :            :
        7471                 :            : #define CONTINUATION_BIT 64
        7472                 :            :
        7473                 :            : static void
        7474                 :      29760 : assemble_emit_exception_table_item(struct assembler *a, int value, int msb)
        7475                 :            : {
        7476                 :            :     assert ((msb | 128) == 128);
        7477                 :            :     assert(value >= 0 && value < (1 << 30));
        7478         [ -  + ]:      29760 :     if (value >= 1 << 24) {
        7479                 :          0 :         write_except_byte(a, (value >> 24) | CONTINUATION_BIT | msb);
        7480                 :          0 :         msb = 0;
        7481                 :            :     }
        7482         [ -  + ]:      29760 :     if (value >= 1 << 18) {
        7483                 :          0 :         write_except_byte(a, ((value >> 18)&0x3f) | CONTINUATION_BIT | msb);
        7484                 :          0 :         msb = 0;
        7485                 :            :     }
        7486         [ +  + ]:      29760 :     if (value >= 1 << 12) {
        7487                 :         21 :         write_except_byte(a, ((value >> 12)&0x3f) | CONTINUATION_BIT | msb);
        7488                 :         21 :         msb = 0;
        7489                 :            :     }
        7490         [ +  + ]:      29760 :     if (value >= 1 << 6) {
        7491                 :      12168 :         write_except_byte(a, ((value >> 6)&0x3f) | CONTINUATION_BIT | msb);
        7492                 :      12168 :         msb = 0;
        7493                 :            :     }
        7494                 :      29760 :     write_except_byte(a, (value&0x3f) | msb);
        7495                 :      29760 : }
        7496                 :            :
        7497                 :            : /* See Objects/exception_handling_notes.txt for details of layout */
        7498                 :            : #define MAX_SIZE_OF_ENTRY 20
        7499                 :            :
        7500                 :            : static int
        7501                 :       7440 : assemble_emit_exception_table_entry(struct assembler *a, int start, int end, basicblock *handler)
        7502                 :            : {
        7503                 :       7440 :     Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table);
        7504         [ +  + ]:       7440 :     if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) {
        7505         [ -  + ]:       2546 :         RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, len * 2));
        7506                 :            :     }
        7507                 :       7440 :     int size = end-start;
        7508                 :            :     assert(end > start);
        7509                 :       7440 :     int target = handler->b_offset;
        7510                 :       7440 :     int depth = handler->b_startdepth - 1;
        7511         [ +  + ]:       7440 :     if (handler->b_preserve_lasti) {
        7512                 :       5296 :         depth -= 1;
        7513                 :            :     }
        7514                 :            :     assert(depth >= 0);
        7515                 :       7440 :     int depth_lasti = (depth<<1) | handler->b_preserve_lasti;
        7516                 :       7440 :     assemble_emit_exception_table_item(a, start, (1<<7));
        7517                 :       7440 :     assemble_emit_exception_table_item(a, size, 0);
        7518                 :       7440 :     assemble_emit_exception_table_item(a, target, 0);
        7519                 :       7440 :     assemble_emit_exception_table_item(a, depth_lasti, 0);
        7520                 :       7440 :     return SUCCESS;
        7521                 :            : }
        7522                 :            :
        7523                 :            : static int
        7524                 :       8041 : assemble_exception_table(struct assembler *a, basicblock *entryblock)
        7525                 :            : {
        7526                 :            :     basicblock *b;
        7527                 :       8041 :     int ioffset = 0;
        7528                 :       8041 :     basicblock *handler = NULL;
        7529                 :       8041 :     int start = -1;
        7530         [ +  + ]:      60209 :     for (b = entryblock; b != NULL; b = b->b_next) {
        7531                 :      52168 :         ioffset = b->b_offset;
        7532         [ +  + ]:     394204 :         for (int i = 0; i < b->b_iused; i++) {
        7533                 :     342036 :             struct cfg_instr *instr = &b->b_instr[i];
        7534         [ +  + ]:     342036 :             if (instr->i_except != handler) {
        7535         [ +  + ]:      12492 :                 if (handler != NULL) {
        7536         [ -  + ]:       7440 :                     RETURN_IF_ERROR(
        7537                 :            :                         assemble_emit_exception_table_entry(a, start, ioffset, handler));
        7538                 :            :                 }
        7539                 :      12492 :                 start = ioffset;
        7540                 :      12492 :                 handler = instr->i_except;
        7541                 :            :             }
        7542                 :     342036 :             ioffset += instr_size(instr);
        7543                 :            :         }
        7544                 :            :     }
        7545         [ -  + ]:       8041 :     if (handler != NULL) {
        7546         [ #  # ]:          0 :         RETURN_IF_ERROR(assemble_emit_exception_table_entry(a, start, ioffset, handler));
        7547                 :            :     }
        7548                 :       8041 :     return SUCCESS;
        7549                 :            : }
        7550                 :            :
        7551                 :            : /* Code location emitting code. See locations.md for a description of the format. */
        7552                 :            :
        7553                 :            : #define MSB 0x80
        7554                 :            :
        7555                 :            : static void
        7556                 :     346578 : write_location_byte(struct assembler* a, int val)
        7557                 :            : {
        7558                 :     346578 :     PyBytes_AS_STRING(a->a_linetable)[a->a_location_off] = val&255;
        7559                 :     346578 :     a->a_location_off++;
        7560                 :     346578 : }
        7561                 :            :
        7562                 :            :
        7563                 :            : static uint8_t *
        7564                 :     445463 : location_pointer(struct assembler* a)
        7565                 :            : {
        7566                 :     445463 :     return (uint8_t *)PyBytes_AS_STRING(a->a_linetable) +
        7567                 :     445463 :         a->a_location_off;
        7568                 :            : }
        7569                 :            :
        7570                 :            : static void
        7571                 :     286095 : write_location_first_byte(struct assembler* a, int code, int length)
        7572                 :            : {
        7573                 :     286095 :     a->a_location_off += write_location_entry_start(
        7574                 :            :         location_pointer(a), code, length);
        7575                 :     286095 : }
        7576                 :            :
        7577                 :            : static void
        7578                 :     119127 : write_location_varint(struct assembler* a, unsigned int val)
        7579                 :            : {
        7580                 :     119127 :     uint8_t *ptr = location_pointer(a);
        7581                 :     119127 :     a->a_location_off += write_varint(ptr, val);
        7582                 :     119127 : }
        7583                 :            :
        7584                 :            :
        7585                 :            : static void
        7586                 :      40241 : write_location_signed_varint(struct assembler* a, int val)
        7587                 :            : {
        7588                 :      40241 :     uint8_t *ptr = location_pointer(a);
        7589                 :      40241 :     a->a_location_off += write_signed_varint(ptr, val);
        7590                 :      40241 : }
        7591                 :            :
        7592                 :            : static void
        7593                 :     133188 : write_location_info_short_form(struct assembler* a, int length, int column, int end_column)
        7594                 :            : {
        7595                 :            :     assert(length > 0 &&  length <= 8);
        7596                 :     133188 :     int column_low_bits = column & 7;
        7597                 :     133188 :     int column_group = column >> 3;
        7598                 :            :     assert(column < 80);
        7599                 :            :     assert(end_column >= column);
        7600                 :            :     assert(end_column - column < 16);
        7601                 :     133188 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_SHORT0 + column_group, length);
        7602                 :     133188 :     write_location_byte(a, (column_low_bits << 4) | (end_column - column));
        7603                 :     133188 : }
        7604                 :            :
        7605                 :            : static void
        7606                 :     106695 : write_location_info_oneline_form(struct assembler* a, int length, int line_delta, int column, int end_column)
        7607                 :            : {
        7608                 :            :     assert(length > 0 &&  length <= 8);
        7609                 :            :     assert(line_delta >= 0 && line_delta < 3);
        7610                 :            :     assert(column < 128);
        7611                 :            :     assert(end_column < 128);
        7612                 :     106695 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_ONE_LINE0 + line_delta, length);
        7613                 :     106695 :     write_location_byte(a, column);
        7614                 :     106695 :     write_location_byte(a, end_column);
        7615                 :     106695 : }
        7616                 :            :
        7617                 :            : static void
        7618                 :      39709 : write_location_info_long_form(struct assembler* a, location loc, int length)
        7619                 :            : {
        7620                 :            :     assert(length > 0 &&  length <= 8);
        7621                 :      39709 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length);
        7622                 :      39709 :     write_location_signed_varint(a, loc.lineno - a->a_lineno);
        7623                 :            :     assert(loc.end_lineno >= loc.lineno);
        7624                 :      39709 :     write_location_varint(a, loc.end_lineno - loc.lineno);
        7625                 :      39709 :     write_location_varint(a, loc.col_offset + 1);
        7626                 :      39709 :     write_location_varint(a, loc.end_col_offset + 1);
        7627                 :      39709 : }
        7628                 :            :
        7629                 :            : static void
        7630                 :       5971 : write_location_info_none(struct assembler* a, int length)
        7631                 :            : {
        7632                 :       5971 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_NONE, length);
        7633                 :       5971 : }
        7634                 :            :
        7635                 :            : static void
        7636                 :        532 : write_location_info_no_column(struct assembler* a, int length, int line_delta)
        7637                 :            : {
        7638                 :        532 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_NO_COLUMNS, length);
        7639                 :        532 :     write_location_signed_varint(a, line_delta);
        7640                 :        532 : }
        7641                 :            :
        7642                 :            : #define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */
        7643                 :            :
        7644                 :            : static int
        7645                 :     286095 : write_location_info_entry(struct assembler* a, location loc, int isize)
        7646                 :            : {
        7647                 :     286095 :     Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable);
        7648         [ +  + ]:     286095 :     if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) {
        7649                 :            :         assert(len > THEORETICAL_MAX_ENTRY_SIZE);
        7650         [ -  + ]:      14595 :         RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
        7651                 :            :     }
        7652         [ +  + ]:     286095 :     if (loc.lineno < 0) {
        7653                 :       5971 :         write_location_info_none(a, isize);
        7654                 :       5971 :         return SUCCESS;
        7655                 :            :     }
        7656                 :     280124 :     int line_delta = loc.lineno - a->a_lineno;
        7657                 :     280124 :     int column = loc.col_offset;
        7658                 :     280124 :     int end_column = loc.end_col_offset;
        7659                 :            :     assert(column >= -1);
        7660                 :            :     assert(end_column >= -1);
        7661   [ +  +  -  + ]:     280124 :     if (column < 0 || end_column < 0) {
        7662   [ -  +  -  - ]:        532 :         if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
        7663                 :        532 :             write_location_info_no_column(a, isize, line_delta);
        7664                 :        532 :             a->a_lineno = loc.lineno;
        7665                 :        532 :             return SUCCESS;
        7666                 :            :         }
        7667                 :            :     }
        7668         [ +  + ]:     279592 :     else if (loc.end_lineno == loc.lineno) {
        7669   [ +  +  +  +  :     254138 :         if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) {
                 +  +  +  - ]
        7670                 :     133188 :             write_location_info_short_form(a, isize, column, end_column);
        7671                 :     133188 :             return SUCCESS;
        7672                 :            :         }
        7673   [ +  +  +  +  :     120950 :         if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) {
                 +  +  +  + ]
        7674                 :     106695 :             write_location_info_oneline_form(a, isize, line_delta, column, end_column);
        7675                 :     106695 :             a->a_lineno = loc.lineno;
        7676                 :     106695 :             return SUCCESS;
        7677                 :            :         }
        7678                 :            :     }
        7679                 :      39709 :     write_location_info_long_form(a, loc, isize);
        7680                 :      39709 :     a->a_lineno = loc.lineno;
        7681                 :      39709 :     return SUCCESS;
        7682                 :            : }
        7683                 :            :
        7684                 :            : static int
        7685                 :     264465 : assemble_emit_location(struct assembler* a, location loc, int isize)
        7686                 :            : {
        7687         [ +  + ]:     264465 :     if (isize == 0) {
        7688                 :       7033 :         return SUCCESS;
        7689                 :            :     }
        7690         [ +  + ]:     286095 :     while (isize > 8) {
        7691         [ -  + ]:      28663 :         RETURN_IF_ERROR(write_location_info_entry(a, loc, 8));
        7692                 :      28663 :         isize -= 8;
        7693                 :            :     }
        7694                 :     257432 :     return write_location_info_entry(a, loc, isize);
        7695                 :            : }
        7696                 :            :
        7697                 :            : static int
        7698                 :       8041 : assemble_location_info(struct assembler *a, basicblock *entryblock, int firstlineno)
        7699                 :            : {
        7700                 :       8041 :     a->a_lineno = firstlineno;
        7701                 :       8041 :     location loc = NO_LOCATION;
        7702                 :       8041 :     int size = 0;
        7703         [ +  + ]:      60209 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7704         [ +  + ]:     394204 :         for (int j = 0; j < b->b_iused; j++) {
        7705         [ +  + ]:     342036 :             if (!same_location(loc, b->b_instr[j].i_loc)) {
        7706         [ -  + ]:     256424 :                 RETURN_IF_ERROR(assemble_emit_location(a, loc, size));
        7707                 :     256424 :                 loc = b->b_instr[j].i_loc;
        7708                 :     256424 :                 size = 0;
        7709                 :            :             }
        7710                 :     342036 :             size += instr_size(&b->b_instr[j]);
        7711                 :            :         }
        7712                 :            :     }
        7713         [ -  + ]:       8041 :     RETURN_IF_ERROR(assemble_emit_location(a, loc, size));
        7714                 :       8041 :     return SUCCESS;
        7715                 :            : }
        7716                 :            :
        7717                 :            : /* assemble_emit_instr()
        7718                 :            :    Extend the bytecode with a new instruction.
        7719                 :            :    Update lnotab if necessary.
        7720                 :            : */
        7721                 :            :
        7722                 :            : static int
        7723                 :     342036 : assemble_emit_instr(struct assembler *a, struct cfg_instr *i)
        7724                 :            : {
        7725                 :     342036 :     Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
        7726                 :            :     _Py_CODEUNIT *code;
        7727                 :            :
        7728                 :     342036 :     int size = instr_size(i);
        7729         [ +  + ]:     342036 :     if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) {
        7730         [ -  + ]:       5892 :         if (len > PY_SSIZE_T_MAX / 2) {
        7731                 :          0 :             return ERROR;
        7732                 :            :         }
        7733         [ -  + ]:       5892 :         RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, len * 2));
        7734                 :            :     }
        7735                 :     342036 :     code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
        7736                 :     342036 :     a->a_offset += size;
        7737                 :     342036 :     write_instr(code, i, size);
        7738                 :     342036 :     return SUCCESS;
        7739                 :            : }
        7740                 :            :
        7741                 :            : static int merge_const_one(PyObject *const_cache, PyObject **obj);
        7742                 :            :
        7743                 :            : static int
        7744                 :       8041 : assemble_emit(struct assembler *a, basicblock *entryblock, int first_lineno,
        7745                 :            :               PyObject *const_cache)
        7746                 :            : {
        7747         [ -  + ]:       8041 :     RETURN_IF_ERROR(assemble_init(a, first_lineno));
        7748                 :            :
        7749         [ +  + ]:      60209 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7750         [ +  + ]:     394204 :         for (int j = 0; j < b->b_iused; j++) {
        7751         [ -  + ]:     342036 :             RETURN_IF_ERROR(assemble_emit_instr(a, &b->b_instr[j]));
        7752                 :            :         }
        7753                 :            :     }
        7754                 :            :
        7755         [ -  + ]:       8041 :     RETURN_IF_ERROR(assemble_location_info(a, entryblock, a->a_lineno));
        7756                 :            :
        7757         [ -  + ]:       8041 :     RETURN_IF_ERROR(assemble_exception_table(a, entryblock));
        7758                 :            :
        7759         [ -  + ]:       8041 :     RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, a->a_except_table_off));
        7760         [ -  + ]:       8041 :     RETURN_IF_ERROR(merge_const_one(const_cache, &a->a_except_table));
        7761                 :            :
        7762         [ -  + ]:       8041 :     RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, a->a_location_off));
        7763         [ -  + ]:       8041 :     RETURN_IF_ERROR(merge_const_one(const_cache, &a->a_linetable));
        7764                 :            :
        7765         [ -  + ]:       8041 :     RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, a->a_offset * sizeof(_Py_CODEUNIT)));
        7766         [ -  + ]:       8041 :     RETURN_IF_ERROR(merge_const_one(const_cache, &a->a_bytecode));
        7767                 :       8041 :     return SUCCESS;
        7768                 :            : }
        7769                 :            :
        7770                 :            : static int
        7771                 :      52168 : normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
        7772                 :      52168 :     struct cfg_instr *last = basicblock_last_instr(b);
        7773   [ +  +  +  + ]:      52168 :     if (last == NULL || !is_jump(last)) {
        7774                 :      30617 :         return SUCCESS;
        7775                 :            :     }
        7776                 :            :     assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
        7777                 :      21551 :     bool is_forward = last->i_target->b_visited == 0;
        7778      [ +  +  + ]:      21551 :     switch(last->i_opcode) {
        7779                 :       5692 :         case JUMP:
        7780         [ +  + ]:       5692 :             last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
        7781                 :       5692 :             return SUCCESS;
        7782                 :        190 :         case JUMP_NO_INTERRUPT:
        7783                 :        190 :             last->i_opcode = is_forward ?
        7784         [ -  + ]:        190 :                 JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
        7785                 :        190 :             return SUCCESS;
        7786                 :            :     }
        7787                 :      15669 :     int reversed_opcode = 0;
        7788   [ +  +  +  +  :      15669 :     switch(last->i_opcode) {
                       +  + ]
        7789                 :        884 :         case POP_JUMP_IF_NOT_NONE:
        7790                 :        884 :             reversed_opcode = POP_JUMP_IF_NONE;
        7791                 :        884 :             break;
        7792                 :        889 :         case POP_JUMP_IF_NONE:
        7793                 :        889 :             reversed_opcode = POP_JUMP_IF_NOT_NONE;
        7794                 :        889 :             break;
        7795                 :       9096 :         case POP_JUMP_IF_FALSE:
        7796                 :       9096 :             reversed_opcode = POP_JUMP_IF_TRUE;
        7797                 :       9096 :             break;
        7798                 :       2468 :         case POP_JUMP_IF_TRUE:
        7799                 :       2468 :             reversed_opcode = POP_JUMP_IF_FALSE;
        7800                 :       2468 :             break;
        7801                 :        437 :         case JUMP_IF_TRUE_OR_POP:
        7802                 :            :         case JUMP_IF_FALSE_OR_POP:
        7803         [ -  + ]:        437 :             if (!is_forward) {
        7804                 :            :                 /* As far as we can tell, the compiler never emits
        7805                 :            :                  * these jumps with a backwards target. If/when this
        7806                 :            :                  * exception is raised, we have found a use case for
        7807                 :            :                  * a backwards version of this jump (or to replace
        7808                 :            :                  * it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP)
        7809                 :            :                  */
        7810                 :          0 :                 PyErr_Format(PyExc_SystemError,
        7811                 :            :                     "unexpected %s jumping backwards",
        7812         [ #  # ]:          0 :                     last->i_opcode == JUMP_IF_TRUE_OR_POP ?
        7813                 :            :                         "JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP");
        7814                 :            :             }
        7815                 :        437 :             return SUCCESS;
        7816                 :            :     }
        7817         [ +  + ]:      15232 :     if (is_forward) {
        7818                 :      14375 :         return SUCCESS;
        7819                 :            :     }
        7820                 :            :
        7821                 :            :     /* transform 'conditional jump T' to
        7822                 :            :      * 'reversed_jump b_next' followed by 'jump_backwards T'
        7823                 :            :      */
        7824                 :            :
        7825                 :        857 :     basicblock *target = last->i_target;
        7826                 :        857 :     basicblock *backwards_jump = cfg_builder_new_block(g);
        7827         [ -  + ]:        857 :     if (backwards_jump == NULL) {
        7828                 :          0 :         return ERROR;
        7829                 :            :     }
        7830                 :        857 :     basicblock_addop(backwards_jump, JUMP, target->b_label.id, NO_LOCATION);
        7831                 :        857 :     backwards_jump->b_instr[0].i_target = target;
        7832                 :        857 :     last->i_opcode = reversed_opcode;
        7833                 :        857 :     last->i_target = b->b_next;
        7834                 :            :
        7835                 :        857 :     backwards_jump->b_cold = b->b_cold;
        7836                 :        857 :     backwards_jump->b_next = b->b_next;
        7837                 :        857 :     b->b_next = backwards_jump;
        7838                 :        857 :     return SUCCESS;
        7839                 :            : }
        7840                 :            :
        7841                 :            : static int
        7842                 :       8041 : normalize_jumps(cfg_builder *g)
        7843                 :            : {
        7844                 :       8041 :     basicblock *entryblock = g->g_entryblock;
        7845         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7846                 :      51311 :         b->b_visited = 0;
        7847                 :            :     }
        7848         [ +  + ]:      60209 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7849                 :      52168 :         b->b_visited = 1;
        7850         [ -  + ]:      52168 :         RETURN_IF_ERROR(normalize_jumps_in_block(g, b));
        7851                 :            :     }
        7852                 :       8041 :     return SUCCESS;
        7853                 :            : }
        7854                 :            :
        7855                 :            : static void
        7856                 :       8225 : assemble_jump_offsets(basicblock *entryblock)
        7857                 :            : {
        7858                 :            :     int bsize, totsize, extended_arg_recompile;
        7859                 :            :
        7860                 :            :     /* Compute the size of each block and fixup jump args.
        7861                 :            :        Replace block pointer with position in bytecode. */
        7862                 :            :     do {
        7863                 :       8225 :         totsize = 0;
        7864         [ +  + ]:      69727 :         for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7865                 :      61502 :             bsize = blocksize(b);
        7866                 :      61502 :             b->b_offset = totsize;
        7867                 :      61502 :             totsize += bsize;
        7868                 :            :         }
        7869                 :       8225 :         extended_arg_recompile = 0;
        7870         [ +  + ]:      69727 :         for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7871                 :      61502 :             bsize = b->b_offset;
        7872         [ +  + ]:     465669 :             for (int i = 0; i < b->b_iused; i++) {
        7873                 :     404167 :                 struct cfg_instr *instr = &b->b_instr[i];
        7874                 :     404167 :                 int isize = instr_size(instr);
        7875                 :            :                 /* Relative jumps are computed relative to
        7876                 :            :                    the instruction pointer after fetching
        7877                 :            :                    the jump instruction.
        7878                 :            :                 */
        7879                 :     404167 :                 bsize += isize;
        7880         [ +  + ]:     404167 :                 if (is_jump(instr)) {
        7881                 :      26506 :                     instr->i_oparg = instr->i_target->b_offset;
        7882         [ +  - ]:      26506 :                     if (is_relative_jump(instr)) {
        7883         [ +  + ]:      26506 :                         if (instr->i_oparg < bsize) {
        7884                 :            :                             assert(IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
        7885                 :       5048 :                             instr->i_oparg = bsize - instr->i_oparg;
        7886                 :            :                         }
        7887                 :            :                         else {
        7888                 :            :                             assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
        7889                 :      21458 :                             instr->i_oparg -= bsize;
        7890                 :            :                         }
        7891                 :            :                     }
        7892                 :            :                     else {
        7893                 :            :                         assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
        7894                 :            :                     }
        7895         [ +  + ]:      26506 :                     if (instr_size(instr) != isize) {
        7896                 :        647 :                         extended_arg_recompile = 1;
        7897                 :            :                     }
        7898                 :            :                 }
        7899                 :            :             }
        7900                 :            :         }
        7901                 :            :
        7902                 :            :     /* XXX: This is an awful hack that could hurt performance, but
        7903                 :            :         on the bright side it should work until we come up
        7904                 :            :         with a better solution.
        7905                 :            :
        7906                 :            :         The issue is that in the first loop blocksize() is called
        7907                 :            :         which calls instr_size() which requires i_oparg be set
        7908                 :            :         appropriately. There is a bootstrap problem because
        7909                 :            :         i_oparg is calculated in the second loop above.
        7910                 :            :
        7911                 :            :         So we loop until we stop seeing new EXTENDED_ARGs.
        7912                 :            :         The only EXTENDED_ARGs that could be popping up are
        7913                 :            :         ones in jump instructions.  So this should converge
        7914                 :            :         fairly quickly.
        7915                 :            :     */
        7916         [ +  + ]:       8225 :     } while (extended_arg_recompile);
        7917                 :       8041 : }
        7918                 :            :
        7919                 :            :
        7920                 :            : // helper functions for add_checks_for_loads_of_unknown_variables
        7921                 :            : static inline void
        7922                 :     204644 : maybe_push(basicblock *b, uint64_t unsafe_mask, basicblock ***sp)
        7923                 :            : {
        7924                 :            :     // Push b if the unsafe mask is giving us any new information.
        7925                 :            :     // To avoid overflowing the stack, only allow each block once.
        7926                 :            :     // Use b->b_visited=1 to mean that b is currently on the stack.
        7927                 :     204644 :     uint64_t both = b->b_unsafe_locals_mask | unsafe_mask;
        7928         [ +  + ]:     204644 :     if (b->b_unsafe_locals_mask != both) {
        7929                 :      33427 :         b->b_unsafe_locals_mask = both;
        7930                 :            :         // More work left to do.
        7931         [ +  + ]:      33427 :         if (!b->b_visited) {
        7932                 :            :             // not on the stack, so push it.
        7933                 :      33175 :             *(*sp)++ = b;
        7934                 :      33175 :             b->b_visited = 1;
        7935                 :            :         }
        7936                 :            :     }
        7937                 :     204644 : }
        7938                 :            :
        7939                 :            : static void
        7940                 :      80806 : scan_block_for_locals(basicblock *b, basicblock ***sp)
        7941                 :            : {
        7942                 :            :     // bit i is set if local i is potentially uninitialized
        7943                 :      80806 :     uint64_t unsafe_mask = b->b_unsafe_locals_mask;
        7944         [ +  + ]:     549175 :     for (int i = 0; i < b->b_iused; i++) {
        7945                 :     468369 :         struct cfg_instr *instr = &b->b_instr[i];
        7946                 :            :         assert(instr->i_opcode != EXTENDED_ARG);
        7947                 :            :         assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode));
        7948         [ +  + ]:     468369 :         if (instr->i_except != NULL) {
        7949                 :     114747 :             maybe_push(instr->i_except, unsafe_mask, sp);
        7950                 :            :         }
        7951         [ +  + ]:     468369 :         if (instr->i_oparg >= 64) {
        7952                 :       3041 :             continue;
        7953                 :            :         }
        7954                 :            :         assert(instr->i_oparg >= 0);
        7955                 :     465328 :         uint64_t bit = (uint64_t)1 << instr->i_oparg;
        7956   [ +  +  +  +  :     465328 :         switch (instr->i_opcode) {
                          + ]
        7957                 :        817 :             case DELETE_FAST:
        7958                 :        817 :                 unsafe_mask |= bit;
        7959                 :        817 :                 break;
        7960                 :      29474 :             case STORE_FAST:
        7961                 :      29474 :                 unsafe_mask &= ~bit;
        7962                 :      29474 :                 break;
        7963                 :        157 :             case LOAD_FAST_CHECK:
        7964                 :            :                 // If this doesn't raise, then the local is defined.
        7965                 :        157 :                 unsafe_mask &= ~bit;
        7966                 :        157 :                 break;
        7967                 :      94654 :             case LOAD_FAST:
        7968         [ +  + ]:      94654 :                 if (unsafe_mask & bit) {
        7969                 :        157 :                     instr->i_opcode = LOAD_FAST_CHECK;
        7970                 :            :                 }
        7971                 :      94654 :                 unsafe_mask &= ~bit;
        7972                 :      94654 :                 break;
        7973                 :            :         }
        7974                 :     468369 :     }
        7975   [ +  +  +  + ]:      80806 :     if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
        7976                 :      46996 :         maybe_push(b->b_next, unsafe_mask, sp);
        7977                 :            :     }
        7978                 :      80806 :     struct cfg_instr *last = basicblock_last_instr(b);
        7979   [ +  -  +  + ]:      80806 :     if (last && is_jump(last)) {
        7980                 :            :         assert(last->i_target != NULL);
        7981                 :      36062 :         maybe_push(last->i_target, unsafe_mask, sp);
        7982                 :            :     }
        7983                 :      80806 : }
        7984                 :            :
        7985                 :            : static int
        7986                 :          0 : fast_scan_many_locals(basicblock *entryblock, int nlocals)
        7987                 :            : {
        7988                 :            :     assert(nlocals > 64);
        7989                 :          0 :     Py_ssize_t *states = PyMem_Calloc(nlocals - 64, sizeof(Py_ssize_t));
        7990         [ #  # ]:          0 :     if (states == NULL) {
        7991                 :          0 :         PyErr_NoMemory();
        7992                 :          0 :         return ERROR;
        7993                 :            :     }
        7994                 :          0 :     Py_ssize_t blocknum = 0;
        7995                 :            :     // state[i - 64] == blocknum if local i is guaranteed to
        7996                 :            :     // be initialized, i.e., if it has had a previous LOAD_FAST or
        7997                 :            :     // STORE_FAST within that basicblock (not followed by DELETE_FAST).
        7998         [ #  # ]:          0 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        7999                 :          0 :         blocknum++;
        8000         [ #  # ]:          0 :         for (int i = 0; i < b->b_iused; i++) {
        8001                 :          0 :             struct cfg_instr *instr = &b->b_instr[i];
        8002                 :            :             assert(instr->i_opcode != EXTENDED_ARG);
        8003                 :            :             assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode));
        8004                 :          0 :             int arg = instr->i_oparg;
        8005         [ #  # ]:          0 :             if (arg < 64) {
        8006                 :          0 :                 continue;
        8007                 :            :             }
        8008                 :            :             assert(arg >= 0);
        8009   [ #  #  #  # ]:          0 :             switch (instr->i_opcode) {
        8010                 :          0 :                 case DELETE_FAST:
        8011                 :          0 :                     states[arg - 64] = blocknum - 1;
        8012                 :          0 :                     break;
        8013                 :          0 :                 case STORE_FAST:
        8014                 :          0 :                     states[arg - 64] = blocknum;
        8015                 :          0 :                     break;
        8016                 :          0 :                 case LOAD_FAST:
        8017         [ #  # ]:          0 :                     if (states[arg - 64] != blocknum) {
        8018                 :          0 :                         instr->i_opcode = LOAD_FAST_CHECK;
        8019                 :            :                     }
        8020                 :          0 :                     states[arg - 64] = blocknum;
        8021                 :          0 :                     break;
        8022                 :            :                 case LOAD_FAST_CHECK:
        8023                 :            :                     Py_UNREACHABLE();
        8024                 :            :             }
        8025                 :          0 :         }
        8026                 :            :     }
        8027                 :          0 :     PyMem_Free(states);
        8028                 :          0 :     return SUCCESS;
        8029                 :            : }
        8030                 :            :
        8031                 :            : static int
        8032                 :       8041 : add_checks_for_loads_of_uninitialized_variables(basicblock *entryblock,
        8033                 :            :                                                 int nlocals,
        8034                 :            :                                                 int nparams)
        8035                 :            : {
        8036         [ +  + ]:       8041 :     if (nlocals == 0) {
        8037                 :       1202 :         return SUCCESS;
        8038                 :            :     }
        8039         [ -  + ]:       6839 :     if (nlocals > 64) {
        8040                 :            :         // To avoid O(nlocals**2) compilation, locals beyond the first
        8041                 :            :         // 64 are only analyzed one basicblock at a time: initialization
        8042                 :            :         // info is not passed between basicblocks.
        8043         [ #  # ]:          0 :         if (fast_scan_many_locals(entryblock, nlocals) < 0) {
        8044                 :          0 :             return ERROR;
        8045                 :            :         }
        8046                 :          0 :         nlocals = 64;
        8047                 :            :     }
        8048                 :       6839 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
        8049         [ -  + ]:       6839 :     if (stack == NULL) {
        8050                 :          0 :         return ERROR;
        8051                 :            :     }
        8052                 :       6839 :     basicblock **sp = stack;
        8053                 :            :
        8054                 :            :     // First origin of being uninitialized:
        8055                 :            :     // The non-parameter locals in the entry block.
        8056                 :       6839 :     uint64_t start_mask = 0;
        8057         [ +  + ]:      16575 :     for (int i = nparams; i < nlocals; i++) {
        8058                 :       9736 :         start_mask |= (uint64_t)1 << i;
        8059                 :            :     }
        8060                 :       6839 :     maybe_push(entryblock, start_mask, &sp);
        8061                 :            :
        8062                 :            :     // Second origin of being uninitialized:
        8063                 :            :     // There could be DELETE_FAST somewhere, so
        8064                 :            :     // be sure to scan each basicblock at least once.
        8065         [ +  + ]:      54470 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        8066                 :      47631 :         scan_block_for_locals(b, &sp);
        8067                 :            :     }
        8068                 :            :
        8069                 :            :     // Now propagate the uncertainty from the origins we found: Use
        8070                 :            :     // LOAD_FAST_CHECK for any LOAD_FAST where the local could be undefined.
        8071         [ +  + ]:      40014 :     while (sp > stack) {
        8072                 :      33175 :         basicblock *b = *--sp;
        8073                 :            :         // mark as no longer on stack
        8074                 :      33175 :         b->b_visited = 0;
        8075                 :      33175 :         scan_block_for_locals(b, &sp);
        8076                 :            :     }
        8077                 :       6839 :     PyMem_Free(stack);
        8078                 :       6839 :     return SUCCESS;
        8079                 :            : }
        8080                 :            :
        8081                 :            : static PyObject *
        8082                 :       8041 : dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
        8083                 :            : {
        8084                 :            :     PyObject *tuple, *k, *v;
        8085                 :       8041 :     Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
        8086                 :            :
        8087                 :       8041 :     tuple = PyTuple_New(size);
        8088         [ -  + ]:       8041 :     if (tuple == NULL)
        8089                 :          0 :         return NULL;
        8090         [ +  + ]:      58190 :     while (PyDict_Next(dict, &pos, &k, &v)) {
        8091                 :      50149 :         i = PyLong_AS_LONG(v);
        8092                 :            :         assert((i - offset) < size);
        8093                 :            :         assert((i - offset) >= 0);
        8094                 :      50149 :         PyTuple_SET_ITEM(tuple, i - offset, Py_NewRef(k));
        8095                 :            :     }
        8096                 :       8041 :     return tuple;
        8097                 :            : }
        8098                 :            :
        8099                 :            : static PyObject *
        8100                 :       8041 : consts_dict_keys_inorder(PyObject *dict)
        8101                 :            : {
        8102                 :            :     PyObject *consts, *k, *v;
        8103                 :       8041 :     Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
        8104                 :            :
        8105                 :       8041 :     consts = PyList_New(size);   /* PyCode_Optimize() requires a list */
        8106         [ -  + ]:       8041 :     if (consts == NULL)
        8107                 :          0 :         return NULL;
        8108         [ +  + ]:      50324 :     while (PyDict_Next(dict, &pos, &k, &v)) {
        8109                 :      42283 :         i = PyLong_AS_LONG(v);
        8110                 :            :         /* The keys of the dictionary can be tuples wrapping a constant.
        8111                 :            :          * (see dict_add_o and _PyCode_ConstantKey). In that case
        8112                 :            :          * the object we want is always second. */
        8113         [ +  + ]:      42283 :         if (PyTuple_CheckExact(k)) {
        8114                 :       4446 :             k = PyTuple_GET_ITEM(k, 1);
        8115                 :            :         }
        8116                 :            :         assert(i < size);
        8117                 :            :         assert(i >= 0);
        8118                 :      42283 :         PyList_SET_ITEM(consts, i, Py_NewRef(k));
        8119                 :            :     }
        8120                 :       8041 :     return consts;
        8121                 :            : }
        8122                 :            :
        8123                 :            : static int
        8124                 :       8041 : compute_code_flags(struct compiler *c)
        8125                 :            : {
        8126                 :       8041 :     PySTEntryObject *ste = c->u->u_ste;
        8127                 :       8041 :     int flags = 0;
        8128         [ +  + ]:       8041 :     if (ste->ste_type == FunctionBlock) {
        8129                 :       6989 :         flags |= CO_NEWLOCALS | CO_OPTIMIZED;
        8130         [ +  + ]:       6989 :         if (ste->ste_nested)
        8131                 :        758 :             flags |= CO_NESTED;
        8132   [ +  +  +  + ]:       6989 :         if (ste->ste_generator && !ste->ste_coroutine)
        8133                 :        374 :             flags |= CO_GENERATOR;
        8134   [ +  +  +  + ]:       6989 :         if (!ste->ste_generator && ste->ste_coroutine)
        8135                 :        155 :             flags |= CO_COROUTINE;
        8136   [ +  +  +  + ]:       6989 :         if (ste->ste_generator && ste->ste_coroutine)
        8137                 :          3 :             flags |= CO_ASYNC_GENERATOR;
        8138         [ +  + ]:       6989 :         if (ste->ste_varargs)
        8139                 :        309 :             flags |= CO_VARARGS;
        8140         [ +  + ]:       6989 :         if (ste->ste_varkeywords)
        8141                 :        216 :             flags |= CO_VARKEYWORDS;
        8142                 :            :     }
        8143                 :            :
        8144                 :            :     /* (Only) inherit compilerflags in PyCF_MASK */
        8145                 :       8041 :     flags |= (c->c_flags.cf_flags & PyCF_MASK);
        8146                 :            :
        8147   [ -  +  -  -  :       8041 :     if ((IS_TOP_LEVEL_AWAIT(c)) &&
                       -  - ]
        8148                 :          0 :          ste->ste_coroutine &&
        8149         [ #  # ]:          0 :          !ste->ste_generator) {
        8150                 :          0 :         flags |= CO_COROUTINE;
        8151                 :            :     }
        8152                 :            :
        8153                 :       8041 :     return flags;
        8154                 :            : }
        8155                 :            :
        8156                 :            : // Merge *obj* with constant cache.
        8157                 :            : // Unlike merge_consts_recursive(), this function doesn't work recursively.
        8158                 :            : static int
        8159                 :      49146 : merge_const_one(PyObject *const_cache, PyObject **obj)
        8160                 :            : {
        8161                 :            :     assert(PyDict_CheckExact(const_cache));
        8162                 :      49146 :     PyObject *key = _PyCode_ConstantKey(*obj);
        8163         [ -  + ]:      49146 :     if (key == NULL) {
        8164                 :          0 :         return ERROR;
        8165                 :            :     }
        8166                 :            :
        8167                 :            :     // t is borrowed reference
        8168                 :      49146 :     PyObject *t = PyDict_SetDefault(const_cache, key, key);
        8169                 :      49146 :     Py_DECREF(key);
        8170         [ -  + ]:      49146 :     if (t == NULL) {
        8171                 :          0 :         return ERROR;
        8172                 :            :     }
        8173         [ +  + ]:      49146 :     if (t == key) {  // obj is new constant.
        8174                 :      33484 :         return SUCCESS;
        8175                 :            :     }
        8176                 :            :
        8177         [ +  - ]:      15662 :     if (PyTuple_CheckExact(t)) {
        8178                 :            :         // t is still borrowed reference
        8179                 :      15662 :         t = PyTuple_GET_ITEM(t, 1);
        8180                 :            :     }
        8181                 :            :
        8182                 :      15662 :     Py_SETREF(*obj, Py_NewRef(t));
        8183                 :      15662 :     return SUCCESS;
        8184                 :            : }
        8185                 :            :
        8186                 :            : // This is in codeobject.c.
        8187                 :            : extern void _Py_set_localsplus_info(int, PyObject *, unsigned char,
        8188                 :            :                                    PyObject *, PyObject *);
        8189                 :            :
        8190                 :            : static void
        8191                 :       8041 : compute_localsplus_info(struct compiler_unit *u, int nlocalsplus,
        8192                 :            :                         PyObject *names, PyObject *kinds)
        8193                 :            : {
        8194                 :            :     PyObject *k, *v;
        8195                 :       8041 :     Py_ssize_t pos = 0;
        8196         [ +  + ]:      31750 :     while (PyDict_Next(u->u_varnames, &pos, &k, &v)) {
        8197                 :      23709 :         int offset = (int)PyLong_AS_LONG(v);
        8198                 :            :         assert(offset >= 0);
        8199                 :            :         assert(offset < nlocalsplus);
        8200                 :            :         // For now we do not distinguish arg kinds.
        8201                 :      23709 :         _PyLocals_Kind kind = CO_FAST_LOCAL;
        8202         [ +  + ]:      23709 :         if (PyDict_GetItem(u->u_cellvars, k) != NULL) {
        8203                 :        303 :             kind |= CO_FAST_CELL;
        8204                 :            :         }
        8205                 :      23709 :         _Py_set_localsplus_info(offset, k, kind, names, kinds);
        8206                 :            :     }
        8207                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
        8208                 :            :
        8209                 :            :     // This counter mirrors the fix done in fix_cell_offsets().
        8210                 :       8041 :     int numdropped = 0;
        8211                 :       8041 :     pos = 0;
        8212         [ +  + ]:       8740 :     while (PyDict_Next(u->u_cellvars, &pos, &k, &v)) {
        8213         [ +  + ]:        699 :         if (PyDict_GetItem(u->u_varnames, k) != NULL) {
        8214                 :            :             // Skip cells that are already covered by locals.
        8215                 :        303 :             numdropped += 1;
        8216                 :        303 :             continue;
        8217                 :            :         }
        8218                 :        396 :         int offset = (int)PyLong_AS_LONG(v);
        8219                 :            :         assert(offset >= 0);
        8220                 :        396 :         offset += nlocals - numdropped;
        8221                 :            :         assert(offset < nlocalsplus);
        8222                 :        396 :         _Py_set_localsplus_info(offset, k, CO_FAST_CELL, names, kinds);
        8223                 :            :     }
        8224                 :            :
        8225                 :       8041 :     pos = 0;
        8226         [ +  + ]:       8979 :     while (PyDict_Next(u->u_freevars, &pos, &k, &v)) {
        8227                 :        938 :         int offset = (int)PyLong_AS_LONG(v);
        8228                 :            :         assert(offset >= 0);
        8229                 :        938 :         offset += nlocals - numdropped;
        8230                 :            :         assert(offset < nlocalsplus);
        8231                 :        938 :         _Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds);
        8232                 :            :     }
        8233                 :       8041 : }
        8234                 :            :
        8235                 :            : static PyCodeObject *
        8236                 :       8041 : makecode(struct compiler_unit *u, struct assembler *a, PyObject *const_cache,
        8237                 :            :          PyObject *constslist, int maxdepth, int nlocalsplus, int code_flags,
        8238                 :            :          PyObject *filename)
        8239                 :            : {
        8240                 :       8041 :     PyCodeObject *co = NULL;
        8241                 :       8041 :     PyObject *names = NULL;
        8242                 :       8041 :     PyObject *consts = NULL;
        8243                 :       8041 :     PyObject *localsplusnames = NULL;
        8244                 :       8041 :     PyObject *localspluskinds = NULL;
        8245                 :       8041 :     names = dict_keys_inorder(u->u_names, 0);
        8246         [ -  + ]:       8041 :     if (!names) {
        8247                 :          0 :         goto error;
        8248                 :            :     }
        8249         [ -  + ]:       8041 :     if (merge_const_one(const_cache, &names) < 0) {
        8250                 :          0 :         goto error;
        8251                 :            :     }
        8252                 :            :
        8253                 :       8041 :     consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */
        8254         [ -  + ]:       8041 :     if (consts == NULL) {
        8255                 :          0 :         goto error;
        8256                 :            :     }
        8257         [ -  + ]:       8041 :     if (merge_const_one(const_cache, &consts) < 0) {
        8258                 :          0 :         goto error;
        8259                 :            :     }
        8260                 :            :
        8261                 :            :     assert(u->u_posonlyargcount < INT_MAX);
        8262                 :            :     assert(u->u_argcount < INT_MAX);
        8263                 :            :     assert(u->u_kwonlyargcount < INT_MAX);
        8264                 :       8041 :     int posonlyargcount = (int)u->u_posonlyargcount;
        8265                 :       8041 :     int posorkwargcount = (int)u->u_argcount;
        8266                 :            :     assert(INT_MAX - posonlyargcount - posorkwargcount > 0);
        8267                 :       8041 :     int kwonlyargcount = (int)u->u_kwonlyargcount;
        8268                 :            :
        8269                 :       8041 :     localsplusnames = PyTuple_New(nlocalsplus);
        8270         [ -  + ]:       8041 :     if (localsplusnames == NULL) {
        8271                 :          0 :         goto error;
        8272                 :            :     }
        8273                 :       8041 :     localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
        8274         [ -  + ]:       8041 :     if (localspluskinds == NULL) {
        8275                 :          0 :         goto error;
        8276                 :            :     }
        8277                 :       8041 :     compute_localsplus_info(u, nlocalsplus, localsplusnames, localspluskinds);
        8278                 :            :
        8279                 :      16082 :     struct _PyCodeConstructor con = {
        8280                 :            :         .filename = filename,
        8281                 :       8041 :         .name = u->u_name,
        8282         [ +  + ]:       8041 :         .qualname = u->u_qualname ? u->u_qualname : u->u_name,
        8283                 :            :         .flags = code_flags,
        8284                 :            :
        8285                 :       8041 :         .code = a->a_bytecode,
        8286                 :       8041 :         .firstlineno = u->u_firstlineno,
        8287                 :       8041 :         .linetable = a->a_linetable,
        8288                 :            :
        8289                 :            :         .consts = consts,
        8290                 :            :         .names = names,
        8291                 :            :
        8292                 :            :         .localsplusnames = localsplusnames,
        8293                 :            :         .localspluskinds = localspluskinds,
        8294                 :            :
        8295                 :       8041 :         .argcount = posonlyargcount + posorkwargcount,
        8296                 :            :         .posonlyargcount = posonlyargcount,
        8297                 :            :         .kwonlyargcount = kwonlyargcount,
        8298                 :            :
        8299                 :            :         .stacksize = maxdepth,
        8300                 :            :
        8301                 :       8041 :         .exceptiontable = a->a_except_table,
        8302                 :            :     };
        8303                 :            :
        8304         [ -  + ]:       8041 :     if (_PyCode_Validate(&con) < 0) {
        8305                 :          0 :         goto error;
        8306                 :            :     }
        8307                 :            :
        8308         [ -  + ]:       8041 :     if (merge_const_one(const_cache, &localsplusnames) < 0) {
        8309                 :          0 :         goto error;
        8310                 :            :     }
        8311                 :       8041 :     con.localsplusnames = localsplusnames;
        8312                 :            :
        8313                 :       8041 :     co = _PyCode_New(&con);
        8314         [ +  - ]:       8041 :     if (co == NULL) {
        8315                 :          0 :         goto error;
        8316                 :            :     }
        8317                 :            :
        8318                 :       8041 :  error:
        8319                 :       8041 :     Py_XDECREF(names);
        8320                 :       8041 :     Py_XDECREF(consts);
        8321                 :       8041 :     Py_XDECREF(localsplusnames);
        8322                 :       8041 :     Py_XDECREF(localspluskinds);
        8323                 :       8041 :     return co;
        8324                 :            : }
        8325                 :            :
        8326                 :            :
        8327                 :            : /* For debugging purposes only */
        8328                 :            : #if 0
        8329                 :            : static void
        8330                 :            : dump_instr(struct cfg_instr *i)
        8331                 :            : {
        8332                 :            :     const char *jrel = (is_relative_jump(i)) ? "jrel " : "";
        8333                 :            :     const char *jabs = (is_jump(i) && !is_relative_jump(i))? "jabs " : "";
        8334                 :            :
        8335                 :            :     char arg[128];
        8336                 :            :
        8337                 :            :     *arg = '\0';
        8338                 :            :     if (HAS_ARG(i->i_opcode)) {
        8339                 :            :         sprintf(arg, "arg: %d ", i->i_oparg);
        8340                 :            :     }
        8341                 :            :     if (HAS_TARGET(i->i_opcode)) {
        8342                 :            :         sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg);
        8343                 :            :     }
        8344                 :            :     fprintf(stderr, "line: %d, opcode: %d %s%s%s\n",
        8345                 :            :                     i->i_loc.lineno, i->i_opcode, arg, jabs, jrel);
        8346                 :            : }
        8347                 :            :
        8348                 :            : static inline int
        8349                 :            : basicblock_returns(const basicblock *b) {
        8350                 :            :     struct cfg_instr *last = basicblock_last_instr(b);
        8351                 :            :     return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST);
        8352                 :            : }
        8353                 :            :
        8354                 :            : static void
        8355                 :            : dump_basicblock(const basicblock *b)
        8356                 :            : {
        8357                 :            :     const char *b_return = basicblock_returns(b) ? "return " : "";
        8358                 :            :     fprintf(stderr, "%d: [EH=%d CLD=%d WRM=%d NO_FT=%d %p] used: %d, depth: %d, offset: %d %s\n",
        8359                 :            :         b->b_label.id, b->b_except_handler, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused,
        8360                 :            :         b->b_startdepth, b->b_offset, b_return);
        8361                 :            :     if (b->b_instr) {
        8362                 :            :         int i;
        8363                 :            :         for (i = 0; i < b->b_iused; i++) {
        8364                 :            :             fprintf(stderr, "  [%02d] ", i);
        8365                 :            :             dump_instr(b->b_instr + i);
        8366                 :            :         }
        8367                 :            :     }
        8368                 :            : }
        8369                 :            : #endif
        8370                 :            :
        8371                 :            :
        8372                 :            : static int
        8373                 :            : translate_jump_labels_to_targets(basicblock *entryblock);
        8374                 :            :
        8375                 :            : static int
        8376                 :            : optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache);
        8377                 :            :
        8378                 :            : static int
        8379                 :            : remove_unused_consts(basicblock *entryblock, PyObject *consts);
        8380                 :            :
        8381                 :            : /* Duplicates exit BBs, so that line numbers can be propagated to them */
        8382                 :            : static int
        8383                 :            : duplicate_exits_without_lineno(cfg_builder *g);
        8384                 :            :
        8385                 :            : static int *
        8386                 :       8041 : build_cellfixedoffsets(struct compiler_unit *u)
        8387                 :            : {
        8388                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
        8389                 :       8041 :     int ncellvars = (int)PyDict_GET_SIZE(u->u_cellvars);
        8390                 :       8041 :     int nfreevars = (int)PyDict_GET_SIZE(u->u_freevars);
        8391                 :            :
        8392                 :       8041 :     int noffsets = ncellvars + nfreevars;
        8393         [ +  - ]:       8041 :     int *fixed = PyMem_New(int, noffsets);
        8394         [ -  + ]:       8041 :     if (fixed == NULL) {
        8395                 :          0 :         PyErr_NoMemory();
        8396                 :          0 :         return NULL;
        8397                 :            :     }
        8398         [ +  + ]:       9678 :     for (int i = 0; i < noffsets; i++) {
        8399                 :       1637 :         fixed[i] = nlocals + i;
        8400                 :            :     }
        8401                 :            :
        8402                 :            :     PyObject *varname, *cellindex;
        8403                 :       8041 :     Py_ssize_t pos = 0;
        8404         [ +  + ]:       8740 :     while (PyDict_Next(u->u_cellvars, &pos, &varname, &cellindex)) {
        8405                 :        699 :         PyObject *varindex = PyDict_GetItem(u->u_varnames, varname);
        8406         [ +  + ]:        699 :         if (varindex != NULL) {
        8407                 :            :             assert(PyLong_AS_LONG(cellindex) < INT_MAX);
        8408                 :            :             assert(PyLong_AS_LONG(varindex) < INT_MAX);
        8409                 :        303 :             int oldindex = (int)PyLong_AS_LONG(cellindex);
        8410                 :        303 :             int argoffset = (int)PyLong_AS_LONG(varindex);
        8411                 :        303 :             fixed[oldindex] = argoffset;
        8412                 :            :         }
        8413                 :            :     }
        8414                 :            :
        8415                 :       8041 :     return fixed;
        8416                 :            : }
        8417                 :            :
        8418                 :            : static int
        8419                 :       8041 : insert_prefix_instructions(struct compiler_unit *u, basicblock *entryblock,
        8420                 :            :                            int *fixed, int nfreevars, int code_flags)
        8421                 :            : {
        8422                 :            :     assert(u->u_firstlineno > 0);
        8423                 :            :
        8424                 :            :     /* Add the generator prefix instructions. */
        8425         [ +  + ]:       8041 :     if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
        8426                 :        532 :         struct cfg_instr make_gen = {
        8427                 :            :             .i_opcode = RETURN_GENERATOR,
        8428                 :            :             .i_oparg = 0,
        8429                 :        532 :             .i_loc = LOCATION(u->u_firstlineno, u->u_firstlineno, -1, -1),
        8430                 :            :             .i_target = NULL,
        8431                 :            :         };
        8432         [ -  + ]:        532 :         RETURN_IF_ERROR(insert_instruction(entryblock, 0, &make_gen));
        8433                 :        532 :         struct cfg_instr pop_top = {
        8434                 :            :             .i_opcode = POP_TOP,
        8435                 :            :             .i_oparg = 0,
        8436                 :            :             .i_loc = NO_LOCATION,
        8437                 :            :             .i_target = NULL,
        8438                 :            :         };
        8439         [ -  + ]:        532 :         RETURN_IF_ERROR(insert_instruction(entryblock, 1, &pop_top));
        8440                 :            :     }
        8441                 :            :
        8442                 :            :     /* Set up cells for any variable that escapes, to be put in a closure. */
        8443                 :       8041 :     const int ncellvars = (int)PyDict_GET_SIZE(u->u_cellvars);
        8444         [ +  + ]:       8041 :     if (ncellvars) {
        8445                 :            :         // u->u_cellvars has the cells out of order so we sort them
        8446                 :            :         // before adding the MAKE_CELL instructions.  Note that we
        8447                 :            :         // adjust for arg cells, which come first.
        8448                 :        399 :         const int nvars = ncellvars + (int)PyDict_GET_SIZE(u->u_varnames);
        8449                 :        399 :         int *sorted = PyMem_RawCalloc(nvars, sizeof(int));
        8450         [ -  + ]:        399 :         if (sorted == NULL) {
        8451                 :          0 :             PyErr_NoMemory();
        8452                 :          0 :             return ERROR;
        8453                 :            :         }
        8454         [ +  + ]:       1098 :         for (int i = 0; i < ncellvars; i++) {
        8455                 :        699 :             sorted[fixed[i]] = i + 1;
        8456                 :            :         }
        8457         [ +  + ]:       2146 :         for (int i = 0, ncellsused = 0; ncellsused < ncellvars; i++) {
        8458                 :       1747 :             int oldindex = sorted[i] - 1;
        8459         [ +  + ]:       1747 :             if (oldindex == -1) {
        8460                 :       1048 :                 continue;
        8461                 :            :             }
        8462                 :        699 :             struct cfg_instr make_cell = {
        8463                 :            :                 .i_opcode = MAKE_CELL,
        8464                 :            :                 // This will get fixed in offset_derefs().
        8465                 :            :                 .i_oparg = oldindex,
        8466                 :            :                 .i_loc = NO_LOCATION,
        8467                 :            :                 .i_target = NULL,
        8468                 :            :             };
        8469         [ -  + ]:        699 :             RETURN_IF_ERROR(insert_instruction(entryblock, ncellsused, &make_cell));
        8470                 :        699 :             ncellsused += 1;
        8471                 :            :         }
        8472                 :        399 :         PyMem_RawFree(sorted);
        8473                 :            :     }
        8474                 :            :
        8475         [ +  + ]:       8041 :     if (nfreevars) {
        8476                 :        627 :         struct cfg_instr copy_frees = {
        8477                 :            :             .i_opcode = COPY_FREE_VARS,
        8478                 :            :             .i_oparg = nfreevars,
        8479                 :            :             .i_loc = NO_LOCATION,
        8480                 :            :             .i_target = NULL,
        8481                 :            :         };
        8482         [ -  + ]:        627 :         RETURN_IF_ERROR(insert_instruction(entryblock, 0, &copy_frees));
        8483                 :            :     }
        8484                 :            :
        8485                 :       8041 :     return SUCCESS;
        8486                 :            : }
        8487                 :            :
        8488                 :            : /* Make sure that all returns have a line number, even if early passes
        8489                 :            :  * have failed to propagate a correct line number.
        8490                 :            :  * The resulting line number may not be correct according to PEP 626,
        8491                 :            :  * but should be "good enough", and no worse than in older versions. */
        8492                 :            : static void
        8493                 :       8041 : guarantee_lineno_for_exits(basicblock *entryblock, int firstlineno) {
        8494                 :       8041 :     int lineno = firstlineno;
        8495                 :            :     assert(lineno > 0);
        8496         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        8497                 :      51311 :         struct cfg_instr *last = basicblock_last_instr(b);
        8498         [ -  + ]:      51311 :         if (last == NULL) {
        8499                 :          0 :             continue;
        8500                 :            :         }
        8501         [ +  + ]:      51311 :         if (last->i_loc.lineno < 0) {
        8502         [ -  + ]:       2747 :             if (last->i_opcode == RETURN_VALUE) {
        8503         [ #  # ]:          0 :                 for (int i = 0; i < b->b_iused; i++) {
        8504                 :            :                     assert(b->b_instr[i].i_loc.lineno < 0);
        8505                 :            :
        8506                 :          0 :                     b->b_instr[i].i_loc.lineno = lineno;
        8507                 :            :                 }
        8508                 :            :             }
        8509                 :            :         }
        8510                 :            :         else {
        8511                 :      48564 :             lineno = last->i_loc.lineno;
        8512                 :            :         }
        8513                 :            :     }
        8514                 :       8041 : }
        8515                 :            :
        8516                 :            : static int
        8517                 :       8041 : fix_cell_offsets(struct compiler_unit *u, basicblock *entryblock, int *fixedmap)
        8518                 :            : {
        8519                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
        8520                 :       8041 :     int ncellvars = (int)PyDict_GET_SIZE(u->u_cellvars);
        8521                 :       8041 :     int nfreevars = (int)PyDict_GET_SIZE(u->u_freevars);
        8522                 :       8041 :     int noffsets = ncellvars + nfreevars;
        8523                 :            :
        8524                 :            :     // First deal with duplicates (arg cells).
        8525                 :       8041 :     int numdropped = 0;
        8526         [ +  + ]:       9678 :     for (int i = 0; i < noffsets ; i++) {
        8527         [ +  + ]:       1637 :         if (fixedmap[i] == i + nlocals) {
        8528                 :       1334 :             fixedmap[i] -= numdropped;
        8529                 :            :         }
        8530                 :            :         else {
        8531                 :            :             // It was a duplicate (cell/arg).
        8532                 :        303 :             numdropped += 1;
        8533                 :            :         }
        8534                 :            :     }
        8535                 :            :
        8536                 :            :     // Then update offsets, either relative to locals or by cell2arg.
        8537         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        8538         [ +  + ]:     400486 :         for (int i = 0; i < b->b_iused; i++) {
        8539                 :     349175 :             struct cfg_instr *inst = &b->b_instr[i];
        8540                 :            :             // This is called before extended args are generated.
        8541                 :            :             assert(inst->i_opcode != EXTENDED_ARG);
        8542                 :     349175 :             int oldoffset = inst->i_oparg;
        8543         [ +  + ]:     349175 :             switch(inst->i_opcode) {
        8544                 :       4195 :                 case MAKE_CELL:
        8545                 :            :                 case LOAD_CLOSURE:
        8546                 :            :                 case LOAD_DEREF:
        8547                 :            :                 case STORE_DEREF:
        8548                 :            :                 case DELETE_DEREF:
        8549                 :            :                 case LOAD_CLASSDEREF:
        8550                 :            :                     assert(oldoffset >= 0);
        8551                 :            :                     assert(oldoffset < noffsets);
        8552                 :            :                     assert(fixedmap[oldoffset] >= 0);
        8553                 :       4195 :                     inst->i_oparg = fixedmap[oldoffset];
        8554                 :            :             }
        8555                 :            :         }
        8556                 :            :     }
        8557                 :            :
        8558                 :       8041 :     return numdropped;
        8559                 :            : }
        8560                 :            :
        8561                 :            :
        8562                 :            : #ifndef NDEBUG
        8563                 :            :
        8564                 :            : static bool
        8565                 :            : no_redundant_nops(cfg_builder *g) {
        8566                 :            :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        8567                 :            :         if (remove_redundant_nops(b) != 0) {
        8568                 :            :             return false;
        8569                 :            :         }
        8570                 :            :     }
        8571                 :            :     return true;
        8572                 :            : }
        8573                 :            :
        8574                 :            : static bool
        8575                 :            : no_redundant_jumps(cfg_builder *g) {
        8576                 :            :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        8577                 :            :         struct cfg_instr *last = basicblock_last_instr(b);
        8578                 :            :         if (last != NULL) {
        8579                 :            :             if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
        8580                 :            :                 assert(last->i_target != b->b_next);
        8581                 :            :                 if (last->i_target == b->b_next) {
        8582                 :            :                     return false;
        8583                 :            :                 }
        8584                 :            :             }
        8585                 :            :         }
        8586                 :            :     }
        8587                 :            :     return true;
        8588                 :            : }
        8589                 :            :
        8590                 :            : static bool
        8591                 :            : opcode_metadata_is_sane(cfg_builder *g) {
        8592                 :            :     bool result = true;
        8593                 :            :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        8594                 :            :         for (int i = 0; i < b->b_iused; i++) {
        8595                 :            :             struct cfg_instr *instr = &b->b_instr[i];
        8596                 :            :             int opcode = instr->i_opcode;
        8597                 :            :             int oparg = instr->i_oparg;
        8598                 :            :             assert(opcode <= MAX_REAL_OPCODE);
        8599                 :            :             for (int jump = 0; jump <= 1; jump++) {
        8600                 :            :                 int popped = _PyOpcode_num_popped(opcode, oparg, jump ? true : false);
        8601                 :            :                 int pushed = _PyOpcode_num_pushed(opcode, oparg, jump ? true : false);
        8602                 :            :                 assert((pushed < 0) == (popped < 0));
        8603                 :            :                 if (pushed >= 0) {
        8604                 :            :                     assert(_PyOpcode_opcode_metadata[opcode].valid_entry);
        8605                 :            :                     int effect = stack_effect(opcode, instr->i_oparg, jump);
        8606                 :            :                     if (effect != pushed - popped) {
        8607                 :            :                        fprintf(stderr,
        8608                 :            :                                "op=%d arg=%d jump=%d: stack_effect (%d) != pushed (%d) - popped (%d)\n",
        8609                 :            :                                opcode, oparg, jump, effect, pushed, popped);
        8610                 :            :                        result = false;
        8611                 :            :                     }
        8612                 :            :                 }
        8613                 :            :             }
        8614                 :            :         }
        8615                 :            :     }
        8616                 :            :     return result;
        8617                 :            : }
        8618                 :            :
        8619                 :            : static bool
        8620                 :            : no_empty_basic_blocks(cfg_builder *g) {
        8621                 :            :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        8622                 :            :         if (b->b_iused == 0) {
        8623                 :            :             return false;
        8624                 :            :         }
        8625                 :            :     }
        8626                 :            :     return true;
        8627                 :            : }
        8628                 :            : #endif
        8629                 :            :
        8630                 :            : static int
        8631                 :       9640 : remove_redundant_jumps(cfg_builder *g) {
        8632                 :            :     /* If a non-empty block ends with a jump instruction, check if the next
        8633                 :            :      * non-empty block reached through normal flow control is the target
        8634                 :            :      * of that jump. If it is, then the jump instruction is redundant and
        8635                 :            :      * can be deleted.
        8636                 :            :      */
        8637                 :            :     assert(no_empty_basic_blocks(g));
        8638         [ +  + ]:      87571 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        8639                 :      77931 :         struct cfg_instr *last = basicblock_last_instr(b);
        8640                 :            :         assert(last != NULL);
        8641                 :            :         assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
        8642   [ +  +  +  +  :      77931 :         if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
              +  -  +  -  -
                          + ]
        8643         [ -  + ]:       9591 :             if (last->i_target == NULL) {
        8644                 :          0 :                 PyErr_SetString(PyExc_SystemError, "jump with NULL target");
        8645                 :          0 :                 return ERROR;
        8646                 :            :             }
        8647         [ +  + ]:       9591 :             if (last->i_target == b->b_next) {
        8648                 :            :                 assert(b->b_next->b_iused);
        8649                 :        871 :                 INSTR_SET_OP0(last, NOP);
        8650                 :            :             }
        8651                 :            :         }
        8652                 :            :     }
        8653                 :       9640 :     return SUCCESS;
        8654                 :            : }
        8655                 :            :
        8656                 :            : static int
        8657                 :       8041 : prepare_localsplus(struct compiler_unit* u, cfg_builder *g, int code_flags)
        8658                 :            : {
        8659                 :            :     assert(PyDict_GET_SIZE(u->u_varnames) < INT_MAX);
        8660                 :            :     assert(PyDict_GET_SIZE(u->u_cellvars) < INT_MAX);
        8661                 :            :     assert(PyDict_GET_SIZE(u->u_freevars) < INT_MAX);
        8662                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
        8663                 :       8041 :     int ncellvars = (int)PyDict_GET_SIZE(u->u_cellvars);
        8664                 :       8041 :     int nfreevars = (int)PyDict_GET_SIZE(u->u_freevars);
        8665                 :            :     assert(INT_MAX - nlocals - ncellvars > 0);
        8666                 :            :     assert(INT_MAX - nlocals - ncellvars - nfreevars > 0);
        8667                 :       8041 :     int nlocalsplus = nlocals + ncellvars + nfreevars;
        8668                 :       8041 :     int* cellfixedoffsets = build_cellfixedoffsets(u);
        8669         [ -  + ]:       8041 :     if (cellfixedoffsets == NULL) {
        8670                 :          0 :         return ERROR;
        8671                 :            :     }
        8672                 :            :
        8673                 :            :
        8674                 :            :     // This must be called before fix_cell_offsets().
        8675         [ -  + ]:       8041 :     if (insert_prefix_instructions(u, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) {
        8676                 :          0 :         PyMem_Free(cellfixedoffsets);
        8677                 :          0 :         return ERROR;
        8678                 :            :     }
        8679                 :            :
        8680                 :       8041 :     int numdropped = fix_cell_offsets(u, g->g_entryblock, cellfixedoffsets);
        8681                 :       8041 :     PyMem_Free(cellfixedoffsets);  // At this point we're done with it.
        8682                 :       8041 :     cellfixedoffsets = NULL;
        8683         [ -  + ]:       8041 :     if (numdropped < 0) {
        8684                 :          0 :         return ERROR;
        8685                 :            :     }
        8686                 :            :
        8687                 :       8041 :     nlocalsplus -= numdropped;
        8688                 :       8041 :     return nlocalsplus;
        8689                 :            : }
        8690                 :            :
        8691                 :            : static int
        8692                 :       8041 : add_return_at_end(struct compiler *c, int addNone)
        8693                 :            : {
        8694                 :            :     /* Make sure every instruction stream that falls off the end returns None.
        8695                 :            :      * This also ensures that no jump target offsets are out of bounds.
        8696                 :            :      */
        8697         [ +  + ]:       8041 :     if (addNone) {
        8698         [ -  + ]:       7982 :         ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
        8699                 :            :     }
        8700         [ -  + ]:       8041 :     ADDOP(c, NO_LOCATION, RETURN_VALUE);
        8701                 :       8041 :     return SUCCESS;
        8702                 :            : }
        8703                 :            :
        8704                 :            : static void propagate_line_numbers(basicblock *entryblock);
        8705                 :            :
        8706                 :            : static int
        8707                 :       8041 : resolve_line_numbers(struct compiler_unit *u, cfg_builder *g)
        8708                 :            : {
        8709                 :            :     /* Set firstlineno if it wasn't explicitly set. */
        8710         [ -  + ]:       8041 :     if (!u->u_firstlineno) {
        8711   [ #  #  #  # ]:          0 :         if (g->g_entryblock->b_instr && g->g_entryblock->b_instr->i_loc.lineno) {
        8712                 :          0 :             u->u_firstlineno = g->g_entryblock->b_instr->i_loc.lineno;
        8713                 :            :         }
        8714                 :            :         else {
        8715                 :          0 :             u->u_firstlineno = 1;
        8716                 :            :         }
        8717                 :            :     }
        8718         [ -  + ]:       8041 :     RETURN_IF_ERROR(duplicate_exits_without_lineno(g));
        8719                 :       8041 :     propagate_line_numbers(g->g_entryblock);
        8720                 :       8041 :     guarantee_lineno_for_exits(g->g_entryblock, u->u_firstlineno);
        8721                 :       8041 :     return SUCCESS;
        8722                 :            : }
        8723                 :            :
        8724                 :            : static int
        8725                 :       8041 : optimize_code_unit(cfg_builder *g, PyObject *consts, PyObject *const_cache,
        8726                 :            :                    int code_flags, int nlocals, int nparams)
        8727                 :            : {
        8728                 :            :     assert(cfg_builder_check(g));
        8729                 :            :     /** Preprocessing **/
        8730                 :            :     /* Map labels to targets and mark exception handlers */
        8731         [ -  + ]:       8041 :     RETURN_IF_ERROR(translate_jump_labels_to_targets(g->g_entryblock));
        8732         [ -  + ]:       8041 :     RETURN_IF_ERROR(mark_except_handlers(g->g_entryblock));
        8733         [ -  + ]:       8041 :     RETURN_IF_ERROR(label_exception_targets(g->g_entryblock));
        8734                 :            :
        8735                 :            :     /** Optimization **/
        8736         [ -  + ]:       8041 :     RETURN_IF_ERROR(optimize_cfg(g, consts, const_cache));
        8737         [ -  + ]:       8041 :     RETURN_IF_ERROR(remove_unused_consts(g->g_entryblock, consts));
        8738         [ -  + ]:       8041 :     RETURN_IF_ERROR(
        8739                 :            :         add_checks_for_loads_of_uninitialized_variables(
        8740                 :            :             g->g_entryblock, nlocals, nparams));
        8741                 :            :
        8742         [ -  + ]:       8041 :     RETURN_IF_ERROR(push_cold_blocks_to_end(g, code_flags));
        8743                 :       8041 :     return SUCCESS;
        8744                 :            : }
        8745                 :            :
        8746                 :            : static PyCodeObject *
        8747                 :       8041 : assemble_code_unit(struct compiler_unit *u, PyObject *const_cache,
        8748                 :            :                    int code_flags, PyObject *filename)
        8749                 :            : {
        8750                 :       8041 :     PyCodeObject *co = NULL;
        8751                 :       8041 :     PyObject *consts = consts_dict_keys_inorder(u->u_consts);
        8752         [ -  + ]:       8041 :     if (consts == NULL) {
        8753                 :          0 :         goto error;
        8754                 :            :     }
        8755                 :            :     cfg_builder g;
        8756         [ -  + ]:       8041 :     if (instr_sequence_to_cfg(&u->u_instr_sequence, &g) < 0) {
        8757                 :          0 :         goto error;
        8758                 :            :     }
        8759                 :       8041 :     int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames);
        8760                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
        8761         [ -  + ]:       8041 :     if (optimize_code_unit(&g, consts, const_cache, code_flags, nlocals, nparams) < 0) {
        8762                 :          0 :         goto error;
        8763                 :            :     }
        8764                 :            :
        8765                 :            :     /** Assembly **/
        8766                 :            :
        8767         [ -  + ]:       8041 :     if (resolve_line_numbers(u, &g) < 0) {
        8768                 :          0 :         goto error;
        8769                 :            :     }
        8770                 :            :
        8771                 :       8041 :     int nlocalsplus = prepare_localsplus(u, &g, code_flags);
        8772         [ -  + ]:       8041 :     if (nlocalsplus < 0) {
        8773                 :          0 :         goto error;
        8774                 :            :     }
        8775                 :            :
        8776                 :       8041 :     int maxdepth = stackdepth(g.g_entryblock, code_flags);
        8777         [ -  + ]:       8041 :     if (maxdepth < 0) {
        8778                 :          0 :         goto error;
        8779                 :            :     }
        8780                 :            :     /* TO DO -- For 3.12, make sure that `maxdepth <= MAX_ALLOWED_STACK_USE` */
        8781                 :            :
        8782                 :       8041 :     convert_exception_handlers_to_nops(g.g_entryblock);
        8783                 :            :
        8784                 :            :     /* Order of basic blocks must have been determined by now */
        8785         [ -  + ]:       8041 :     if (normalize_jumps(&g) < 0) {
        8786                 :          0 :         goto error;
        8787                 :            :     }
        8788                 :            :     assert(no_redundant_jumps(&g));
        8789                 :            :     assert(opcode_metadata_is_sane(&g));
        8790                 :            :
        8791                 :            :     /* Can't modify the bytecode after computing jump offsets. */
        8792                 :       8041 :     assemble_jump_offsets(g.g_entryblock);
        8793                 :            :
        8794                 :            :     struct assembler a;
        8795                 :       8041 :     int res = assemble_emit(&a, g.g_entryblock, u->u_firstlineno, const_cache);
        8796         [ +  - ]:       8041 :     if (res == SUCCESS) {
        8797                 :       8041 :         co = makecode(u, &a, const_cache, consts, maxdepth, nlocalsplus,
        8798                 :            :                       code_flags, filename);
        8799                 :            :     }
        8800                 :       8041 :     assemble_free(&a);
        8801                 :            :
        8802                 :       8041 :  error:
        8803                 :       8041 :     Py_XDECREF(consts);
        8804                 :       8041 :     cfg_builder_fini(&g);
        8805                 :       8041 :     return co;
        8806                 :            : }
        8807                 :            :
        8808                 :            : static PyCodeObject *
        8809                 :       8041 : assemble(struct compiler *c, int addNone)
        8810                 :            : {
        8811                 :       8041 :     struct compiler_unit *u = c->u;
        8812                 :       8041 :     PyObject *const_cache = c->c_const_cache;
        8813                 :       8041 :     PyObject *filename = c->c_filename;
        8814                 :            :
        8815                 :       8041 :     int code_flags = compute_code_flags(c);
        8816         [ -  + ]:       8041 :     if (code_flags < 0) {
        8817                 :          0 :         return NULL;
        8818                 :            :     }
        8819                 :            :
        8820         [ -  + ]:       8041 :     if (add_return_at_end(c, addNone) < 0) {
        8821                 :          0 :         return NULL;
        8822                 :            :     }
        8823                 :            :
        8824                 :       8041 :     return assemble_code_unit(u, const_cache, code_flags, filename);
        8825                 :            : }
        8826                 :            :
        8827                 :            : static PyObject*
        8828                 :       3579 : get_const_value(int opcode, int oparg, PyObject *co_consts)
        8829                 :            : {
        8830                 :       3579 :     PyObject *constant = NULL;
        8831                 :            :     assert(HAS_CONST(opcode));
        8832         [ +  - ]:       3579 :     if (opcode == LOAD_CONST) {
        8833                 :       3579 :         constant = PyList_GET_ITEM(co_consts, oparg);
        8834                 :            :     }
        8835                 :            :
        8836         [ -  + ]:       3579 :     if (constant == NULL) {
        8837                 :          0 :         PyErr_SetString(PyExc_SystemError,
        8838                 :            :                         "Internal error: failed to get value of a constant");
        8839                 :          0 :         return NULL;
        8840                 :            :     }
        8841                 :       3579 :     return Py_NewRef(constant);
        8842                 :            : }
        8843                 :            :
        8844                 :            : /* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n
        8845                 :            :    with    LOAD_CONST (c1, c2, ... cn).
        8846                 :            :    The consts table must still be in list form so that the
        8847                 :            :    new constant (c1, c2, ... cn) can be appended.
        8848                 :            :    Called with codestr pointing to the first LOAD_CONST.
        8849                 :            : */
        8850                 :            : static int
        8851                 :       3656 : fold_tuple_on_constants(PyObject *const_cache,
        8852                 :            :                         struct cfg_instr *inst,
        8853                 :            :                         int n, PyObject *consts)
        8854                 :            : {
        8855                 :            :     /* Pre-conditions */
        8856                 :            :     assert(PyDict_CheckExact(const_cache));
        8857                 :            :     assert(PyList_CheckExact(consts));
        8858                 :            :     assert(inst[n].i_opcode == BUILD_TUPLE);
        8859                 :            :     assert(inst[n].i_oparg == n);
        8860                 :            :
        8861         [ +  + ]:       5606 :     for (int i = 0; i < n; i++) {
        8862   [ +  +  +  -  :       4706 :         if (!HAS_CONST(inst[i].i_opcode)) {
                       +  + ]
        8863                 :       2756 :             return SUCCESS;
        8864                 :            :         }
        8865                 :            :     }
        8866                 :            :
        8867                 :            :     /* Buildup new tuple of constants */
        8868                 :        900 :     PyObject *newconst = PyTuple_New(n);
        8869         [ -  + ]:        900 :     if (newconst == NULL) {
        8870                 :          0 :         return ERROR;
        8871                 :            :     }
        8872         [ +  + ]:       2412 :     for (int i = 0; i < n; i++) {
        8873                 :       1512 :         int op = inst[i].i_opcode;
        8874                 :       1512 :         int arg = inst[i].i_oparg;
        8875                 :       1512 :         PyObject *constant = get_const_value(op, arg, consts);
        8876         [ -  + ]:       1512 :         if (constant == NULL) {
        8877                 :          0 :             return ERROR;
        8878                 :            :         }
        8879                 :       1512 :         PyTuple_SET_ITEM(newconst, i, constant);
        8880                 :            :     }
        8881         [ -  + ]:        900 :     if (merge_const_one(const_cache, &newconst) < 0) {
        8882                 :          0 :         Py_DECREF(newconst);
        8883                 :          0 :         return ERROR;
        8884                 :            :     }
        8885                 :            :
        8886                 :            :     Py_ssize_t index;
        8887         [ +  + ]:      60079 :     for (index = 0; index < PyList_GET_SIZE(consts); index++) {
        8888         [ +  + ]:      59427 :         if (PyList_GET_ITEM(consts, index) == newconst) {
        8889                 :        248 :             break;
        8890                 :            :         }
        8891                 :            :     }
        8892         [ +  + ]:        900 :     if (index == PyList_GET_SIZE(consts)) {
        8893         [ -  + ]:        652 :         if ((size_t)index >= (size_t)INT_MAX - 1) {
        8894                 :          0 :             Py_DECREF(newconst);
        8895                 :          0 :             PyErr_SetString(PyExc_OverflowError, "too many constants");
        8896                 :          0 :             return ERROR;
        8897                 :            :         }
        8898         [ -  + ]:        652 :         if (PyList_Append(consts, newconst)) {
        8899                 :          0 :             Py_DECREF(newconst);
        8900                 :          0 :             return ERROR;
        8901                 :            :         }
        8902                 :            :     }
        8903                 :        900 :     Py_DECREF(newconst);
        8904         [ +  + ]:       2412 :     for (int i = 0; i < n; i++) {
        8905                 :       1512 :         INSTR_SET_OP0(&inst[i], NOP);
        8906                 :            :     }
        8907                 :        900 :     INSTR_SET_OP1(&inst[n], LOAD_CONST, (int)index);
        8908                 :        900 :     return SUCCESS;
        8909                 :            : }
        8910                 :            :
        8911                 :            : #define VISITED (-1)
        8912                 :            :
        8913                 :            : // Replace an arbitrary run of SWAPs and NOPs with an optimal one that has the
        8914                 :            : // same effect.
        8915                 :            : static int
        8916                 :        774 : swaptimize(basicblock *block, int *ix)
        8917                 :            : {
        8918                 :            :     // NOTE: "./python -m test test_patma" serves as a good, quick stress test
        8919                 :            :     // for this function. Make sure to blow away cached *.pyc files first!
        8920                 :            :     assert(*ix < block->b_iused);
        8921                 :        774 :     struct cfg_instr *instructions = &block->b_instr[*ix];
        8922                 :            :     // Find the length of the current sequence of SWAPs and NOPs, and record the
        8923                 :            :     // maximum depth of the stack manipulations:
        8924                 :            :     assert(instructions[0].i_opcode == SWAP);
        8925                 :        774 :     int depth = instructions[0].i_oparg;
        8926                 :        774 :     int len = 0;
        8927                 :        774 :     int more = false;
        8928                 :        774 :     int limit = block->b_iused - *ix;
        8929         [ +  - ]:        792 :     while (++len < limit) {
        8930                 :        792 :         int opcode = instructions[len].i_opcode;
        8931         [ +  + ]:        792 :         if (opcode == SWAP) {
        8932                 :         18 :             depth = Py_MAX(depth, instructions[len].i_oparg);
        8933                 :         18 :             more = true;
        8934                 :            :         }
        8935         [ +  - ]:        774 :         else if (opcode != NOP) {
        8936                 :        774 :             break;
        8937                 :            :         }
        8938                 :            :     }
        8939                 :            :     // It's already optimal if there's only one SWAP:
        8940         [ +  + ]:        774 :     if (!more) {
        8941                 :        756 :         return SUCCESS;
        8942                 :            :     }
        8943                 :            :     // Create an array with elements {0, 1, 2, ..., depth - 1}:
        8944                 :         18 :     int *stack = PyMem_Malloc(depth * sizeof(int));
        8945         [ -  + ]:         18 :     if (stack == NULL) {
        8946                 :          0 :         PyErr_NoMemory();
        8947                 :          0 :         return ERROR;
        8948                 :            :     }
        8949         [ +  + ]:         72 :     for (int i = 0; i < depth; i++) {
        8950                 :         54 :         stack[i] = i;
        8951                 :            :     }
        8952                 :            :     // Simulate the combined effect of these instructions by "running" them on
        8953                 :            :     // our "stack":
        8954         [ +  + ]:         54 :     for (int i = 0; i < len; i++) {
        8955         [ +  - ]:         36 :         if (instructions[i].i_opcode == SWAP) {
        8956                 :         36 :             int oparg = instructions[i].i_oparg;
        8957                 :         36 :             int top = stack[0];
        8958                 :            :             // SWAPs are 1-indexed:
        8959                 :         36 :             stack[0] = stack[oparg - 1];
        8960                 :         36 :             stack[oparg - 1] = top;
        8961                 :            :         }
        8962                 :            :     }
        8963                 :            :     // Now we can begin! Our approach here is based on a solution to a closely
        8964                 :            :     // related problem (https://cs.stackexchange.com/a/13938). It's easiest to
        8965                 :            :     // think of this algorithm as determining the steps needed to efficiently
        8966                 :            :     // "un-shuffle" our stack. By performing the moves in *reverse* order,
        8967                 :            :     // though, we can efficiently *shuffle* it! For this reason, we will be
        8968                 :            :     // replacing instructions starting from the *end* of the run. Since the
        8969                 :            :     // solution is optimal, we don't need to worry about running out of space:
        8970                 :         18 :     int current = len - 1;
        8971         [ +  + ]:         72 :     for (int i = 0; i < depth; i++) {
        8972                 :            :         // Skip items that have already been visited, or just happen to be in
        8973                 :            :         // the correct location:
        8974   [ +  +  -  + ]:         54 :         if (stack[i] == VISITED || stack[i] == i) {
        8975                 :         36 :             continue;
        8976                 :            :         }
        8977                 :            :         // Okay, we've found an item that hasn't been visited. It forms a cycle
        8978                 :            :         // with other items; traversing the cycle and swapping each item with
        8979                 :            :         // the next will put them all in the correct place. The weird
        8980                 :            :         // loop-and-a-half is necessary to insert 0 into every cycle, since we
        8981                 :            :         // can only swap from that position:
        8982                 :         18 :         int j = i;
        8983                 :         54 :         while (true) {
        8984                 :            :             // Skip the actual swap if our item is zero, since swapping the top
        8985                 :            :             // item with itself is pointless:
        8986         [ +  + ]:         72 :             if (j) {
        8987                 :            :                 assert(0 <= current);
        8988                 :            :                 // SWAPs are 1-indexed:
        8989                 :         36 :                 instructions[current].i_opcode = SWAP;
        8990                 :         36 :                 instructions[current--].i_oparg = j + 1;
        8991                 :            :             }
        8992         [ +  + ]:         72 :             if (stack[j] == VISITED) {
        8993                 :            :                 // Completed the cycle:
        8994                 :            :                 assert(j == i);
        8995                 :         18 :                 break;
        8996                 :            :             }
        8997                 :         54 :             int next_j = stack[j];
        8998                 :         54 :             stack[j] = VISITED;
        8999                 :         54 :             j = next_j;
        9000                 :            :         }
        9001                 :            :     }
        9002                 :            :     // NOP out any unused instructions:
        9003         [ -  + ]:         18 :     while (0 <= current) {
        9004                 :          0 :         INSTR_SET_OP0(&instructions[current--], NOP);
        9005                 :            :     }
        9006                 :         18 :     PyMem_Free(stack);
        9007                 :         18 :     *ix += len - 1;
        9008                 :         18 :     return SUCCESS;
        9009                 :            : }
        9010                 :            :
        9011                 :            : // This list is pretty small, since it's only okay to reorder opcodes that:
        9012                 :            : // - can't affect control flow (like jumping or raising exceptions)
        9013                 :            : // - can't invoke arbitrary code (besides finalizers)
        9014                 :            : // - only touch the TOS (and pop it when finished)
        9015                 :            : #define SWAPPABLE(opcode) \
        9016                 :            :     ((opcode) == STORE_FAST || (opcode) == POP_TOP)
        9017                 :            :
        9018                 :            : static int
        9019                 :       1174 : next_swappable_instruction(basicblock *block, int i, int lineno)
        9020                 :            : {
        9021         [ +  + ]:       1174 :     while (++i < block->b_iused) {
        9022                 :       1170 :         struct cfg_instr *instruction = &block->b_instr[i];
        9023   [ +  +  +  + ]:       1170 :         if (0 <= lineno && instruction->i_loc.lineno != lineno) {
        9024                 :            :             // Optimizing across this instruction could cause user-visible
        9025                 :            :             // changes in the names bound between line tracing events!
        9026                 :        120 :             return -1;
        9027                 :            :         }
        9028         [ -  + ]:       1050 :         if (instruction->i_opcode == NOP) {
        9029                 :          0 :             continue;
        9030                 :            :         }
        9031   [ +  +  +  + ]:       1050 :         if (SWAPPABLE(instruction->i_opcode)) {
        9032                 :        528 :             return i;
        9033                 :            :         }
        9034                 :        522 :         return -1;
        9035                 :            :     }
        9036                 :          4 :     return -1;
        9037                 :            : }
        9038                 :            :
        9039                 :            : // Attempt to apply SWAPs statically by swapping *instructions* rather than
        9040                 :            : // stack items. For example, we can replace SWAP(2), POP_TOP, STORE_FAST(42)
        9041                 :            : // with the more efficient NOP, STORE_FAST(42), POP_TOP.
        9042                 :            : static void
        9043                 :        774 : apply_static_swaps(basicblock *block, int i)
        9044                 :            : {
        9045                 :            :     // SWAPs are to our left, and potential swaperands are to our right:
        9046         [ +  + ]:       1002 :     for (; 0 <= i; i--) {
        9047                 :            :         assert(i < block->b_iused);
        9048                 :        974 :         struct cfg_instr *swap = &block->b_instr[i];
        9049         [ +  + ]:        974 :         if (swap->i_opcode != SWAP) {
        9050   [ +  +  +  -  :        200 :             if (swap->i_opcode == NOP || SWAPPABLE(swap->i_opcode)) {
                       -  + ]
        9051                 :            :                 // Nope, but we know how to handle these. Keep looking:
        9052                 :        100 :                 continue;
        9053                 :            :             }
        9054                 :            :             // We can't reason about what this instruction does. Bail:
        9055                 :        746 :             return;
        9056                 :            :         }
        9057                 :        774 :         int j = next_swappable_instruction(block, i, -1);
        9058         [ +  + ]:        774 :         if (j < 0) {
        9059                 :        390 :             return;
        9060                 :            :         }
        9061                 :        384 :         int k = j;
        9062                 :        384 :         int lineno = block->b_instr[j].i_loc.lineno;
        9063         [ +  + ]:        528 :         for (int count = swap->i_oparg - 1; 0 < count; count--) {
        9064                 :        400 :             k = next_swappable_instruction(block, k, lineno);
        9065         [ +  + ]:        400 :             if (k < 0) {
        9066                 :        256 :                 return;
        9067                 :            :             }
        9068                 :            :         }
        9069                 :            :         // Success!
        9070                 :        128 :         INSTR_SET_OP0(swap, NOP);
        9071                 :        128 :         struct cfg_instr temp = block->b_instr[j];
        9072                 :        128 :         block->b_instr[j] = block->b_instr[k];
        9073                 :        128 :         block->b_instr[k] = temp;
        9074                 :            :     }
        9075                 :            : }
        9076                 :            :
        9077                 :            : // Attempt to eliminate jumps to jumps by updating inst to jump to
        9078                 :            : // target->i_target using the provided opcode. Return whether or not the
        9079                 :            : // optimization was successful.
        9080                 :            : static bool
        9081                 :       1741 : jump_thread(struct cfg_instr *inst, struct cfg_instr *target, int opcode)
        9082                 :            : {
        9083                 :            :     assert(is_jump(inst));
        9084                 :            :     assert(is_jump(target));
        9085                 :            :     // bpo-45773: If inst->i_target == target->i_target, then nothing actually
        9086                 :            :     // changes (and we fall into an infinite loop):
        9087   [ +  +  +  + ]:       1741 :     if ((inst->i_loc.lineno == target->i_loc.lineno || target->i_loc.lineno == -1) &&
        9088         [ +  - ]:       1686 :         inst->i_target != target->i_target)
        9089                 :            :     {
        9090                 :       1686 :         inst->i_target = target->i_target;
        9091                 :       1686 :         inst->i_opcode = opcode;
        9092                 :       1686 :         return true;
        9093                 :            :     }
        9094                 :         55 :     return false;
        9095                 :            : }
        9096                 :            :
        9097                 :            : /* Maximum size of basic block that should be copied in optimizer */
        9098                 :            : #define MAX_COPY_SIZE 4
        9099                 :            :
        9100                 :            : /* Optimization */
        9101                 :            : static int
        9102                 :      58917 : optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
        9103                 :            : {
        9104                 :            :     assert(PyDict_CheckExact(const_cache));
        9105                 :            :     assert(PyList_CheckExact(consts));
        9106                 :            :     struct cfg_instr nop;
        9107                 :      58917 :     INSTR_SET_OP0(&nop, NOP);
        9108                 :            :     struct cfg_instr *target;
        9109         [ +  + ]:     439462 :     for (int i = 0; i < bb->b_iused; i++) {
        9110                 :     380545 :         struct cfg_instr *inst = &bb->b_instr[i];
        9111                 :     380545 :         int oparg = inst->i_oparg;
        9112         [ +  + ]:     380545 :         int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
        9113   [ +  +  +  +  :     380545 :         if (HAS_TARGET(inst->i_opcode)) {
                 +  +  +  + ]
        9114                 :            :             assert(inst->i_target->b_iused > 0);
        9115                 :      29208 :             target = &inst->i_target->b_instr[0];
        9116                 :      29208 :             assert(!IS_ASSEMBLER_OPCODE(target->i_opcode));
        9117                 :            :         }
        9118                 :            :         else {
        9119                 :     351337 :             target = &nop;
        9120                 :            :         }
        9121                 :            :         assert(!IS_ASSEMBLER_OPCODE(inst->i_opcode));
        9122   [ +  +  +  +  :     380545 :         switch (inst->i_opcode) {
              +  +  +  +  +
                 +  +  +  + ]
        9123                 :            :             /* Remove LOAD_CONST const; conditional jump */
        9124   [ +  -  +  +  :      59096 :             case LOAD_CONST:
                          + ]
        9125                 :            :             {
        9126                 :            :                 PyObject* cnt;
        9127                 :            :                 int is_true;
        9128                 :            :                 int jump_if_true;
        9129                 :            :                 switch(nextop) {
        9130                 :        225 :                     case POP_JUMP_IF_FALSE:
        9131                 :            :                     case POP_JUMP_IF_TRUE:
        9132                 :        225 :                         cnt = get_const_value(inst->i_opcode, oparg, consts);
        9133         [ -  + ]:        225 :                         if (cnt == NULL) {
        9134                 :          0 :                             goto error;
        9135                 :            :                         }
        9136                 :        225 :                         is_true = PyObject_IsTrue(cnt);
        9137                 :        225 :                         Py_DECREF(cnt);
        9138         [ -  + ]:        225 :                         if (is_true == -1) {
        9139                 :          0 :                             goto error;
        9140                 :            :                         }
        9141                 :        225 :                         INSTR_SET_OP0(inst, NOP);
        9142                 :        225 :                         jump_if_true = nextop == POP_JUMP_IF_TRUE;
        9143         [ +  + ]:        225 :                         if (is_true == jump_if_true) {
        9144                 :        111 :                             bb->b_instr[i+1].i_opcode = JUMP;
        9145                 :            :                         }
        9146                 :            :                         else {
        9147                 :        114 :                             INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
        9148                 :            :                         }
        9149                 :        225 :                         break;
        9150                 :          0 :                     case JUMP_IF_FALSE_OR_POP:
        9151                 :            :                     case JUMP_IF_TRUE_OR_POP:
        9152                 :          0 :                         cnt = get_const_value(inst->i_opcode, oparg, consts);
        9153         [ #  # ]:          0 :                         if (cnt == NULL) {
        9154                 :          0 :                             goto error;
        9155                 :            :                         }
        9156                 :          0 :                         is_true = PyObject_IsTrue(cnt);
        9157                 :          0 :                         Py_DECREF(cnt);
        9158         [ #  # ]:          0 :                         if (is_true == -1) {
        9159                 :          0 :                             goto error;
        9160                 :            :                         }
        9161                 :          0 :                         jump_if_true = nextop == JUMP_IF_TRUE_OR_POP;
        9162         [ #  # ]:          0 :                         if (is_true == jump_if_true) {
        9163                 :          0 :                             bb->b_instr[i+1].i_opcode = JUMP;
        9164                 :            :                         }
        9165                 :            :                         else {
        9166                 :          0 :                             INSTR_SET_OP0(inst, NOP);
        9167                 :          0 :                             INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
        9168                 :            :                         }
        9169                 :          0 :                         break;
        9170                 :       1842 :                     case IS_OP:
        9171                 :       1842 :                         cnt = get_const_value(inst->i_opcode, oparg, consts);
        9172         [ -  + ]:       1842 :                         if (cnt == NULL) {
        9173                 :          0 :                             goto error;
        9174                 :            :                         }
        9175         [ +  + ]:       1842 :                         int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0;
        9176   [ +  +  +  +  :       1842 :                         if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) {
                       +  + ]
        9177                 :       1776 :                             unsigned char nextarg = bb->b_instr[i+1].i_oparg;
        9178                 :       1776 :                             INSTR_SET_OP0(inst, NOP);
        9179                 :       1776 :                             INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
        9180                 :       1776 :                             bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ?
        9181         [ +  + ]:       1776 :                                     POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE;
        9182                 :            :                         }
        9183                 :       1842 :                         Py_DECREF(cnt);
        9184                 :       1842 :                         break;
        9185                 :      11689 :                     case RETURN_VALUE:
        9186                 :      11689 :                         INSTR_SET_OP0(inst, NOP);
        9187                 :      11689 :                         INSTR_SET_OP1(&bb->b_instr[++i], RETURN_CONST, oparg);
        9188                 :      11689 :                         break;
        9189                 :            :                 }
        9190                 :      59096 :                 break;
        9191                 :            :             }
        9192                 :            :
        9193                 :            :                 /* Try to fold tuples of constants.
        9194                 :            :                    Skip over BUILD_TUPLE(1) UNPACK_SEQUENCE(1).
        9195                 :            :                    Replace BUILD_TUPLE(2) UNPACK_SEQUENCE(2) with SWAP(2).
        9196                 :            :                    Replace BUILD_TUPLE(3) UNPACK_SEQUENCE(3) with SWAP(3). */
        9197                 :       3790 :             case BUILD_TUPLE:
        9198   [ +  +  +  - ]:       3790 :                 if (nextop == UNPACK_SEQUENCE && oparg == bb->b_instr[i+1].i_oparg) {
        9199                 :            :                     switch(oparg) {
        9200                 :          0 :                         case 1:
        9201                 :          0 :                             INSTR_SET_OP0(inst, NOP);
        9202                 :          0 :                             INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
        9203                 :          0 :                             continue;
        9204                 :        116 :                         case 2:
        9205                 :            :                         case 3:
        9206                 :        116 :                             INSTR_SET_OP0(inst, NOP);
        9207                 :        116 :                             bb->b_instr[i+1].i_opcode = SWAP;
        9208                 :        116 :                             continue;
        9209                 :            :                     }
        9210                 :            :                 }
        9211         [ +  + ]:       3674 :                 if (i >= oparg) {
        9212         [ -  + ]:       3656 :                     if (fold_tuple_on_constants(const_cache, inst-oparg, oparg, consts)) {
        9213                 :          0 :                         goto error;
        9214                 :            :                     }
        9215                 :            :                 }
        9216                 :       3674 :                 break;
        9217                 :            :
        9218                 :            :                 /* Simplify conditional jump to conditional jump where the
        9219                 :            :                    result of the first test implies the success of a similar
        9220                 :            :                    test or the failure of the opposite test.
        9221                 :            :                    Arises in code like:
        9222                 :            :                    "a and b or c"
        9223                 :            :                    "(a and b) and c"
        9224                 :            :                    "(a or b) or c"
        9225                 :            :                    "(a or b) and c"
        9226                 :            :                    x:JUMP_IF_FALSE_OR_POP y   y:JUMP_IF_FALSE_OR_POP z
        9227                 :            :                       -->  x:JUMP_IF_FALSE_OR_POP z
        9228                 :            :                    x:JUMP_IF_FALSE_OR_POP y   y:JUMP_IF_TRUE_OR_POP z
        9229                 :            :                       -->  x:POP_JUMP_IF_FALSE y+1
        9230                 :            :                    where y+1 is the instruction following the second test.
        9231                 :            :                 */
        9232                 :        198 :             case JUMP_IF_FALSE_OR_POP:
        9233   [ -  -  +  + ]:        198 :                 switch (target->i_opcode) {
        9234                 :          0 :                     case POP_JUMP_IF_FALSE:
        9235                 :          0 :                         i -= jump_thread(inst, target, POP_JUMP_IF_FALSE);
        9236                 :          0 :                         break;
        9237                 :          0 :                     case JUMP:
        9238                 :            :                     case JUMP_IF_FALSE_OR_POP:
        9239                 :          0 :                         i -= jump_thread(inst, target, JUMP_IF_FALSE_OR_POP);
        9240                 :          0 :                         break;
        9241                 :         23 :                     case JUMP_IF_TRUE_OR_POP:
        9242                 :            :                     case POP_JUMP_IF_TRUE:
        9243         [ +  + ]:         23 :                         if (inst->i_loc.lineno == target->i_loc.lineno) {
        9244                 :            :                             // We don't need to bother checking for loops here,
        9245                 :            :                             // since a block's b_next cannot point to itself:
        9246                 :            :                             assert(inst->i_target != inst->i_target->b_next);
        9247                 :         20 :                             inst->i_opcode = POP_JUMP_IF_FALSE;
        9248                 :         20 :                             inst->i_target = inst->i_target->b_next;
        9249                 :         20 :                             --i;
        9250                 :            :                         }
        9251                 :         23 :                         break;
        9252                 :            :                 }
        9253                 :        198 :                 break;
        9254                 :        260 :             case JUMP_IF_TRUE_OR_POP:
        9255   [ -  -  +  + ]:        260 :                 switch (target->i_opcode) {
        9256                 :          0 :                     case POP_JUMP_IF_TRUE:
        9257                 :          0 :                         i -= jump_thread(inst, target, POP_JUMP_IF_TRUE);
        9258                 :          0 :                         break;
        9259                 :          0 :                     case JUMP:
        9260                 :            :                     case JUMP_IF_TRUE_OR_POP:
        9261                 :          0 :                         i -= jump_thread(inst, target, JUMP_IF_TRUE_OR_POP);
        9262                 :          0 :                         break;
        9263                 :          3 :                     case JUMP_IF_FALSE_OR_POP:
        9264                 :            :                     case POP_JUMP_IF_FALSE:
        9265         [ +  + ]:          3 :                         if (inst->i_loc.lineno == target->i_loc.lineno) {
        9266                 :            :                             // We don't need to bother checking for loops here,
        9267                 :            :                             // since a block's b_next cannot point to itself:
        9268                 :            :                             assert(inst->i_target != inst->i_target->b_next);
        9269                 :          1 :                             inst->i_opcode = POP_JUMP_IF_TRUE;
        9270                 :          1 :                             inst->i_target = inst->i_target->b_next;
        9271                 :          1 :                             --i;
        9272                 :            :                         }
        9273                 :          3 :                         break;
        9274                 :            :                 }
        9275                 :        260 :                 break;
        9276                 :       1858 :             case POP_JUMP_IF_NOT_NONE:
        9277                 :            :             case POP_JUMP_IF_NONE:
        9278         [ +  + ]:       1858 :                 switch (target->i_opcode) {
        9279                 :         88 :                     case JUMP:
        9280                 :         88 :                         i -= jump_thread(inst, target, inst->i_opcode);
        9281                 :            :                 }
        9282                 :       1858 :                 break;
        9283                 :       9842 :             case POP_JUMP_IF_FALSE:
        9284         [ +  + ]:       9842 :                 switch (target->i_opcode) {
        9285                 :        770 :                     case JUMP:
        9286                 :        770 :                         i -= jump_thread(inst, target, POP_JUMP_IF_FALSE);
        9287                 :            :                 }
        9288                 :       9842 :                 break;
        9289                 :       2568 :             case POP_JUMP_IF_TRUE:
        9290         [ +  + ]:       2568 :                 switch (target->i_opcode) {
        9291                 :        102 :                     case JUMP:
        9292                 :        102 :                         i -= jump_thread(inst, target, POP_JUMP_IF_TRUE);
        9293                 :            :                 }
        9294                 :       2568 :                 break;
        9295                 :       7643 :             case JUMP:
        9296         [ +  + ]:       7643 :                 switch (target->i_opcode) {
        9297                 :        781 :                     case JUMP:
        9298                 :        781 :                         i -= jump_thread(inst, target, JUMP);
        9299                 :            :                 }
        9300                 :       7643 :                 break;
        9301                 :       1707 :             case FOR_ITER:
        9302                 :       1707 :                 if (target->i_opcode == JUMP) {
        9303                 :            :                     /* This will not work now because the jump (at target) could
        9304                 :            :                      * be forward or backward and FOR_ITER only jumps forward. We
        9305                 :            :                      * can re-enable this if ever we implement a backward version
        9306                 :            :                      * of FOR_ITER.
        9307                 :            :                      */
        9308                 :            :                     /*
        9309                 :            :                     i -= jump_thread(inst, target, FOR_ITER);
        9310                 :            :                     */
        9311                 :            :                 }
        9312                 :       1707 :                 break;
        9313                 :        774 :             case SWAP:
        9314         [ -  + ]:        774 :                 if (oparg == 1) {
        9315                 :          0 :                     INSTR_SET_OP0(inst, NOP);
        9316                 :          0 :                     break;
        9317                 :            :                 }
        9318         [ -  + ]:        774 :                 if (swaptimize(bb, &i) < 0) {
        9319                 :          0 :                     goto error;
        9320                 :            :                 }
        9321                 :        774 :                 apply_static_swaps(bb, i);
        9322                 :        774 :                 break;
        9323                 :       1196 :             case KW_NAMES:
        9324                 :       1196 :                 break;
        9325                 :      16270 :             case PUSH_NULL:
        9326   [ +  +  +  - ]:      16270 :                 if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) {
        9327                 :      12538 :                     INSTR_SET_OP0(inst, NOP);
        9328                 :      12538 :                     inst[1].i_oparg |= 1;
        9329                 :            :                 }
        9330                 :      16270 :                 break;
        9331                 :     380545 :             default:
        9332                 :            :                 /* All HAS_CONST opcodes should be handled with LOAD_CONST */
        9333                 :            :                 assert (!HAS_CONST(inst->i_opcode));
        9334                 :            :         }
        9335                 :            :     }
        9336                 :      58917 :     return SUCCESS;
        9337                 :          0 : error:
        9338                 :          0 :     return ERROR;
        9339                 :            : }
        9340                 :            :
        9341                 :            : /* If this block ends with an unconditional jump to a small exit block, then
        9342                 :            :  * remove the jump and extend this block with the target.
        9343                 :            :  * Returns 1 if extended, 0 if no change, and -1 on error.
        9344                 :            :  */
        9345                 :            : static int
        9346                 :     117834 : inline_small_exit_blocks(basicblock *bb) {
        9347                 :     117834 :     struct cfg_instr *last = basicblock_last_instr(bb);
        9348         [ +  + ]:     117834 :     if (last == NULL) {
        9349                 :          2 :         return 0;
        9350                 :            :     }
        9351   [ +  +  +  +  :     117832 :     if (!IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
              +  -  +  -  +
                          - ]
        9352                 :     101919 :         return 0;
        9353                 :            :     }
        9354                 :      15913 :     basicblock *target = last->i_target;
        9355   [ +  +  +  + ]:      15913 :     if (basicblock_exits_scope(target) && target->b_iused <= MAX_COPY_SIZE) {
        9356                 :       2155 :         INSTR_SET_OP0(last, NOP);
        9357         [ -  + ]:       2155 :         RETURN_IF_ERROR(basicblock_append_instructions(bb, target));
        9358                 :       2155 :         return 1;
        9359                 :            :     }
        9360                 :      13758 :     return 0;
        9361                 :            : }
        9362                 :            :
        9363                 :            : static int
        9364                 :     169145 : remove_redundant_nops(basicblock *bb) {
        9365                 :            :     /* Remove NOPs when legal to do so. */
        9366                 :     169145 :     int dest = 0;
        9367                 :     169145 :     int prev_lineno = -1;
        9368         [ +  + ]:    1255026 :     for (int src = 0; src < bb->b_iused; src++) {
        9369                 :    1085881 :         int lineno = bb->b_instr[src].i_loc.lineno;
        9370         [ +  + ]:    1085881 :         if (bb->b_instr[src].i_opcode == NOP) {
        9371                 :            :             /* Eliminate no-op if it doesn't have a line number */
        9372         [ +  + ]:      44398 :             if (lineno < 0) {
        9373                 :      14631 :                 continue;
        9374                 :            :             }
        9375                 :            :             /* or, if the previous instruction had the same line number. */
        9376         [ +  + ]:      29767 :             if (prev_lineno == lineno) {
        9377                 :      10829 :                 continue;
        9378                 :            :             }
        9379                 :            :             /* or, if the next instruction has same line number or no line number */
        9380         [ +  + ]:      18938 :             if (src < bb->b_iused - 1) {
        9381                 :      17062 :                 int next_lineno = bb->b_instr[src+1].i_loc.lineno;
        9382         [ +  + ]:      17062 :                 if (next_lineno == lineno) {
        9383                 :      15529 :                     continue;
        9384                 :            :                 }
        9385         [ +  + ]:       1533 :                 if (next_lineno < 0) {
        9386                 :        620 :                     bb->b_instr[src+1].i_loc = bb->b_instr[src].i_loc;
        9387                 :        620 :                     continue;
        9388                 :            :                 }
        9389                 :            :             }
        9390                 :            :             else {
        9391                 :       1876 :                 basicblock* next = bb->b_next;
        9392   [ +  -  -  + ]:       1876 :                 while (next && next->b_iused == 0) {
        9393                 :          0 :                     next = next->b_next;
        9394                 :            :                 }
        9395                 :            :                 /* or if last instruction in BB and next BB has same line number */
        9396         [ +  - ]:       1876 :                 if (next) {
        9397         [ +  + ]:       1876 :                     if (lineno == next->b_instr[0].i_loc.lineno) {
        9398                 :         26 :                         continue;
        9399                 :            :                     }
        9400                 :            :                 }
        9401                 :            :             }
        9402                 :            :
        9403                 :            :         }
        9404         [ +  + ]:    1044246 :         if (dest != src) {
        9405                 :     150272 :             bb->b_instr[dest] = bb->b_instr[src];
        9406                 :            :         }
        9407                 :    1044246 :         dest++;
        9408                 :    1044246 :         prev_lineno = lineno;
        9409                 :            :     }
        9410                 :            :     assert(dest <= bb->b_iused);
        9411                 :     169145 :     int num_removed = bb->b_iused - dest;
        9412                 :     169145 :     bb->b_iused = dest;
        9413                 :     169145 :     return num_removed;
        9414                 :            : }
        9415                 :            :
        9416                 :            : static int
        9417                 :       8041 : check_cfg(cfg_builder *g) {
        9418         [ +  + ]:      69608 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9419                 :            :         /* Raise SystemError if jump or exit is not last instruction in the block. */
        9420         [ +  + ]:     448179 :         for (int i = 0; i < b->b_iused; i++) {
        9421                 :     386612 :             int opcode = b->b_instr[i].i_opcode;
        9422                 :            :             assert(!IS_ASSEMBLER_OPCODE(opcode));
        9423   [ +  +  +  +  :     386612 :             if (IS_TERMINATOR_OPCODE(opcode)) {
              +  -  +  +  +
                          + ]
        9424         [ -  + ]:      47043 :                 if (i != b->b_iused - 1) {
        9425                 :          0 :                     PyErr_SetString(PyExc_SystemError, "malformed control flow graph.");
        9426                 :          0 :                     return ERROR;
        9427                 :            :                 }
        9428                 :            :             }
        9429                 :            :         }
        9430                 :            :     }
        9431                 :       8041 :     return SUCCESS;
        9432                 :            : }
        9433                 :            :
        9434                 :            : static int
        9435                 :       8041 : mark_reachable(basicblock *entryblock) {
        9436                 :       8041 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
        9437         [ -  + ]:       8041 :     if (stack == NULL) {
        9438                 :          0 :         return ERROR;
        9439                 :            :     }
        9440                 :       8041 :     basicblock **sp = stack;
        9441                 :       8041 :     entryblock->b_predecessors = 1;
        9442                 :       8041 :     *sp++ = entryblock;
        9443         [ +  + ]:      58659 :     while (sp > stack) {
        9444                 :      50618 :         basicblock *b = *(--sp);
        9445                 :      50618 :         b->b_visited = 1;
        9446   [ +  +  +  + ]:      50618 :         if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
        9447         [ +  + ]:      27620 :             if (!b->b_next->b_visited) {
        9448                 :            :                 assert(b->b_next->b_predecessors == 0);
        9449                 :      23751 :                 *sp++ = b->b_next;
        9450                 :            :             }
        9451                 :      27620 :             b->b_next->b_predecessors++;
        9452                 :            :         }
        9453         [ +  + ]:     396779 :         for (int i = 0; i < b->b_iused; i++) {
        9454                 :            :             basicblock *target;
        9455                 :     346161 :             struct cfg_instr *instr = &b->b_instr[i];
        9456   [ +  +  +  + ]:     346161 :             if (is_jump(instr) || is_block_push(instr)) {
        9457                 :      26115 :                 target = instr->i_target;
        9458         [ +  + ]:      26115 :                 if (!target->b_visited) {
        9459                 :            :                     assert(target->b_predecessors == 0 || target == b->b_next);
        9460                 :      18826 :                     *sp++ = target;
        9461                 :            :                 }
        9462                 :      26115 :                 target->b_predecessors++;
        9463                 :            :             }
        9464                 :            :         }
        9465                 :            :     }
        9466                 :       8041 :     PyMem_Free(stack);
        9467                 :       8041 :     return SUCCESS;
        9468                 :            : }
        9469                 :            :
        9470                 :            : static void
        9471                 :      16082 : eliminate_empty_basic_blocks(cfg_builder *g) {
        9472                 :            :     /* Eliminate empty blocks */
        9473         [ +  + ]:     125615 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9474                 :     109533 :         basicblock *next = b->b_next;
        9475   [ +  +  +  + ]:     120484 :         while (next && next->b_iused == 0) {
        9476                 :      10951 :             next = next->b_next;
        9477                 :            :         }
        9478                 :     109533 :         b->b_next = next;
        9479                 :            :     }
        9480   [ +  -  -  + ]:      16082 :     while(g->g_entryblock && g->g_entryblock->b_iused == 0) {
        9481                 :          0 :         g->g_entryblock = g->g_entryblock->b_next;
        9482                 :            :     }
        9483         [ +  + ]:     125615 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9484                 :            :         assert(b->b_iused > 0);
        9485         [ +  + ]:     842148 :         for (int i = 0; i < b->b_iused; i++) {
        9486                 :     732615 :             struct cfg_instr *instr = &b->b_instr[i];
        9487   [ +  +  +  +  :     732615 :             if (HAS_TARGET(instr->i_opcode)) {
                 +  +  +  + ]
        9488                 :      55640 :                 basicblock *target = instr->i_target;
        9489         [ +  + ]:      59816 :                 while (target->b_iused == 0) {
        9490                 :       4176 :                     target = target->b_next;
        9491                 :            :                 }
        9492                 :      55640 :                 instr->i_target = target;
        9493                 :            :                 assert(instr->i_target && instr->i_target->b_iused > 0);
        9494                 :            :             }
        9495                 :            :         }
        9496                 :            :     }
        9497                 :      16082 : }
        9498                 :            :
        9499                 :            :
        9500                 :            : /* If an instruction has no line number, but it's predecessor in the BB does,
        9501                 :            :  * then copy the line number. If a successor block has no line number, and only
        9502                 :            :  * one predecessor, then inherit the line number.
        9503                 :            :  * This ensures that all exit blocks (with one predecessor) receive a line number.
        9504                 :            :  * Also reduces the size of the line number table,
        9505                 :            :  * but has no impact on the generated line number events.
        9506                 :            :  */
        9507                 :            : static void
        9508                 :       8041 : propagate_line_numbers(basicblock *entryblock) {
        9509         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        9510                 :      51311 :         struct cfg_instr *last = basicblock_last_instr(b);
        9511         [ -  + ]:      51311 :         if (last == NULL) {
        9512                 :          0 :             continue;
        9513                 :            :         }
        9514                 :            :
        9515                 :      51311 :         location prev_location = NO_LOCATION;
        9516         [ +  + ]:     398096 :         for (int i = 0; i < b->b_iused; i++) {
        9517         [ +  + ]:     346785 :             if (b->b_instr[i].i_loc.lineno < 0) {
        9518                 :      32742 :                 b->b_instr[i].i_loc = prev_location;
        9519                 :            :             }
        9520                 :            :             else {
        9521                 :     314043 :                 prev_location = b->b_instr[i].i_loc;
        9522                 :            :             }
        9523                 :            :         }
        9524   [ +  +  +  + ]:      51311 :         if (BB_HAS_FALLTHROUGH(b) && b->b_next->b_predecessors == 1) {
        9525                 :            :             assert(b->b_next->b_iused);
        9526         [ +  + ]:      21271 :             if (b->b_next->b_instr[0].i_loc.lineno < 0) {
        9527                 :       1752 :                 b->b_next->b_instr[0].i_loc = prev_location;
        9528                 :            :             }
        9529                 :            :         }
        9530         [ +  + ]:      51311 :         if (is_jump(last)) {
        9531                 :      20694 :             basicblock *target = last->i_target;
        9532         [ +  + ]:      20694 :             if (target->b_predecessors == 1) {
        9533         [ +  + ]:       9137 :                 if (target->b_instr[0].i_loc.lineno < 0) {
        9534                 :       3522 :                     target->b_instr[0].i_loc = prev_location;
        9535                 :            :                 }
        9536                 :            :             }
        9537                 :            :         }
        9538                 :            :     }
        9539                 :       8041 : }
        9540                 :            :
        9541                 :            :
        9542                 :            : /* Calculate the actual jump target from the target_label */
        9543                 :            : static int
        9544                 :       8041 : translate_jump_labels_to_targets(basicblock *entryblock)
        9545                 :            : {
        9546                 :       8041 :     int max_label = -1;
        9547         [ +  + ]:      69608 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        9548         [ +  + ]:      61567 :         if (b->b_label.id > max_label) {
        9549                 :      20366 :             max_label = b->b_label.id;
        9550                 :            :         }
        9551                 :            :     }
        9552                 :       8041 :     size_t mapsize = sizeof(basicblock *) * (max_label + 1);
        9553                 :       8041 :     basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize);
        9554         [ -  + ]:       8041 :     if (!label2block) {
        9555                 :          0 :         PyErr_NoMemory();
        9556                 :          0 :         return ERROR;
        9557                 :            :     }
        9558                 :       8041 :     memset(label2block, 0, mapsize);
        9559         [ +  + ]:      69608 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        9560         [ +  + ]:      61567 :         if (b->b_label.id >= 0) {
        9561                 :      33597 :             label2block[b->b_label.id] = b;
        9562                 :            :         }
        9563                 :            :     }
        9564         [ +  + ]:      69608 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        9565         [ +  + ]:     448179 :         for (int i = 0; i < b->b_iused; i++) {
        9566                 :     386612 :             struct cfg_instr *instr = &b->b_instr[i];
        9567                 :            :             assert(instr->i_target == NULL);
        9568   [ +  +  +  +  :     386612 :             if (HAS_TARGET(instr->i_opcode)) {
                 +  +  +  + ]
        9569                 :      29525 :                 int lbl = instr->i_oparg;
        9570                 :            :                 assert(lbl >= 0 && lbl <= max_label);
        9571                 :      29525 :                 instr->i_target = label2block[lbl];
        9572                 :            :                 assert(instr->i_target != NULL);
        9573                 :            :                 assert(instr->i_target->b_label.id == lbl);
        9574                 :            :             }
        9575                 :            :         }
        9576                 :            :     }
        9577                 :       8041 :     PyMem_Free(label2block);
        9578                 :       8041 :     return SUCCESS;
        9579                 :            : }
        9580                 :            :
        9581                 :            : /* Perform optimizations on a control flow graph.
        9582                 :            :    The consts object should still be in list form to allow new constants
        9583                 :            :    to be appended.
        9584                 :            :
        9585                 :            :    Code trasnformations that reduce code size initially fill the gaps with
        9586                 :            :    NOPs.  Later those NOPs are removed.
        9587                 :            : */
        9588                 :            :
        9589                 :            : static int
        9590                 :       8041 : optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache)
        9591                 :            : {
        9592                 :            :     assert(PyDict_CheckExact(const_cache));
        9593         [ -  + ]:       8041 :     RETURN_IF_ERROR(check_cfg(g));
        9594                 :       8041 :     eliminate_empty_basic_blocks(g);
        9595         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9596         [ -  + ]:      58917 :         RETURN_IF_ERROR(inline_small_exit_blocks(b));
        9597                 :            :     }
        9598                 :            :     assert(no_empty_basic_blocks(g));
        9599         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9600         [ -  + ]:      58917 :         RETURN_IF_ERROR(optimize_basic_block(const_cache, b, consts));
        9601                 :      58917 :         remove_redundant_nops(b);
        9602                 :            :         assert(b->b_predecessors == 0);
        9603                 :            :     }
        9604         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9605         [ -  + ]:      58917 :         RETURN_IF_ERROR(inline_small_exit_blocks(b));
        9606                 :            :     }
        9607         [ -  + ]:       8041 :     RETURN_IF_ERROR(mark_reachable(g->g_entryblock));
        9608                 :            :
        9609                 :            :     /* Delete unreachable instructions */
        9610         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9611         [ +  + ]:      58917 :        if (b->b_predecessors == 0) {
        9612                 :       8299 :             b->b_iused = 0;
        9613                 :            :        }
        9614                 :            :     }
        9615         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9616                 :      58917 :         remove_redundant_nops(b);
        9617                 :            :     }
        9618                 :       8041 :     eliminate_empty_basic_blocks(g);
        9619                 :            :     assert(no_redundant_nops(g));
        9620         [ -  + ]:       8041 :     RETURN_IF_ERROR(remove_redundant_jumps(g));
        9621                 :       8041 :     return SUCCESS;
        9622                 :            : }
        9623                 :            :
        9624                 :            :
        9625                 :            : static int
        9626                 :       8041 : remove_unused_consts(basicblock *entryblock, PyObject *consts)
        9627                 :            : {
        9628                 :            :     assert(PyList_CheckExact(consts));
        9629                 :       8041 :     Py_ssize_t nconsts = PyList_GET_SIZE(consts);
        9630         [ -  + ]:       8041 :     if (nconsts == 0) {
        9631                 :          0 :         return SUCCESS;  /* nothing to do */
        9632                 :            :     }
        9633                 :            :
        9634                 :       8041 :     Py_ssize_t *index_map = NULL;
        9635                 :       8041 :     Py_ssize_t *reverse_index_map = NULL;
        9636                 :       8041 :     int err = ERROR;
        9637                 :            :
        9638                 :       8041 :     index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t));
        9639         [ -  + ]:       8041 :     if (index_map == NULL) {
        9640                 :          0 :         goto end;
        9641                 :            :     }
        9642         [ +  + ]:      42935 :     for (Py_ssize_t i = 1; i < nconsts; i++) {
        9643                 :      34894 :         index_map[i] = -1;
        9644                 :            :     }
        9645                 :            :     // The first constant may be docstring; keep it always.
        9646                 :       8041 :     index_map[0] = 0;
        9647                 :            :
        9648                 :            :     /* mark used consts */
        9649         [ +  + ]:      58657 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        9650         [ +  + ]:     396619 :         for (int i = 0; i < b->b_iused; i++) {
        9651   [ +  +  +  +  :     346003 :             if (HAS_CONST(b->b_instr[i].i_opcode)) {
                       +  + ]
        9652                 :      50633 :                 int index = b->b_instr[i].i_oparg;
        9653                 :      50633 :                 index_map[index] = index;
        9654                 :            :             }
        9655                 :            :         }
        9656                 :            :     }
        9657                 :            :     /* now index_map[i] == i if consts[i] is used, -1 otherwise */
        9658                 :            :
        9659                 :            :     /* condense consts */
        9660                 :       8041 :     Py_ssize_t n_used_consts = 0;
        9661         [ +  + ]:      50976 :     for (int i = 0; i < nconsts; i++) {
        9662         [ +  + ]:      42935 :         if (index_map[i] != -1) {
        9663                 :            :             assert(index_map[i] == i);
        9664                 :      41021 :             index_map[n_used_consts++] = index_map[i];
        9665                 :            :         }
        9666                 :            :     }
        9667         [ +  + ]:       8041 :     if (n_used_consts == nconsts) {
        9668                 :            :         /* nothing to do */
        9669                 :       6315 :         err = SUCCESS;
        9670                 :       6315 :         goto end;
        9671                 :            :     }
        9672                 :            :
        9673                 :            :     /* move all used consts to the beginning of the consts list */
        9674                 :            :     assert(n_used_consts < nconsts);
        9675         [ +  + ]:      13141 :     for (Py_ssize_t i = 0; i < n_used_consts; i++) {
        9676                 :      11415 :         Py_ssize_t old_index = index_map[i];
        9677                 :            :         assert(i <= old_index && old_index < nconsts);
        9678         [ +  + ]:      11415 :         if (i != old_index) {
        9679                 :       5660 :             PyObject *value = PyList_GET_ITEM(consts, index_map[i]);
        9680                 :            :             assert(value != NULL);
        9681                 :       5660 :             PyList_SetItem(consts, i, Py_NewRef(value));
        9682                 :            :         }
        9683                 :            :     }
        9684                 :            :
        9685                 :            :     /* truncate the consts list at its new size */
        9686         [ -  + ]:       1726 :     if (PyList_SetSlice(consts, n_used_consts, nconsts, NULL) < 0) {
        9687                 :          0 :         goto end;
        9688                 :            :     }
        9689                 :            :
        9690                 :            :     /* adjust const indices in the bytecode */
        9691                 :       1726 :     reverse_index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t));
        9692         [ -  + ]:       1726 :     if (reverse_index_map == NULL) {
        9693                 :          0 :         goto end;
        9694                 :            :     }
        9695         [ +  + ]:      15055 :     for (Py_ssize_t i = 0; i < nconsts; i++) {
        9696                 :      13329 :         reverse_index_map[i] = -1;
        9697                 :            :     }
        9698         [ +  + ]:      13141 :     for (Py_ssize_t i = 0; i < n_used_consts; i++) {
        9699                 :            :         assert(index_map[i] != -1);
        9700                 :            :         assert(reverse_index_map[index_map[i]] == -1);
        9701                 :      11415 :         reverse_index_map[index_map[i]] = i;
        9702                 :            :     }
        9703                 :            :
        9704         [ +  + ]:      10610 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        9705         [ +  + ]:      81122 :         for (int i = 0; i < b->b_iused; i++) {
        9706   [ +  +  +  +  :      72238 :             if (HAS_CONST(b->b_instr[i].i_opcode)) {
                       +  + ]
        9707                 :      12700 :                 int index = b->b_instr[i].i_oparg;
        9708                 :            :                 assert(reverse_index_map[index] >= 0);
        9709                 :            :                 assert(reverse_index_map[index] < n_used_consts);
        9710                 :      12700 :                 b->b_instr[i].i_oparg = (int)reverse_index_map[index];
        9711                 :            :             }
        9712                 :            :         }
        9713                 :            :     }
        9714                 :            :
        9715                 :       1726 :     err = SUCCESS;
        9716                 :       8041 : end:
        9717                 :       8041 :     PyMem_Free(index_map);
        9718                 :       8041 :     PyMem_Free(reverse_index_map);
        9719                 :       8041 :     return err;
        9720                 :            : }
        9721                 :            :
        9722                 :            : static inline bool
        9723                 :      49183 : is_exit_without_lineno(basicblock *b) {
        9724         [ +  + ]:      49183 :     if (!basicblock_exits_scope(b)) {
        9725                 :      35956 :         return false;
        9726                 :            :     }
        9727         [ +  + ]:      18439 :     for (int i = 0; i < b->b_iused; i++) {
        9728         [ +  + ]:      15101 :         if (b->b_instr[i].i_loc.lineno >= 0) {
        9729                 :       9889 :             return false;
        9730                 :            :         }
        9731                 :            :     }
        9732                 :       3338 :     return true;
        9733                 :            : }
        9734                 :            :
        9735                 :            : /* PEP 626 mandates that the f_lineno of a frame is correct
        9736                 :            :  * after a frame terminates. It would be prohibitively expensive
        9737                 :            :  * to continuously update the f_lineno field at runtime,
        9738                 :            :  * so we make sure that all exiting instruction (raises and returns)
        9739                 :            :  * have a valid line number, allowing us to compute f_lineno lazily.
        9740                 :            :  * We can do this by duplicating the exit blocks without line number
        9741                 :            :  * so that none have more than one predecessor. We can then safely
        9742                 :            :  * copy the line number from the sole predecessor block.
        9743                 :            :  */
        9744                 :            : static int
        9745                 :       8041 : duplicate_exits_without_lineno(cfg_builder *g)
        9746                 :            : {
        9747                 :            :     assert(no_empty_basic_blocks(g));
        9748                 :            :     /* Copy all exit blocks without line number that are targets of a jump.
        9749                 :            :      */
        9750                 :       8041 :     basicblock *entryblock = g->g_entryblock;
        9751         [ +  + ]:      59351 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        9752                 :      51310 :         struct cfg_instr *last = basicblock_last_instr(b);
        9753                 :            :         assert(last != NULL);
        9754         [ +  + ]:      51310 :         if (is_jump(last)) {
        9755                 :      20694 :             basicblock *target = last->i_target;
        9756   [ +  +  +  + ]:      20694 :             if (is_exit_without_lineno(target) && target->b_predecessors > 1) {
        9757                 :        514 :                 basicblock *new_target = copy_basicblock(g, target);
        9758         [ -  + ]:        514 :                 if (new_target == NULL) {
        9759                 :          0 :                     return ERROR;
        9760                 :            :                 }
        9761                 :        514 :                 new_target->b_instr[0].i_loc = last->i_loc;
        9762                 :        514 :                 last->i_target = new_target;
        9763                 :        514 :                 target->b_predecessors--;
        9764                 :        514 :                 new_target->b_predecessors = 1;
        9765                 :        514 :                 new_target->b_next = target->b_next;
        9766                 :        514 :                 target->b_next = new_target;
        9767                 :            :             }
        9768                 :            :         }
        9769                 :            :     }
        9770                 :            :
        9771                 :            :     /* Any remaining reachable exit blocks without line number can only be reached by
        9772                 :            :      * fall through, and thus can only have a single predecessor */
        9773         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
        9774   [ +  +  +  -  :      51311 :         if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) {
                       +  - ]
        9775         [ +  + ]:      28489 :             if (is_exit_without_lineno(b->b_next)) {
        9776                 :       1096 :                 struct cfg_instr *last = basicblock_last_instr(b);
        9777                 :            :                 assert(last != NULL);
        9778                 :       1096 :                 b->b_next->b_instr[0].i_loc = last->i_loc;
        9779                 :            :             }
        9780                 :            :         }
        9781                 :            :     }
        9782                 :       8041 :     return SUCCESS;
        9783                 :            : }
        9784                 :            :
        9785                 :            :
        9786                 :            : /* Access to compiler optimizations for unit tests.
        9787                 :            :  *
        9788                 :            :  * _PyCompile_CodeGen takes and AST, applies code-gen and
        9789                 :            :  * returns the unoptimized CFG as an instruction list.
        9790                 :            :  *
        9791                 :            :  * _PyCompile_OptimizeCfg takes an instruction list, constructs
        9792                 :            :  * a CFG, optimizes it and converts back to an instruction list.
        9793                 :            :  *
        9794                 :            :  * An instruction list is a PyList where each item is either
        9795                 :            :  * a tuple describing a single instruction:
        9796                 :            :  * (opcode, oparg, lineno, end_lineno, col, end_col), or
        9797                 :            :  * a jump target label marking the beginning of a basic block.
        9798                 :            :  */
        9799                 :            :
        9800                 :            : static int
        9801                 :          0 : instructions_to_cfg(PyObject *instructions, cfg_builder *g)
        9802                 :            : {
        9803                 :            :     assert(PyList_Check(instructions));
        9804                 :            :
        9805                 :          0 :     Py_ssize_t num_insts = PyList_GET_SIZE(instructions);
        9806                 :          0 :     bool *is_target = PyMem_Calloc(num_insts, sizeof(bool));
        9807         [ #  # ]:          0 :     if (is_target == NULL) {
        9808                 :          0 :         return ERROR;
        9809                 :            :     }
        9810         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < num_insts; i++) {
        9811                 :          0 :         PyObject *item = PyList_GET_ITEM(instructions, i);
        9812   [ #  #  #  # ]:          0 :         if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
        9813                 :          0 :             PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
        9814                 :          0 :             goto error;
        9815                 :            :         }
        9816                 :          0 :         int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
        9817         [ #  # ]:          0 :         if (PyErr_Occurred()) {
        9818                 :          0 :             goto error;
        9819                 :            :         }
        9820   [ #  #  #  #  :          0 :         if (HAS_TARGET(opcode)) {
                 #  #  #  # ]
        9821                 :          0 :             int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
        9822         [ #  # ]:          0 :             if (PyErr_Occurred()) {
        9823                 :          0 :                 goto error;
        9824                 :            :             }
        9825   [ #  #  #  # ]:          0 :             if (oparg < 0 || oparg >= num_insts) {
        9826                 :          0 :                 PyErr_SetString(PyExc_ValueError, "label out of range");
        9827                 :          0 :                 goto error;
        9828                 :            :             }
        9829                 :          0 :             is_target[oparg] = true;
        9830                 :            :         }
        9831                 :            :     }
        9832                 :            :
        9833         [ #  # ]:          0 :     for (int i = 0; i < num_insts; i++) {
        9834         [ #  # ]:          0 :         if (is_target[i]) {
        9835                 :          0 :             jump_target_label lbl = {i};
        9836         [ #  # ]:          0 :             RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
        9837                 :            :         }
        9838                 :          0 :         PyObject *item = PyList_GET_ITEM(instructions, i);
        9839   [ #  #  #  # ]:          0 :         if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
        9840                 :          0 :             PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
        9841                 :          0 :             goto error;
        9842                 :            :         }
        9843                 :          0 :         int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
        9844         [ #  # ]:          0 :         if (PyErr_Occurred()) {
        9845                 :          0 :             goto error;
        9846                 :            :         }
        9847                 :            :         int oparg;
        9848   [ #  #  #  #  :          0 :         if (HAS_ARG(opcode)) {
              #  #  #  #  #
                    #  #  # ]
        9849                 :          0 :             oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
        9850         [ #  # ]:          0 :             if (PyErr_Occurred()) {
        9851                 :          0 :                 goto error;
        9852                 :            :             }
        9853                 :            :         }
        9854                 :            :         else {
        9855                 :          0 :             oparg = 0;
        9856                 :            :         }
        9857                 :            :         location loc;
        9858                 :          0 :         loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
        9859         [ #  # ]:          0 :         if (PyErr_Occurred()) {
        9860                 :          0 :             goto error;
        9861                 :            :         }
        9862                 :          0 :         loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3));
        9863         [ #  # ]:          0 :         if (PyErr_Occurred()) {
        9864                 :          0 :             goto error;
        9865                 :            :         }
        9866                 :          0 :         loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4));
        9867         [ #  # ]:          0 :         if (PyErr_Occurred()) {
        9868                 :          0 :             goto error;
        9869                 :            :         }
        9870                 :          0 :         loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5));
        9871         [ #  # ]:          0 :         if (PyErr_Occurred()) {
        9872                 :          0 :             goto error;
        9873                 :            :         }
        9874         [ #  # ]:          0 :         RETURN_IF_ERROR(cfg_builder_addop(g, opcode, oparg, loc));
        9875                 :            :     }
        9876                 :          0 :     struct cfg_instr *last = basicblock_last_instr(g->g_curblock);
        9877   [ #  #  #  #  :          0 :     if (last && !IS_TERMINATOR_OPCODE(last->i_opcode)) {
              #  #  #  #  #
                    #  #  # ]
        9878         [ #  # ]:          0 :         RETURN_IF_ERROR(cfg_builder_addop(g, RETURN_VALUE, 0, NO_LOCATION));
        9879                 :            :     }
        9880                 :          0 :     PyMem_Free(is_target);
        9881                 :          0 :     return SUCCESS;
        9882                 :          0 : error:
        9883                 :          0 :     PyMem_Free(is_target);
        9884                 :          0 :     return ERROR;
        9885                 :            : }
        9886                 :            :
        9887                 :            : static PyObject *
        9888                 :          0 : instr_sequence_to_instructions(instr_sequence *seq) {
        9889                 :          0 :     PyObject *instructions = PyList_New(0);
        9890         [ #  # ]:          0 :     if (instructions == NULL) {
        9891                 :          0 :         return NULL;
        9892                 :            :     }
        9893         [ #  # ]:          0 :     for (int i = 0; i < seq->s_used; i++) {
        9894                 :          0 :         instruction *instr = &seq->s_instrs[i];
        9895                 :          0 :         location loc = instr->i_loc;
        9896   [ #  #  #  #  :          0 :         int arg = HAS_TARGET(instr->i_opcode) ?
                       #  # ]
        9897         [ #  # ]:          0 :                   seq->s_labelmap[instr->i_oparg] : instr->i_oparg;
        9898                 :            :
        9899                 :          0 :         PyObject *inst_tuple = Py_BuildValue(
        9900                 :            :             "(iiiiii)", instr->i_opcode, arg,
        9901                 :            :             loc.lineno, loc.end_lineno,
        9902                 :            :             loc.col_offset, loc.end_col_offset);
        9903         [ #  # ]:          0 :         if (inst_tuple == NULL) {
        9904                 :          0 :             goto error;
        9905                 :            :         }
        9906                 :            :
        9907                 :          0 :         int res = PyList_Append(instructions, inst_tuple);
        9908                 :          0 :         Py_DECREF(inst_tuple);
        9909         [ #  # ]:          0 :         if (res != 0) {
        9910                 :          0 :             goto error;
        9911                 :            :         }
        9912                 :            :     }
        9913                 :          0 :     return instructions;
        9914                 :          0 : error:
        9915                 :          0 :     Py_XDECREF(instructions);
        9916                 :          0 :     return NULL;
        9917                 :            : }
        9918                 :            :
        9919                 :            : static PyObject *
        9920                 :          0 : cfg_to_instructions(cfg_builder *g)
        9921                 :            : {
        9922                 :          0 :     PyObject *instructions = PyList_New(0);
        9923         [ #  # ]:          0 :     if (instructions == NULL) {
        9924                 :          0 :         return NULL;
        9925                 :            :     }
        9926                 :          0 :     int lbl = 0;
        9927         [ #  # ]:          0 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9928                 :          0 :         b->b_label = (jump_target_label){lbl};
        9929                 :          0 :         lbl += b->b_iused;
        9930                 :            :     }
        9931         [ #  # ]:          0 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
        9932         [ #  # ]:          0 :         for (int i = 0; i < b->b_iused; i++) {
        9933                 :          0 :             struct cfg_instr *instr = &b->b_instr[i];
        9934                 :          0 :             location loc = instr->i_loc;
        9935   [ #  #  #  #  :          0 :             int arg = HAS_TARGET(instr->i_opcode) ?
                       #  # ]
        9936         [ #  # ]:          0 :                       instr->i_target->b_label.id : instr->i_oparg;
        9937                 :            :
        9938                 :          0 :             PyObject *inst_tuple = Py_BuildValue(
        9939                 :            :                 "(iiiiii)", instr->i_opcode, arg,
        9940                 :            :                 loc.lineno, loc.end_lineno,
        9941                 :            :                 loc.col_offset, loc.end_col_offset);
        9942         [ #  # ]:          0 :             if (inst_tuple == NULL) {
        9943                 :          0 :                 goto error;
        9944                 :            :             }
        9945                 :            :
        9946         [ #  # ]:          0 :             if (PyList_Append(instructions, inst_tuple) != 0) {
        9947                 :          0 :                 Py_DECREF(inst_tuple);
        9948                 :          0 :                 goto error;
        9949                 :            :             }
        9950                 :          0 :             Py_DECREF(inst_tuple);
        9951                 :            :         }
        9952                 :            :     }
        9953                 :            :
        9954                 :          0 :     return instructions;
        9955                 :          0 : error:
        9956                 :          0 :     Py_DECREF(instructions);
        9957                 :          0 :     return NULL;
        9958                 :            : }
        9959                 :            :
        9960                 :            : PyObject *
        9961                 :          0 : _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
        9962                 :            :                    int optimize)
        9963                 :            : {
        9964                 :          0 :     PyObject *res = NULL;
        9965                 :            :
        9966         [ #  # ]:          0 :     if (!PyAST_Check(ast)) {
        9967                 :          0 :         PyErr_SetString(PyExc_TypeError, "expected an AST");
        9968                 :          0 :         return NULL;
        9969                 :            :     }
        9970                 :            :
        9971                 :          0 :     PyArena *arena = _PyArena_New();
        9972         [ #  # ]:          0 :     if (arena == NULL) {
        9973                 :          0 :         return NULL;
        9974                 :            :     }
        9975                 :            :
        9976                 :          0 :     mod_ty mod = PyAST_obj2mod(ast, arena, 0 /* exec */);
        9977   [ #  #  #  # ]:          0 :     if (mod == NULL || !_PyAST_Validate(mod)) {
        9978                 :          0 :         _PyArena_Free(arena);
        9979                 :          0 :         return NULL;
        9980                 :            :     }
        9981                 :            :
        9982                 :          0 :     struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena);
        9983         [ #  # ]:          0 :     if (c == NULL) {
        9984                 :          0 :         _PyArena_Free(arena);
        9985                 :          0 :         return NULL;
        9986                 :            :     }
        9987                 :            :
        9988         [ #  # ]:          0 :     if (compiler_codegen(c, mod) < 0) {
        9989                 :          0 :         goto finally;
        9990                 :            :     }
        9991                 :            :
        9992                 :          0 :     res = instr_sequence_to_instructions(INSTR_SEQUENCE(c));
        9993                 :            :
        9994                 :          0 : finally:
        9995                 :          0 :     compiler_exit_scope(c);
        9996                 :          0 :     compiler_free(c);
        9997                 :          0 :     _PyArena_Free(arena);
        9998                 :          0 :     return res;
        9999                 :            : }
       10000                 :            :
       10001                 :            : PyObject *
       10002                 :          0 : _PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts)
       10003                 :            : {
       10004                 :          0 :     PyObject *res = NULL;
       10005                 :          0 :     PyObject *const_cache = PyDict_New();
       10006         [ #  # ]:          0 :     if (const_cache == NULL) {
       10007                 :          0 :         return NULL;
       10008                 :            :     }
       10009                 :            :
       10010                 :            :     cfg_builder g;
       10011                 :          0 :     memset(&g, 0, sizeof(cfg_builder));
       10012         [ #  # ]:          0 :     if (cfg_builder_init(&g) < 0) {
       10013                 :          0 :         goto error;
       10014                 :            :     }
       10015         [ #  # ]:          0 :     if (instructions_to_cfg(instructions, &g) < 0) {
       10016                 :          0 :         goto error;
       10017                 :            :     }
       10018                 :          0 :     int code_flags = 0, nlocals = 0, nparams = 0;
       10019         [ #  # ]:          0 :     if (optimize_code_unit(&g, consts, const_cache, code_flags, nlocals, nparams) < 0) {
       10020                 :          0 :         goto error;
       10021                 :            :     }
       10022                 :          0 :     res = cfg_to_instructions(&g);
       10023                 :          0 : error:
       10024                 :          0 :     Py_DECREF(const_cache);
       10025                 :          0 :     cfg_builder_fini(&g);
       10026                 :          0 :     return res;
       10027                 :            : }
       10028                 :            :
       10029                 :            :
       10030                 :            : /* Retained for API compatibility.
       10031                 :            :  * Optimization is now done in optimize_cfg */
       10032                 :            :
       10033                 :            : PyObject *
       10034                 :          0 : PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts),
       10035                 :            :                 PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj))
       10036                 :            : {
       10037                 :          0 :     return Py_NewRef(code);
       10038                 :            : }

Generated by: LCOV version 1.14