diff options
author | Damien George <damien.p.george@gmail.com> | 2015-11-02 21:55:42 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2015-11-13 12:49:18 +0000 |
commit | d8c834c95d506db979ec871417de90b7951edc30 (patch) | |
tree | 929cb08dde61d960d18f47bd80f56114ff10bb4f /py/bc.c | |
parent | c8e9c0d89afa90694790fd48e1bf527487a5beb7 (diff) |
py: Add MICROPY_PERSISTENT_CODE_LOAD/SAVE to load/save bytecode.
MICROPY_PERSISTENT_CODE must be enabled, and then enabling
MICROPY_PERSISTENT_CODE_LOAD/SAVE (either or both) will allow loading
and/or saving of code (at the moment just bytecode) from/to a .mpy file.
Diffstat (limited to 'py/bc.c')
-rw-r--r-- | py/bc.c | 131 |
1 files changed, 131 insertions, 0 deletions
@@ -32,6 +32,7 @@ #include "py/nlr.h" #include "py/objfun.h" #include "py/runtime0.h" +#include "py/bc0.h" #include "py/bc.h" #if 0 // print debugging info @@ -266,3 +267,133 @@ continue2:; dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); dump_args(code_state->state, n_state); } + +#if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE + +// The following table encodes the number of bytes that a specific opcode +// takes up. There are 3 special opcodes that always have an extra byte: +// MP_BC_MAKE_CLOSURE +// MP_BC_MAKE_CLOSURE_DEFARGS +// MP_BC_RAISE_VARARGS +// There are 4 special opcodes that have an extra byte only when +// MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE is enabled: +// MP_BC_LOAD_NAME +// MP_BC_LOAD_GLOBAL +// MP_BC_LOAD_ATTR +// MP_BC_STORE_ATTR +#define OC4(a, b, c, d) (a | (b << 2) | (c << 4) | (d << 6)) +#define U (0) // undefined opcode +#define B (MP_OPCODE_BYTE) // single byte +#define Q (MP_OPCODE_QSTR) // single byte plus 2-byte qstr +#define V (MP_OPCODE_VAR_UINT) // single byte plus variable encoded unsigned int +#define O (MP_OPCODE_OFFSET) // single byte plus 2-byte bytecode offset +STATIC const byte opcode_format_table[64] = { + OC4(U, U, U, U), // 0x00-0x03 + OC4(U, U, U, U), // 0x04-0x07 + OC4(U, U, U, U), // 0x08-0x0b + OC4(U, U, U, U), // 0x0c-0x0f + OC4(B, B, B, U), // 0x10-0x13 + OC4(V, U, Q, V), // 0x14-0x17 + OC4(B, U, V, V), // 0x18-0x1b + OC4(Q, Q, Q, Q), // 0x1c-0x1f + OC4(B, B, V, V), // 0x20-0x23 + OC4(Q, Q, Q, B), // 0x24-0x27 + OC4(V, V, Q, Q), // 0x28-0x2b + OC4(U, U, U, U), // 0x2c-0x2f + OC4(B, B, B, B), // 0x30-0x33 + OC4(B, O, O, O), // 0x34-0x37 + OC4(O, O, U, U), // 0x38-0x3b + OC4(U, O, B, O), // 0x3c-0x3f + OC4(O, B, B, O), // 0x40-0x43 + OC4(B, B, O, B), // 0x44-0x47 + OC4(U, U, U, U), // 0x48-0x4b + OC4(U, U, U, U), // 0x4c-0x4f + OC4(V, V, V, V), // 0x50-0x53 + OC4(B, V, V, V), // 0x54-0x57 + OC4(V, V, V, B), // 0x58-0x5b + OC4(B, B, B, U), // 0x5c-0x5f + OC4(V, V, V, V), // 0x60-0x63 + OC4(V, V, V, V), // 0x64-0x67 + OC4(Q, Q, B, U), // 0x68-0x6b + OC4(U, U, U, U), // 0x6c-0x6f + + OC4(B, B, B, B), // 0x70-0x73 + OC4(B, B, B, B), // 0x74-0x77 + OC4(B, B, B, B), // 0x78-0x7b + OC4(B, B, B, B), // 0x7c-0x7f + OC4(B, B, B, B), // 0x80-0x83 + OC4(B, B, B, B), // 0x84-0x87 + OC4(B, B, B, B), // 0x88-0x8b + OC4(B, B, B, B), // 0x8c-0x8f + OC4(B, B, B, B), // 0x90-0x93 + OC4(B, B, B, B), // 0x94-0x97 + OC4(B, B, B, B), // 0x98-0x9b + OC4(B, B, B, B), // 0x9c-0x9f + OC4(B, B, B, B), // 0xa0-0xa3 + OC4(B, B, B, B), // 0xa4-0xa7 + OC4(B, B, B, B), // 0xa8-0xab + OC4(B, B, B, B), // 0xac-0xaf + + OC4(B, B, B, B), // 0xb0-0xb3 + OC4(B, B, B, B), // 0xb4-0xb7 + OC4(B, B, B, B), // 0xb8-0xbb + OC4(B, B, B, B), // 0xbc-0xbf + + OC4(B, B, B, B), // 0xc0-0xc3 + OC4(B, B, B, B), // 0xc4-0xc7 + OC4(B, B, B, B), // 0xc8-0xcb + OC4(B, B, B, B), // 0xcc-0xcf + + OC4(B, B, B, B), // 0xd0-0xd3 + OC4(B, B, B, B), // 0xd4-0xd7 + OC4(B, B, B, B), // 0xd8-0xdb + OC4(B, B, B, B), // 0xdc-0xdf + + OC4(B, B, B, B), // 0xe0-0xe3 + OC4(B, B, B, B), // 0xe4-0xe7 + OC4(B, B, B, B), // 0xe8-0xeb + OC4(B, B, B, B), // 0xec-0xef + + OC4(B, B, B, B), // 0xf0-0xf3 + OC4(B, B, B, B), // 0xf4-0xf7 + OC4(B, B, U, U), // 0xf8-0xfb + OC4(U, U, U, U), // 0xfc-0xff +}; +#undef OC4 +#undef U +#undef B +#undef Q +#undef V +#undef O + +uint mp_opcode_format(const byte *ip, size_t *opcode_size) { + uint f = (opcode_format_table[*ip >> 2] >> (2 * (*ip & 3))) & 3; + const byte *ip_start = ip; + if (f == MP_OPCODE_QSTR) { + ip += 3; + } else { + int extra_byte = ( + *ip == MP_BC_RAISE_VARARGS + || *ip == MP_BC_MAKE_CLOSURE + || *ip == MP_BC_MAKE_CLOSURE_DEFARGS + #if MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE + || *ip == MP_BC_LOAD_NAME + || *ip == MP_BC_LOAD_GLOBAL + || *ip == MP_BC_LOAD_ATTR + || *ip == MP_BC_STORE_ATTR + #endif + ); + ip += 1; + if (f == MP_OPCODE_VAR_UINT) { + while ((*ip++ & 0x80) != 0) { + } + } else if (f == MP_OPCODE_OFFSET) { + ip += 2; + } + ip += extra_byte; + } + *opcode_size = ip - ip_start; + return f; +} + +#endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE |