LCOV - code coverage report
Current view: top level - py - emitbc.c (source / functions) Hit Total Coverage
Test: unix_coverage_v1.19.1-724-gfb7d21153.info Lines: 457 457 100.0 %
Date: 2022-12-01 09:37:31 Functions: 71 71 100.0 %
Branches: 161 176 91.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * This file is part of the MicroPython project, http://micropython.org/
       3                 :            :  *
       4                 :            :  * The MIT License (MIT)
       5                 :            :  *
       6                 :            :  * Copyright (c) 2013-2019 Damien P. George
       7                 :            :  *
       8                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a copy
       9                 :            :  * of this software and associated documentation files (the "Software"), to deal
      10                 :            :  * in the Software without restriction, including without limitation the rights
      11                 :            :  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      12                 :            :  * copies of the Software, and to permit persons to whom the Software is
      13                 :            :  * furnished to do so, subject to the following conditions:
      14                 :            :  *
      15                 :            :  * The above copyright notice and this permission notice shall be included in
      16                 :            :  * all copies or substantial portions of the Software.
      17                 :            :  *
      18                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      19                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      21                 :            :  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      22                 :            :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      23                 :            :  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      24                 :            :  * THE SOFTWARE.
      25                 :            :  */
      26                 :            : 
      27                 :            : #include <stdbool.h>
      28                 :            : #include <stdint.h>
      29                 :            : #include <stdio.h>
      30                 :            : #include <string.h>
      31                 :            : #include <unistd.h>
      32                 :            : #include <assert.h>
      33                 :            : 
      34                 :            : #include "py/mpstate.h"
      35                 :            : #include "py/smallint.h"
      36                 :            : #include "py/emit.h"
      37                 :            : #include "py/bc0.h"
      38                 :            : 
      39                 :            : #if MICROPY_ENABLE_COMPILER
      40                 :            : 
      41                 :            : #define DUMMY_DATA_SIZE (MP_ENCODE_UINT_MAX_BYTES)
      42                 :            : 
      43                 :            : struct _emit_t {
      44                 :            :     // Accessed as mp_obj_t, so must be aligned as such, and we rely on the
      45                 :            :     // memory allocator returning a suitably aligned pointer.
      46                 :            :     // Should work for cases when mp_obj_t is 64-bit on a 32-bit machine.
      47                 :            :     byte dummy_data[DUMMY_DATA_SIZE];
      48                 :            : 
      49                 :            :     pass_kind_t pass : 8;
      50                 :            : 
      51                 :            :     // Set to true if the code generator should suppress emitted code due to it
      52                 :            :     // being dead code.  This can happen when opcodes immediately follow an
      53                 :            :     // unconditional flow control (eg jump or raise).
      54                 :            :     bool suppress;
      55                 :            : 
      56                 :            :     int stack_size;
      57                 :            : 
      58                 :            :     mp_emit_common_t *emit_common;
      59                 :            :     scope_t *scope;
      60                 :            : 
      61                 :            :     mp_uint_t last_source_line_offset;
      62                 :            :     mp_uint_t last_source_line;
      63                 :            : 
      64                 :            :     size_t max_num_labels;
      65                 :            :     size_t *label_offsets;
      66                 :            : 
      67                 :            :     size_t code_info_offset;
      68                 :            :     size_t code_info_size;
      69                 :            :     size_t bytecode_offset;
      70                 :            :     size_t bytecode_size;
      71                 :            :     byte *code_base; // stores both byte code and code info
      72                 :            :     bool overflow;
      73                 :            : 
      74                 :            :     size_t n_info;
      75                 :            :     size_t n_cell;
      76                 :            : };
      77                 :            : 
      78                 :       3560 : emit_t *emit_bc_new(mp_emit_common_t *emit_common) {
      79                 :       3560 :     emit_t *emit = m_new0(emit_t, 1);
      80                 :       3560 :     emit->emit_common = emit_common;
      81                 :       3560 :     return emit;
      82                 :            : }
      83                 :            : 
      84                 :       3556 : void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels) {
      85                 :       3556 :     emit->max_num_labels = max_num_labels;
      86                 :       3556 :     emit->label_offsets = m_new(size_t, emit->max_num_labels);
      87                 :       3556 : }
      88                 :            : 
      89                 :       3538 : void emit_bc_free(emit_t *emit) {
      90                 :       3538 :     m_del(size_t, emit->label_offsets, emit->max_num_labels);
      91                 :       3538 :     m_del_obj(emit_t, emit);
      92                 :       3538 : }
      93                 :            : 
      94                 :            : // all functions must go through this one to emit code info
      95                 :     357846 : STATIC uint8_t *emit_get_cur_to_write_code_info(void *emit_in, size_t num_bytes_to_write) {
      96                 :     357846 :     emit_t *emit = emit_in;
      97         [ +  + ]:     357846 :     if (emit->pass < MP_PASS_EMIT) {
      98                 :     182851 :         emit->code_info_offset += num_bytes_to_write;
      99                 :     182851 :         return emit->dummy_data;
     100                 :            :     } else {
     101         [ -  + ]:     174995 :         assert(emit->code_info_offset + num_bytes_to_write <= emit->code_info_size);
     102                 :     174995 :         byte *c = emit->code_base + emit->code_info_offset;
     103                 :     174995 :         emit->code_info_offset += num_bytes_to_write;
     104                 :     174995 :         return c;
     105                 :            :     }
     106                 :            : }
     107                 :            : 
     108                 :      37655 : STATIC void emit_write_code_info_byte(emit_t *emit, byte val) {
     109                 :      37655 :     *emit_get_cur_to_write_code_info(emit, 1) = val;
     110                 :      37655 : }
     111                 :            : 
     112                 :      32358 : STATIC void emit_write_code_info_qstr(emit_t *emit, qstr qst) {
     113                 :      32358 :     mp_encode_uint(emit, emit_get_cur_to_write_code_info, mp_emit_common_use_qstr(emit->emit_common, qst));
     114                 :      32358 : }
     115                 :            : 
     116                 :            : #if MICROPY_ENABLE_SOURCE_LINE
     117                 :     279988 : STATIC void emit_write_code_info_bytes_lines(emit_t *emit, mp_uint_t bytes_to_skip, mp_uint_t lines_to_skip) {
     118         [ -  + ]:     279988 :     assert(bytes_to_skip > 0 || lines_to_skip > 0);
     119         [ +  + ]:     567821 :     while (bytes_to_skip > 0 || lines_to_skip > 0) {
     120                 :     287833 :         mp_uint_t b, l;
     121         [ +  + ]:     287833 :         if (lines_to_skip <= 6 || bytes_to_skip > 0xf) {
     122                 :            :             // use 0b0LLBBBBB encoding
     123                 :     271786 :             b = MIN(bytes_to_skip, 0x1f);
     124         [ +  + ]:     271786 :             if (b < bytes_to_skip) {
     125                 :            :                 // we can't skip any lines until we skip all the bytes
     126                 :            :                 l = 0;
     127                 :            :             } else {
     128                 :     271531 :                 l = MIN(lines_to_skip, 0x3);
     129                 :            :             }
     130                 :     271786 :             *emit_get_cur_to_write_code_info(emit, 1) = b | (l << 5);
     131                 :            :         } else {
     132                 :            :             // use 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte)
     133                 :      16047 :             b = MIN(bytes_to_skip, 0xf);
     134                 :      16047 :             l = MIN(lines_to_skip, 0x7ff);
     135                 :      16047 :             byte *ci = emit_get_cur_to_write_code_info(emit, 2);
     136                 :      16047 :             ci[0] = 0x80 | b | ((l >> 4) & 0x70);
     137                 :      16047 :             ci[1] = l;
     138                 :            :         }
     139                 :     287833 :         bytes_to_skip -= b;
     140                 :     287833 :         lines_to_skip -= l;
     141                 :            :     }
     142                 :     279988 : }
     143                 :            : #endif
     144                 :            : 
     145                 :            : // all functions must go through this one to emit byte code
     146                 :    2242950 : STATIC uint8_t *emit_get_cur_to_write_bytecode(void *emit_in, size_t num_bytes_to_write) {
     147                 :    2242950 :     emit_t *emit = emit_in;
     148         [ +  + ]:    2242950 :     if (emit->suppress) {
     149                 :       9720 :         return emit->dummy_data;
     150                 :            :     }
     151         [ +  + ]:    2233230 :     if (emit->pass < MP_PASS_EMIT) {
     152                 :     945969 :         emit->bytecode_offset += num_bytes_to_write;
     153                 :     945969 :         return emit->dummy_data;
     154                 :            :     } else {
     155         [ -  + ]:    1287261 :         assert(emit->bytecode_offset + num_bytes_to_write <= emit->bytecode_size);
     156                 :    1287261 :         byte *c = emit->code_base + emit->code_info_size + emit->bytecode_offset;
     157                 :    1287261 :         emit->bytecode_offset += num_bytes_to_write;
     158                 :    1287261 :         return c;
     159                 :            :     }
     160                 :            : }
     161                 :            : 
     162                 :       1136 : STATIC void emit_write_bytecode_raw_byte(emit_t *emit, byte b1) {
     163                 :       1136 :     byte *c = emit_get_cur_to_write_bytecode(emit, 1);
     164                 :       1136 :     c[0] = b1;
     165                 :       1136 : }
     166                 :            : 
     167                 :    1304322 : STATIC void emit_write_bytecode_byte(emit_t *emit, int stack_adj, byte b1) {
     168                 :    1304322 :     mp_emit_bc_adjust_stack_size(emit, stack_adj);
     169                 :    1304323 :     byte *c = emit_get_cur_to_write_bytecode(emit, 1);
     170                 :    1304321 :     c[0] = b1;
     171                 :    1304321 : }
     172                 :            : 
     173                 :            : // Similar to mp_encode_uint(), just some extra handling to encode sign
     174                 :       7042 : STATIC void emit_write_bytecode_byte_int(emit_t *emit, int stack_adj, byte b1, mp_int_t num) {
     175                 :       7042 :     emit_write_bytecode_byte(emit, stack_adj, b1);
     176                 :            : 
     177                 :            :     // We store each 7 bits in a separate byte, and that's how many bytes needed
     178                 :       7042 :     byte buf[MP_ENCODE_UINT_MAX_BYTES];
     179                 :       7042 :     byte *p = buf + sizeof(buf);
     180                 :            :     // We encode in little-ending order, but store in big-endian, to help decoding
     181                 :      14267 :     do {
     182                 :      14267 :         *--p = num & 0x7f;
     183                 :      14267 :         num >>= 7;
     184         [ +  + ]:      14267 :     } while (num != 0 && num != -1);
     185                 :            :     // Make sure that highest bit we stored (mask 0x40) matches sign
     186                 :            :     // of the number. If not, store extra byte just to encode sign
     187   [ +  +  +  + ]:       7042 :     if (num == -1 && (*p & 0x40) == 0) {
     188                 :        180 :         *--p = 0x7f;
     189   [ +  +  +  + ]:       6862 :     } else if (num == 0 && (*p & 0x40) != 0) {
     190                 :       2173 :         *--p = 0;
     191                 :            :     }
     192                 :            : 
     193                 :       7042 :     byte *c = emit_get_cur_to_write_bytecode(emit, buf + sizeof(buf) - p);
     194         [ +  + ]:      16619 :     while (p != buf + sizeof(buf) - 1) {
     195                 :       9577 :         *c++ = *p++ | 0x80;
     196                 :            :     }
     197                 :       7041 :     *c = *p;
     198                 :       7041 : }
     199                 :            : 
     200                 :     694881 : STATIC void emit_write_bytecode_byte_uint(emit_t *emit, int stack_adj, byte b, mp_uint_t val) {
     201                 :     694881 :     emit_write_bytecode_byte(emit, stack_adj, b);
     202                 :     694878 :     mp_encode_uint(emit, emit_get_cur_to_write_bytecode, val);
     203                 :     694877 : }
     204                 :            : 
     205                 :      32771 : STATIC void emit_write_bytecode_byte_const(emit_t *emit, int stack_adj, byte b, mp_uint_t n) {
     206                 :      32771 :     emit_write_bytecode_byte_uint(emit, stack_adj, b, n);
     207                 :      32771 : }
     208                 :            : 
     209                 :     332428 : STATIC void emit_write_bytecode_byte_qstr(emit_t *emit, int stack_adj, byte b, qstr qst) {
     210                 :     332428 :     emit_write_bytecode_byte_uint(emit, stack_adj, b, mp_emit_common_use_qstr(emit->emit_common, qst));
     211                 :     332425 : }
     212                 :            : 
     213                 :      18316 : STATIC void emit_write_bytecode_byte_obj(emit_t *emit, int stack_adj, byte b, mp_obj_t obj) {
     214                 :      18316 :     emit_write_bytecode_byte_const(emit, stack_adj, b, mp_emit_common_use_const_obj(emit->emit_common, obj));
     215                 :      18316 : }
     216                 :            : 
     217                 :      14455 : STATIC void emit_write_bytecode_byte_child(emit_t *emit, int stack_adj, byte b, mp_raw_code_t *rc) {
     218         [ +  + ]:      17458 :     emit_write_bytecode_byte_const(emit, stack_adj, b,
     219                 :            :         mp_emit_common_alloc_const_child(emit->emit_common, rc));
     220                 :            :     #if MICROPY_PY_SYS_SETTRACE
     221                 :            :     rc->line_of_definition = emit->last_source_line;
     222                 :            :     #endif
     223                 :      14455 : }
     224                 :            : 
     225                 :            : // Emit a jump opcode to a destination label.
     226                 :            : // The offset to the label is relative to the ip following this instruction.
     227                 :            : // The offset is encoded as either 1 or 2 bytes, depending on how big it is.
     228                 :            : // The encoding of this jump opcode can change size from one pass to the next,
     229                 :            : // but it must only ever decrease in size on successive passes.
     230                 :     238694 : STATIC void emit_write_bytecode_byte_label(emit_t *emit, int stack_adj, byte b1, mp_uint_t label) {
     231                 :     238694 :     mp_emit_bc_adjust_stack_size(emit, stack_adj);
     232                 :            : 
     233         [ +  + ]:     238694 :     if (emit->suppress) {
     234                 :            :         return;
     235                 :            :     }
     236                 :            : 
     237                 :            :     // Determine if the jump offset is signed or unsigned, based on the opcode.
     238                 :     235573 :     const bool is_signed = b1 <= MP_BC_POP_JUMP_IF_FALSE;
     239                 :            : 
     240                 :            :     // Default to a 2-byte encoding (the largest) with an unknown jump offset.
     241                 :     235573 :     unsigned int jump_encoding_size = 1;
     242                 :     235573 :     ssize_t bytecode_offset = 0;
     243                 :            : 
     244                 :            :     // Compute the jump size and offset only when code size is known.
     245         [ +  + ]:     235573 :     if (emit->pass >= MP_PASS_CODE_SIZE) {
     246                 :            :         // The -2 accounts for this jump opcode taking 2 bytes (at least).
     247                 :     187539 :         bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 2;
     248                 :            : 
     249                 :            :         // Check if the bytecode_offset is small enough to use a 1-byte encoding.
     250   [ +  +  +  + ]:     187539 :         if ((is_signed && -64 <= bytecode_offset && bytecode_offset <= 63)
     251         [ +  + ]:     159117 :             || (!is_signed && (size_t)bytecode_offset <= 127)) {
     252                 :            :             // Use a 1-byte jump offset.
     253                 :     116626 :             jump_encoding_size = 0;
     254                 :            :         }
     255                 :            : 
     256                 :            :         // Adjust the offset depending on the size of the encoding of the offset.
     257                 :     187539 :         bytecode_offset -= jump_encoding_size;
     258                 :            : 
     259         [ -  + ]:     187539 :         assert(is_signed || bytecode_offset >= 0);
     260                 :            :     }
     261                 :            : 
     262                 :            :     // Emit the opcode.
     263                 :     235573 :     byte *c = emit_get_cur_to_write_bytecode(emit, 2 + jump_encoding_size);
     264                 :     235573 :     c[0] = b1;
     265         [ +  + ]:     235573 :     if (jump_encoding_size == 0) {
     266         [ +  + ]:     116626 :         if (is_signed) {
     267                 :      28422 :             bytecode_offset += 0x40;
     268                 :            :         }
     269         [ -  + ]:     116626 :         assert(0 <= bytecode_offset && bytecode_offset <= 0x7f);
     270                 :     116626 :         c[1] = bytecode_offset;
     271                 :            :     } else {
     272         [ +  + ]:     118947 :         if (is_signed) {
     273                 :      33740 :             bytecode_offset += 0x4000;
     274                 :            :         }
     275   [ +  +  +  + ]:     118947 :         if (emit->pass == MP_PASS_EMIT && !(0 <= bytecode_offset && bytecode_offset <= 0x7fff)) {
     276                 :         69 :             emit->overflow = true;
     277                 :            :         }
     278                 :     118947 :         c[1] = 0x80 | (bytecode_offset & 0x7f);
     279                 :     118947 :         c[2] = bytecode_offset >> 7;
     280                 :            :     }
     281                 :            : }
     282                 :            : 
     283                 :      23745 : void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
     284                 :      23745 :     emit->pass = pass;
     285                 :      23745 :     emit->stack_size = 0;
     286                 :      23745 :     emit->suppress = false;
     287                 :      23745 :     emit->scope = scope;
     288                 :      23745 :     emit->last_source_line_offset = 0;
     289                 :      23745 :     emit->last_source_line = 1;
     290                 :      23745 :     emit->bytecode_offset = 0;
     291                 :      23745 :     emit->code_info_offset = 0;
     292                 :      23745 :     emit->overflow = false;
     293                 :            : 
     294                 :            :     // Write local state size, exception stack size, scope flags and number of arguments
     295                 :            :     {
     296                 :      23745 :         mp_uint_t n_state = scope->num_locals + scope->stack_size;
     297         [ +  + ]:      23745 :         if (n_state == 0) {
     298                 :            :             // Need at least 1 entry in the state, in the case an exception is
     299                 :            :             // propagated through this function, the exception is returned in
     300                 :            :             // the highest slot in the state (fastn[0], see vm.c).
     301                 :      12062 :             n_state = 1;
     302                 :            :         }
     303                 :            :         #if MICROPY_DEBUG_VM_STACK_OVERFLOW
     304                 :            :         // An extra slot in the stack is needed to detect VM stack overflow
     305                 :            :         n_state += 1;
     306                 :            :         #endif
     307                 :            : 
     308                 :      23745 :         size_t n_exc_stack = scope->exc_stack_size;
     309         [ +  + ]:      27418 :         MP_BC_PRELUDE_SIG_ENCODE(n_state, n_exc_stack, scope, emit_write_code_info_byte, emit);
     310                 :            :     }
     311                 :            : 
     312                 :            :     // Write number of cells and size of the source code info
     313         [ +  + ]:      23746 :     if (emit->pass >= MP_PASS_CODE_SIZE) {
     314                 :       9806 :         size_t n_info = emit->n_info;
     315                 :       9806 :         size_t n_cell = emit->n_cell;
     316   [ +  +  +  + ]:       9974 :         MP_BC_PRELUDE_SIZE_ENCODE(n_info, n_cell, emit_write_code_info_byte, emit);
     317                 :            :     }
     318                 :            : 
     319                 :      23746 :     emit->n_info = emit->code_info_offset;
     320                 :            : 
     321                 :            :     // Write the name of this function.
     322                 :      23746 :     emit_write_code_info_qstr(emit, scope->simple_name);
     323                 :            : 
     324                 :            :     // Write argument names, needed to resolve positional args passed as keywords.
     325                 :            :     {
     326                 :            :         // For a given argument position (indexed by i) we need to find the
     327                 :            :         // corresponding id_info which is a parameter, as it has the correct
     328                 :            :         // qstr name to use as the argument name.  Note that it's not a simple
     329                 :            :         // 1-1 mapping (ie i!=j in general) because of possible closed-over
     330                 :            :         // variables.  In the case that the argument i has no corresponding
     331                 :            :         // parameter we use "*" as its name (since no argument can ever be named
     332                 :            :         // "*").  We could use a blank qstr but "*" is better for debugging.
     333                 :            :         // Note: there is some wasted RAM here for the case of storing a qstr
     334                 :            :         // for each closed-over variable, and maybe there is a better way to do
     335                 :            :         // it, but that would require changes to mp_setup_code_state.
     336         [ +  + ]:      32359 :         for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
     337                 :      15365 :             qstr qst = MP_QSTR__star_;
     338         [ +  + ]:      15365 :             for (int j = 0; j < scope->id_info_len; ++j) {
     339                 :      14741 :                 id_info_t *id = &scope->id_info[j];
     340   [ +  +  +  + ]:      14741 :                 if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
     341                 :       7989 :                     qst = id->qst;
     342                 :       7989 :                     break;
     343                 :            :                 }
     344                 :            :             }
     345                 :       8613 :             emit_write_code_info_qstr(emit, qst);
     346                 :            :         }
     347                 :            :     }
     348                 :      23745 : }
     349                 :            : 
     350                 :      23741 : bool mp_emit_bc_end_pass(emit_t *emit) {
     351         [ +  + ]:      23741 :     if (emit->pass == MP_PASS_SCOPE) {
     352                 :            :         return true;
     353                 :            :     }
     354                 :            : 
     355                 :            :     // check stack is back to zero size
     356         [ -  + ]:      14644 :     assert(emit->stack_size == 0);
     357                 :            : 
     358                 :            :     // Calculate size of source code info section
     359                 :      14644 :     emit->n_info = emit->code_info_offset - emit->n_info;
     360                 :            : 
     361                 :            :     // Emit closure section of prelude
     362                 :      14644 :     emit->n_cell = 0;
     363         [ +  + ]:      73641 :     for (size_t i = 0; i < emit->scope->id_info_len; ++i) {
     364                 :      58997 :         id_info_t *id = &emit->scope->id_info[i];
     365         [ +  + ]:      58997 :         if (id->kind == ID_INFO_KIND_CELL) {
     366         [ -  + ]:        261 :             assert(id->local_num <= 255);
     367                 :        261 :             emit_write_code_info_byte(emit, id->local_num); // write the local which should be converted to a cell
     368                 :        261 :             ++emit->n_cell;
     369                 :            :         }
     370                 :            :     }
     371                 :            : 
     372         [ +  + ]:      14644 :     if (emit->pass == MP_PASS_CODE_SIZE) {
     373                 :            :         // calculate size of total code-info + bytecode, in bytes
     374                 :       4838 :         emit->code_info_size = emit->code_info_offset;
     375                 :       4838 :         emit->bytecode_size = emit->bytecode_offset;
     376                 :       4838 :         emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size);
     377                 :            : 
     378         [ +  + ]:       9806 :     } else if (emit->pass == MP_PASS_EMIT) {
     379                 :            :         // Code info and/or bytecode can shrink during this pass.
     380         [ -  + ]:       4968 :         assert(emit->code_info_offset <= emit->code_info_size);
     381         [ -  + ]:       4968 :         assert(emit->bytecode_offset <= emit->bytecode_size);
     382                 :            : 
     383         [ +  + ]:       4968 :         if (emit->code_info_offset != emit->code_info_size
     384         [ +  + ]:       4967 :             || emit->bytecode_offset != emit->bytecode_size) {
     385                 :            :             // Code info and/or bytecode changed size in this pass, so request the
     386                 :            :             // compiler to do another pass with these updated sizes.
     387                 :        130 :             emit->code_info_size = emit->code_info_offset;
     388                 :        130 :             emit->bytecode_size = emit->bytecode_offset;
     389                 :        130 :             return false;
     390                 :            :         }
     391                 :            : 
     392         [ +  + ]:       4838 :         if (emit->overflow) {
     393                 :          2 :             mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("bytecode overflow"));
     394                 :            :         }
     395                 :            : 
     396                 :            :         // Bytecode is finalised, assign it to the raw code object.
     397                 :       4836 :         mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base,
     398                 :            :             #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS
     399                 :            :             emit->code_info_size + emit->bytecode_size,
     400                 :            :             #endif
     401                 :       4836 :             emit->emit_common->children,
     402                 :            :             #if MICROPY_PERSISTENT_CODE_SAVE
     403                 :            :             emit->emit_common->ct_cur_child,
     404                 :            :             #endif
     405                 :       4836 :             emit->scope->scope_flags);
     406                 :            :     }
     407                 :            : 
     408                 :            :     return true;
     409                 :            : }
     410                 :            : 
     411                 :    1965375 : void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
     412         [ +  + ]:    1965375 :     if (emit->pass == MP_PASS_SCOPE) {
     413                 :            :         return;
     414                 :            :     }
     415         [ -  + ]:    1661226 :     assert((mp_int_t)emit->stack_size + delta >= 0);
     416                 :    1661226 :     emit->stack_size += delta;
     417         [ +  + ]:    1661226 :     if (emit->stack_size > emit->scope->stack_size) {
     418                 :      17936 :         emit->scope->stack_size = emit->stack_size;
     419                 :            :     }
     420                 :            : }
     421                 :            : 
     422                 :     841832 : void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
     423                 :            :     #if MICROPY_ENABLE_SOURCE_LINE
     424         [ +  + ]:     841832 :     if (MP_STATE_VM(mp_optimise_value) >= 3) {
     425                 :            :         // If we compile with -O3, don't store line numbers.
     426                 :            :         return;
     427                 :            :     }
     428         [ +  + ]:     841784 :     if (source_line > emit->last_source_line) {
     429                 :     279988 :         mp_uint_t bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset;
     430                 :     279988 :         mp_uint_t lines_to_skip = source_line - emit->last_source_line;
     431                 :     279988 :         emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip);
     432                 :     279988 :         emit->last_source_line_offset = emit->bytecode_offset;
     433                 :     279988 :         emit->last_source_line = source_line;
     434                 :            :     }
     435                 :            :     #else
     436                 :            :     (void)emit;
     437                 :            :     (void)source_line;
     438                 :            :     #endif
     439                 :            : }
     440                 :            : 
     441                 :     246839 : void mp_emit_bc_label_assign(emit_t *emit, mp_uint_t l) {
     442                 :            :     // Assiging a label ends any dead-code region, and all following opcodes
     443                 :            :     // should be emitted (until another unconditional flow control).
     444                 :     246839 :     emit->suppress = false;
     445                 :            : 
     446                 :     246839 :     mp_emit_bc_adjust_stack_size(emit, 0);
     447         [ +  + ]:     246839 :     if (emit->pass == MP_PASS_SCOPE) {
     448                 :            :         return;
     449                 :            :     }
     450                 :            : 
     451                 :            :     // Label offsets can change from one pass to the next, but they must only
     452                 :            :     // decrease (ie code can only shrink).  There will be multiple MP_PASS_EMIT
     453                 :            :     // stages until the labels no longer change, which is when the code size
     454                 :            :     // stays constant after a MP_PASS_EMIT.
     455         [ -  + ]:     213944 :     assert(l < emit->max_num_labels);
     456   [ +  +  -  + ]:     213944 :     assert(emit->pass == MP_PASS_STACK_SIZE || emit->bytecode_offset <= emit->label_offsets[l]);
     457                 :            : 
     458                 :            :     // Assign label offset.
     459                 :     213944 :     emit->label_offsets[l] = emit->bytecode_offset;
     460                 :            : }
     461                 :            : 
     462                 :       6247 : void mp_emit_bc_import(emit_t *emit, qstr qst, int kind) {
     463                 :       6247 :     MP_STATIC_ASSERT(MP_BC_IMPORT_NAME + MP_EMIT_IMPORT_NAME == MP_BC_IMPORT_NAME);
     464                 :       6247 :     MP_STATIC_ASSERT(MP_BC_IMPORT_NAME + MP_EMIT_IMPORT_FROM == MP_BC_IMPORT_FROM);
     465         [ +  + ]:       6247 :     int stack_adj = kind == MP_EMIT_IMPORT_FROM ? 1 : -1;
     466         [ +  + ]:       4623 :     if (kind == MP_EMIT_IMPORT_STAR) {
     467                 :        186 :         emit_write_bytecode_byte(emit, stack_adj, MP_BC_IMPORT_STAR);
     468                 :            :     } else {
     469                 :       6061 :         emit_write_bytecode_byte_qstr(emit, stack_adj, MP_BC_IMPORT_NAME + kind, qst);
     470                 :            :     }
     471                 :       6247 : }
     472                 :            : 
     473                 :      76883 : void mp_emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
     474                 :      76883 :     MP_STATIC_ASSERT(MP_BC_LOAD_CONST_FALSE + (MP_TOKEN_KW_NONE - MP_TOKEN_KW_FALSE) == MP_BC_LOAD_CONST_NONE);
     475                 :      76883 :     MP_STATIC_ASSERT(MP_BC_LOAD_CONST_FALSE + (MP_TOKEN_KW_TRUE - MP_TOKEN_KW_FALSE) == MP_BC_LOAD_CONST_TRUE);
     476         [ +  + ]:      76883 :     if (tok == MP_TOKEN_ELLIPSIS) {
     477                 :         12 :         emit_write_bytecode_byte_obj(emit, 1, MP_BC_LOAD_CONST_OBJ, MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj));
     478                 :            :     } else {
     479                 :      76871 :         emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_CONST_FALSE + (tok - MP_TOKEN_KW_FALSE));
     480                 :            :     }
     481                 :      76882 : }
     482                 :            : 
     483                 :      61567 : void mp_emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg) {
     484         [ -  + ]:      61567 :     assert(MP_SMALL_INT_FITS(arg));
     485                 :      61567 :     if (-MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS <= arg
     486         [ +  + ]:      61567 :         && arg < MP_BC_LOAD_CONST_SMALL_INT_MULTI_NUM - MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS) {
     487                 :      54525 :         emit_write_bytecode_byte(emit, 1,
     488                 :      54525 :             MP_BC_LOAD_CONST_SMALL_INT_MULTI + MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS + arg);
     489                 :            :     } else {
     490                 :       7042 :         emit_write_bytecode_byte_int(emit, 1, MP_BC_LOAD_CONST_SMALL_INT, arg);
     491                 :            :     }
     492                 :      61566 : }
     493                 :            : 
     494                 :      40403 : void mp_emit_bc_load_const_str(emit_t *emit, qstr qst) {
     495                 :      40403 :     emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_CONST_STRING, qst);
     496                 :      40402 : }
     497                 :            : 
     498                 :      18304 : void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj) {
     499                 :      18304 :     emit_write_bytecode_byte_obj(emit, 1, MP_BC_LOAD_CONST_OBJ, obj);
     500                 :      18304 : }
     501                 :            : 
     502                 :       1783 : void mp_emit_bc_load_null(emit_t *emit) {
     503                 :       1783 :     emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_NULL);
     504                 :       1783 : }
     505                 :            : 
     506                 :      25798 : void mp_emit_bc_load_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     507                 :      25798 :     MP_STATIC_ASSERT(MP_BC_LOAD_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_LOAD_FAST_N);
     508                 :      25798 :     MP_STATIC_ASSERT(MP_BC_LOAD_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_LOAD_DEREF);
     509                 :      25798 :     (void)qst;
     510         [ +  + ]:      25798 :     if (kind == MP_EMIT_IDOP_LOCAL_FAST && local_num <= 15) {
     511                 :      25201 :         emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_FAST_MULTI + local_num);
     512                 :            :     } else {
     513                 :        597 :         emit_write_bytecode_byte_uint(emit, 1, MP_BC_LOAD_FAST_N + kind, local_num);
     514                 :            :     }
     515                 :      25798 : }
     516                 :            : 
     517                 :     186481 : void mp_emit_bc_load_global(emit_t *emit, qstr qst, int kind) {
     518                 :     186481 :     MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_LOAD_NAME);
     519                 :     186481 :     MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_LOAD_GLOBAL);
     520                 :     186481 :     (void)qst;
     521                 :     186481 :     emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_NAME + kind, qst);
     522                 :     186480 : }
     523                 :            : 
     524                 :      23909 : void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) {
     525                 :      23909 :     int stack_adj = 1 - 2 * is_super;
     526         [ +  + ]:      47740 :     emit_write_bytecode_byte_qstr(emit, stack_adj, is_super ? MP_BC_LOAD_SUPER_METHOD : MP_BC_LOAD_METHOD, qst);
     527                 :      23909 : }
     528                 :            : 
     529                 :       2376 : void mp_emit_bc_load_build_class(emit_t *emit) {
     530                 :       2376 :     emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_BUILD_CLASS);
     531                 :       2376 : }
     532                 :            : 
     533                 :       8845 : void mp_emit_bc_subscr(emit_t *emit, int kind) {
     534         [ +  + ]:       8845 :     if (kind == MP_EMIT_SUBSCR_LOAD) {
     535                 :       6252 :         emit_write_bytecode_byte(emit, -1, MP_BC_LOAD_SUBSCR);
     536                 :            :     } else {
     537         [ +  + ]:       2593 :         if (kind == MP_EMIT_SUBSCR_DELETE) {
     538                 :        283 :             mp_emit_bc_load_null(emit);
     539                 :        283 :             mp_emit_bc_rot_three(emit);
     540                 :            :         }
     541                 :       2593 :         emit_write_bytecode_byte(emit, -3, MP_BC_STORE_SUBSCR);
     542                 :            :     }
     543                 :       8845 : }
     544                 :            : 
     545                 :      17216 : void mp_emit_bc_attr(emit_t *emit, qstr qst, int kind) {
     546         [ +  + ]:      17216 :     if (kind == MP_EMIT_ATTR_LOAD) {
     547                 :      13660 :         emit_write_bytecode_byte_qstr(emit, 0, MP_BC_LOAD_ATTR, qst);
     548                 :            :     } else {
     549         [ +  + ]:       3556 :         if (kind == MP_EMIT_ATTR_DELETE) {
     550                 :         74 :             mp_emit_bc_load_null(emit);
     551                 :         74 :             mp_emit_bc_rot_two(emit);
     552                 :            :         }
     553                 :       3556 :         emit_write_bytecode_byte_qstr(emit, -2, MP_BC_STORE_ATTR, qst);
     554                 :            :     }
     555                 :      17216 : }
     556                 :            : 
     557                 :       6775 : void mp_emit_bc_store_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     558                 :       6775 :     MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_STORE_FAST_N);
     559                 :       6775 :     MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_STORE_DEREF);
     560                 :       6775 :     (void)qst;
     561         [ +  + ]:       6775 :     if (kind == MP_EMIT_IDOP_LOCAL_FAST && local_num <= 15) {
     562                 :       6118 :         emit_write_bytecode_byte(emit, -1, MP_BC_STORE_FAST_MULTI + local_num);
     563                 :            :     } else {
     564                 :        657 :         emit_write_bytecode_byte_uint(emit, -1, MP_BC_STORE_FAST_N + kind, local_num);
     565                 :            :     }
     566                 :       6775 : }
     567                 :            : 
     568                 :      57990 : void mp_emit_bc_store_global(emit_t *emit, qstr qst, int kind) {
     569                 :      57990 :     MP_STATIC_ASSERT(MP_BC_STORE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_STORE_NAME);
     570                 :      57990 :     MP_STATIC_ASSERT(MP_BC_STORE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_STORE_GLOBAL);
     571                 :      57990 :     emit_write_bytecode_byte_qstr(emit, -1, MP_BC_STORE_NAME + kind, qst);
     572                 :      57990 : }
     573                 :            : 
     574                 :        319 : void mp_emit_bc_delete_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     575                 :        319 :     MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_DELETE_FAST);
     576                 :        319 :     MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_DELETE_DEREF);
     577                 :        319 :     (void)qst;
     578                 :        319 :     emit_write_bytecode_byte_uint(emit, 0, MP_BC_DELETE_FAST + kind, local_num);
     579                 :        319 : }
     580                 :            : 
     581                 :        369 : void mp_emit_bc_delete_global(emit_t *emit, qstr qst, int kind) {
     582                 :        369 :     MP_STATIC_ASSERT(MP_BC_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_DELETE_NAME);
     583                 :        369 :     MP_STATIC_ASSERT(MP_BC_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_DELETE_GLOBAL);
     584                 :        369 :     emit_write_bytecode_byte_qstr(emit, 0, MP_BC_DELETE_NAME + kind, qst);
     585                 :        369 : }
     586                 :            : 
     587                 :      46993 : void mp_emit_bc_dup_top(emit_t *emit) {
     588                 :      46993 :     emit_write_bytecode_byte(emit, 1, MP_BC_DUP_TOP);
     589                 :      46993 : }
     590                 :            : 
     591                 :        676 : void mp_emit_bc_dup_top_two(emit_t *emit) {
     592                 :        676 :     emit_write_bytecode_byte(emit, 2, MP_BC_DUP_TOP_TWO);
     593                 :        676 : }
     594                 :            : 
     595                 :     143537 : void mp_emit_bc_pop_top(emit_t *emit) {
     596                 :     143537 :     emit_write_bytecode_byte(emit, -1, MP_BC_POP_TOP);
     597                 :     143538 : }
     598                 :            : 
     599                 :       1152 : void mp_emit_bc_rot_two(emit_t *emit) {
     600                 :       1152 :     emit_write_bytecode_byte(emit, 0, MP_BC_ROT_TWO);
     601                 :       1152 : }
     602                 :            : 
     603                 :        746 : void mp_emit_bc_rot_three(emit_t *emit) {
     604                 :        746 :     emit_write_bytecode_byte(emit, 0, MP_BC_ROT_THREE);
     605                 :        746 : }
     606                 :            : 
     607                 :       7868 : void mp_emit_bc_jump(emit_t *emit, mp_uint_t label) {
     608                 :       7868 :     emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label);
     609                 :       7868 :     emit->suppress = true;
     610                 :       7868 : }
     611                 :            : 
     612                 :      54248 : void mp_emit_bc_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label) {
     613         [ +  + ]:      54248 :     if (cond) {
     614                 :       4463 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_TRUE, label);
     615                 :            :     } else {
     616                 :      49785 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_FALSE, label);
     617                 :            :     }
     618                 :      54248 : }
     619                 :            : 
     620                 :        454 : void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label) {
     621         [ +  + ]:        454 :     if (cond) {
     622                 :        221 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_TRUE_OR_POP, label);
     623                 :            :     } else {
     624                 :        233 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_FALSE_OR_POP, label);
     625                 :            :     }
     626                 :        454 : }
     627                 :            : 
     628                 :        666 : void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_depth) {
     629         [ +  + ]:        666 :     if (except_depth == 0) {
     630         [ +  + ]:        482 :         if (label & MP_EMIT_BREAK_FROM_FOR) {
     631                 :            :             // need to pop the iterator if we are breaking out of a for loop
     632                 :        184 :             emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP);
     633                 :            :             // also pop the iter_buf
     634         [ +  + ]:        736 :             for (size_t i = 0; i < MP_OBJ_ITER_BUF_NSLOTS - 1; ++i) {
     635                 :        552 :                 emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP);
     636                 :            :             }
     637                 :            :         }
     638                 :        482 :         emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
     639                 :            :     } else {
     640                 :        184 :         emit_write_bytecode_byte_label(emit, 0, MP_BC_UNWIND_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
     641                 :        184 :         emit_write_bytecode_raw_byte(emit, ((label & MP_EMIT_BREAK_FROM_FOR) ? 0x80 : 0) | except_depth);
     642                 :            :     }
     643                 :        666 :     emit->suppress = true;
     644                 :        666 : }
     645                 :            : 
     646                 :      83222 : void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind) {
     647                 :      83222 :     MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_WITH == MP_BC_SETUP_WITH);
     648                 :      83222 :     MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_EXCEPT == MP_BC_SETUP_EXCEPT);
     649                 :      83222 :     MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_FINALLY == MP_BC_SETUP_FINALLY);
     650                 :            :     // The SETUP_WITH opcode pops ctx_mgr from the top of the stack
     651                 :            :     // and then pushes 3 entries: __exit__, ctx_mgr, as_value.
     652         [ +  + ]:      83222 :     int stack_adj = kind == MP_EMIT_SETUP_BLOCK_WITH ? 2 : 0;
     653                 :      83222 :     emit_write_bytecode_byte_label(emit, stack_adj, MP_BC_SETUP_WITH + kind, label);
     654                 :      83222 : }
     655                 :            : 
     656                 :      36651 : void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) {
     657                 :      36651 :     mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE);
     658                 :      36651 :     mp_emit_bc_label_assign(emit, label);
     659                 :            :     // The +2 is to ensure we have enough stack space to call the __exit__ method
     660                 :      36651 :     emit_write_bytecode_byte(emit, 2, MP_BC_WITH_CLEANUP);
     661                 :            :     // Cancel the +2 above, plus the +2 from mp_emit_bc_setup_block(MP_EMIT_SETUP_BLOCK_WITH)
     662                 :      36651 :     mp_emit_bc_adjust_stack_size(emit, -4);
     663                 :      36651 : }
     664                 :            : 
     665                 :      83222 : void mp_emit_bc_end_finally(emit_t *emit) {
     666                 :      83222 :     emit_write_bytecode_byte(emit, -1, MP_BC_END_FINALLY);
     667                 :      83222 : }
     668                 :            : 
     669                 :       3617 : void mp_emit_bc_get_iter(emit_t *emit, bool use_stack) {
     670         [ +  + ]:       3617 :     int stack_adj = use_stack ? MP_OBJ_ITER_BUF_NSLOTS - 1 : 0;
     671                 :       3617 :     emit_write_bytecode_byte(emit, stack_adj, use_stack ? MP_BC_GET_ITER_STACK : MP_BC_GET_ITER);
     672                 :       3617 : }
     673                 :            : 
     674                 :       2284 : void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) {
     675                 :       2284 :     emit_write_bytecode_byte_label(emit, 1, MP_BC_FOR_ITER, label);
     676                 :       2284 : }
     677                 :            : 
     678                 :       2284 : void mp_emit_bc_for_iter_end(emit_t *emit) {
     679                 :       2284 :     mp_emit_bc_adjust_stack_size(emit, -MP_OBJ_ITER_BUF_NSLOTS);
     680                 :       2284 : }
     681                 :            : 
     682                 :      89952 : void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) {
     683                 :      89952 :     (void)within_exc_handler;
     684                 :      89952 :     emit_write_bytecode_byte_label(emit, 0, MP_BC_POP_EXCEPT_JUMP, label);
     685                 :      89952 :     emit->suppress = true;
     686                 :      89952 : }
     687                 :            : 
     688                 :       2070 : void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) {
     689                 :       2070 :     emit_write_bytecode_byte(emit, 0, MP_BC_UNARY_OP_MULTI + op);
     690                 :       2070 : }
     691                 :            : 
     692                 :      67113 : void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op) {
     693                 :      67113 :     bool invert = false;
     694         [ +  + ]:      67113 :     if (op == MP_BINARY_OP_NOT_IN) {
     695                 :            :         invert = true;
     696                 :            :         op = MP_BINARY_OP_IN;
     697         [ +  + ]:      66872 :     } else if (op == MP_BINARY_OP_IS_NOT) {
     698                 :        952 :         invert = true;
     699                 :        952 :         op = MP_BINARY_OP_IS;
     700                 :            :     }
     701                 :      67113 :     emit_write_bytecode_byte(emit, -1, MP_BC_BINARY_OP_MULTI + op);
     702         [ +  + ]:      67113 :     if (invert) {
     703                 :       1193 :         emit_write_bytecode_byte(emit, 0, MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NOT);
     704                 :            :     }
     705                 :      67113 : }
     706                 :            : 
     707                 :      12012 : void mp_emit_bc_build(emit_t *emit, mp_uint_t n_args, int kind) {
     708                 :      12012 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_TUPLE == MP_BC_BUILD_TUPLE);
     709                 :      12012 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_LIST == MP_BC_BUILD_LIST);
     710                 :      12012 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_MAP == MP_BC_BUILD_MAP);
     711                 :      12012 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_SET == MP_BC_BUILD_SET);
     712                 :      12012 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_SLICE == MP_BC_BUILD_SLICE);
     713         [ +  + ]:      12012 :     int stack_adj = kind == MP_EMIT_BUILD_MAP ? 1 : 1 - n_args;
     714                 :      12012 :     emit_write_bytecode_byte_uint(emit, stack_adj, MP_BC_BUILD_TUPLE + kind, n_args);
     715                 :      12012 : }
     716                 :            : 
     717                 :       3428 : void mp_emit_bc_store_map(emit_t *emit) {
     718                 :       3428 :     emit_write_bytecode_byte(emit, -2, MP_BC_STORE_MAP);
     719                 :       3428 : }
     720                 :            : 
     721                 :        332 : void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) {
     722                 :        332 :     int t;
     723                 :        332 :     int n;
     724         [ +  + ]:        332 :     if (kind == SCOPE_LIST_COMP) {
     725                 :            :         n = 0;
     726                 :            :         t = 0;
     727         [ +  + ]:         53 :     } else if (!MICROPY_PY_BUILTINS_SET || kind == SCOPE_DICT_COMP) {
     728                 :            :         n = 1;
     729                 :            :         t = 1;
     730                 :          5 :     } else if (MICROPY_PY_BUILTINS_SET) {
     731                 :          5 :         n = 0;
     732                 :          5 :         t = 2;
     733                 :            :     }
     734                 :            :     // the lower 2 bits of the opcode argument indicate the collection type
     735                 :        332 :     emit_write_bytecode_byte_uint(emit, -1 - n, MP_BC_STORE_COMP, ((collection_stack_index + n) << 2) | t);
     736                 :        332 : }
     737                 :            : 
     738                 :        640 : void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) {
     739                 :        640 :     emit_write_bytecode_byte_uint(emit, -1 + n_args, MP_BC_UNPACK_SEQUENCE, n_args);
     740                 :        640 : }
     741                 :            : 
     742                 :        177 : void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right) {
     743                 :        177 :     emit_write_bytecode_byte_uint(emit, -1 + n_left + n_right + 1, MP_BC_UNPACK_EX, n_left | (n_right << 8));
     744                 :        177 : }
     745                 :            : 
     746                 :      14239 : void mp_emit_bc_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
     747         [ +  + ]:      14239 :     if (n_pos_defaults == 0 && n_kw_defaults == 0) {
     748                 :      13503 :         emit_write_bytecode_byte_child(emit, 1, MP_BC_MAKE_FUNCTION, scope->raw_code);
     749                 :            :     } else {
     750                 :        736 :         emit_write_bytecode_byte_child(emit, -1, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code);
     751                 :            :     }
     752                 :      14239 : }
     753                 :            : 
     754                 :        216 : void mp_emit_bc_make_closure(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
     755         [ +  + ]:        216 :     if (n_pos_defaults == 0 && n_kw_defaults == 0) {
     756                 :        207 :         int stack_adj = -n_closed_over + 1;
     757                 :        207 :         emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE, scope->raw_code);
     758                 :        207 :         emit_write_bytecode_raw_byte(emit, n_closed_over);
     759                 :            :     } else {
     760         [ -  + ]:          9 :         assert(n_closed_over <= 255);
     761                 :          9 :         int stack_adj = -2 - (mp_int_t)n_closed_over + 1;
     762                 :          9 :         emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code);
     763                 :          9 :         emit_write_bytecode_raw_byte(emit, n_closed_over);
     764                 :            :     }
     765                 :        216 : }
     766                 :            : 
     767                 :     314949 : STATIC void emit_bc_call_function_method_helper(emit_t *emit, int stack_adj, mp_uint_t bytecode_base, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
     768         [ +  + ]:     314949 :     if (star_flags) {
     769                 :            :         // each positional arg is one object, each kwarg is two objects, the key
     770                 :            :         // and the value and one extra object for the star args bitmap.
     771                 :        724 :         stack_adj -= (int)n_positional + 2 * (int)n_keyword + 1;
     772                 :        724 :         emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base + 1, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints?
     773                 :            :     } else {
     774                 :     314225 :         stack_adj -= (int)n_positional + 2 * (int)n_keyword;
     775                 :     314225 :         emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints?
     776                 :            :     }
     777                 :     314949 : }
     778                 :            : 
     779                 :     291044 : void mp_emit_bc_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
     780                 :     291044 :     emit_bc_call_function_method_helper(emit, 0, MP_BC_CALL_FUNCTION, n_positional, n_keyword, star_flags);
     781                 :     291044 : }
     782                 :            : 
     783                 :      23905 : void mp_emit_bc_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
     784                 :      23905 :     emit_bc_call_function_method_helper(emit, -1, MP_BC_CALL_METHOD, n_positional, n_keyword, star_flags);
     785                 :      23905 : }
     786                 :            : 
     787                 :      28814 : void mp_emit_bc_return_value(emit_t *emit) {
     788                 :      28814 :     emit_write_bytecode_byte(emit, -1, MP_BC_RETURN_VALUE);
     789                 :      28814 :     emit->suppress = true;
     790                 :      28814 : }
     791                 :            : 
     792                 :       5134 : void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) {
     793                 :       5134 :     MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 1 == MP_BC_RAISE_OBJ);
     794                 :       5134 :     MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 2 == MP_BC_RAISE_FROM);
     795         [ -  + ]:       5134 :     assert(n_args <= 2);
     796                 :       5134 :     emit_write_bytecode_byte(emit, -n_args, MP_BC_RAISE_LAST + n_args);
     797                 :       5134 :     emit->suppress = true;
     798                 :       5134 : }
     799                 :            : 
     800                 :       2159 : void mp_emit_bc_yield(emit_t *emit, int kind) {
     801                 :       2159 :     MP_STATIC_ASSERT(MP_BC_YIELD_VALUE + 1 == MP_BC_YIELD_FROM);
     802                 :       2159 :     emit_write_bytecode_byte(emit, -kind, MP_BC_YIELD_VALUE + kind);
     803                 :       2159 :     emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
     804                 :       2159 : }
     805                 :            : 
     806                 :      44950 : void mp_emit_bc_start_except_handler(emit_t *emit) {
     807                 :      44950 :     mp_emit_bc_adjust_stack_size(emit, 4); // stack adjust for the exception instance, +3 for possible UNWIND_JUMP state
     808                 :      44950 : }
     809                 :            : 
     810                 :      44946 : void mp_emit_bc_end_except_handler(emit_t *emit) {
     811                 :      44946 :     mp_emit_bc_adjust_stack_size(emit, -3); // stack adjust
     812                 :      44946 : }
     813                 :            : 
     814                 :            : #if MICROPY_EMIT_NATIVE
     815                 :            : const emit_method_table_t emit_bc_method_table = {
     816                 :            :     #if MICROPY_DYNAMIC_COMPILER
     817                 :            :     NULL,
     818                 :            :     NULL,
     819                 :            :     #endif
     820                 :            : 
     821                 :            :     mp_emit_bc_start_pass,
     822                 :            :     mp_emit_bc_end_pass,
     823                 :            :     mp_emit_bc_adjust_stack_size,
     824                 :            :     mp_emit_bc_set_source_line,
     825                 :            : 
     826                 :            :     {
     827                 :            :         mp_emit_bc_load_local,
     828                 :            :         mp_emit_bc_load_global,
     829                 :            :     },
     830                 :            :     {
     831                 :            :         mp_emit_bc_store_local,
     832                 :            :         mp_emit_bc_store_global,
     833                 :            :     },
     834                 :            :     {
     835                 :            :         mp_emit_bc_delete_local,
     836                 :            :         mp_emit_bc_delete_global,
     837                 :            :     },
     838                 :            : 
     839                 :            :     mp_emit_bc_label_assign,
     840                 :            :     mp_emit_bc_import,
     841                 :            :     mp_emit_bc_load_const_tok,
     842                 :            :     mp_emit_bc_load_const_small_int,
     843                 :            :     mp_emit_bc_load_const_str,
     844                 :            :     mp_emit_bc_load_const_obj,
     845                 :            :     mp_emit_bc_load_null,
     846                 :            :     mp_emit_bc_load_method,
     847                 :            :     mp_emit_bc_load_build_class,
     848                 :            :     mp_emit_bc_subscr,
     849                 :            :     mp_emit_bc_attr,
     850                 :            :     mp_emit_bc_dup_top,
     851                 :            :     mp_emit_bc_dup_top_two,
     852                 :            :     mp_emit_bc_pop_top,
     853                 :            :     mp_emit_bc_rot_two,
     854                 :            :     mp_emit_bc_rot_three,
     855                 :            :     mp_emit_bc_jump,
     856                 :            :     mp_emit_bc_pop_jump_if,
     857                 :            :     mp_emit_bc_jump_if_or_pop,
     858                 :            :     mp_emit_bc_unwind_jump,
     859                 :            :     mp_emit_bc_setup_block,
     860                 :            :     mp_emit_bc_with_cleanup,
     861                 :            :     mp_emit_bc_end_finally,
     862                 :            :     mp_emit_bc_get_iter,
     863                 :            :     mp_emit_bc_for_iter,
     864                 :            :     mp_emit_bc_for_iter_end,
     865                 :            :     mp_emit_bc_pop_except_jump,
     866                 :            :     mp_emit_bc_unary_op,
     867                 :            :     mp_emit_bc_binary_op,
     868                 :            :     mp_emit_bc_build,
     869                 :            :     mp_emit_bc_store_map,
     870                 :            :     mp_emit_bc_store_comp,
     871                 :            :     mp_emit_bc_unpack_sequence,
     872                 :            :     mp_emit_bc_unpack_ex,
     873                 :            :     mp_emit_bc_make_function,
     874                 :            :     mp_emit_bc_make_closure,
     875                 :            :     mp_emit_bc_call_function,
     876                 :            :     mp_emit_bc_call_method,
     877                 :            :     mp_emit_bc_return_value,
     878                 :            :     mp_emit_bc_raise_varargs,
     879                 :            :     mp_emit_bc_yield,
     880                 :            : 
     881                 :            :     mp_emit_bc_start_except_handler,
     882                 :            :     mp_emit_bc_end_except_handler,
     883                 :            : };
     884                 :            : #else
     885                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops = {
     886                 :            :     mp_emit_bc_load_local,
     887                 :            :     mp_emit_bc_load_global,
     888                 :            : };
     889                 :            : 
     890                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops = {
     891                 :            :     mp_emit_bc_store_local,
     892                 :            :     mp_emit_bc_store_global,
     893                 :            : };
     894                 :            : 
     895                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_delete_id_ops = {
     896                 :            :     mp_emit_bc_delete_local,
     897                 :            :     mp_emit_bc_delete_global,
     898                 :            : };
     899                 :            : #endif
     900                 :            : 
     901                 :            : #endif // MICROPY_ENABLE_COMPILER

Generated by: LCOV version 1.15-5-g462f71d