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 : 3891 : emit_t *emit_bc_new(mp_emit_common_t *emit_common) {
79 : 3891 : emit_t *emit = m_new0(emit_t, 1);
80 : 3891 : emit->emit_common = emit_common;
81 : 3891 : return emit;
82 : : }
83 : :
84 : 3887 : void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels) {
85 : 3887 : emit->max_num_labels = max_num_labels;
86 : 3887 : emit->label_offsets = m_new(size_t, emit->max_num_labels);
87 : 3887 : }
88 : :
89 : 3868 : void emit_bc_free(emit_t *emit) {
90 : 3868 : m_del(size_t, emit->label_offsets, emit->max_num_labels);
91 : 3869 : m_del_obj(emit_t, emit);
92 : 3869 : }
93 : :
94 : : // all functions must go through this one to emit code info
95 : 385141 : static uint8_t *emit_get_cur_to_write_code_info(void *emit_in, size_t num_bytes_to_write) {
96 : 385141 : emit_t *emit = emit_in;
97 [ + + ]: 385141 : if (emit->pass < MP_PASS_EMIT) {
98 : 204005 : emit->code_info_offset += num_bytes_to_write;
99 : 204005 : return emit->dummy_data;
100 : : } else {
101 [ - + ]: 181136 : assert(emit->code_info_offset + num_bytes_to_write <= emit->code_info_size);
102 : 181136 : byte *c = emit->code_base + emit->code_info_offset;
103 : 181136 : emit->code_info_offset += num_bytes_to_write;
104 : 181136 : return c;
105 : : }
106 : : }
107 : :
108 : 41721 : static void emit_write_code_info_byte(emit_t *emit, byte val) {
109 : 41721 : *emit_get_cur_to_write_code_info(emit, 1) = val;
110 : 41722 : }
111 : :
112 : 36153 : static void emit_write_code_info_qstr(emit_t *emit, qstr qst) {
113 : 36153 : mp_encode_uint(emit, emit_get_cur_to_write_code_info, mp_emit_common_use_qstr(emit->emit_common, qst));
114 : 36153 : }
115 : :
116 : : #if MICROPY_ENABLE_SOURCE_LINE
117 : 297847 : static void emit_write_code_info_bytes_lines(emit_t *emit, mp_uint_t bytes_to_skip, mp_uint_t lines_to_skip) {
118 [ + - ]: 297847 : assert(bytes_to_skip > 0 || lines_to_skip > 0);
119 [ + + ]: 605112 : while (bytes_to_skip > 0 || lines_to_skip > 0) {
120 : 307265 : mp_uint_t b, l;
121 [ + + ]: 307265 : if (lines_to_skip <= 6 || bytes_to_skip > 0xf) {
122 : : // use 0b0LLBBBBB encoding
123 : 288584 : b = MIN(bytes_to_skip, 0x1f);
124 [ + + ]: 288584 : if (b < bytes_to_skip) {
125 : : // we can't skip any lines until we skip all the bytes
126 : : l = 0;
127 : : } else {
128 : 288304 : l = MIN(lines_to_skip, 0x3);
129 : : }
130 : 288584 : *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 : 18681 : b = MIN(bytes_to_skip, 0xf);
134 : 18681 : l = MIN(lines_to_skip, 0x7ff);
135 : 18681 : byte *ci = emit_get_cur_to_write_code_info(emit, 2);
136 : 18681 : ci[0] = 0x80 | b | ((l >> 4) & 0x70);
137 : 18681 : ci[1] = l;
138 : : }
139 : 307265 : bytes_to_skip -= b;
140 : 307265 : lines_to_skip -= l;
141 : : }
142 : 297847 : }
143 : : #endif
144 : :
145 : : // all functions must go through this one to emit byte code
146 : 2377042 : static uint8_t *emit_get_cur_to_write_bytecode(void *emit_in, size_t num_bytes_to_write) {
147 : 2377042 : emit_t *emit = emit_in;
148 [ + + ]: 2377042 : if (emit->suppress) {
149 : 10844 : return emit->dummy_data;
150 : : }
151 [ + + ]: 2366198 : if (emit->pass < MP_PASS_EMIT) {
152 : 1046343 : emit->bytecode_offset += num_bytes_to_write;
153 : 1046343 : return emit->dummy_data;
154 : : } else {
155 [ - + ]: 1319855 : assert(emit->bytecode_offset + num_bytes_to_write <= emit->bytecode_size);
156 : 1319855 : byte *c = emit->code_base + emit->code_info_size + emit->bytecode_offset;
157 : 1319855 : emit->bytecode_offset += num_bytes_to_write;
158 : 1319855 : return c;
159 : : }
160 : : }
161 : :
162 : 1328 : static void emit_write_bytecode_raw_byte(emit_t *emit, byte b1) {
163 : 1328 : byte *c = emit_get_cur_to_write_bytecode(emit, 1);
164 : 1328 : c[0] = b1;
165 : 1328 : }
166 : :
167 : 1386872 : static void emit_write_bytecode_byte(emit_t *emit, int stack_adj, byte b1) {
168 : 1386872 : mp_emit_bc_adjust_stack_size(emit, stack_adj);
169 : 1386869 : byte *c = emit_get_cur_to_write_bytecode(emit, 1);
170 : 1386871 : c[0] = b1;
171 : 1386871 : }
172 : :
173 : : // Similar to mp_encode_uint(), just some extra handling to encode sign
174 : 7951 : static void emit_write_bytecode_byte_int(emit_t *emit, int stack_adj, byte b1, mp_int_t num) {
175 : 7951 : 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 : 7951 : byte buf[MP_ENCODE_UINT_MAX_BYTES];
179 : 7951 : byte *p = buf + sizeof(buf);
180 : : // We encode in little-ending order, but store in big-endian, to help decoding
181 : 16214 : do {
182 : 16214 : *--p = num & 0x7f;
183 : 16214 : num >>= 7;
184 [ + + ]: 16214 : } 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 [ + + + + ]: 7842 : if (num == -1 && (*p & 0x40) == 0) {
188 : 167 : *--p = 0x7f;
189 [ + + + + ]: 7675 : } else if (num == 0 && (*p & 0x40) != 0) {
190 : 2254 : *--p = 0;
191 : : }
192 : :
193 : 7842 : byte *c = emit_get_cur_to_write_bytecode(emit, buf + sizeof(buf) - p);
194 [ + + ]: 18635 : while (p != buf + sizeof(buf) - 1) {
195 : 10793 : *c++ = *p++ | 0x80;
196 : : }
197 : 7950 : *c = *p;
198 : 7950 : }
199 : :
200 : 740604 : static void emit_write_bytecode_byte_uint(emit_t *emit, int stack_adj, byte b, mp_uint_t val) {
201 : 740604 : emit_write_bytecode_byte(emit, stack_adj, b);
202 : 740598 : mp_encode_uint(emit, emit_get_cur_to_write_bytecode, val);
203 : 740599 : }
204 : :
205 : 36058 : static void emit_write_bytecode_byte_const(emit_t *emit, int stack_adj, byte b, mp_uint_t n) {
206 : 36058 : emit_write_bytecode_byte_uint(emit, stack_adj, b, n);
207 : 36058 : }
208 : :
209 : 360458 : static void emit_write_bytecode_byte_qstr(emit_t *emit, int stack_adj, byte b, qstr qst) {
210 : 360458 : emit_write_bytecode_byte_uint(emit, stack_adj, b, mp_emit_common_use_qstr(emit->emit_common, qst));
211 : 360456 : }
212 : :
213 : 19849 : static void emit_write_bytecode_byte_obj(emit_t *emit, int stack_adj, byte b, mp_obj_t obj) {
214 : 19849 : emit_write_bytecode_byte_const(emit, stack_adj, b, mp_emit_common_use_const_obj(emit->emit_common, obj));
215 : 19849 : }
216 : :
217 : 16209 : static void emit_write_bytecode_byte_child(emit_t *emit, int stack_adj, byte b, mp_raw_code_t *rc) {
218 [ + + ]: 19525 : 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 : 16209 : }
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 : 243809 : static void emit_write_bytecode_byte_label(emit_t *emit, int stack_adj, byte b1, mp_uint_t label) {
231 : 243809 : mp_emit_bc_adjust_stack_size(emit, stack_adj);
232 : :
233 [ + + ]: 243809 : if (emit->suppress) {
234 : : return;
235 : : }
236 : :
237 : : // Determine if the jump offset is signed or unsigned, based on the opcode.
238 : 240261 : 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 : 240261 : unsigned int jump_encoding_size = 1;
242 : 240261 : ssize_t bytecode_offset = 0;
243 : :
244 : : // Compute the jump size and offset only when code size is known.
245 [ + + ]: 240261 : if (emit->pass >= MP_PASS_CODE_SIZE) {
246 : : // The -2 accounts for this jump opcode taking 2 bytes (at least).
247 : 189343 : 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 [ + + + + ]: 189343 : if ((is_signed && -64 <= bytecode_offset && bytecode_offset <= 63)
251 [ + + ]: 159581 : || (!is_signed && (size_t)bytecode_offset <= 127)) {
252 : : // Use a 1-byte jump offset.
253 : 118224 : jump_encoding_size = 0;
254 : : }
255 : :
256 : : // Adjust the offset depending on the size of the encoding of the offset.
257 : 189343 : bytecode_offset -= jump_encoding_size;
258 : :
259 [ - + ]: 189343 : assert(is_signed || bytecode_offset >= 0);
260 : : }
261 : :
262 : : // Emit the opcode.
263 : 240261 : byte *c = emit_get_cur_to_write_bytecode(emit, 2 + jump_encoding_size);
264 : 240261 : c[0] = b1;
265 [ + + ]: 240261 : if (jump_encoding_size == 0) {
266 [ + + ]: 118224 : if (is_signed) {
267 : 29762 : bytecode_offset += 0x40;
268 : : }
269 [ - + ]: 118224 : assert(0 <= bytecode_offset && bytecode_offset <= 0x7f);
270 : 118224 : c[1] = bytecode_offset;
271 : : } else {
272 [ + + ]: 122037 : if (is_signed) {
273 : 36211 : bytecode_offset += 0x4000;
274 : : }
275 [ + + + + ]: 122037 : if (emit->pass == MP_PASS_EMIT && !(0 <= bytecode_offset && bytecode_offset <= 0x7fff)) {
276 : 69 : emit->overflow = true;
277 : : }
278 : 122037 : c[1] = 0x80 | (bytecode_offset & 0x7f);
279 : 122037 : c[2] = bytecode_offset >> 7;
280 : : }
281 : : }
282 : :
283 : 26427 : void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
284 : 26427 : emit->pass = pass;
285 : 26427 : emit->stack_size = 0;
286 : 26427 : emit->suppress = false;
287 : 26427 : emit->scope = scope;
288 : 26427 : emit->last_source_line_offset = 0;
289 : 26427 : emit->last_source_line = 1;
290 : 26427 : emit->bytecode_offset = 0;
291 : 26427 : emit->code_info_offset = 0;
292 : 26427 : emit->overflow = false;
293 : :
294 : : // Write local state size, exception stack size, scope flags and number of arguments
295 : : {
296 : 26427 : mp_uint_t n_state = scope->num_locals + scope->stack_size;
297 [ + + ]: 26427 : 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 : 13503 : 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 : 26427 : size_t n_exc_stack = scope->exc_stack_size;
309 [ + + ]: 30379 : 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 [ + + ]: 26426 : if (emit->pass >= MP_PASS_CODE_SIZE) {
314 : 10817 : size_t n_info = emit->n_info;
315 : 10817 : size_t n_cell = emit->n_cell;
316 [ + + + + ]: 11008 : MP_BC_PRELUDE_SIZE_ENCODE(n_info, n_cell, emit_write_code_info_byte, emit);
317 : : }
318 : :
319 : 26426 : emit->n_info = emit->code_info_offset;
320 : :
321 : : // Write the name of this function.
322 : 26426 : 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 [ + + ]: 36153 : for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
337 : 17553 : qstr qst = MP_QSTR__star_;
338 [ + + ]: 17553 : for (int j = 0; j < scope->id_info_len; ++j) {
339 : 16842 : id_info_t *id = &scope->id_info[j];
340 [ + + + + ]: 16842 : if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
341 : 9016 : qst = id->qst;
342 : 9016 : break;
343 : : }
344 : : }
345 : 9727 : emit_write_code_info_qstr(emit, qst);
346 : : }
347 : : }
348 : 26425 : }
349 : :
350 : 26422 : bool mp_emit_bc_end_pass(emit_t *emit) {
351 [ + + ]: 26422 : if (emit->pass == MP_PASS_SCOPE) {
352 : : return true;
353 : : }
354 : :
355 : : // check stack is back to zero size
356 [ - + ]: 16154 : assert(emit->stack_size == 0);
357 : :
358 : : // Calculate size of source code info section
359 : 16154 : emit->n_info = emit->code_info_offset - emit->n_info;
360 : :
361 : : // Emit closure section of prelude
362 : 16154 : emit->n_cell = 0;
363 [ + + ]: 82548 : for (size_t i = 0; i < emit->scope->id_info_len; ++i) {
364 : 66392 : id_info_t *id = &emit->scope->id_info[i];
365 [ + + ]: 66392 : if (id->kind == ID_INFO_KIND_CELL) {
366 [ - + ]: 336 : assert(id->local_num <= 255);
367 : 336 : emit_write_code_info_byte(emit, id->local_num); // write the local which should be converted to a cell
368 : 338 : ++emit->n_cell;
369 : : }
370 : : }
371 : :
372 [ + + ]: 16156 : if (emit->pass == MP_PASS_CODE_SIZE) {
373 : : // calculate size of total code-info + bytecode, in bytes
374 : 5337 : emit->code_info_size = emit->code_info_offset;
375 : 5337 : emit->bytecode_size = emit->bytecode_offset;
376 : 5337 : emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size);
377 : :
378 [ + + ]: 10819 : } else if (emit->pass == MP_PASS_EMIT) {
379 : : // Code info and/or bytecode can shrink during this pass.
380 [ - + ]: 5481 : assert(emit->code_info_offset <= emit->code_info_size);
381 [ - + ]: 5481 : assert(emit->bytecode_offset <= emit->bytecode_size);
382 : :
383 [ + + ]: 5481 : if (emit->code_info_offset != emit->code_info_size
384 [ + + ]: 5480 : || 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 : 143 : emit->code_info_size = emit->code_info_offset;
388 : 143 : emit->bytecode_size = emit->bytecode_offset;
389 : 143 : return false;
390 : : }
391 : :
392 [ + + ]: 5338 : if (emit->overflow) {
393 : 2 : mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("bytecode overflow"));
394 : : }
395 : :
396 : : #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS
397 : 5336 : size_t bytecode_len = emit->code_info_size + emit->bytecode_size;
398 : : #if MICROPY_DEBUG_PRINTERS
399 : 5336 : emit->scope->raw_code_data_len = bytecode_len;
400 : : #endif
401 : : #endif
402 : :
403 : : // Bytecode is finalised, assign it to the raw code object.
404 : 5336 : mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base,
405 : 5336 : emit->emit_common->children,
406 : : #if MICROPY_PERSISTENT_CODE_SAVE
407 : : bytecode_len,
408 : : emit->emit_common->ct_cur_child,
409 : : #endif
410 : 5336 : emit->scope->scope_flags);
411 : : }
412 : :
413 : : return true;
414 : : }
415 : :
416 : 1810917 : void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
417 [ + + ]: 1810917 : if (emit->pass == MP_PASS_SCOPE) {
418 : : return;
419 : : }
420 [ - + ]: 1507918 : assert((mp_int_t)emit->stack_size + delta >= 0);
421 : 1507918 : emit->stack_size += delta;
422 [ + + ]: 1507918 : if (emit->stack_size > emit->scope->stack_size) {
423 : 19763 : emit->scope->stack_size = emit->stack_size;
424 : : }
425 : : }
426 : :
427 : 896555 : void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
428 : : #if MICROPY_ENABLE_SOURCE_LINE
429 [ + + ]: 896555 : if (MP_STATE_VM(mp_optimise_value) >= 3) {
430 : : // If we compile with -O3, don't store line numbers.
431 : : return;
432 : : }
433 [ + + ]: 896507 : if (source_line > emit->last_source_line) {
434 : 297847 : mp_uint_t bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset;
435 : 297847 : mp_uint_t lines_to_skip = source_line - emit->last_source_line;
436 : 297847 : emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip);
437 : 297847 : emit->last_source_line_offset = emit->bytecode_offset;
438 : 297847 : emit->last_source_line = source_line;
439 : : }
440 : : #else
441 : : (void)emit;
442 : : (void)source_line;
443 : : #endif
444 : : }
445 : :
446 : 253116 : void mp_emit_bc_label_assign(emit_t *emit, mp_uint_t l) {
447 : : // Assigning a label ends any dead-code region, and all following opcodes
448 : : // should be emitted (until another unconditional flow control).
449 : 253116 : emit->suppress = false;
450 : :
451 [ + + ]: 253116 : if (emit->pass == MP_PASS_SCOPE) {
452 : : return;
453 : : }
454 : :
455 : : // Label offsets can change from one pass to the next, but they must only
456 : : // decrease (ie code can only shrink). There will be multiple MP_PASS_EMIT
457 : : // stages until the labels no longer change, which is when the code size
458 : : // stays constant after a MP_PASS_EMIT.
459 [ - + ]: 217422 : assert(l < emit->max_num_labels);
460 [ + + - + ]: 217422 : assert(emit->pass == MP_PASS_STACK_SIZE || emit->bytecode_offset <= emit->label_offsets[l]);
461 : :
462 : : // Assign label offset.
463 : 217422 : emit->label_offsets[l] = emit->bytecode_offset;
464 : : }
465 : :
466 : 6603 : void mp_emit_bc_import(emit_t *emit, qstr qst, int kind) {
467 : 6603 : MP_STATIC_ASSERT(MP_BC_IMPORT_NAME + MP_EMIT_IMPORT_NAME == MP_BC_IMPORT_NAME);
468 : 6603 : MP_STATIC_ASSERT(MP_BC_IMPORT_NAME + MP_EMIT_IMPORT_FROM == MP_BC_IMPORT_FROM);
469 [ + + ]: 6603 : int stack_adj = kind == MP_EMIT_IMPORT_FROM ? 1 : -1;
470 [ + + ]: 4831 : if (kind == MP_EMIT_IMPORT_STAR) {
471 : 215 : emit_write_bytecode_byte(emit, stack_adj, MP_BC_IMPORT_STAR);
472 : : } else {
473 : 6388 : emit_write_bytecode_byte_qstr(emit, stack_adj, MP_BC_IMPORT_NAME + kind, qst);
474 : : }
475 : 6603 : }
476 : :
477 : 83044 : void mp_emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
478 : 83044 : MP_STATIC_ASSERT(MP_BC_LOAD_CONST_FALSE + (MP_TOKEN_KW_NONE - MP_TOKEN_KW_FALSE) == MP_BC_LOAD_CONST_NONE);
479 : 83044 : MP_STATIC_ASSERT(MP_BC_LOAD_CONST_FALSE + (MP_TOKEN_KW_TRUE - MP_TOKEN_KW_FALSE) == MP_BC_LOAD_CONST_TRUE);
480 [ + + ]: 83044 : if (tok == MP_TOKEN_ELLIPSIS) {
481 : 12 : emit_write_bytecode_byte_obj(emit, 1, MP_BC_LOAD_CONST_OBJ, MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj));
482 : : } else {
483 : 83032 : emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_CONST_FALSE + (tok - MP_TOKEN_KW_FALSE));
484 : : }
485 : 83046 : }
486 : :
487 : 67438 : void mp_emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg) {
488 [ - + ]: 67438 : assert(MP_SMALL_INT_FITS(arg));
489 : 67438 : if (-MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS <= arg
490 [ + + ]: 67438 : && arg < MP_BC_LOAD_CONST_SMALL_INT_MULTI_NUM - MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS) {
491 : 59487 : emit_write_bytecode_byte(emit, 1,
492 : 59487 : MP_BC_LOAD_CONST_SMALL_INT_MULTI + MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS + arg);
493 : : } else {
494 : 7951 : emit_write_bytecode_byte_int(emit, 1, MP_BC_LOAD_CONST_SMALL_INT, arg);
495 : : }
496 : 67437 : }
497 : :
498 : 45518 : void mp_emit_bc_load_const_str(emit_t *emit, qstr qst) {
499 : 45518 : emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_CONST_STRING, qst);
500 : 45517 : }
501 : :
502 : 19837 : void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj) {
503 : 19837 : emit_write_bytecode_byte_obj(emit, 1, MP_BC_LOAD_CONST_OBJ, obj);
504 : 19837 : }
505 : :
506 : 2082 : void mp_emit_bc_load_null(emit_t *emit) {
507 : 2082 : emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_NULL);
508 : 2082 : }
509 : :
510 : 30524 : void mp_emit_bc_load_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
511 : 30524 : MP_STATIC_ASSERT(MP_BC_LOAD_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_LOAD_FAST_N);
512 : 30524 : MP_STATIC_ASSERT(MP_BC_LOAD_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_LOAD_DEREF);
513 : 30524 : (void)qst;
514 [ + + ]: 30524 : if (kind == MP_EMIT_IDOP_LOCAL_FAST && local_num <= 15) {
515 : 29631 : emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_FAST_MULTI + local_num);
516 : : } else {
517 : 893 : emit_write_bytecode_byte_uint(emit, 1, MP_BC_LOAD_FAST_N + kind, local_num);
518 : : }
519 : 30524 : }
520 : :
521 : 196930 : void mp_emit_bc_load_global(emit_t *emit, qstr qst, int kind) {
522 : 196930 : MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_LOAD_NAME);
523 : 196930 : MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_LOAD_GLOBAL);
524 : 196930 : (void)qst;
525 : 196930 : emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_NAME + kind, qst);
526 : 196931 : }
527 : :
528 : 28158 : void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) {
529 : 28158 : int stack_adj = 1 - 2 * is_super;
530 [ + + ]: 56203 : emit_write_bytecode_byte_qstr(emit, stack_adj, is_super ? MP_BC_LOAD_SUPER_METHOD : MP_BC_LOAD_METHOD, qst);
531 : 28158 : }
532 : :
533 : 2628 : void mp_emit_bc_load_build_class(emit_t *emit) {
534 : 2628 : emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_BUILD_CLASS);
535 : 2628 : }
536 : :
537 : 10079 : void mp_emit_bc_subscr(emit_t *emit, int kind) {
538 [ + + ]: 10079 : if (kind == MP_EMIT_SUBSCR_LOAD) {
539 : 7201 : emit_write_bytecode_byte(emit, -1, MP_BC_LOAD_SUBSCR);
540 : : } else {
541 [ + + ]: 2878 : if (kind == MP_EMIT_SUBSCR_DELETE) {
542 : 318 : mp_emit_bc_load_null(emit);
543 : 318 : mp_emit_bc_rot_three(emit);
544 : : }
545 : 2878 : emit_write_bytecode_byte(emit, -3, MP_BC_STORE_SUBSCR);
546 : : }
547 : 10079 : }
548 : :
549 : 22300 : void mp_emit_bc_attr(emit_t *emit, qstr qst, int kind) {
550 [ + + ]: 22300 : if (kind == MP_EMIT_ATTR_LOAD) {
551 : 17797 : emit_write_bytecode_byte_qstr(emit, 0, MP_BC_LOAD_ATTR, qst);
552 : : } else {
553 [ + + ]: 4503 : if (kind == MP_EMIT_ATTR_DELETE) {
554 : 84 : mp_emit_bc_load_null(emit);
555 : 84 : mp_emit_bc_rot_two(emit);
556 : : }
557 : 4503 : emit_write_bytecode_byte_qstr(emit, -2, MP_BC_STORE_ATTR, qst);
558 : : }
559 : 22300 : }
560 : :
561 : 8016 : void mp_emit_bc_store_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
562 : 8016 : MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_STORE_FAST_N);
563 : 8016 : MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_STORE_DEREF);
564 : 8016 : (void)qst;
565 [ + + ]: 8016 : if (kind == MP_EMIT_IDOP_LOCAL_FAST && local_num <= 15) {
566 : 7185 : emit_write_bytecode_byte(emit, -1, MP_BC_STORE_FAST_MULTI + local_num);
567 : : } else {
568 : 831 : emit_write_bytecode_byte_uint(emit, -1, MP_BC_STORE_FAST_N + kind, local_num);
569 : : }
570 : 8016 : }
571 : :
572 : 60733 : void mp_emit_bc_store_global(emit_t *emit, qstr qst, int kind) {
573 : 60733 : MP_STATIC_ASSERT(MP_BC_STORE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_STORE_NAME);
574 : 60733 : MP_STATIC_ASSERT(MP_BC_STORE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_STORE_GLOBAL);
575 : 60733 : emit_write_bytecode_byte_qstr(emit, -1, MP_BC_STORE_NAME + kind, qst);
576 : 60733 : }
577 : :
578 : 410 : void mp_emit_bc_delete_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
579 : 410 : MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_DELETE_FAST);
580 : 410 : MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_DELETE_DEREF);
581 : 410 : (void)qst;
582 : 410 : emit_write_bytecode_byte_uint(emit, 0, MP_BC_DELETE_FAST + kind, local_num);
583 : 410 : }
584 : :
585 : 433 : void mp_emit_bc_delete_global(emit_t *emit, qstr qst, int kind) {
586 : 433 : MP_STATIC_ASSERT(MP_BC_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_DELETE_NAME);
587 : 433 : MP_STATIC_ASSERT(MP_BC_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_DELETE_GLOBAL);
588 : 433 : emit_write_bytecode_byte_qstr(emit, 0, MP_BC_DELETE_NAME + kind, qst);
589 : 433 : }
590 : :
591 : 47641 : void mp_emit_bc_dup_top(emit_t *emit) {
592 : 47641 : emit_write_bytecode_byte(emit, 1, MP_BC_DUP_TOP);
593 : 47641 : }
594 : :
595 : 745 : void mp_emit_bc_dup_top_two(emit_t *emit) {
596 : 745 : emit_write_bytecode_byte(emit, 2, MP_BC_DUP_TOP_TWO);
597 : 745 : }
598 : :
599 : 150762 : void mp_emit_bc_pop_top(emit_t *emit) {
600 : 150762 : emit_write_bytecode_byte(emit, -1, MP_BC_POP_TOP);
601 : 150761 : }
602 : :
603 : 1300 : void mp_emit_bc_rot_two(emit_t *emit) {
604 : 1300 : emit_write_bytecode_byte(emit, 0, MP_BC_ROT_TWO);
605 : 1300 : }
606 : :
607 : 857 : void mp_emit_bc_rot_three(emit_t *emit) {
608 : 857 : emit_write_bytecode_byte(emit, 0, MP_BC_ROT_THREE);
609 : 857 : }
610 : :
611 : 9236 : void mp_emit_bc_jump(emit_t *emit, mp_uint_t label) {
612 : 9236 : emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label);
613 : 9236 : emit->suppress = true;
614 : 9236 : }
615 : :
616 : 56691 : void mp_emit_bc_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label) {
617 [ + + ]: 56691 : if (cond) {
618 : 5163 : emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_TRUE, label);
619 : : } else {
620 : 51528 : emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_FALSE, label);
621 : : }
622 : 56691 : }
623 : :
624 : 505 : void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label) {
625 [ + + ]: 505 : if (cond) {
626 : 255 : emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_TRUE_OR_POP, label);
627 : : } else {
628 : 250 : emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_FALSE_OR_POP, label);
629 : : }
630 : 505 : }
631 : :
632 : 777 : void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_depth) {
633 [ + + ]: 777 : if (except_depth == 0) {
634 [ + + ]: 535 : if (label & MP_EMIT_BREAK_FROM_FOR) {
635 : : // need to pop the iterator if we are breaking out of a for loop
636 : 203 : emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP);
637 : : // also pop the iter_buf
638 [ + + ]: 812 : for (size_t i = 0; i < MP_OBJ_ITER_BUF_NSLOTS - 1; ++i) {
639 : 609 : emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP);
640 : : }
641 : : }
642 : 535 : emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
643 : : } else {
644 : 242 : emit_write_bytecode_byte_label(emit, 0, MP_BC_UNWIND_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
645 : 242 : emit_write_bytecode_raw_byte(emit, ((label & MP_EMIT_BREAK_FROM_FOR) ? 0x80 : 0) | except_depth);
646 : : }
647 : 777 : emit->suppress = true;
648 : 777 : }
649 : :
650 : 83744 : void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind) {
651 : 83744 : MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_WITH == MP_BC_SETUP_WITH);
652 : 83744 : MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_EXCEPT == MP_BC_SETUP_EXCEPT);
653 : 83744 : MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_FINALLY == MP_BC_SETUP_FINALLY);
654 : : // The SETUP_WITH opcode pops ctx_mgr from the top of the stack
655 : : // and then pushes 3 entries: __exit__, ctx_mgr, as_value.
656 [ + + ]: 83744 : int stack_adj = kind == MP_EMIT_SETUP_BLOCK_WITH ? 2 : 0;
657 : 83744 : emit_write_bytecode_byte_label(emit, stack_adj, MP_BC_SETUP_WITH + kind, label);
658 : 83744 : }
659 : :
660 : 36708 : void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) {
661 : 36708 : mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE);
662 : 36708 : mp_emit_bc_label_assign(emit, label);
663 : : // The +2 is to ensure we have enough stack space to call the __exit__ method
664 : 36708 : emit_write_bytecode_byte(emit, 2, MP_BC_WITH_CLEANUP);
665 : : // Cancel the +2 above, plus the +2 from mp_emit_bc_setup_block(MP_EMIT_SETUP_BLOCK_WITH)
666 : 36708 : mp_emit_bc_adjust_stack_size(emit, -4);
667 : 36708 : }
668 : :
669 : : #if MICROPY_PY_ASYNC_AWAIT
670 : 70 : void mp_emit_bc_async_with_setup_finally(emit_t *emit, mp_uint_t label_aexit_no_exc, mp_uint_t label_finally_block, mp_uint_t label_ret_unwind_jump) {
671 : : // The async-with body has executed and no exception was raised, the execution fell through to this point.
672 : : // Stack: (..., ctx_mgr)
673 : :
674 : : // Finish async-with body and prepare to enter "finally" block.
675 : 70 : mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE); // to tell end_finally there's no exception
676 : 70 : mp_emit_bc_rot_two(emit);
677 : 70 : mp_emit_bc_jump(emit, label_aexit_no_exc); // jump to code to call __aexit__
678 : :
679 : : // Start of "finally" block which is entered via one of: an exception propagating out, a return, an unwind jump.
680 : 70 : mp_emit_bc_label_assign(emit, label_finally_block);
681 : :
682 : : // Detect which case we have by the TOS being an exception or not.
683 : 70 : mp_emit_bc_dup_top(emit);
684 : 70 : mp_emit_bc_load_global(emit, MP_QSTR_BaseException, MP_EMIT_IDOP_GLOBAL_GLOBAL);
685 : 70 : mp_emit_bc_binary_op(emit, MP_BINARY_OP_EXCEPTION_MATCH);
686 : 70 : mp_emit_bc_pop_jump_if(emit, false, label_ret_unwind_jump); // if not an exception then we have return or unwind jump.
687 : 70 : }
688 : : #endif
689 : :
690 : 83744 : void mp_emit_bc_end_finally(emit_t *emit) {
691 : 83744 : emit_write_bytecode_byte(emit, -1, MP_BC_END_FINALLY);
692 : 83744 : }
693 : :
694 : 4125 : void mp_emit_bc_get_iter(emit_t *emit, bool use_stack) {
695 [ + + ]: 4125 : int stack_adj = use_stack ? MP_OBJ_ITER_BUF_NSLOTS - 1 : 0;
696 : 4125 : emit_write_bytecode_byte(emit, stack_adj, use_stack ? MP_BC_GET_ITER_STACK : MP_BC_GET_ITER);
697 : 4125 : }
698 : :
699 : 2537 : void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) {
700 : 2537 : emit_write_bytecode_byte_label(emit, 1, MP_BC_FOR_ITER, label);
701 : 2537 : }
702 : :
703 : 2537 : void mp_emit_bc_for_iter_end(emit_t *emit) {
704 : 2537 : mp_emit_bc_adjust_stack_size(emit, -MP_OBJ_ITER_BUF_NSLOTS);
705 : 2537 : }
706 : :
707 : 90319 : void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) {
708 : 90319 : (void)within_exc_handler;
709 : 90319 : emit_write_bytecode_byte_label(emit, 0, MP_BC_POP_EXCEPT_JUMP, label);
710 : 90319 : emit->suppress = true;
711 : 90319 : }
712 : :
713 : 2240 : void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) {
714 : 2240 : emit_write_bytecode_byte(emit, 0, MP_BC_UNARY_OP_MULTI + op);
715 : 2240 : }
716 : :
717 : 70139 : void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op) {
718 : 70139 : bool invert = false;
719 [ + + ]: 70139 : if (op == MP_BINARY_OP_NOT_IN) {
720 : : invert = true;
721 : : op = MP_BINARY_OP_IN;
722 [ + + ]: 69879 : } else if (op == MP_BINARY_OP_IS_NOT) {
723 : 1060 : invert = true;
724 : 1060 : op = MP_BINARY_OP_IS;
725 : : }
726 : 70139 : emit_write_bytecode_byte(emit, -1, MP_BC_BINARY_OP_MULTI + op);
727 [ + + ]: 70139 : if (invert) {
728 : 1320 : emit_write_bytecode_byte(emit, 0, MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NOT);
729 : : }
730 : 70139 : }
731 : :
732 : 13091 : void mp_emit_bc_build(emit_t *emit, mp_uint_t n_args, int kind) {
733 : 13091 : MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_TUPLE == MP_BC_BUILD_TUPLE);
734 : 13091 : MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_LIST == MP_BC_BUILD_LIST);
735 : 13091 : MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_MAP == MP_BC_BUILD_MAP);
736 : 13091 : MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_SET == MP_BC_BUILD_SET);
737 : 13091 : MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_SLICE == MP_BC_BUILD_SLICE);
738 [ + + ]: 13091 : int stack_adj = kind == MP_EMIT_BUILD_MAP ? 1 : 1 - n_args;
739 : 13091 : emit_write_bytecode_byte_uint(emit, stack_adj, MP_BC_BUILD_TUPLE + kind, n_args);
740 : 13091 : }
741 : :
742 : 3747 : void mp_emit_bc_store_map(emit_t *emit) {
743 : 3747 : emit_write_bytecode_byte(emit, -2, MP_BC_STORE_MAP);
744 : 3747 : }
745 : :
746 : 351 : void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) {
747 : 351 : int t;
748 : 351 : int n;
749 [ + + ]: 351 : if (kind == SCOPE_LIST_COMP) {
750 : : n = 0;
751 : : t = 0;
752 [ + + ]: 53 : } else if (!MICROPY_PY_BUILTINS_SET || kind == SCOPE_DICT_COMP) {
753 : : n = 1;
754 : : t = 1;
755 : 5 : } else if (MICROPY_PY_BUILTINS_SET) {
756 : 5 : n = 0;
757 : 5 : t = 2;
758 : : }
759 : : // the lower 2 bits of the opcode argument indicate the collection type
760 : 351 : emit_write_bytecode_byte_uint(emit, -1 - n, MP_BC_STORE_COMP, ((collection_stack_index + n) << 2) | t);
761 : 351 : }
762 : :
763 : 766 : void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) {
764 : 766 : emit_write_bytecode_byte_uint(emit, -1 + n_args, MP_BC_UNPACK_SEQUENCE, n_args);
765 : 766 : }
766 : :
767 : 177 : void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right) {
768 : 177 : emit_write_bytecode_byte_uint(emit, -1 + n_left + n_right + 1, MP_BC_UNPACK_EX, n_left | (n_right << 8));
769 : 177 : }
770 : :
771 : 15935 : void mp_emit_bc_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
772 [ + + ]: 15935 : if (n_pos_defaults == 0 && n_kw_defaults == 0) {
773 : 15060 : emit_write_bytecode_byte_child(emit, 1, MP_BC_MAKE_FUNCTION, scope->raw_code);
774 : : } else {
775 : 875 : emit_write_bytecode_byte_child(emit, -1, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code);
776 : : }
777 : 15935 : }
778 : :
779 : 274 : 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) {
780 [ + + ]: 274 : if (n_pos_defaults == 0 && n_kw_defaults == 0) {
781 : 265 : int stack_adj = -n_closed_over + 1;
782 : 265 : emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE, scope->raw_code);
783 : 265 : emit_write_bytecode_raw_byte(emit, n_closed_over);
784 : : } else {
785 [ - + ]: 9 : assert(n_closed_over <= 255);
786 : 9 : int stack_adj = -2 - (mp_int_t)n_closed_over + 1;
787 : 9 : emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code);
788 : 9 : emit_write_bytecode_raw_byte(emit, n_closed_over);
789 : : }
790 : 274 : }
791 : :
792 : 327576 : 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) {
793 [ + + ]: 327576 : if (star_flags) {
794 : : // each positional arg is one object, each kwarg is two objects, the key
795 : : // and the value and one extra object for the star args bitmap.
796 : 789 : stack_adj -= (int)n_positional + 2 * (int)n_keyword + 1;
797 : 789 : emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base + 1, (n_keyword << 8) | n_positional);
798 : : } else {
799 : 326787 : stack_adj -= (int)n_positional + 2 * (int)n_keyword;
800 : 326787 : emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base, (n_keyword << 8) | n_positional);
801 : : }
802 : 327576 : }
803 : :
804 : 299422 : void mp_emit_bc_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
805 : 299422 : emit_bc_call_function_method_helper(emit, 0, MP_BC_CALL_FUNCTION, n_positional, n_keyword, star_flags);
806 : 299422 : }
807 : :
808 : 28154 : void mp_emit_bc_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
809 : 28154 : emit_bc_call_function_method_helper(emit, -1, MP_BC_CALL_METHOD, n_positional, n_keyword, star_flags);
810 : 28154 : }
811 : :
812 : 32249 : void mp_emit_bc_return_value(emit_t *emit) {
813 : 32249 : emit_write_bytecode_byte(emit, -1, MP_BC_RETURN_VALUE);
814 : 32248 : emit->suppress = true;
815 : 32248 : }
816 : :
817 : 5877 : void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) {
818 : 5877 : MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 1 == MP_BC_RAISE_OBJ);
819 : 5877 : MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 2 == MP_BC_RAISE_FROM);
820 [ - + ]: 5877 : assert(n_args <= 2);
821 : 5877 : emit_write_bytecode_byte(emit, -n_args, MP_BC_RAISE_LAST + n_args);
822 : 5877 : emit->suppress = true;
823 : 5877 : }
824 : :
825 : 2584 : void mp_emit_bc_yield(emit_t *emit, int kind) {
826 : 2584 : MP_STATIC_ASSERT(MP_BC_YIELD_VALUE + 1 == MP_BC_YIELD_FROM);
827 : 2584 : emit_write_bytecode_byte(emit, -kind, MP_BC_YIELD_VALUE + kind);
828 : 2584 : emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
829 : 2584 : }
830 : :
831 : 45121 : void mp_emit_bc_start_except_handler(emit_t *emit) {
832 : 45121 : mp_emit_bc_adjust_stack_size(emit, 4); // stack adjust for the exception instance, +3 for possible UNWIND_JUMP state
833 : 45121 : }
834 : :
835 : 45117 : void mp_emit_bc_end_except_handler(emit_t *emit) {
836 : 45117 : mp_emit_bc_adjust_stack_size(emit, -3); // stack adjust
837 : 45117 : }
838 : :
839 : : #if MICROPY_EMIT_NATIVE
840 : : const emit_method_table_t emit_bc_method_table = {
841 : : #if MICROPY_DYNAMIC_COMPILER
842 : : NULL,
843 : : NULL,
844 : : #endif
845 : :
846 : : mp_emit_bc_start_pass,
847 : : mp_emit_bc_end_pass,
848 : : mp_emit_bc_adjust_stack_size,
849 : : mp_emit_bc_set_source_line,
850 : :
851 : : {
852 : : mp_emit_bc_load_local,
853 : : mp_emit_bc_load_global,
854 : : },
855 : : {
856 : : mp_emit_bc_store_local,
857 : : mp_emit_bc_store_global,
858 : : },
859 : : {
860 : : mp_emit_bc_delete_local,
861 : : mp_emit_bc_delete_global,
862 : : },
863 : :
864 : : mp_emit_bc_label_assign,
865 : : mp_emit_bc_import,
866 : : mp_emit_bc_load_const_tok,
867 : : mp_emit_bc_load_const_small_int,
868 : : mp_emit_bc_load_const_str,
869 : : mp_emit_bc_load_const_obj,
870 : : mp_emit_bc_load_null,
871 : : mp_emit_bc_load_method,
872 : : mp_emit_bc_load_build_class,
873 : : mp_emit_bc_subscr,
874 : : mp_emit_bc_attr,
875 : : mp_emit_bc_dup_top,
876 : : mp_emit_bc_dup_top_two,
877 : : mp_emit_bc_pop_top,
878 : : mp_emit_bc_rot_two,
879 : : mp_emit_bc_rot_three,
880 : : mp_emit_bc_jump,
881 : : mp_emit_bc_pop_jump_if,
882 : : mp_emit_bc_jump_if_or_pop,
883 : : mp_emit_bc_unwind_jump,
884 : : mp_emit_bc_setup_block,
885 : : mp_emit_bc_with_cleanup,
886 : : #if MICROPY_PY_ASYNC_AWAIT
887 : : mp_emit_bc_async_with_setup_finally,
888 : : #endif
889 : : mp_emit_bc_end_finally,
890 : : mp_emit_bc_get_iter,
891 : : mp_emit_bc_for_iter,
892 : : mp_emit_bc_for_iter_end,
893 : : mp_emit_bc_pop_except_jump,
894 : : mp_emit_bc_unary_op,
895 : : mp_emit_bc_binary_op,
896 : : mp_emit_bc_build,
897 : : mp_emit_bc_store_map,
898 : : mp_emit_bc_store_comp,
899 : : mp_emit_bc_unpack_sequence,
900 : : mp_emit_bc_unpack_ex,
901 : : mp_emit_bc_make_function,
902 : : mp_emit_bc_make_closure,
903 : : mp_emit_bc_call_function,
904 : : mp_emit_bc_call_method,
905 : : mp_emit_bc_return_value,
906 : : mp_emit_bc_raise_varargs,
907 : : mp_emit_bc_yield,
908 : :
909 : : mp_emit_bc_start_except_handler,
910 : : mp_emit_bc_end_except_handler,
911 : : };
912 : : #else
913 : : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops = {
914 : : mp_emit_bc_load_local,
915 : : mp_emit_bc_load_global,
916 : : };
917 : :
918 : : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops = {
919 : : mp_emit_bc_store_local,
920 : : mp_emit_bc_store_global,
921 : : };
922 : :
923 : : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_delete_id_ops = {
924 : : mp_emit_bc_delete_local,
925 : : mp_emit_bc_delete_global,
926 : : };
927 : : #endif
928 : :
929 : : #endif // MICROPY_ENABLE_COMPILER
|