bc.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013, 2014 Damien P. George
  7. * Copyright (c) 2014 Paul Sokolovsky
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. */
  27. #ifndef MICROPY_INCLUDED_PY_BC_H
  28. #define MICROPY_INCLUDED_PY_BC_H
  29. #include "py/runtime.h"
  30. #include "py/objfun.h"
  31. // bytecode layout:
  32. //
  33. // func signature : var uint
  34. // contains six values interleaved bit-wise as: xSSSSEAA [xFSSKAED repeated]
  35. // x = extension another byte follows
  36. // S = n_state - 1 number of entries in Python value stack
  37. // E = n_exc_stack number of entries in exception stack
  38. // F = scope_flags four bits of flags, MP_SCOPE_FLAG_xxx
  39. // A = n_pos_args number of arguments this function takes
  40. // K = n_kwonly_args number of keyword-only arguments this function takes
  41. // D = n_def_pos_args number of default positional arguments
  42. //
  43. // prelude size : var uint
  44. // contains two values interleaved bit-wise as: xIIIIIIC repeated
  45. // x = extension another byte follows
  46. // I = n_info number of bytes in source info section
  47. // C = n_cells number of bytes/cells in closure section
  48. //
  49. // source info section:
  50. // simple_name : var qstr
  51. // source_file : var qstr
  52. // <line number info>
  53. //
  54. // closure section:
  55. // local_num0 : byte
  56. // ... : byte
  57. // local_numN : byte N = n_cells-1
  58. //
  59. // <word alignment padding> only needed if bytecode contains pointers
  60. //
  61. // <bytecode>
  62. //
  63. //
  64. // constant table layout:
  65. //
  66. // argname0 : obj (qstr)
  67. // ... : obj (qstr)
  68. // argnameN : obj (qstr) N = num_pos_args + num_kwonly_args
  69. // const0 : obj
  70. // constN : obj
  71. #define MP_BC_PRELUDE_SIG_ENCODE(S, E, scope, out_byte, out_env) \
  72. do { \
  73. /*// Get values to store in prelude */ \
  74. size_t F = scope->scope_flags & MP_SCOPE_FLAG_ALL_SIG; \
  75. size_t A = scope->num_pos_args; \
  76. size_t K = scope->num_kwonly_args; \
  77. size_t D = scope->num_def_pos_args; \
  78. \
  79. /* Adjust S to shrink range, to compress better */ \
  80. S -= 1; \
  81. \
  82. /* Encode prelude */ \
  83. /* xSSSSEAA */ \
  84. uint8_t z = (S & 0xf) << 3 | (E & 1) << 2 | (A & 3); \
  85. S >>= 4; \
  86. E >>= 1; \
  87. A >>= 2; \
  88. while (S | E | F | A | K | D) { \
  89. out_byte(out_env, 0x80 | z); \
  90. /* xFSSKAED */ \
  91. z = (F & 1) << 6 | (S & 3) << 4 | (K & 1) << 3 \
  92. | (A & 1) << 2 | (E & 1) << 1 | (D & 1); \
  93. S >>= 2; \
  94. E >>= 1; \
  95. F >>= 1; \
  96. A >>= 1; \
  97. K >>= 1; \
  98. D >>= 1; \
  99. } \
  100. out_byte(out_env, z); \
  101. } while (0)
  102. #define MP_BC_PRELUDE_SIG_DECODE_INTO(ip, S, E, F, A, K, D) \
  103. do { \
  104. uint8_t z = *(ip)++; \
  105. /* xSSSSEAA */ \
  106. S = (z >> 3) & 0xf; \
  107. E = (z >> 2) & 0x1; \
  108. F = 0; \
  109. A = z & 0x3; \
  110. K = 0; \
  111. D = 0; \
  112. for (unsigned n = 0; z & 0x80; ++n) { \
  113. z = *(ip)++; \
  114. /* xFSSKAED */ \
  115. S |= (z & 0x30) << (2 * n); \
  116. E |= (z & 0x02) << n; \
  117. F |= ((z & 0x40) >> 6) << n; \
  118. A |= (z & 0x4) << n; \
  119. K |= ((z & 0x08) >> 3) << n; \
  120. D |= (z & 0x1) << n; \
  121. } \
  122. S += 1; \
  123. } while (0)
  124. #define MP_BC_PRELUDE_SIG_DECODE(ip) \
  125. size_t n_state, n_exc_stack, scope_flags, n_pos_args, n_kwonly_args, n_def_pos_args; \
  126. MP_BC_PRELUDE_SIG_DECODE_INTO(ip, n_state, n_exc_stack, scope_flags, n_pos_args, n_kwonly_args, n_def_pos_args)
  127. #define MP_BC_PRELUDE_SIZE_ENCODE(I, C, out_byte, out_env) \
  128. do { \
  129. /* Encode bit-wise as: xIIIIIIC */ \
  130. uint8_t z = 0; \
  131. do { \
  132. z = (I & 0x3f) << 1 | (C & 1); \
  133. C >>= 1; \
  134. I >>= 6; \
  135. if (C | I) { \
  136. z |= 0x80; \
  137. } \
  138. out_byte(out_env, z); \
  139. } while (C | I); \
  140. } while (0)
  141. #define MP_BC_PRELUDE_SIZE_DECODE_INTO(ip, I, C) \
  142. do { \
  143. uint8_t z; \
  144. C = 0; \
  145. I = 0; \
  146. for (unsigned n = 0;; ++n) { \
  147. z = *(ip)++; \
  148. /* xIIIIIIC */ \
  149. C |= (z & 1) << n; \
  150. I |= ((z & 0x7e) >> 1) << (6 * n); \
  151. if (!(z & 0x80)) { \
  152. break; \
  153. } \
  154. } \
  155. } while (0)
  156. #define MP_BC_PRELUDE_SIZE_DECODE(ip) \
  157. size_t n_info, n_cell; \
  158. MP_BC_PRELUDE_SIZE_DECODE_INTO(ip, n_info, n_cell)
  159. // Sentinel value for mp_code_state_t.exc_sp_idx
  160. #define MP_CODE_STATE_EXC_SP_IDX_SENTINEL ((uint16_t)-1)
  161. // To convert mp_code_state_t.exc_sp_idx to/from a pointer to mp_exc_stack_t
  162. #define MP_CODE_STATE_EXC_SP_IDX_FROM_PTR(exc_stack, exc_sp) ((exc_sp) + 1 - (exc_stack))
  163. #define MP_CODE_STATE_EXC_SP_IDX_TO_PTR(exc_stack, exc_sp_idx) ((exc_stack) + (exc_sp_idx) - 1)
  164. typedef struct _mp_bytecode_prelude_t {
  165. uint n_state;
  166. uint n_exc_stack;
  167. uint scope_flags;
  168. uint n_pos_args;
  169. uint n_kwonly_args;
  170. uint n_def_pos_args;
  171. qstr qstr_block_name;
  172. qstr qstr_source_file;
  173. const byte *line_info;
  174. const byte *opcodes;
  175. } mp_bytecode_prelude_t;
  176. // Exception stack entry
  177. typedef struct _mp_exc_stack_t {
  178. const byte *handler;
  179. // bit 0 is currently unused
  180. // bit 1 is whether the opcode was SETUP_WITH or SETUP_FINALLY
  181. mp_obj_t *val_sp;
  182. // Saved exception
  183. mp_obj_base_t *prev_exc;
  184. } mp_exc_stack_t;
  185. typedef struct _mp_code_state_t {
  186. // The fun_bc entry points to the underlying function object that is being executed.
  187. // It is needed to access the start of bytecode and the const_table.
  188. // It is also needed to prevent the GC from reclaiming the bytecode during execution,
  189. // because the ip pointer below will always point to the interior of the bytecode.
  190. mp_obj_fun_bc_t *fun_bc;
  191. const byte *ip;
  192. mp_obj_t *sp;
  193. uint16_t n_state;
  194. uint16_t exc_sp_idx;
  195. mp_obj_dict_t *old_globals;
  196. #if MICROPY_STACKLESS
  197. struct _mp_code_state_t *prev;
  198. #endif
  199. #if MICROPY_PY_SYS_SETTRACE
  200. struct _mp_code_state_t *prev_state;
  201. struct _mp_obj_frame_t *frame;
  202. #endif
  203. // Variable-length
  204. mp_obj_t state[0];
  205. // Variable-length, never accessed by name, only as (void*)(state + n_state)
  206. // mp_exc_stack_t exc_state[0];
  207. } mp_code_state_t;
  208. mp_uint_t mp_decode_uint(const byte **ptr);
  209. mp_uint_t mp_decode_uint_value(const byte *ptr);
  210. const byte *mp_decode_uint_skip(const byte *ptr);
  211. mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp_obj_t inject_exc);
  212. mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, size_t n_args, size_t n_kw, const mp_obj_t *args);
  213. void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args);
  214. void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *code, mp_uint_t len, const mp_uint_t *const_table);
  215. void mp_bytecode_print2(const mp_print_t *print, const byte *code, size_t len, const mp_uint_t *const_table);
  216. const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip);
  217. #define mp_bytecode_print_inst(print, code, const_table) mp_bytecode_print2(print, code, 1, const_table)
  218. // Helper macros to access pointer with least significant bits holding flags
  219. #define MP_TAGPTR_PTR(x) ((void *)((uintptr_t)(x) & ~((uintptr_t)3)))
  220. #define MP_TAGPTR_TAG0(x) ((uintptr_t)(x) & 1)
  221. #define MP_TAGPTR_TAG1(x) ((uintptr_t)(x) & 2)
  222. #define MP_TAGPTR_MAKE(ptr, tag) ((void *)((uintptr_t)(ptr) | (tag)))
  223. #if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE
  224. uint mp_opcode_format(const byte *ip, size_t *opcode_size, bool count_var_uint);
  225. #endif
  226. static inline size_t mp_bytecode_get_source_line(const byte *line_info, size_t bc_offset) {
  227. size_t source_line = 1;
  228. size_t c;
  229. while ((c = *line_info)) {
  230. size_t b, l;
  231. if ((c & 0x80) == 0) {
  232. // 0b0LLBBBBB encoding
  233. b = c & 0x1f;
  234. l = c >> 5;
  235. line_info += 1;
  236. } else {
  237. // 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte)
  238. b = c & 0xf;
  239. l = ((c << 4) & 0x700) | line_info[1];
  240. line_info += 2;
  241. }
  242. if (bc_offset >= b) {
  243. bc_offset -= b;
  244. source_line += l;
  245. } else {
  246. // found source line corresponding to bytecode offset
  247. break;
  248. }
  249. }
  250. return source_line;
  251. }
  252. #endif // MICROPY_INCLUDED_PY_BC_H