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:
pythontech
Date:
Sat Apr 16 17:11:56 2016 +0000
Revision:
0:5868e8752d44
Split off library from repl

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) 2014 Damien P. George
pythontech 0:5868e8752d44 7 * Copyright (c) 2014 Paul Sokolovsky
pythontech 0:5868e8752d44 8 *
pythontech 0:5868e8752d44 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
pythontech 0:5868e8752d44 10 * of this software and associated documentation files (the "Software"), to deal
pythontech 0:5868e8752d44 11 * in the Software without restriction, including without limitation the rights
pythontech 0:5868e8752d44 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pythontech 0:5868e8752d44 13 * copies of the Software, and to permit persons to whom the Software is
pythontech 0:5868e8752d44 14 * furnished to do so, subject to the following conditions:
pythontech 0:5868e8752d44 15 *
pythontech 0:5868e8752d44 16 * The above copyright notice and this permission notice shall be included in
pythontech 0:5868e8752d44 17 * all copies or substantial portions of the Software.
pythontech 0:5868e8752d44 18 *
pythontech 0:5868e8752d44 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pythontech 0:5868e8752d44 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pythontech 0:5868e8752d44 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pythontech 0:5868e8752d44 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pythontech 0:5868e8752d44 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pythontech 0:5868e8752d44 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pythontech 0:5868e8752d44 25 * THE SOFTWARE.
pythontech 0:5868e8752d44 26 */
pythontech 0:5868e8752d44 27
pythontech 0:5868e8752d44 28 #include <stdbool.h>
pythontech 0:5868e8752d44 29 #include <string.h>
pythontech 0:5868e8752d44 30 #include <assert.h>
pythontech 0:5868e8752d44 31
pythontech 0:5868e8752d44 32 #include "py/nlr.h"
pythontech 0:5868e8752d44 33 #include "py/objfun.h"
pythontech 0:5868e8752d44 34 #include "py/runtime0.h"
pythontech 0:5868e8752d44 35 #include "py/bc0.h"
pythontech 0:5868e8752d44 36 #include "py/bc.h"
pythontech 0:5868e8752d44 37
pythontech 0:5868e8752d44 38 #if 0 // print debugging info
pythontech 0:5868e8752d44 39 #define DEBUG_PRINT (1)
pythontech 0:5868e8752d44 40 #else // don't print debugging info
pythontech 0:5868e8752d44 41 #define DEBUG_PRINT (0)
pythontech 0:5868e8752d44 42 #define DEBUG_printf(...) (void)0
pythontech 0:5868e8752d44 43 #endif
pythontech 0:5868e8752d44 44
pythontech 0:5868e8752d44 45 mp_uint_t mp_decode_uint(const byte **ptr) {
pythontech 0:5868e8752d44 46 mp_uint_t unum = 0;
pythontech 0:5868e8752d44 47 byte val;
pythontech 0:5868e8752d44 48 const byte *p = *ptr;
pythontech 0:5868e8752d44 49 do {
pythontech 0:5868e8752d44 50 val = *p++;
pythontech 0:5868e8752d44 51 unum = (unum << 7) | (val & 0x7f);
pythontech 0:5868e8752d44 52 } while ((val & 0x80) != 0);
pythontech 0:5868e8752d44 53 *ptr = p;
pythontech 0:5868e8752d44 54 return unum;
pythontech 0:5868e8752d44 55 }
pythontech 0:5868e8752d44 56
pythontech 0:5868e8752d44 57 STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected, size_t given) {
pythontech 0:5868e8752d44 58 #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
pythontech 0:5868e8752d44 59 // generic message, used also for other argument issues
pythontech 0:5868e8752d44 60 (void)f;
pythontech 0:5868e8752d44 61 (void)expected;
pythontech 0:5868e8752d44 62 (void)given;
pythontech 0:5868e8752d44 63 mp_arg_error_terse_mismatch();
pythontech 0:5868e8752d44 64 #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL
pythontech 0:5868e8752d44 65 (void)f;
pythontech 0:5868e8752d44 66 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
pythontech 0:5868e8752d44 67 "function takes %d positional arguments but %d were given", expected, given));
pythontech 0:5868e8752d44 68 #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
pythontech 0:5868e8752d44 69 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
pythontech 0:5868e8752d44 70 "%q() takes %d positional arguments but %d were given",
pythontech 0:5868e8752d44 71 mp_obj_fun_get_name(MP_OBJ_FROM_PTR(f)), expected, given));
pythontech 0:5868e8752d44 72 #endif
pythontech 0:5868e8752d44 73 }
pythontech 0:5868e8752d44 74
pythontech 0:5868e8752d44 75 #if DEBUG_PRINT
pythontech 0:5868e8752d44 76 STATIC void dump_args(const mp_obj_t *a, size_t sz) {
pythontech 0:5868e8752d44 77 DEBUG_printf("%p: ", a);
pythontech 0:5868e8752d44 78 for (size_t i = 0; i < sz; i++) {
pythontech 0:5868e8752d44 79 DEBUG_printf("%p ", a[i]);
pythontech 0:5868e8752d44 80 }
pythontech 0:5868e8752d44 81 DEBUG_printf("\n");
pythontech 0:5868e8752d44 82 }
pythontech 0:5868e8752d44 83 #else
pythontech 0:5868e8752d44 84 #define dump_args(...) (void)0
pythontech 0:5868e8752d44 85 #endif
pythontech 0:5868e8752d44 86
pythontech 0:5868e8752d44 87 // On entry code_state should be allocated somewhere (stack/heap) and
pythontech 0:5868e8752d44 88 // contain the following valid entries:
pythontech 0:5868e8752d44 89 // - code_state->ip should contain the offset in bytes from the start of
pythontech 0:5868e8752d44 90 // the bytecode chunk to just after n_state and n_exc_stack
pythontech 0:5868e8752d44 91 // - code_state->n_state should be set to the state size (locals plus stack)
pythontech 0:5868e8752d44 92 void mp_setup_code_state(mp_code_state *code_state, mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) {
pythontech 0:5868e8752d44 93 // This function is pretty complicated. It's main aim is to be efficient in speed and RAM
pythontech 0:5868e8752d44 94 // usage for the common case of positional only args.
pythontech 0:5868e8752d44 95 size_t n_state = code_state->n_state;
pythontech 0:5868e8752d44 96
pythontech 0:5868e8752d44 97 // ip comes in as an offset into bytecode, so turn it into a true pointer
pythontech 0:5868e8752d44 98 code_state->ip = self->bytecode + (size_t)code_state->ip;
pythontech 0:5868e8752d44 99
pythontech 0:5868e8752d44 100 // store pointer to constant table
pythontech 0:5868e8752d44 101 code_state->const_table = self->const_table;
pythontech 0:5868e8752d44 102
pythontech 0:5868e8752d44 103 #if MICROPY_STACKLESS
pythontech 0:5868e8752d44 104 code_state->prev = NULL;
pythontech 0:5868e8752d44 105 #endif
pythontech 0:5868e8752d44 106
pythontech 0:5868e8752d44 107 // get params
pythontech 0:5868e8752d44 108 size_t scope_flags = *code_state->ip++;
pythontech 0:5868e8752d44 109 size_t n_pos_args = *code_state->ip++;
pythontech 0:5868e8752d44 110 size_t n_kwonly_args = *code_state->ip++;
pythontech 0:5868e8752d44 111 size_t n_def_pos_args = *code_state->ip++;
pythontech 0:5868e8752d44 112
pythontech 0:5868e8752d44 113 code_state->sp = &code_state->state[0] - 1;
pythontech 0:5868e8752d44 114 code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1;
pythontech 0:5868e8752d44 115
pythontech 0:5868e8752d44 116 // zero out the local stack to begin with
pythontech 0:5868e8752d44 117 memset(code_state->state, 0, n_state * sizeof(*code_state->state));
pythontech 0:5868e8752d44 118
pythontech 0:5868e8752d44 119 const mp_obj_t *kwargs = args + n_args;
pythontech 0:5868e8752d44 120
pythontech 0:5868e8752d44 121 // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed)
pythontech 0:5868e8752d44 122 mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - n_pos_args - n_kwonly_args];
pythontech 0:5868e8752d44 123
pythontech 0:5868e8752d44 124 // check positional arguments
pythontech 0:5868e8752d44 125
pythontech 0:5868e8752d44 126 if (n_args > n_pos_args) {
pythontech 0:5868e8752d44 127 // given more than enough arguments
pythontech 0:5868e8752d44 128 if ((scope_flags & MP_SCOPE_FLAG_VARARGS) == 0) {
pythontech 0:5868e8752d44 129 fun_pos_args_mismatch(self, n_pos_args, n_args);
pythontech 0:5868e8752d44 130 }
pythontech 0:5868e8752d44 131 // put extra arguments in varargs tuple
pythontech 0:5868e8752d44 132 *var_pos_kw_args-- = mp_obj_new_tuple(n_args - n_pos_args, args + n_pos_args);
pythontech 0:5868e8752d44 133 n_args = n_pos_args;
pythontech 0:5868e8752d44 134 } else {
pythontech 0:5868e8752d44 135 if ((scope_flags & MP_SCOPE_FLAG_VARARGS) != 0) {
pythontech 0:5868e8752d44 136 DEBUG_printf("passing empty tuple as *args\n");
pythontech 0:5868e8752d44 137 *var_pos_kw_args-- = mp_const_empty_tuple;
pythontech 0:5868e8752d44 138 }
pythontech 0:5868e8752d44 139 // Apply processing and check below only if we don't have kwargs,
pythontech 0:5868e8752d44 140 // otherwise, kw handling code below has own extensive checks.
pythontech 0:5868e8752d44 141 if (n_kw == 0 && (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) == 0) {
pythontech 0:5868e8752d44 142 if (n_args >= (size_t)(n_pos_args - n_def_pos_args)) {
pythontech 0:5868e8752d44 143 // given enough arguments, but may need to use some default arguments
pythontech 0:5868e8752d44 144 for (size_t i = n_args; i < n_pos_args; i++) {
pythontech 0:5868e8752d44 145 code_state->state[n_state - 1 - i] = self->extra_args[i - (n_pos_args - n_def_pos_args)];
pythontech 0:5868e8752d44 146 }
pythontech 0:5868e8752d44 147 } else {
pythontech 0:5868e8752d44 148 fun_pos_args_mismatch(self, n_pos_args - n_def_pos_args, n_args);
pythontech 0:5868e8752d44 149 }
pythontech 0:5868e8752d44 150 }
pythontech 0:5868e8752d44 151 }
pythontech 0:5868e8752d44 152
pythontech 0:5868e8752d44 153 // copy positional args into state
pythontech 0:5868e8752d44 154 for (size_t i = 0; i < n_args; i++) {
pythontech 0:5868e8752d44 155 code_state->state[n_state - 1 - i] = args[i];
pythontech 0:5868e8752d44 156 }
pythontech 0:5868e8752d44 157
pythontech 0:5868e8752d44 158 // check keyword arguments
pythontech 0:5868e8752d44 159
pythontech 0:5868e8752d44 160 if (n_kw != 0 || (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) {
pythontech 0:5868e8752d44 161 DEBUG_printf("Initial args: ");
pythontech 0:5868e8752d44 162 dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args);
pythontech 0:5868e8752d44 163
pythontech 0:5868e8752d44 164 mp_obj_t dict = MP_OBJ_NULL;
pythontech 0:5868e8752d44 165 if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
pythontech 0:5868e8752d44 166 dict = mp_obj_new_dict(n_kw); // TODO: better go conservative with 0?
pythontech 0:5868e8752d44 167 *var_pos_kw_args = dict;
pythontech 0:5868e8752d44 168 }
pythontech 0:5868e8752d44 169
pythontech 0:5868e8752d44 170 // get pointer to arg_names array
pythontech 0:5868e8752d44 171 const mp_obj_t *arg_names = (const mp_obj_t*)code_state->const_table;
pythontech 0:5868e8752d44 172
pythontech 0:5868e8752d44 173 for (size_t i = 0; i < n_kw; i++) {
pythontech 0:5868e8752d44 174 mp_obj_t wanted_arg_name = kwargs[2 * i];
pythontech 0:5868e8752d44 175 for (size_t j = 0; j < n_pos_args + n_kwonly_args; j++) {
pythontech 0:5868e8752d44 176 if (wanted_arg_name == arg_names[j]) {
pythontech 0:5868e8752d44 177 if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) {
pythontech 0:5868e8752d44 178 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
pythontech 0:5868e8752d44 179 "function got multiple values for argument '%q'", MP_OBJ_QSTR_VALUE(wanted_arg_name)));
pythontech 0:5868e8752d44 180 }
pythontech 0:5868e8752d44 181 code_state->state[n_state - 1 - j] = kwargs[2 * i + 1];
pythontech 0:5868e8752d44 182 goto continue2;
pythontech 0:5868e8752d44 183 }
pythontech 0:5868e8752d44 184 }
pythontech 0:5868e8752d44 185 // Didn't find name match with positional args
pythontech 0:5868e8752d44 186 if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) {
pythontech 0:5868e8752d44 187 nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
pythontech 0:5868e8752d44 188 }
pythontech 0:5868e8752d44 189 mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
pythontech 0:5868e8752d44 190 continue2:;
pythontech 0:5868e8752d44 191 }
pythontech 0:5868e8752d44 192
pythontech 0:5868e8752d44 193 DEBUG_printf("Args with kws flattened: ");
pythontech 0:5868e8752d44 194 dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args);
pythontech 0:5868e8752d44 195
pythontech 0:5868e8752d44 196 // fill in defaults for positional args
pythontech 0:5868e8752d44 197 mp_obj_t *d = &code_state->state[n_state - n_pos_args];
pythontech 0:5868e8752d44 198 mp_obj_t *s = &self->extra_args[n_def_pos_args - 1];
pythontech 0:5868e8752d44 199 for (size_t i = n_def_pos_args; i > 0; i--, d++, s--) {
pythontech 0:5868e8752d44 200 if (*d == MP_OBJ_NULL) {
pythontech 0:5868e8752d44 201 *d = *s;
pythontech 0:5868e8752d44 202 }
pythontech 0:5868e8752d44 203 }
pythontech 0:5868e8752d44 204
pythontech 0:5868e8752d44 205 DEBUG_printf("Args after filling default positional: ");
pythontech 0:5868e8752d44 206 dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args);
pythontech 0:5868e8752d44 207
pythontech 0:5868e8752d44 208 // Check that all mandatory positional args are specified
pythontech 0:5868e8752d44 209 while (d < &code_state->state[n_state]) {
pythontech 0:5868e8752d44 210 if (*d++ == MP_OBJ_NULL) {
pythontech 0:5868e8752d44 211 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
pythontech 0:5868e8752d44 212 "function missing required positional argument #%d", &code_state->state[n_state] - d));
pythontech 0:5868e8752d44 213 }
pythontech 0:5868e8752d44 214 }
pythontech 0:5868e8752d44 215
pythontech 0:5868e8752d44 216 // Check that all mandatory keyword args are specified
pythontech 0:5868e8752d44 217 // Fill in default kw args if we have them
pythontech 0:5868e8752d44 218 for (size_t i = 0; i < n_kwonly_args; i++) {
pythontech 0:5868e8752d44 219 if (code_state->state[n_state - 1 - n_pos_args - i] == MP_OBJ_NULL) {
pythontech 0:5868e8752d44 220 mp_map_elem_t *elem = NULL;
pythontech 0:5868e8752d44 221 if ((scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) {
pythontech 0:5868e8752d44 222 elem = mp_map_lookup(&((mp_obj_dict_t*)MP_OBJ_TO_PTR(self->extra_args[n_def_pos_args]))->map, arg_names[n_pos_args + i], MP_MAP_LOOKUP);
pythontech 0:5868e8752d44 223 }
pythontech 0:5868e8752d44 224 if (elem != NULL) {
pythontech 0:5868e8752d44 225 code_state->state[n_state - 1 - n_pos_args - i] = elem->value;
pythontech 0:5868e8752d44 226 } else {
pythontech 0:5868e8752d44 227 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
pythontech 0:5868e8752d44 228 "function missing required keyword argument '%q'", MP_OBJ_QSTR_VALUE(arg_names[n_pos_args + i])));
pythontech 0:5868e8752d44 229 }
pythontech 0:5868e8752d44 230 }
pythontech 0:5868e8752d44 231 }
pythontech 0:5868e8752d44 232
pythontech 0:5868e8752d44 233 } else {
pythontech 0:5868e8752d44 234 // no keyword arguments given
pythontech 0:5868e8752d44 235 if (n_kwonly_args != 0) {
pythontech 0:5868e8752d44 236 nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
pythontech 0:5868e8752d44 237 "function missing keyword-only argument"));
pythontech 0:5868e8752d44 238 }
pythontech 0:5868e8752d44 239 if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
pythontech 0:5868e8752d44 240 *var_pos_kw_args = mp_obj_new_dict(0);
pythontech 0:5868e8752d44 241 }
pythontech 0:5868e8752d44 242 }
pythontech 0:5868e8752d44 243
pythontech 0:5868e8752d44 244 // get the ip and skip argument names
pythontech 0:5868e8752d44 245 const byte *ip = code_state->ip;
pythontech 0:5868e8752d44 246
pythontech 0:5868e8752d44 247 // store pointer to code_info and jump over it
pythontech 0:5868e8752d44 248 {
pythontech 0:5868e8752d44 249 code_state->code_info = ip;
pythontech 0:5868e8752d44 250 const byte *ip2 = ip;
pythontech 0:5868e8752d44 251 size_t code_info_size = mp_decode_uint(&ip2);
pythontech 0:5868e8752d44 252 ip += code_info_size;
pythontech 0:5868e8752d44 253 }
pythontech 0:5868e8752d44 254
pythontech 0:5868e8752d44 255 // bytecode prelude: initialise closed over variables
pythontech 0:5868e8752d44 256 size_t local_num;
pythontech 0:5868e8752d44 257 while ((local_num = *ip++) != 255) {
pythontech 0:5868e8752d44 258 code_state->state[n_state - 1 - local_num] =
pythontech 0:5868e8752d44 259 mp_obj_new_cell(code_state->state[n_state - 1 - local_num]);
pythontech 0:5868e8752d44 260 }
pythontech 0:5868e8752d44 261
pythontech 0:5868e8752d44 262 // now that we skipped over the prelude, set the ip for the VM
pythontech 0:5868e8752d44 263 code_state->ip = ip;
pythontech 0:5868e8752d44 264
pythontech 0:5868e8752d44 265 DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", n_pos_args, n_kwonly_args);
pythontech 0:5868e8752d44 266 dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args);
pythontech 0:5868e8752d44 267 dump_args(code_state->state, n_state);
pythontech 0:5868e8752d44 268 }
pythontech 0:5868e8752d44 269
pythontech 0:5868e8752d44 270 #if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE
pythontech 0:5868e8752d44 271
pythontech 0:5868e8752d44 272 // The following table encodes the number of bytes that a specific opcode
pythontech 0:5868e8752d44 273 // takes up. There are 3 special opcodes that always have an extra byte:
pythontech 0:5868e8752d44 274 // MP_BC_MAKE_CLOSURE
pythontech 0:5868e8752d44 275 // MP_BC_MAKE_CLOSURE_DEFARGS
pythontech 0:5868e8752d44 276 // MP_BC_RAISE_VARARGS
pythontech 0:5868e8752d44 277 // There are 4 special opcodes that have an extra byte only when
pythontech 0:5868e8752d44 278 // MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE is enabled:
pythontech 0:5868e8752d44 279 // MP_BC_LOAD_NAME
pythontech 0:5868e8752d44 280 // MP_BC_LOAD_GLOBAL
pythontech 0:5868e8752d44 281 // MP_BC_LOAD_ATTR
pythontech 0:5868e8752d44 282 // MP_BC_STORE_ATTR
pythontech 0:5868e8752d44 283 #define OC4(a, b, c, d) (a | (b << 2) | (c << 4) | (d << 6))
pythontech 0:5868e8752d44 284 #define U (0) // undefined opcode
pythontech 0:5868e8752d44 285 #define B (MP_OPCODE_BYTE) // single byte
pythontech 0:5868e8752d44 286 #define Q (MP_OPCODE_QSTR) // single byte plus 2-byte qstr
pythontech 0:5868e8752d44 287 #define V (MP_OPCODE_VAR_UINT) // single byte plus variable encoded unsigned int
pythontech 0:5868e8752d44 288 #define O (MP_OPCODE_OFFSET) // single byte plus 2-byte bytecode offset
pythontech 0:5868e8752d44 289 STATIC const byte opcode_format_table[64] = {
pythontech 0:5868e8752d44 290 OC4(U, U, U, U), // 0x00-0x03
pythontech 0:5868e8752d44 291 OC4(U, U, U, U), // 0x04-0x07
pythontech 0:5868e8752d44 292 OC4(U, U, U, U), // 0x08-0x0b
pythontech 0:5868e8752d44 293 OC4(U, U, U, U), // 0x0c-0x0f
pythontech 0:5868e8752d44 294 OC4(B, B, B, U), // 0x10-0x13
pythontech 0:5868e8752d44 295 OC4(V, U, Q, V), // 0x14-0x17
pythontech 0:5868e8752d44 296 OC4(B, U, V, V), // 0x18-0x1b
pythontech 0:5868e8752d44 297 OC4(Q, Q, Q, Q), // 0x1c-0x1f
pythontech 0:5868e8752d44 298 OC4(B, B, V, V), // 0x20-0x23
pythontech 0:5868e8752d44 299 OC4(Q, Q, Q, B), // 0x24-0x27
pythontech 0:5868e8752d44 300 OC4(V, V, Q, Q), // 0x28-0x2b
pythontech 0:5868e8752d44 301 OC4(U, U, U, U), // 0x2c-0x2f
pythontech 0:5868e8752d44 302 OC4(B, B, B, B), // 0x30-0x33
pythontech 0:5868e8752d44 303 OC4(B, O, O, O), // 0x34-0x37
pythontech 0:5868e8752d44 304 OC4(O, O, U, U), // 0x38-0x3b
pythontech 0:5868e8752d44 305 OC4(U, O, B, O), // 0x3c-0x3f
pythontech 0:5868e8752d44 306 OC4(O, B, B, O), // 0x40-0x43
pythontech 0:5868e8752d44 307 OC4(B, B, O, U), // 0x44-0x47
pythontech 0:5868e8752d44 308 OC4(U, U, U, U), // 0x48-0x4b
pythontech 0:5868e8752d44 309 OC4(U, U, U, U), // 0x4c-0x4f
pythontech 0:5868e8752d44 310 OC4(V, V, V, V), // 0x50-0x53
pythontech 0:5868e8752d44 311 OC4(B, V, V, V), // 0x54-0x57
pythontech 0:5868e8752d44 312 OC4(V, V, V, B), // 0x58-0x5b
pythontech 0:5868e8752d44 313 OC4(B, B, B, U), // 0x5c-0x5f
pythontech 0:5868e8752d44 314 OC4(V, V, V, V), // 0x60-0x63
pythontech 0:5868e8752d44 315 OC4(V, V, V, V), // 0x64-0x67
pythontech 0:5868e8752d44 316 OC4(Q, Q, B, U), // 0x68-0x6b
pythontech 0:5868e8752d44 317 OC4(U, U, U, U), // 0x6c-0x6f
pythontech 0:5868e8752d44 318
pythontech 0:5868e8752d44 319 OC4(B, B, B, B), // 0x70-0x73
pythontech 0:5868e8752d44 320 OC4(B, B, B, B), // 0x74-0x77
pythontech 0:5868e8752d44 321 OC4(B, B, B, B), // 0x78-0x7b
pythontech 0:5868e8752d44 322 OC4(B, B, B, B), // 0x7c-0x7f
pythontech 0:5868e8752d44 323 OC4(B, B, B, B), // 0x80-0x83
pythontech 0:5868e8752d44 324 OC4(B, B, B, B), // 0x84-0x87
pythontech 0:5868e8752d44 325 OC4(B, B, B, B), // 0x88-0x8b
pythontech 0:5868e8752d44 326 OC4(B, B, B, B), // 0x8c-0x8f
pythontech 0:5868e8752d44 327 OC4(B, B, B, B), // 0x90-0x93
pythontech 0:5868e8752d44 328 OC4(B, B, B, B), // 0x94-0x97
pythontech 0:5868e8752d44 329 OC4(B, B, B, B), // 0x98-0x9b
pythontech 0:5868e8752d44 330 OC4(B, B, B, B), // 0x9c-0x9f
pythontech 0:5868e8752d44 331 OC4(B, B, B, B), // 0xa0-0xa3
pythontech 0:5868e8752d44 332 OC4(B, B, B, B), // 0xa4-0xa7
pythontech 0:5868e8752d44 333 OC4(B, B, B, B), // 0xa8-0xab
pythontech 0:5868e8752d44 334 OC4(B, B, B, B), // 0xac-0xaf
pythontech 0:5868e8752d44 335
pythontech 0:5868e8752d44 336 OC4(B, B, B, B), // 0xb0-0xb3
pythontech 0:5868e8752d44 337 OC4(B, B, B, B), // 0xb4-0xb7
pythontech 0:5868e8752d44 338 OC4(B, B, B, B), // 0xb8-0xbb
pythontech 0:5868e8752d44 339 OC4(B, B, B, B), // 0xbc-0xbf
pythontech 0:5868e8752d44 340
pythontech 0:5868e8752d44 341 OC4(B, B, B, B), // 0xc0-0xc3
pythontech 0:5868e8752d44 342 OC4(B, B, B, B), // 0xc4-0xc7
pythontech 0:5868e8752d44 343 OC4(B, B, B, B), // 0xc8-0xcb
pythontech 0:5868e8752d44 344 OC4(B, B, B, B), // 0xcc-0xcf
pythontech 0:5868e8752d44 345
pythontech 0:5868e8752d44 346 OC4(B, B, B, B), // 0xd0-0xd3
pythontech 0:5868e8752d44 347 OC4(B, B, B, B), // 0xd4-0xd7
pythontech 0:5868e8752d44 348 OC4(B, B, B, B), // 0xd8-0xdb
pythontech 0:5868e8752d44 349 OC4(B, B, B, B), // 0xdc-0xdf
pythontech 0:5868e8752d44 350
pythontech 0:5868e8752d44 351 OC4(B, B, B, B), // 0xe0-0xe3
pythontech 0:5868e8752d44 352 OC4(B, B, B, B), // 0xe4-0xe7
pythontech 0:5868e8752d44 353 OC4(B, B, B, B), // 0xe8-0xeb
pythontech 0:5868e8752d44 354 OC4(B, B, B, B), // 0xec-0xef
pythontech 0:5868e8752d44 355
pythontech 0:5868e8752d44 356 OC4(B, B, B, B), // 0xf0-0xf3
pythontech 0:5868e8752d44 357 OC4(B, B, B, B), // 0xf4-0xf7
pythontech 0:5868e8752d44 358 OC4(B, B, B, U), // 0xf8-0xfb
pythontech 0:5868e8752d44 359 OC4(U, U, U, U), // 0xfc-0xff
pythontech 0:5868e8752d44 360 };
pythontech 0:5868e8752d44 361 #undef OC4
pythontech 0:5868e8752d44 362 #undef U
pythontech 0:5868e8752d44 363 #undef B
pythontech 0:5868e8752d44 364 #undef Q
pythontech 0:5868e8752d44 365 #undef V
pythontech 0:5868e8752d44 366 #undef O
pythontech 0:5868e8752d44 367
pythontech 0:5868e8752d44 368 uint mp_opcode_format(const byte *ip, size_t *opcode_size) {
pythontech 0:5868e8752d44 369 uint f = (opcode_format_table[*ip >> 2] >> (2 * (*ip & 3))) & 3;
pythontech 0:5868e8752d44 370 const byte *ip_start = ip;
pythontech 0:5868e8752d44 371 if (f == MP_OPCODE_QSTR) {
pythontech 0:5868e8752d44 372 ip += 3;
pythontech 0:5868e8752d44 373 } else {
pythontech 0:5868e8752d44 374 int extra_byte = (
pythontech 0:5868e8752d44 375 *ip == MP_BC_RAISE_VARARGS
pythontech 0:5868e8752d44 376 || *ip == MP_BC_MAKE_CLOSURE
pythontech 0:5868e8752d44 377 || *ip == MP_BC_MAKE_CLOSURE_DEFARGS
pythontech 0:5868e8752d44 378 #if MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE
pythontech 0:5868e8752d44 379 || *ip == MP_BC_LOAD_NAME
pythontech 0:5868e8752d44 380 || *ip == MP_BC_LOAD_GLOBAL
pythontech 0:5868e8752d44 381 || *ip == MP_BC_LOAD_ATTR
pythontech 0:5868e8752d44 382 || *ip == MP_BC_STORE_ATTR
pythontech 0:5868e8752d44 383 #endif
pythontech 0:5868e8752d44 384 );
pythontech 0:5868e8752d44 385 ip += 1;
pythontech 0:5868e8752d44 386 if (f == MP_OPCODE_VAR_UINT) {
pythontech 0:5868e8752d44 387 while ((*ip++ & 0x80) != 0) {
pythontech 0:5868e8752d44 388 }
pythontech 0:5868e8752d44 389 } else if (f == MP_OPCODE_OFFSET) {
pythontech 0:5868e8752d44 390 ip += 2;
pythontech 0:5868e8752d44 391 }
pythontech 0:5868e8752d44 392 ip += extra_byte;
pythontech 0:5868e8752d44 393 }
pythontech 0:5868e8752d44 394 *opcode_size = ip - ip_start;
pythontech 0:5868e8752d44 395 return f;
pythontech 0:5868e8752d44 396 }
pythontech 0:5868e8752d44 397
pythontech 0:5868e8752d44 398 #endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE