Port of MicroPython to the mbed platform. See micropython-repl for an interactive program.

Dependents:   micropython-repl

This a port of MicroPython to the mbed Classic platform.

This provides an interpreter running on the board's USB serial connection.

Getting Started

Import the micropython-repl program into your IDE workspace on developer.mbed.org. Compile and download to your board. Connect to the USB serial port in your usual manner. You should get a startup message similar to the following:

  MicroPython v1.7-155-gdddcdd8 on 2016-04-23; K64F with ARM
  Type "help()" for more information.
  >>>

Then you can start using micropython. For example:

  >>> from mbed import DigitalOut
  >>> from pins import LED1
  >>> led = DigitalOut(LED1)
  >>> led.write(1)

Requirements

You need approximately 100K of flash memory, so this will be no good for boards with smaller amounts of storage.

Caveats

This can be considered an alpha release of the port; things may not work; APIs may change in later releases. It is NOT an official part part the micropython project, so if anything doesn't work, blame me. If it does work, most of the credit is due to micropython.

  • Only a few of the mbed classes are available in micropython so far, and not all methods of those that are.
  • Only a few boards have their full range of pin names available; for others, only a few standard ones (USBTX, USBRX, LED1) are implemented.
  • The garbage collector is not yet implemented. The interpreter will gradually consume memory and then fail.
  • Exceptions from the mbed classes are not yet handled.
  • Asynchronous processing (e.g. events on inputs) is not supported.

Credits

  • Damien P. George and other contributors who created micropython.
  • Colin Hogben, author of this port.
Committer:
Colin Hogben
Date:
Wed Apr 27 22:11:29 2016 +0100
Revision:
10:33521d742af1
Parent:
0:5868e8752d44
Update README and version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pythontech 0:5868e8752d44 1 /*
pythontech 0:5868e8752d44 2 * This file is part of the Micro Python project, http://micropython.org/
pythontech 0:5868e8752d44 3 *
pythontech 0:5868e8752d44 4 * The MIT License (MIT)
pythontech 0:5868e8752d44 5 *
pythontech 0:5868e8752d44 6 * Copyright (c) 2013, 2014 Damien P. George
pythontech 0:5868e8752d44 7 *
pythontech 0:5868e8752d44 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
pythontech 0:5868e8752d44 9 * of this software and associated documentation files (the "Software"), to deal
pythontech 0:5868e8752d44 10 * in the Software without restriction, including without limitation the rights
pythontech 0:5868e8752d44 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pythontech 0:5868e8752d44 12 * copies of the Software, and to permit persons to whom the Software is
pythontech 0:5868e8752d44 13 * furnished to do so, subject to the following conditions:
pythontech 0:5868e8752d44 14 *
pythontech 0:5868e8752d44 15 * The above copyright notice and this permission notice shall be included in
pythontech 0:5868e8752d44 16 * all copies or substantial portions of the Software.
pythontech 0:5868e8752d44 17 *
pythontech 0:5868e8752d44 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pythontech 0:5868e8752d44 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pythontech 0:5868e8752d44 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pythontech 0:5868e8752d44 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pythontech 0:5868e8752d44 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pythontech 0:5868e8752d44 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pythontech 0:5868e8752d44 24 * THE SOFTWARE.
pythontech 0:5868e8752d44 25 */
pythontech 0:5868e8752d44 26
pythontech 0:5868e8752d44 27 #include <stdbool.h>
pythontech 0:5868e8752d44 28 #include <stdint.h>
pythontech 0:5868e8752d44 29 #include <stdio.h>
pythontech 0:5868e8752d44 30 #include <string.h>
pythontech 0:5868e8752d44 31 #include <assert.h>
pythontech 0:5868e8752d44 32
pythontech 0:5868e8752d44 33 #include "py/mpstate.h"
pythontech 0:5868e8752d44 34 #include "py/emit.h"
pythontech 0:5868e8752d44 35 #include "py/bc0.h"
pythontech 0:5868e8752d44 36
pythontech 0:5868e8752d44 37 #if MICROPY_ENABLE_COMPILER
pythontech 0:5868e8752d44 38
pythontech 0:5868e8752d44 39 #define BYTES_FOR_INT ((BYTES_PER_WORD * 8 + 6) / 7)
pythontech 0:5868e8752d44 40 #define DUMMY_DATA_SIZE (BYTES_FOR_INT)
pythontech 0:5868e8752d44 41
pythontech 0:5868e8752d44 42 struct _emit_t {
pythontech 0:5868e8752d44 43 // Accessed as mp_obj_t, so must be aligned as such, and we rely on the
pythontech 0:5868e8752d44 44 // memory allocator returning a suitably aligned pointer.
pythontech 0:5868e8752d44 45 // Should work for cases when mp_obj_t is 64-bit on a 32-bit machine.
pythontech 0:5868e8752d44 46 byte dummy_data[DUMMY_DATA_SIZE];
pythontech 0:5868e8752d44 47
pythontech 0:5868e8752d44 48 pass_kind_t pass : 8;
pythontech 0:5868e8752d44 49 mp_uint_t last_emit_was_return_value : 8;
pythontech 0:5868e8752d44 50
pythontech 0:5868e8752d44 51 int stack_size;
pythontech 0:5868e8752d44 52
pythontech 0:5868e8752d44 53 scope_t *scope;
pythontech 0:5868e8752d44 54
pythontech 0:5868e8752d44 55 mp_uint_t last_source_line_offset;
pythontech 0:5868e8752d44 56 mp_uint_t last_source_line;
pythontech 0:5868e8752d44 57
pythontech 0:5868e8752d44 58 mp_uint_t max_num_labels;
pythontech 0:5868e8752d44 59 mp_uint_t *label_offsets;
pythontech 0:5868e8752d44 60
pythontech 0:5868e8752d44 61 size_t code_info_offset;
pythontech 0:5868e8752d44 62 size_t code_info_size;
pythontech 0:5868e8752d44 63 size_t bytecode_offset;
pythontech 0:5868e8752d44 64 size_t bytecode_size;
pythontech 0:5868e8752d44 65 byte *code_base; // stores both byte code and code info
pythontech 0:5868e8752d44 66
pythontech 0:5868e8752d44 67 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 68 uint16_t ct_cur_obj;
pythontech 0:5868e8752d44 69 uint16_t ct_num_obj;
pythontech 0:5868e8752d44 70 uint16_t ct_cur_raw_code;
pythontech 0:5868e8752d44 71 #endif
pythontech 0:5868e8752d44 72 mp_uint_t *const_table;
pythontech 0:5868e8752d44 73 };
pythontech 0:5868e8752d44 74
pythontech 0:5868e8752d44 75 emit_t *emit_bc_new(void) {
pythontech 0:5868e8752d44 76 emit_t *emit = m_new0(emit_t, 1);
pythontech 0:5868e8752d44 77 return emit;
pythontech 0:5868e8752d44 78 }
pythontech 0:5868e8752d44 79
pythontech 0:5868e8752d44 80 void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels) {
pythontech 0:5868e8752d44 81 emit->max_num_labels = max_num_labels;
pythontech 0:5868e8752d44 82 emit->label_offsets = m_new(mp_uint_t, emit->max_num_labels);
pythontech 0:5868e8752d44 83 }
pythontech 0:5868e8752d44 84
pythontech 0:5868e8752d44 85 void emit_bc_free(emit_t *emit) {
pythontech 0:5868e8752d44 86 m_del(mp_uint_t, emit->label_offsets, emit->max_num_labels);
pythontech 0:5868e8752d44 87 m_del_obj(emit_t, emit);
pythontech 0:5868e8752d44 88 }
pythontech 0:5868e8752d44 89
pythontech 0:5868e8752d44 90 typedef byte *(*emit_allocator_t)(emit_t *emit, int nbytes);
pythontech 0:5868e8752d44 91
pythontech 0:5868e8752d44 92 STATIC void emit_write_uint(emit_t *emit, emit_allocator_t allocator, mp_uint_t val) {
pythontech 0:5868e8752d44 93 // We store each 7 bits in a separate byte, and that's how many bytes needed
pythontech 0:5868e8752d44 94 byte buf[BYTES_FOR_INT];
pythontech 0:5868e8752d44 95 byte *p = buf + sizeof(buf);
pythontech 0:5868e8752d44 96 // We encode in little-ending order, but store in big-endian, to help decoding
pythontech 0:5868e8752d44 97 do {
pythontech 0:5868e8752d44 98 *--p = val & 0x7f;
pythontech 0:5868e8752d44 99 val >>= 7;
pythontech 0:5868e8752d44 100 } while (val != 0);
pythontech 0:5868e8752d44 101 byte *c = allocator(emit, buf + sizeof(buf) - p);
pythontech 0:5868e8752d44 102 while (p != buf + sizeof(buf) - 1) {
pythontech 0:5868e8752d44 103 *c++ = *p++ | 0x80;
pythontech 0:5868e8752d44 104 }
pythontech 0:5868e8752d44 105 *c = *p;
pythontech 0:5868e8752d44 106 }
pythontech 0:5868e8752d44 107
pythontech 0:5868e8752d44 108 // all functions must go through this one to emit code info
pythontech 0:5868e8752d44 109 STATIC byte *emit_get_cur_to_write_code_info(emit_t *emit, int num_bytes_to_write) {
pythontech 0:5868e8752d44 110 //printf("emit %d\n", num_bytes_to_write);
pythontech 0:5868e8752d44 111 if (emit->pass < MP_PASS_EMIT) {
pythontech 0:5868e8752d44 112 emit->code_info_offset += num_bytes_to_write;
pythontech 0:5868e8752d44 113 return emit->dummy_data;
pythontech 0:5868e8752d44 114 } else {
pythontech 0:5868e8752d44 115 assert(emit->code_info_offset + num_bytes_to_write <= emit->code_info_size);
pythontech 0:5868e8752d44 116 byte *c = emit->code_base + emit->code_info_offset;
pythontech 0:5868e8752d44 117 emit->code_info_offset += num_bytes_to_write;
pythontech 0:5868e8752d44 118 return c;
pythontech 0:5868e8752d44 119 }
pythontech 0:5868e8752d44 120 }
pythontech 0:5868e8752d44 121
pythontech 0:5868e8752d44 122 STATIC void emit_write_code_info_byte(emit_t* emit, byte val) {
pythontech 0:5868e8752d44 123 *emit_get_cur_to_write_code_info(emit, 1) = val;
pythontech 0:5868e8752d44 124 }
pythontech 0:5868e8752d44 125
pythontech 0:5868e8752d44 126 STATIC void emit_write_code_info_uint(emit_t* emit, mp_uint_t val) {
pythontech 0:5868e8752d44 127 emit_write_uint(emit, emit_get_cur_to_write_code_info, val);
pythontech 0:5868e8752d44 128 }
pythontech 0:5868e8752d44 129
pythontech 0:5868e8752d44 130 STATIC void emit_write_code_info_qstr(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 131 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 132 assert((qst >> 16) == 0);
pythontech 0:5868e8752d44 133 byte *c = emit_get_cur_to_write_code_info(emit, 2);
pythontech 0:5868e8752d44 134 c[0] = qst;
pythontech 0:5868e8752d44 135 c[1] = qst >> 8;
pythontech 0:5868e8752d44 136 #else
pythontech 0:5868e8752d44 137 emit_write_uint(emit, emit_get_cur_to_write_code_info, qst);
pythontech 0:5868e8752d44 138 #endif
pythontech 0:5868e8752d44 139 }
pythontech 0:5868e8752d44 140
pythontech 0:5868e8752d44 141 #if MICROPY_ENABLE_SOURCE_LINE
pythontech 0:5868e8752d44 142 STATIC void emit_write_code_info_bytes_lines(emit_t *emit, mp_uint_t bytes_to_skip, mp_uint_t lines_to_skip) {
pythontech 0:5868e8752d44 143 assert(bytes_to_skip > 0 || lines_to_skip > 0);
pythontech 0:5868e8752d44 144 //printf(" %d %d\n", bytes_to_skip, lines_to_skip);
pythontech 0:5868e8752d44 145 while (bytes_to_skip > 0 || lines_to_skip > 0) {
pythontech 0:5868e8752d44 146 mp_uint_t b, l;
pythontech 0:5868e8752d44 147 if (lines_to_skip <= 6) {
pythontech 0:5868e8752d44 148 // use 0b0LLBBBBB encoding
pythontech 0:5868e8752d44 149 b = MIN(bytes_to_skip, 0x1f);
pythontech 0:5868e8752d44 150 l = MIN(lines_to_skip, 0x3);
pythontech 0:5868e8752d44 151 *emit_get_cur_to_write_code_info(emit, 1) = b | (l << 5);
pythontech 0:5868e8752d44 152 } else {
pythontech 0:5868e8752d44 153 // use 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte)
pythontech 0:5868e8752d44 154 b = MIN(bytes_to_skip, 0xf);
pythontech 0:5868e8752d44 155 l = MIN(lines_to_skip, 0x7ff);
pythontech 0:5868e8752d44 156 byte *ci = emit_get_cur_to_write_code_info(emit, 2);
pythontech 0:5868e8752d44 157 ci[0] = 0x80 | b | ((l >> 4) & 0x70);
pythontech 0:5868e8752d44 158 ci[1] = l;
pythontech 0:5868e8752d44 159 }
pythontech 0:5868e8752d44 160 bytes_to_skip -= b;
pythontech 0:5868e8752d44 161 lines_to_skip -= l;
pythontech 0:5868e8752d44 162 }
pythontech 0:5868e8752d44 163 }
pythontech 0:5868e8752d44 164 #endif
pythontech 0:5868e8752d44 165
pythontech 0:5868e8752d44 166 // all functions must go through this one to emit byte code
pythontech 0:5868e8752d44 167 STATIC byte *emit_get_cur_to_write_bytecode(emit_t *emit, int num_bytes_to_write) {
pythontech 0:5868e8752d44 168 //printf("emit %d\n", num_bytes_to_write);
pythontech 0:5868e8752d44 169 if (emit->pass < MP_PASS_EMIT) {
pythontech 0:5868e8752d44 170 emit->bytecode_offset += num_bytes_to_write;
pythontech 0:5868e8752d44 171 return emit->dummy_data;
pythontech 0:5868e8752d44 172 } else {
pythontech 0:5868e8752d44 173 assert(emit->bytecode_offset + num_bytes_to_write <= emit->bytecode_size);
pythontech 0:5868e8752d44 174 byte *c = emit->code_base + emit->code_info_size + emit->bytecode_offset;
pythontech 0:5868e8752d44 175 emit->bytecode_offset += num_bytes_to_write;
pythontech 0:5868e8752d44 176 return c;
pythontech 0:5868e8752d44 177 }
pythontech 0:5868e8752d44 178 }
pythontech 0:5868e8752d44 179
pythontech 0:5868e8752d44 180 STATIC void emit_write_bytecode_byte(emit_t *emit, byte b1) {
pythontech 0:5868e8752d44 181 byte *c = emit_get_cur_to_write_bytecode(emit, 1);
pythontech 0:5868e8752d44 182 c[0] = b1;
pythontech 0:5868e8752d44 183 }
pythontech 0:5868e8752d44 184
pythontech 0:5868e8752d44 185 STATIC void emit_write_bytecode_byte_byte(emit_t* emit, byte b1, byte b2) {
pythontech 0:5868e8752d44 186 assert((b2 & (~0xff)) == 0);
pythontech 0:5868e8752d44 187 byte *c = emit_get_cur_to_write_bytecode(emit, 2);
pythontech 0:5868e8752d44 188 c[0] = b1;
pythontech 0:5868e8752d44 189 c[1] = b2;
pythontech 0:5868e8752d44 190 }
pythontech 0:5868e8752d44 191
pythontech 0:5868e8752d44 192 // Similar to emit_write_bytecode_uint(), just some extra handling to encode sign
pythontech 0:5868e8752d44 193 STATIC void emit_write_bytecode_byte_int(emit_t *emit, byte b1, mp_int_t num) {
pythontech 0:5868e8752d44 194 emit_write_bytecode_byte(emit, b1);
pythontech 0:5868e8752d44 195
pythontech 0:5868e8752d44 196 // We store each 7 bits in a separate byte, and that's how many bytes needed
pythontech 0:5868e8752d44 197 byte buf[BYTES_FOR_INT];
pythontech 0:5868e8752d44 198 byte *p = buf + sizeof(buf);
pythontech 0:5868e8752d44 199 // We encode in little-ending order, but store in big-endian, to help decoding
pythontech 0:5868e8752d44 200 do {
pythontech 0:5868e8752d44 201 *--p = num & 0x7f;
pythontech 0:5868e8752d44 202 num >>= 7;
pythontech 0:5868e8752d44 203 } while (num != 0 && num != -1);
pythontech 0:5868e8752d44 204 // Make sure that highest bit we stored (mask 0x40) matches sign
pythontech 0:5868e8752d44 205 // of the number. If not, store extra byte just to encode sign
pythontech 0:5868e8752d44 206 if (num == -1 && (*p & 0x40) == 0) {
pythontech 0:5868e8752d44 207 *--p = 0x7f;
pythontech 0:5868e8752d44 208 } else if (num == 0 && (*p & 0x40) != 0) {
pythontech 0:5868e8752d44 209 *--p = 0;
pythontech 0:5868e8752d44 210 }
pythontech 0:5868e8752d44 211
pythontech 0:5868e8752d44 212 byte *c = emit_get_cur_to_write_bytecode(emit, buf + sizeof(buf) - p);
pythontech 0:5868e8752d44 213 while (p != buf + sizeof(buf) - 1) {
pythontech 0:5868e8752d44 214 *c++ = *p++ | 0x80;
pythontech 0:5868e8752d44 215 }
pythontech 0:5868e8752d44 216 *c = *p;
pythontech 0:5868e8752d44 217 }
pythontech 0:5868e8752d44 218
pythontech 0:5868e8752d44 219 STATIC void emit_write_bytecode_byte_uint(emit_t *emit, byte b, mp_uint_t val) {
pythontech 0:5868e8752d44 220 emit_write_bytecode_byte(emit, b);
pythontech 0:5868e8752d44 221 emit_write_uint(emit, emit_get_cur_to_write_bytecode, val);
pythontech 0:5868e8752d44 222 }
pythontech 0:5868e8752d44 223
pythontech 0:5868e8752d44 224 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 225 STATIC void emit_write_bytecode_byte_const(emit_t *emit, byte b, mp_uint_t n, mp_uint_t c) {
pythontech 0:5868e8752d44 226 if (emit->pass == MP_PASS_EMIT) {
pythontech 0:5868e8752d44 227 emit->const_table[n] = c;
pythontech 0:5868e8752d44 228 }
pythontech 0:5868e8752d44 229 emit_write_bytecode_byte_uint(emit, b, n);
pythontech 0:5868e8752d44 230 }
pythontech 0:5868e8752d44 231 #endif
pythontech 0:5868e8752d44 232
pythontech 0:5868e8752d44 233 STATIC void emit_write_bytecode_byte_qstr(emit_t* emit, byte b, qstr qst) {
pythontech 0:5868e8752d44 234 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 235 assert((qst >> 16) == 0);
pythontech 0:5868e8752d44 236 byte *c = emit_get_cur_to_write_bytecode(emit, 3);
pythontech 0:5868e8752d44 237 c[0] = b;
pythontech 0:5868e8752d44 238 c[1] = qst;
pythontech 0:5868e8752d44 239 c[2] = qst >> 8;
pythontech 0:5868e8752d44 240 #else
pythontech 0:5868e8752d44 241 emit_write_bytecode_byte_uint(emit, b, qst);
pythontech 0:5868e8752d44 242 #endif
pythontech 0:5868e8752d44 243 }
pythontech 0:5868e8752d44 244
pythontech 0:5868e8752d44 245 STATIC void emit_write_bytecode_byte_obj(emit_t *emit, byte b, mp_obj_t obj) {
pythontech 0:5868e8752d44 246 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 247 emit_write_bytecode_byte_const(emit, b,
pythontech 0:5868e8752d44 248 emit->scope->num_pos_args + emit->scope->num_kwonly_args
pythontech 0:5868e8752d44 249 + emit->ct_cur_obj++, (mp_uint_t)obj);
pythontech 0:5868e8752d44 250 #else
pythontech 0:5868e8752d44 251 // aligns the pointer so it is friendly to GC
pythontech 0:5868e8752d44 252 emit_write_bytecode_byte(emit, b);
pythontech 0:5868e8752d44 253 emit->bytecode_offset = (size_t)MP_ALIGN(emit->bytecode_offset, sizeof(mp_obj_t));
pythontech 0:5868e8752d44 254 mp_obj_t *c = (mp_obj_t*)emit_get_cur_to_write_bytecode(emit, sizeof(mp_obj_t));
pythontech 0:5868e8752d44 255 // Verify thar c is already uint-aligned
pythontech 0:5868e8752d44 256 assert(c == MP_ALIGN(c, sizeof(mp_obj_t)));
pythontech 0:5868e8752d44 257 *c = obj;
pythontech 0:5868e8752d44 258 #endif
pythontech 0:5868e8752d44 259 }
pythontech 0:5868e8752d44 260
pythontech 0:5868e8752d44 261 STATIC void emit_write_bytecode_byte_raw_code(emit_t *emit, byte b, mp_raw_code_t *rc) {
pythontech 0:5868e8752d44 262 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 263 emit_write_bytecode_byte_const(emit, b,
pythontech 0:5868e8752d44 264 emit->scope->num_pos_args + emit->scope->num_kwonly_args
pythontech 0:5868e8752d44 265 + emit->ct_num_obj + emit->ct_cur_raw_code++, (mp_uint_t)(uintptr_t)rc);
pythontech 0:5868e8752d44 266 #else
pythontech 0:5868e8752d44 267 // aligns the pointer so it is friendly to GC
pythontech 0:5868e8752d44 268 emit_write_bytecode_byte(emit, b);
pythontech 0:5868e8752d44 269 emit->bytecode_offset = (size_t)MP_ALIGN(emit->bytecode_offset, sizeof(void*));
pythontech 0:5868e8752d44 270 void **c = (void**)emit_get_cur_to_write_bytecode(emit, sizeof(void*));
pythontech 0:5868e8752d44 271 // Verify thar c is already uint-aligned
pythontech 0:5868e8752d44 272 assert(c == MP_ALIGN(c, sizeof(void*)));
pythontech 0:5868e8752d44 273 *c = rc;
pythontech 0:5868e8752d44 274 #endif
pythontech 0:5868e8752d44 275 }
pythontech 0:5868e8752d44 276
pythontech 0:5868e8752d44 277 // unsigned labels are relative to ip following this instruction, stored as 16 bits
pythontech 0:5868e8752d44 278 STATIC void emit_write_bytecode_byte_unsigned_label(emit_t *emit, byte b1, mp_uint_t label) {
pythontech 0:5868e8752d44 279 mp_uint_t bytecode_offset;
pythontech 0:5868e8752d44 280 if (emit->pass < MP_PASS_EMIT) {
pythontech 0:5868e8752d44 281 bytecode_offset = 0;
pythontech 0:5868e8752d44 282 } else {
pythontech 0:5868e8752d44 283 bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 3;
pythontech 0:5868e8752d44 284 }
pythontech 0:5868e8752d44 285 byte *c = emit_get_cur_to_write_bytecode(emit, 3);
pythontech 0:5868e8752d44 286 c[0] = b1;
pythontech 0:5868e8752d44 287 c[1] = bytecode_offset;
pythontech 0:5868e8752d44 288 c[2] = bytecode_offset >> 8;
pythontech 0:5868e8752d44 289 }
pythontech 0:5868e8752d44 290
pythontech 0:5868e8752d44 291 // signed labels are relative to ip following this instruction, stored as 16 bits, in excess
pythontech 0:5868e8752d44 292 STATIC void emit_write_bytecode_byte_signed_label(emit_t *emit, byte b1, mp_uint_t label) {
pythontech 0:5868e8752d44 293 int bytecode_offset;
pythontech 0:5868e8752d44 294 if (emit->pass < MP_PASS_EMIT) {
pythontech 0:5868e8752d44 295 bytecode_offset = 0;
pythontech 0:5868e8752d44 296 } else {
pythontech 0:5868e8752d44 297 bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 3 + 0x8000;
pythontech 0:5868e8752d44 298 }
pythontech 0:5868e8752d44 299 byte *c = emit_get_cur_to_write_bytecode(emit, 3);
pythontech 0:5868e8752d44 300 c[0] = b1;
pythontech 0:5868e8752d44 301 c[1] = bytecode_offset;
pythontech 0:5868e8752d44 302 c[2] = bytecode_offset >> 8;
pythontech 0:5868e8752d44 303 }
pythontech 0:5868e8752d44 304
pythontech 0:5868e8752d44 305 #if MICROPY_EMIT_NATIVE
pythontech 0:5868e8752d44 306 STATIC void mp_emit_bc_set_native_type(emit_t *emit, mp_uint_t op, mp_uint_t arg1, qstr arg2) {
pythontech 0:5868e8752d44 307 (void)emit;
pythontech 0:5868e8752d44 308 (void)op;
pythontech 0:5868e8752d44 309 (void)arg1;
pythontech 0:5868e8752d44 310 (void)arg2;
pythontech 0:5868e8752d44 311 }
pythontech 0:5868e8752d44 312 #endif
pythontech 0:5868e8752d44 313
pythontech 0:5868e8752d44 314 void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
pythontech 0:5868e8752d44 315 emit->pass = pass;
pythontech 0:5868e8752d44 316 emit->stack_size = 0;
pythontech 0:5868e8752d44 317 emit->last_emit_was_return_value = false;
pythontech 0:5868e8752d44 318 emit->scope = scope;
pythontech 0:5868e8752d44 319 emit->last_source_line_offset = 0;
pythontech 0:5868e8752d44 320 emit->last_source_line = 1;
pythontech 0:5868e8752d44 321 if (pass < MP_PASS_EMIT) {
pythontech 0:5868e8752d44 322 memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(mp_uint_t));
pythontech 0:5868e8752d44 323 }
pythontech 0:5868e8752d44 324 emit->bytecode_offset = 0;
pythontech 0:5868e8752d44 325 emit->code_info_offset = 0;
pythontech 0:5868e8752d44 326
pythontech 0:5868e8752d44 327 // Write local state size and exception stack size.
pythontech 0:5868e8752d44 328 {
pythontech 0:5868e8752d44 329 mp_uint_t n_state = scope->num_locals + scope->stack_size;
pythontech 0:5868e8752d44 330 if (n_state == 0) {
pythontech 0:5868e8752d44 331 // Need at least 1 entry in the state, in the case an exception is
pythontech 0:5868e8752d44 332 // propagated through this function, the exception is returned in
pythontech 0:5868e8752d44 333 // the highest slot in the state (fastn[0], see vm.c).
pythontech 0:5868e8752d44 334 n_state = 1;
pythontech 0:5868e8752d44 335 }
pythontech 0:5868e8752d44 336 emit_write_code_info_uint(emit, n_state);
pythontech 0:5868e8752d44 337 emit_write_code_info_uint(emit, scope->exc_stack_size);
pythontech 0:5868e8752d44 338 }
pythontech 0:5868e8752d44 339
pythontech 0:5868e8752d44 340 // Write scope flags and number of arguments.
pythontech 0:5868e8752d44 341 // TODO check that num args all fit in a byte
pythontech 0:5868e8752d44 342 emit_write_code_info_byte(emit, emit->scope->scope_flags);
pythontech 0:5868e8752d44 343 emit_write_code_info_byte(emit, emit->scope->num_pos_args);
pythontech 0:5868e8752d44 344 emit_write_code_info_byte(emit, emit->scope->num_kwonly_args);
pythontech 0:5868e8752d44 345 emit_write_code_info_byte(emit, emit->scope->num_def_pos_args);
pythontech 0:5868e8752d44 346
pythontech 0:5868e8752d44 347 // Write size of the rest of the code info. We don't know how big this
pythontech 0:5868e8752d44 348 // variable uint will be on the MP_PASS_CODE_SIZE pass so we reserve 2 bytes
pythontech 0:5868e8752d44 349 // for it and hope that is enough! TODO assert this or something.
pythontech 0:5868e8752d44 350 if (pass == MP_PASS_EMIT) {
pythontech 0:5868e8752d44 351 emit_write_code_info_uint(emit, emit->code_info_size - emit->code_info_offset);
pythontech 0:5868e8752d44 352 } else {
pythontech 0:5868e8752d44 353 emit_get_cur_to_write_code_info(emit, 2);
pythontech 0:5868e8752d44 354 }
pythontech 0:5868e8752d44 355
pythontech 0:5868e8752d44 356 // Write the name and source file of this function.
pythontech 0:5868e8752d44 357 emit_write_code_info_qstr(emit, scope->simple_name);
pythontech 0:5868e8752d44 358 emit_write_code_info_qstr(emit, scope->source_file);
pythontech 0:5868e8752d44 359
pythontech 0:5868e8752d44 360 // bytecode prelude: initialise closed over variables
pythontech 0:5868e8752d44 361 for (int i = 0; i < scope->id_info_len; i++) {
pythontech 0:5868e8752d44 362 id_info_t *id = &scope->id_info[i];
pythontech 0:5868e8752d44 363 if (id->kind == ID_INFO_KIND_CELL) {
pythontech 0:5868e8752d44 364 assert(id->local_num < 255);
pythontech 0:5868e8752d44 365 emit_write_bytecode_byte(emit, id->local_num); // write the local which should be converted to a cell
pythontech 0:5868e8752d44 366 }
pythontech 0:5868e8752d44 367 }
pythontech 0:5868e8752d44 368 emit_write_bytecode_byte(emit, 255); // end of list sentinel
pythontech 0:5868e8752d44 369
pythontech 0:5868e8752d44 370 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 371 emit->ct_cur_obj = 0;
pythontech 0:5868e8752d44 372 emit->ct_cur_raw_code = 0;
pythontech 0:5868e8752d44 373 #endif
pythontech 0:5868e8752d44 374
pythontech 0:5868e8752d44 375 if (pass == MP_PASS_EMIT) {
pythontech 0:5868e8752d44 376 // Write argument names (needed to resolve positional args passed as
pythontech 0:5868e8752d44 377 // keywords). We store them as full word-sized objects for efficient access
pythontech 0:5868e8752d44 378 // in mp_setup_code_state this is the start of the prelude and is guaranteed
pythontech 0:5868e8752d44 379 // to be aligned on a word boundary.
pythontech 0:5868e8752d44 380
pythontech 0:5868e8752d44 381 // For a given argument position (indexed by i) we need to find the
pythontech 0:5868e8752d44 382 // corresponding id_info which is a parameter, as it has the correct
pythontech 0:5868e8752d44 383 // qstr name to use as the argument name. Note that it's not a simple
pythontech 0:5868e8752d44 384 // 1-1 mapping (ie i!=j in general) because of possible closed-over
pythontech 0:5868e8752d44 385 // variables. In the case that the argument i has no corresponding
pythontech 0:5868e8752d44 386 // parameter we use "*" as its name (since no argument can ever be named
pythontech 0:5868e8752d44 387 // "*"). We could use a blank qstr but "*" is better for debugging.
pythontech 0:5868e8752d44 388 // Note: there is some wasted RAM here for the case of storing a qstr
pythontech 0:5868e8752d44 389 // for each closed-over variable, and maybe there is a better way to do
pythontech 0:5868e8752d44 390 // it, but that would require changes to mp_setup_code_state.
pythontech 0:5868e8752d44 391 for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
pythontech 0:5868e8752d44 392 qstr qst = MP_QSTR__star_;
pythontech 0:5868e8752d44 393 for (int j = 0; j < scope->id_info_len; ++j) {
pythontech 0:5868e8752d44 394 id_info_t *id = &scope->id_info[j];
pythontech 0:5868e8752d44 395 if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
pythontech 0:5868e8752d44 396 qst = id->qst;
pythontech 0:5868e8752d44 397 break;
pythontech 0:5868e8752d44 398 }
pythontech 0:5868e8752d44 399 }
pythontech 0:5868e8752d44 400 emit->const_table[i] = (mp_uint_t)MP_OBJ_NEW_QSTR(qst);
pythontech 0:5868e8752d44 401 }
pythontech 0:5868e8752d44 402 }
pythontech 0:5868e8752d44 403 }
pythontech 0:5868e8752d44 404
pythontech 0:5868e8752d44 405 void mp_emit_bc_end_pass(emit_t *emit) {
pythontech 0:5868e8752d44 406 if (emit->pass == MP_PASS_SCOPE) {
pythontech 0:5868e8752d44 407 return;
pythontech 0:5868e8752d44 408 }
pythontech 0:5868e8752d44 409
pythontech 0:5868e8752d44 410 // check stack is back to zero size
pythontech 0:5868e8752d44 411 if (emit->stack_size != 0) {
pythontech 0:5868e8752d44 412 mp_printf(&mp_plat_print, "ERROR: stack size not back to zero; got %d\n", emit->stack_size);
pythontech 0:5868e8752d44 413 }
pythontech 0:5868e8752d44 414
pythontech 0:5868e8752d44 415 emit_write_code_info_byte(emit, 0); // end of line number info
pythontech 0:5868e8752d44 416
pythontech 0:5868e8752d44 417 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 418 assert(emit->pass <= MP_PASS_STACK_SIZE || (emit->ct_num_obj == emit->ct_cur_obj));
pythontech 0:5868e8752d44 419 emit->ct_num_obj = emit->ct_cur_obj;
pythontech 0:5868e8752d44 420 #endif
pythontech 0:5868e8752d44 421
pythontech 0:5868e8752d44 422 if (emit->pass == MP_PASS_CODE_SIZE) {
pythontech 0:5868e8752d44 423 #if !MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 424 // so bytecode is aligned
pythontech 0:5868e8752d44 425 emit->code_info_offset = (size_t)MP_ALIGN(emit->code_info_offset, sizeof(mp_uint_t));
pythontech 0:5868e8752d44 426 #endif
pythontech 0:5868e8752d44 427
pythontech 0:5868e8752d44 428 // calculate size of total code-info + bytecode, in bytes
pythontech 0:5868e8752d44 429 emit->code_info_size = emit->code_info_offset;
pythontech 0:5868e8752d44 430 emit->bytecode_size = emit->bytecode_offset;
pythontech 0:5868e8752d44 431 emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size);
pythontech 0:5868e8752d44 432
pythontech 0:5868e8752d44 433 #if MICROPY_PERSISTENT_CODE
pythontech 0:5868e8752d44 434 emit->const_table = m_new0(mp_uint_t,
pythontech 0:5868e8752d44 435 emit->scope->num_pos_args + emit->scope->num_kwonly_args
pythontech 0:5868e8752d44 436 + emit->ct_cur_obj + emit->ct_cur_raw_code);
pythontech 0:5868e8752d44 437 #else
pythontech 0:5868e8752d44 438 emit->const_table = m_new0(mp_uint_t,
pythontech 0:5868e8752d44 439 emit->scope->num_pos_args + emit->scope->num_kwonly_args);
pythontech 0:5868e8752d44 440 #endif
pythontech 0:5868e8752d44 441
pythontech 0:5868e8752d44 442 } else if (emit->pass == MP_PASS_EMIT) {
pythontech 0:5868e8752d44 443 mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base,
pythontech 0:5868e8752d44 444 emit->code_info_size + emit->bytecode_size,
pythontech 0:5868e8752d44 445 emit->const_table,
pythontech 0:5868e8752d44 446 #if MICROPY_PERSISTENT_CODE_SAVE
pythontech 0:5868e8752d44 447 emit->ct_cur_obj, emit->ct_cur_raw_code,
pythontech 0:5868e8752d44 448 #endif
pythontech 0:5868e8752d44 449 emit->scope->scope_flags);
pythontech 0:5868e8752d44 450 }
pythontech 0:5868e8752d44 451 }
pythontech 0:5868e8752d44 452
pythontech 0:5868e8752d44 453 bool mp_emit_bc_last_emit_was_return_value(emit_t *emit) {
pythontech 0:5868e8752d44 454 return emit->last_emit_was_return_value;
pythontech 0:5868e8752d44 455 }
pythontech 0:5868e8752d44 456
pythontech 0:5868e8752d44 457 void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
pythontech 0:5868e8752d44 458 emit->stack_size += delta;
pythontech 0:5868e8752d44 459 }
pythontech 0:5868e8752d44 460
pythontech 0:5868e8752d44 461 void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
pythontech 0:5868e8752d44 462 //printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->bytecode_offset);
pythontech 0:5868e8752d44 463 #if MICROPY_ENABLE_SOURCE_LINE
pythontech 0:5868e8752d44 464 if (MP_STATE_VM(mp_optimise_value) >= 3) {
pythontech 0:5868e8752d44 465 // If we compile with -O3, don't store line numbers.
pythontech 0:5868e8752d44 466 return;
pythontech 0:5868e8752d44 467 }
pythontech 0:5868e8752d44 468 if (source_line > emit->last_source_line) {
pythontech 0:5868e8752d44 469 mp_uint_t bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset;
pythontech 0:5868e8752d44 470 mp_uint_t lines_to_skip = source_line - emit->last_source_line;
pythontech 0:5868e8752d44 471 emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip);
pythontech 0:5868e8752d44 472 emit->last_source_line_offset = emit->bytecode_offset;
pythontech 0:5868e8752d44 473 emit->last_source_line = source_line;
pythontech 0:5868e8752d44 474 }
pythontech 0:5868e8752d44 475 #else
pythontech 0:5868e8752d44 476 (void)emit;
pythontech 0:5868e8752d44 477 (void)source_line;
pythontech 0:5868e8752d44 478 #endif
pythontech 0:5868e8752d44 479 }
pythontech 0:5868e8752d44 480
pythontech 0:5868e8752d44 481 STATIC void emit_bc_pre(emit_t *emit, mp_int_t stack_size_delta) {
pythontech 0:5868e8752d44 482 if (emit->pass == MP_PASS_SCOPE) {
pythontech 0:5868e8752d44 483 return;
pythontech 0:5868e8752d44 484 }
pythontech 0:5868e8752d44 485 assert((mp_int_t)emit->stack_size + stack_size_delta >= 0);
pythontech 0:5868e8752d44 486 emit->stack_size += stack_size_delta;
pythontech 0:5868e8752d44 487 if (emit->stack_size > emit->scope->stack_size) {
pythontech 0:5868e8752d44 488 emit->scope->stack_size = emit->stack_size;
pythontech 0:5868e8752d44 489 }
pythontech 0:5868e8752d44 490 emit->last_emit_was_return_value = false;
pythontech 0:5868e8752d44 491 }
pythontech 0:5868e8752d44 492
pythontech 0:5868e8752d44 493 void mp_emit_bc_label_assign(emit_t *emit, mp_uint_t l) {
pythontech 0:5868e8752d44 494 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 495 if (emit->pass == MP_PASS_SCOPE) {
pythontech 0:5868e8752d44 496 return;
pythontech 0:5868e8752d44 497 }
pythontech 0:5868e8752d44 498 assert(l < emit->max_num_labels);
pythontech 0:5868e8752d44 499 if (emit->pass < MP_PASS_EMIT) {
pythontech 0:5868e8752d44 500 // assign label offset
pythontech 0:5868e8752d44 501 assert(emit->label_offsets[l] == (mp_uint_t)-1);
pythontech 0:5868e8752d44 502 emit->label_offsets[l] = emit->bytecode_offset;
pythontech 0:5868e8752d44 503 } else {
pythontech 0:5868e8752d44 504 // ensure label offset has not changed from MP_PASS_CODE_SIZE to MP_PASS_EMIT
pythontech 0:5868e8752d44 505 //printf("l%d: (at %d vs %d)\n", l, emit->bytecode_offset, emit->label_offsets[l]);
pythontech 0:5868e8752d44 506 assert(emit->label_offsets[l] == emit->bytecode_offset);
pythontech 0:5868e8752d44 507 }
pythontech 0:5868e8752d44 508 }
pythontech 0:5868e8752d44 509
pythontech 0:5868e8752d44 510 void mp_emit_bc_import_name(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 511 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 512 emit_write_bytecode_byte_qstr(emit, MP_BC_IMPORT_NAME, qst);
pythontech 0:5868e8752d44 513 }
pythontech 0:5868e8752d44 514
pythontech 0:5868e8752d44 515 void mp_emit_bc_import_from(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 516 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 517 emit_write_bytecode_byte_qstr(emit, MP_BC_IMPORT_FROM, qst);
pythontech 0:5868e8752d44 518 }
pythontech 0:5868e8752d44 519
pythontech 0:5868e8752d44 520 void mp_emit_bc_import_star(emit_t *emit) {
pythontech 0:5868e8752d44 521 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 522 emit_write_bytecode_byte(emit, MP_BC_IMPORT_STAR);
pythontech 0:5868e8752d44 523 }
pythontech 0:5868e8752d44 524
pythontech 0:5868e8752d44 525 void mp_emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
pythontech 0:5868e8752d44 526 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 527 switch (tok) {
pythontech 0:5868e8752d44 528 case MP_TOKEN_KW_FALSE: emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_FALSE); break;
pythontech 0:5868e8752d44 529 case MP_TOKEN_KW_NONE: emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_NONE); break;
pythontech 0:5868e8752d44 530 case MP_TOKEN_KW_TRUE: emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_TRUE); break;
pythontech 0:5868e8752d44 531 no_other_choice:
pythontech 0:5868e8752d44 532 case MP_TOKEN_ELLIPSIS: emit_write_bytecode_byte_obj(emit, MP_BC_LOAD_CONST_OBJ, MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj)); break;
pythontech 0:5868e8752d44 533 default: assert(0); goto no_other_choice; // to help flow control analysis
pythontech 0:5868e8752d44 534 }
pythontech 0:5868e8752d44 535 }
pythontech 0:5868e8752d44 536
pythontech 0:5868e8752d44 537 void mp_emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg) {
pythontech 0:5868e8752d44 538 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 539 if (-16 <= arg && arg <= 47) {
pythontech 0:5868e8752d44 540 emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_SMALL_INT_MULTI + 16 + arg);
pythontech 0:5868e8752d44 541 } else {
pythontech 0:5868e8752d44 542 emit_write_bytecode_byte_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg);
pythontech 0:5868e8752d44 543 }
pythontech 0:5868e8752d44 544 }
pythontech 0:5868e8752d44 545
pythontech 0:5868e8752d44 546 void mp_emit_bc_load_const_str(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 547 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 548 emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_CONST_STRING, qst);
pythontech 0:5868e8752d44 549 }
pythontech 0:5868e8752d44 550
pythontech 0:5868e8752d44 551 void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj) {
pythontech 0:5868e8752d44 552 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 553 emit_write_bytecode_byte_obj(emit, MP_BC_LOAD_CONST_OBJ, obj);
pythontech 0:5868e8752d44 554 }
pythontech 0:5868e8752d44 555
pythontech 0:5868e8752d44 556 void mp_emit_bc_load_null(emit_t *emit) {
pythontech 0:5868e8752d44 557 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 558 emit_write_bytecode_byte(emit, MP_BC_LOAD_NULL);
pythontech 0:5868e8752d44 559 };
pythontech 0:5868e8752d44 560
pythontech 0:5868e8752d44 561 void mp_emit_bc_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 562 (void)qst;
pythontech 0:5868e8752d44 563 assert(local_num >= 0);
pythontech 0:5868e8752d44 564 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 565 if (local_num <= 15) {
pythontech 0:5868e8752d44 566 emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_MULTI + local_num);
pythontech 0:5868e8752d44 567 } else {
pythontech 0:5868e8752d44 568 emit_write_bytecode_byte_uint(emit, MP_BC_LOAD_FAST_N, local_num);
pythontech 0:5868e8752d44 569 }
pythontech 0:5868e8752d44 570 }
pythontech 0:5868e8752d44 571
pythontech 0:5868e8752d44 572 void mp_emit_bc_load_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 573 (void)qst;
pythontech 0:5868e8752d44 574 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 575 emit_write_bytecode_byte_uint(emit, MP_BC_LOAD_DEREF, local_num);
pythontech 0:5868e8752d44 576 }
pythontech 0:5868e8752d44 577
pythontech 0:5868e8752d44 578 void mp_emit_bc_load_name(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 579 (void)qst;
pythontech 0:5868e8752d44 580 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 581 emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_NAME, qst);
pythontech 0:5868e8752d44 582 if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) {
pythontech 0:5868e8752d44 583 emit_write_bytecode_byte(emit, 0);
pythontech 0:5868e8752d44 584 }
pythontech 0:5868e8752d44 585 }
pythontech 0:5868e8752d44 586
pythontech 0:5868e8752d44 587 void mp_emit_bc_load_global(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 588 (void)qst;
pythontech 0:5868e8752d44 589 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 590 emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_GLOBAL, qst);
pythontech 0:5868e8752d44 591 if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) {
pythontech 0:5868e8752d44 592 emit_write_bytecode_byte(emit, 0);
pythontech 0:5868e8752d44 593 }
pythontech 0:5868e8752d44 594 }
pythontech 0:5868e8752d44 595
pythontech 0:5868e8752d44 596 void mp_emit_bc_load_attr(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 597 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 598 emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_ATTR, qst);
pythontech 0:5868e8752d44 599 if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) {
pythontech 0:5868e8752d44 600 emit_write_bytecode_byte(emit, 0);
pythontech 0:5868e8752d44 601 }
pythontech 0:5868e8752d44 602 }
pythontech 0:5868e8752d44 603
pythontech 0:5868e8752d44 604 void mp_emit_bc_load_method(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 605 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 606 emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_METHOD, qst);
pythontech 0:5868e8752d44 607 }
pythontech 0:5868e8752d44 608
pythontech 0:5868e8752d44 609 void mp_emit_bc_load_build_class(emit_t *emit) {
pythontech 0:5868e8752d44 610 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 611 emit_write_bytecode_byte(emit, MP_BC_LOAD_BUILD_CLASS);
pythontech 0:5868e8752d44 612 }
pythontech 0:5868e8752d44 613
pythontech 0:5868e8752d44 614 void mp_emit_bc_load_subscr(emit_t *emit) {
pythontech 0:5868e8752d44 615 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 616 emit_write_bytecode_byte(emit, MP_BC_LOAD_SUBSCR);
pythontech 0:5868e8752d44 617 }
pythontech 0:5868e8752d44 618
pythontech 0:5868e8752d44 619 void mp_emit_bc_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 620 (void)qst;
pythontech 0:5868e8752d44 621 assert(local_num >= 0);
pythontech 0:5868e8752d44 622 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 623 if (local_num <= 15) {
pythontech 0:5868e8752d44 624 emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_MULTI + local_num);
pythontech 0:5868e8752d44 625 } else {
pythontech 0:5868e8752d44 626 emit_write_bytecode_byte_uint(emit, MP_BC_STORE_FAST_N, local_num);
pythontech 0:5868e8752d44 627 }
pythontech 0:5868e8752d44 628 }
pythontech 0:5868e8752d44 629
pythontech 0:5868e8752d44 630 void mp_emit_bc_store_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 631 (void)qst;
pythontech 0:5868e8752d44 632 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 633 emit_write_bytecode_byte_uint(emit, MP_BC_STORE_DEREF, local_num);
pythontech 0:5868e8752d44 634 }
pythontech 0:5868e8752d44 635
pythontech 0:5868e8752d44 636 void mp_emit_bc_store_name(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 637 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 638 emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_NAME, qst);
pythontech 0:5868e8752d44 639 }
pythontech 0:5868e8752d44 640
pythontech 0:5868e8752d44 641 void mp_emit_bc_store_global(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 642 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 643 emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_GLOBAL, qst);
pythontech 0:5868e8752d44 644 }
pythontech 0:5868e8752d44 645
pythontech 0:5868e8752d44 646 void mp_emit_bc_store_attr(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 647 emit_bc_pre(emit, -2);
pythontech 0:5868e8752d44 648 emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_ATTR, qst);
pythontech 0:5868e8752d44 649 if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) {
pythontech 0:5868e8752d44 650 emit_write_bytecode_byte(emit, 0);
pythontech 0:5868e8752d44 651 }
pythontech 0:5868e8752d44 652 }
pythontech 0:5868e8752d44 653
pythontech 0:5868e8752d44 654 void mp_emit_bc_store_subscr(emit_t *emit) {
pythontech 0:5868e8752d44 655 emit_bc_pre(emit, -3);
pythontech 0:5868e8752d44 656 emit_write_bytecode_byte(emit, MP_BC_STORE_SUBSCR);
pythontech 0:5868e8752d44 657 }
pythontech 0:5868e8752d44 658
pythontech 0:5868e8752d44 659 void mp_emit_bc_delete_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 660 (void)qst;
pythontech 0:5868e8752d44 661 emit_write_bytecode_byte_uint(emit, MP_BC_DELETE_FAST, local_num);
pythontech 0:5868e8752d44 662 }
pythontech 0:5868e8752d44 663
pythontech 0:5868e8752d44 664 void mp_emit_bc_delete_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
pythontech 0:5868e8752d44 665 (void)qst;
pythontech 0:5868e8752d44 666 emit_write_bytecode_byte_uint(emit, MP_BC_DELETE_DEREF, local_num);
pythontech 0:5868e8752d44 667 }
pythontech 0:5868e8752d44 668
pythontech 0:5868e8752d44 669 void mp_emit_bc_delete_name(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 670 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 671 emit_write_bytecode_byte_qstr(emit, MP_BC_DELETE_NAME, qst);
pythontech 0:5868e8752d44 672 }
pythontech 0:5868e8752d44 673
pythontech 0:5868e8752d44 674 void mp_emit_bc_delete_global(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 675 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 676 emit_write_bytecode_byte_qstr(emit, MP_BC_DELETE_GLOBAL, qst);
pythontech 0:5868e8752d44 677 }
pythontech 0:5868e8752d44 678
pythontech 0:5868e8752d44 679 void mp_emit_bc_delete_attr(emit_t *emit, qstr qst) {
pythontech 0:5868e8752d44 680 mp_emit_bc_load_null(emit);
pythontech 0:5868e8752d44 681 mp_emit_bc_rot_two(emit);
pythontech 0:5868e8752d44 682 mp_emit_bc_store_attr(emit, qst);
pythontech 0:5868e8752d44 683 }
pythontech 0:5868e8752d44 684
pythontech 0:5868e8752d44 685 void mp_emit_bc_delete_subscr(emit_t *emit) {
pythontech 0:5868e8752d44 686 mp_emit_bc_load_null(emit);
pythontech 0:5868e8752d44 687 mp_emit_bc_rot_three(emit);
pythontech 0:5868e8752d44 688 mp_emit_bc_store_subscr(emit);
pythontech 0:5868e8752d44 689 }
pythontech 0:5868e8752d44 690
pythontech 0:5868e8752d44 691 void mp_emit_bc_dup_top(emit_t *emit) {
pythontech 0:5868e8752d44 692 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 693 emit_write_bytecode_byte(emit, MP_BC_DUP_TOP);
pythontech 0:5868e8752d44 694 }
pythontech 0:5868e8752d44 695
pythontech 0:5868e8752d44 696 void mp_emit_bc_dup_top_two(emit_t *emit) {
pythontech 0:5868e8752d44 697 emit_bc_pre(emit, 2);
pythontech 0:5868e8752d44 698 emit_write_bytecode_byte(emit, MP_BC_DUP_TOP_TWO);
pythontech 0:5868e8752d44 699 }
pythontech 0:5868e8752d44 700
pythontech 0:5868e8752d44 701 void mp_emit_bc_pop_top(emit_t *emit) {
pythontech 0:5868e8752d44 702 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 703 emit_write_bytecode_byte(emit, MP_BC_POP_TOP);
pythontech 0:5868e8752d44 704 }
pythontech 0:5868e8752d44 705
pythontech 0:5868e8752d44 706 void mp_emit_bc_rot_two(emit_t *emit) {
pythontech 0:5868e8752d44 707 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 708 emit_write_bytecode_byte(emit, MP_BC_ROT_TWO);
pythontech 0:5868e8752d44 709 }
pythontech 0:5868e8752d44 710
pythontech 0:5868e8752d44 711 void mp_emit_bc_rot_three(emit_t *emit) {
pythontech 0:5868e8752d44 712 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 713 emit_write_bytecode_byte(emit, MP_BC_ROT_THREE);
pythontech 0:5868e8752d44 714 }
pythontech 0:5868e8752d44 715
pythontech 0:5868e8752d44 716 void mp_emit_bc_jump(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 717 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 718 emit_write_bytecode_byte_signed_label(emit, MP_BC_JUMP, label);
pythontech 0:5868e8752d44 719 }
pythontech 0:5868e8752d44 720
pythontech 0:5868e8752d44 721 void mp_emit_bc_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label) {
pythontech 0:5868e8752d44 722 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 723 if (cond) {
pythontech 0:5868e8752d44 724 emit_write_bytecode_byte_signed_label(emit, MP_BC_POP_JUMP_IF_TRUE, label);
pythontech 0:5868e8752d44 725 } else {
pythontech 0:5868e8752d44 726 emit_write_bytecode_byte_signed_label(emit, MP_BC_POP_JUMP_IF_FALSE, label);
pythontech 0:5868e8752d44 727 }
pythontech 0:5868e8752d44 728 }
pythontech 0:5868e8752d44 729
pythontech 0:5868e8752d44 730 void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label) {
pythontech 0:5868e8752d44 731 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 732 if (cond) {
pythontech 0:5868e8752d44 733 emit_write_bytecode_byte_signed_label(emit, MP_BC_JUMP_IF_TRUE_OR_POP, label);
pythontech 0:5868e8752d44 734 } else {
pythontech 0:5868e8752d44 735 emit_write_bytecode_byte_signed_label(emit, MP_BC_JUMP_IF_FALSE_OR_POP, label);
pythontech 0:5868e8752d44 736 }
pythontech 0:5868e8752d44 737 }
pythontech 0:5868e8752d44 738
pythontech 0:5868e8752d44 739 void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_depth) {
pythontech 0:5868e8752d44 740 if (except_depth == 0) {
pythontech 0:5868e8752d44 741 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 742 if (label & MP_EMIT_BREAK_FROM_FOR) {
pythontech 0:5868e8752d44 743 // need to pop the iterator if we are breaking out of a for loop
pythontech 0:5868e8752d44 744 emit_write_bytecode_byte(emit, MP_BC_POP_TOP);
pythontech 0:5868e8752d44 745 }
pythontech 0:5868e8752d44 746 emit_write_bytecode_byte_signed_label(emit, MP_BC_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
pythontech 0:5868e8752d44 747 } else {
pythontech 0:5868e8752d44 748 emit_write_bytecode_byte_signed_label(emit, MP_BC_UNWIND_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
pythontech 0:5868e8752d44 749 emit_write_bytecode_byte(emit, ((label & MP_EMIT_BREAK_FROM_FOR) ? 0x80 : 0) | except_depth);
pythontech 0:5868e8752d44 750 }
pythontech 0:5868e8752d44 751 }
pythontech 0:5868e8752d44 752
pythontech 0:5868e8752d44 753 void mp_emit_bc_setup_with(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 754 // TODO We can probably optimise the amount of needed stack space, since
pythontech 0:5868e8752d44 755 // we don't actually need 4 slots during the entire with block, only in
pythontech 0:5868e8752d44 756 // the cleanup handler in certain cases. It needs some thinking.
pythontech 0:5868e8752d44 757 emit_bc_pre(emit, 4);
pythontech 0:5868e8752d44 758 emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_WITH, label);
pythontech 0:5868e8752d44 759 }
pythontech 0:5868e8752d44 760
pythontech 0:5868e8752d44 761 void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 762 mp_emit_bc_pop_block(emit);
pythontech 0:5868e8752d44 763 mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE);
pythontech 0:5868e8752d44 764 mp_emit_bc_label_assign(emit, label);
pythontech 0:5868e8752d44 765 emit_bc_pre(emit, -4);
pythontech 0:5868e8752d44 766 emit_write_bytecode_byte(emit, MP_BC_WITH_CLEANUP);
pythontech 0:5868e8752d44 767 }
pythontech 0:5868e8752d44 768
pythontech 0:5868e8752d44 769 void mp_emit_bc_setup_except(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 770 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 771 emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_EXCEPT, label);
pythontech 0:5868e8752d44 772 }
pythontech 0:5868e8752d44 773
pythontech 0:5868e8752d44 774 void mp_emit_bc_setup_finally(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 775 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 776 emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_FINALLY, label);
pythontech 0:5868e8752d44 777 }
pythontech 0:5868e8752d44 778
pythontech 0:5868e8752d44 779 void mp_emit_bc_end_finally(emit_t *emit) {
pythontech 0:5868e8752d44 780 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 781 emit_write_bytecode_byte(emit, MP_BC_END_FINALLY);
pythontech 0:5868e8752d44 782 }
pythontech 0:5868e8752d44 783
pythontech 0:5868e8752d44 784 void mp_emit_bc_get_iter(emit_t *emit) {
pythontech 0:5868e8752d44 785 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 786 emit_write_bytecode_byte(emit, MP_BC_GET_ITER);
pythontech 0:5868e8752d44 787 }
pythontech 0:5868e8752d44 788
pythontech 0:5868e8752d44 789 void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) {
pythontech 0:5868e8752d44 790 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 791 emit_write_bytecode_byte_unsigned_label(emit, MP_BC_FOR_ITER, label);
pythontech 0:5868e8752d44 792 }
pythontech 0:5868e8752d44 793
pythontech 0:5868e8752d44 794 void mp_emit_bc_for_iter_end(emit_t *emit) {
pythontech 0:5868e8752d44 795 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 796 }
pythontech 0:5868e8752d44 797
pythontech 0:5868e8752d44 798 void mp_emit_bc_pop_block(emit_t *emit) {
pythontech 0:5868e8752d44 799 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 800 emit_write_bytecode_byte(emit, MP_BC_POP_BLOCK);
pythontech 0:5868e8752d44 801 }
pythontech 0:5868e8752d44 802
pythontech 0:5868e8752d44 803 void mp_emit_bc_pop_except(emit_t *emit) {
pythontech 0:5868e8752d44 804 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 805 emit_write_bytecode_byte(emit, MP_BC_POP_EXCEPT);
pythontech 0:5868e8752d44 806 }
pythontech 0:5868e8752d44 807
pythontech 0:5868e8752d44 808 void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) {
pythontech 0:5868e8752d44 809 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 810 emit_write_bytecode_byte(emit, MP_BC_UNARY_OP_MULTI + op);
pythontech 0:5868e8752d44 811 }
pythontech 0:5868e8752d44 812
pythontech 0:5868e8752d44 813 void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op) {
pythontech 0:5868e8752d44 814 bool invert = false;
pythontech 0:5868e8752d44 815 if (op == MP_BINARY_OP_NOT_IN) {
pythontech 0:5868e8752d44 816 invert = true;
pythontech 0:5868e8752d44 817 op = MP_BINARY_OP_IN;
pythontech 0:5868e8752d44 818 } else if (op == MP_BINARY_OP_IS_NOT) {
pythontech 0:5868e8752d44 819 invert = true;
pythontech 0:5868e8752d44 820 op = MP_BINARY_OP_IS;
pythontech 0:5868e8752d44 821 }
pythontech 0:5868e8752d44 822 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 823 emit_write_bytecode_byte(emit, MP_BC_BINARY_OP_MULTI + op);
pythontech 0:5868e8752d44 824 if (invert) {
pythontech 0:5868e8752d44 825 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 826 emit_write_bytecode_byte(emit, MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NOT);
pythontech 0:5868e8752d44 827 }
pythontech 0:5868e8752d44 828 }
pythontech 0:5868e8752d44 829
pythontech 0:5868e8752d44 830 void mp_emit_bc_build_tuple(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 831 emit_bc_pre(emit, 1 - n_args);
pythontech 0:5868e8752d44 832 emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_TUPLE, n_args);
pythontech 0:5868e8752d44 833 }
pythontech 0:5868e8752d44 834
pythontech 0:5868e8752d44 835 void mp_emit_bc_build_list(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 836 emit_bc_pre(emit, 1 - n_args);
pythontech 0:5868e8752d44 837 emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_LIST, n_args);
pythontech 0:5868e8752d44 838 }
pythontech 0:5868e8752d44 839
pythontech 0:5868e8752d44 840 void mp_emit_bc_list_append(emit_t *emit, mp_uint_t list_stack_index) {
pythontech 0:5868e8752d44 841 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 842 emit_write_bytecode_byte_uint(emit, MP_BC_LIST_APPEND, list_stack_index);
pythontech 0:5868e8752d44 843 }
pythontech 0:5868e8752d44 844
pythontech 0:5868e8752d44 845 void mp_emit_bc_build_map(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 846 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 847 emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_MAP, n_args);
pythontech 0:5868e8752d44 848 }
pythontech 0:5868e8752d44 849
pythontech 0:5868e8752d44 850 void mp_emit_bc_store_map(emit_t *emit) {
pythontech 0:5868e8752d44 851 emit_bc_pre(emit, -2);
pythontech 0:5868e8752d44 852 emit_write_bytecode_byte(emit, MP_BC_STORE_MAP);
pythontech 0:5868e8752d44 853 }
pythontech 0:5868e8752d44 854
pythontech 0:5868e8752d44 855 void mp_emit_bc_map_add(emit_t *emit, mp_uint_t map_stack_index) {
pythontech 0:5868e8752d44 856 emit_bc_pre(emit, -2);
pythontech 0:5868e8752d44 857 emit_write_bytecode_byte_uint(emit, MP_BC_MAP_ADD, map_stack_index);
pythontech 0:5868e8752d44 858 }
pythontech 0:5868e8752d44 859
pythontech 0:5868e8752d44 860 #if MICROPY_PY_BUILTINS_SET
pythontech 0:5868e8752d44 861 void mp_emit_bc_build_set(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 862 emit_bc_pre(emit, 1 - n_args);
pythontech 0:5868e8752d44 863 emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_SET, n_args);
pythontech 0:5868e8752d44 864 }
pythontech 0:5868e8752d44 865
pythontech 0:5868e8752d44 866 void mp_emit_bc_set_add(emit_t *emit, mp_uint_t set_stack_index) {
pythontech 0:5868e8752d44 867 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 868 emit_write_bytecode_byte_uint(emit, MP_BC_SET_ADD, set_stack_index);
pythontech 0:5868e8752d44 869 }
pythontech 0:5868e8752d44 870 #endif
pythontech 0:5868e8752d44 871
pythontech 0:5868e8752d44 872 #if MICROPY_PY_BUILTINS_SLICE
pythontech 0:5868e8752d44 873 void mp_emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 874 emit_bc_pre(emit, 1 - n_args);
pythontech 0:5868e8752d44 875 emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_SLICE, n_args);
pythontech 0:5868e8752d44 876 }
pythontech 0:5868e8752d44 877 #endif
pythontech 0:5868e8752d44 878
pythontech 0:5868e8752d44 879 void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 880 emit_bc_pre(emit, -1 + n_args);
pythontech 0:5868e8752d44 881 emit_write_bytecode_byte_uint(emit, MP_BC_UNPACK_SEQUENCE, n_args);
pythontech 0:5868e8752d44 882 }
pythontech 0:5868e8752d44 883
pythontech 0:5868e8752d44 884 void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right) {
pythontech 0:5868e8752d44 885 emit_bc_pre(emit, -1 + n_left + n_right + 1);
pythontech 0:5868e8752d44 886 emit_write_bytecode_byte_uint(emit, MP_BC_UNPACK_EX, n_left | (n_right << 8));
pythontech 0:5868e8752d44 887 }
pythontech 0:5868e8752d44 888
pythontech 0:5868e8752d44 889 void mp_emit_bc_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
pythontech 0:5868e8752d44 890 if (n_pos_defaults == 0 && n_kw_defaults == 0) {
pythontech 0:5868e8752d44 891 emit_bc_pre(emit, 1);
pythontech 0:5868e8752d44 892 emit_write_bytecode_byte_raw_code(emit, MP_BC_MAKE_FUNCTION, scope->raw_code);
pythontech 0:5868e8752d44 893 } else {
pythontech 0:5868e8752d44 894 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 895 emit_write_bytecode_byte_raw_code(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code);
pythontech 0:5868e8752d44 896 }
pythontech 0:5868e8752d44 897 }
pythontech 0:5868e8752d44 898
pythontech 0:5868e8752d44 899 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) {
pythontech 0:5868e8752d44 900 if (n_pos_defaults == 0 && n_kw_defaults == 0) {
pythontech 0:5868e8752d44 901 emit_bc_pre(emit, -n_closed_over + 1);
pythontech 0:5868e8752d44 902 emit_write_bytecode_byte_raw_code(emit, MP_BC_MAKE_CLOSURE, scope->raw_code);
pythontech 0:5868e8752d44 903 emit_write_bytecode_byte(emit, n_closed_over);
pythontech 0:5868e8752d44 904 } else {
pythontech 0:5868e8752d44 905 assert(n_closed_over <= 255);
pythontech 0:5868e8752d44 906 emit_bc_pre(emit, -2 - n_closed_over + 1);
pythontech 0:5868e8752d44 907 emit_write_bytecode_byte_raw_code(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code);
pythontech 0:5868e8752d44 908 emit_write_bytecode_byte(emit, n_closed_over);
pythontech 0:5868e8752d44 909 }
pythontech 0:5868e8752d44 910 }
pythontech 0:5868e8752d44 911
pythontech 0:5868e8752d44 912 STATIC void emit_bc_call_function_method_helper(emit_t *emit, mp_int_t stack_adj, mp_uint_t bytecode_base, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
pythontech 0:5868e8752d44 913 if (star_flags) {
pythontech 0:5868e8752d44 914 emit_bc_pre(emit, stack_adj - (mp_int_t)n_positional - 2 * (mp_int_t)n_keyword - 2);
pythontech 0:5868e8752d44 915 emit_write_bytecode_byte_uint(emit, bytecode_base + 1, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints?
pythontech 0:5868e8752d44 916 } else {
pythontech 0:5868e8752d44 917 emit_bc_pre(emit, stack_adj - (mp_int_t)n_positional - 2 * (mp_int_t)n_keyword);
pythontech 0:5868e8752d44 918 emit_write_bytecode_byte_uint(emit, bytecode_base, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints?
pythontech 0:5868e8752d44 919 }
pythontech 0:5868e8752d44 920 }
pythontech 0:5868e8752d44 921
pythontech 0:5868e8752d44 922 void mp_emit_bc_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
pythontech 0:5868e8752d44 923 emit_bc_call_function_method_helper(emit, 0, MP_BC_CALL_FUNCTION, n_positional, n_keyword, star_flags);
pythontech 0:5868e8752d44 924 }
pythontech 0:5868e8752d44 925
pythontech 0:5868e8752d44 926 void mp_emit_bc_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
pythontech 0:5868e8752d44 927 emit_bc_call_function_method_helper(emit, -1, MP_BC_CALL_METHOD, n_positional, n_keyword, star_flags);
pythontech 0:5868e8752d44 928 }
pythontech 0:5868e8752d44 929
pythontech 0:5868e8752d44 930 void mp_emit_bc_return_value(emit_t *emit) {
pythontech 0:5868e8752d44 931 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 932 emit->last_emit_was_return_value = true;
pythontech 0:5868e8752d44 933 emit_write_bytecode_byte(emit, MP_BC_RETURN_VALUE);
pythontech 0:5868e8752d44 934 }
pythontech 0:5868e8752d44 935
pythontech 0:5868e8752d44 936 void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) {
pythontech 0:5868e8752d44 937 assert(0 <= n_args && n_args <= 2);
pythontech 0:5868e8752d44 938 emit_bc_pre(emit, -n_args);
pythontech 0:5868e8752d44 939 emit_write_bytecode_byte_byte(emit, MP_BC_RAISE_VARARGS, n_args);
pythontech 0:5868e8752d44 940 }
pythontech 0:5868e8752d44 941
pythontech 0:5868e8752d44 942 void mp_emit_bc_yield_value(emit_t *emit) {
pythontech 0:5868e8752d44 943 emit_bc_pre(emit, 0);
pythontech 0:5868e8752d44 944 emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
pythontech 0:5868e8752d44 945 emit_write_bytecode_byte(emit, MP_BC_YIELD_VALUE);
pythontech 0:5868e8752d44 946 }
pythontech 0:5868e8752d44 947
pythontech 0:5868e8752d44 948 void mp_emit_bc_yield_from(emit_t *emit) {
pythontech 0:5868e8752d44 949 emit_bc_pre(emit, -1);
pythontech 0:5868e8752d44 950 emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
pythontech 0:5868e8752d44 951 emit_write_bytecode_byte(emit, MP_BC_YIELD_FROM);
pythontech 0:5868e8752d44 952 }
pythontech 0:5868e8752d44 953
pythontech 0:5868e8752d44 954 void mp_emit_bc_start_except_handler(emit_t *emit) {
pythontech 0:5868e8752d44 955 mp_emit_bc_adjust_stack_size(emit, 6); // stack adjust for the 3 exception items, +3 for possible UNWIND_JUMP state
pythontech 0:5868e8752d44 956 }
pythontech 0:5868e8752d44 957
pythontech 0:5868e8752d44 958 void mp_emit_bc_end_except_handler(emit_t *emit) {
pythontech 0:5868e8752d44 959 mp_emit_bc_adjust_stack_size(emit, -5); // stack adjust
pythontech 0:5868e8752d44 960 }
pythontech 0:5868e8752d44 961
pythontech 0:5868e8752d44 962 #if MICROPY_EMIT_NATIVE
pythontech 0:5868e8752d44 963 const emit_method_table_t emit_bc_method_table = {
pythontech 0:5868e8752d44 964 mp_emit_bc_set_native_type,
pythontech 0:5868e8752d44 965 mp_emit_bc_start_pass,
pythontech 0:5868e8752d44 966 mp_emit_bc_end_pass,
pythontech 0:5868e8752d44 967 mp_emit_bc_last_emit_was_return_value,
pythontech 0:5868e8752d44 968 mp_emit_bc_adjust_stack_size,
pythontech 0:5868e8752d44 969 mp_emit_bc_set_source_line,
pythontech 0:5868e8752d44 970
pythontech 0:5868e8752d44 971 {
pythontech 0:5868e8752d44 972 mp_emit_bc_load_fast,
pythontech 0:5868e8752d44 973 mp_emit_bc_load_deref,
pythontech 0:5868e8752d44 974 mp_emit_bc_load_name,
pythontech 0:5868e8752d44 975 mp_emit_bc_load_global,
pythontech 0:5868e8752d44 976 },
pythontech 0:5868e8752d44 977 {
pythontech 0:5868e8752d44 978 mp_emit_bc_store_fast,
pythontech 0:5868e8752d44 979 mp_emit_bc_store_deref,
pythontech 0:5868e8752d44 980 mp_emit_bc_store_name,
pythontech 0:5868e8752d44 981 mp_emit_bc_store_global,
pythontech 0:5868e8752d44 982 },
pythontech 0:5868e8752d44 983 {
pythontech 0:5868e8752d44 984 mp_emit_bc_delete_fast,
pythontech 0:5868e8752d44 985 mp_emit_bc_delete_deref,
pythontech 0:5868e8752d44 986 mp_emit_bc_delete_name,
pythontech 0:5868e8752d44 987 mp_emit_bc_delete_global,
pythontech 0:5868e8752d44 988 },
pythontech 0:5868e8752d44 989
pythontech 0:5868e8752d44 990 mp_emit_bc_label_assign,
pythontech 0:5868e8752d44 991 mp_emit_bc_import_name,
pythontech 0:5868e8752d44 992 mp_emit_bc_import_from,
pythontech 0:5868e8752d44 993 mp_emit_bc_import_star,
pythontech 0:5868e8752d44 994 mp_emit_bc_load_const_tok,
pythontech 0:5868e8752d44 995 mp_emit_bc_load_const_small_int,
pythontech 0:5868e8752d44 996 mp_emit_bc_load_const_str,
pythontech 0:5868e8752d44 997 mp_emit_bc_load_const_obj,
pythontech 0:5868e8752d44 998 mp_emit_bc_load_null,
pythontech 0:5868e8752d44 999 mp_emit_bc_load_attr,
pythontech 0:5868e8752d44 1000 mp_emit_bc_load_method,
pythontech 0:5868e8752d44 1001 mp_emit_bc_load_build_class,
pythontech 0:5868e8752d44 1002 mp_emit_bc_load_subscr,
pythontech 0:5868e8752d44 1003 mp_emit_bc_store_attr,
pythontech 0:5868e8752d44 1004 mp_emit_bc_store_subscr,
pythontech 0:5868e8752d44 1005 mp_emit_bc_delete_attr,
pythontech 0:5868e8752d44 1006 mp_emit_bc_delete_subscr,
pythontech 0:5868e8752d44 1007 mp_emit_bc_dup_top,
pythontech 0:5868e8752d44 1008 mp_emit_bc_dup_top_two,
pythontech 0:5868e8752d44 1009 mp_emit_bc_pop_top,
pythontech 0:5868e8752d44 1010 mp_emit_bc_rot_two,
pythontech 0:5868e8752d44 1011 mp_emit_bc_rot_three,
pythontech 0:5868e8752d44 1012 mp_emit_bc_jump,
pythontech 0:5868e8752d44 1013 mp_emit_bc_pop_jump_if,
pythontech 0:5868e8752d44 1014 mp_emit_bc_jump_if_or_pop,
pythontech 0:5868e8752d44 1015 mp_emit_bc_unwind_jump,
pythontech 0:5868e8752d44 1016 mp_emit_bc_unwind_jump,
pythontech 0:5868e8752d44 1017 mp_emit_bc_setup_with,
pythontech 0:5868e8752d44 1018 mp_emit_bc_with_cleanup,
pythontech 0:5868e8752d44 1019 mp_emit_bc_setup_except,
pythontech 0:5868e8752d44 1020 mp_emit_bc_setup_finally,
pythontech 0:5868e8752d44 1021 mp_emit_bc_end_finally,
pythontech 0:5868e8752d44 1022 mp_emit_bc_get_iter,
pythontech 0:5868e8752d44 1023 mp_emit_bc_for_iter,
pythontech 0:5868e8752d44 1024 mp_emit_bc_for_iter_end,
pythontech 0:5868e8752d44 1025 mp_emit_bc_pop_block,
pythontech 0:5868e8752d44 1026 mp_emit_bc_pop_except,
pythontech 0:5868e8752d44 1027 mp_emit_bc_unary_op,
pythontech 0:5868e8752d44 1028 mp_emit_bc_binary_op,
pythontech 0:5868e8752d44 1029 mp_emit_bc_build_tuple,
pythontech 0:5868e8752d44 1030 mp_emit_bc_build_list,
pythontech 0:5868e8752d44 1031 mp_emit_bc_list_append,
pythontech 0:5868e8752d44 1032 mp_emit_bc_build_map,
pythontech 0:5868e8752d44 1033 mp_emit_bc_store_map,
pythontech 0:5868e8752d44 1034 mp_emit_bc_map_add,
pythontech 0:5868e8752d44 1035 #if MICROPY_PY_BUILTINS_SET
pythontech 0:5868e8752d44 1036 mp_emit_bc_build_set,
pythontech 0:5868e8752d44 1037 mp_emit_bc_set_add,
pythontech 0:5868e8752d44 1038 #endif
pythontech 0:5868e8752d44 1039 #if MICROPY_PY_BUILTINS_SLICE
pythontech 0:5868e8752d44 1040 mp_emit_bc_build_slice,
pythontech 0:5868e8752d44 1041 #endif
pythontech 0:5868e8752d44 1042 mp_emit_bc_unpack_sequence,
pythontech 0:5868e8752d44 1043 mp_emit_bc_unpack_ex,
pythontech 0:5868e8752d44 1044 mp_emit_bc_make_function,
pythontech 0:5868e8752d44 1045 mp_emit_bc_make_closure,
pythontech 0:5868e8752d44 1046 mp_emit_bc_call_function,
pythontech 0:5868e8752d44 1047 mp_emit_bc_call_method,
pythontech 0:5868e8752d44 1048 mp_emit_bc_return_value,
pythontech 0:5868e8752d44 1049 mp_emit_bc_raise_varargs,
pythontech 0:5868e8752d44 1050 mp_emit_bc_yield_value,
pythontech 0:5868e8752d44 1051 mp_emit_bc_yield_from,
pythontech 0:5868e8752d44 1052
pythontech 0:5868e8752d44 1053 mp_emit_bc_start_except_handler,
pythontech 0:5868e8752d44 1054 mp_emit_bc_end_except_handler,
pythontech 0:5868e8752d44 1055 };
pythontech 0:5868e8752d44 1056 #else
pythontech 0:5868e8752d44 1057 const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops = {
pythontech 0:5868e8752d44 1058 mp_emit_bc_load_fast,
pythontech 0:5868e8752d44 1059 mp_emit_bc_load_deref,
pythontech 0:5868e8752d44 1060 mp_emit_bc_load_name,
pythontech 0:5868e8752d44 1061 mp_emit_bc_load_global,
pythontech 0:5868e8752d44 1062 };
pythontech 0:5868e8752d44 1063
pythontech 0:5868e8752d44 1064 const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops = {
pythontech 0:5868e8752d44 1065 mp_emit_bc_store_fast,
pythontech 0:5868e8752d44 1066 mp_emit_bc_store_deref,
pythontech 0:5868e8752d44 1067 mp_emit_bc_store_name,
pythontech 0:5868e8752d44 1068 mp_emit_bc_store_global,
pythontech 0:5868e8752d44 1069 };
pythontech 0:5868e8752d44 1070
pythontech 0:5868e8752d44 1071 const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_delete_id_ops = {
pythontech 0:5868e8752d44 1072 mp_emit_bc_delete_fast,
pythontech 0:5868e8752d44 1073 mp_emit_bc_delete_deref,
pythontech 0:5868e8752d44 1074 mp_emit_bc_delete_name,
pythontech 0:5868e8752d44 1075 mp_emit_bc_delete_global,
pythontech 0:5868e8752d44 1076 };
pythontech 0:5868e8752d44 1077 #endif
pythontech 0:5868e8752d44 1078
pythontech 0:5868e8752d44 1079 #endif //MICROPY_ENABLE_COMPILER