summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/emitbc.c19
-rw-r--r--py/showbc.c15
-rw-r--r--py/vm.c24
3 files changed, 48 insertions, 10 deletions
diff --git a/py/emitbc.c b/py/emitbc.c
index 365ec458a2..161e8c7f6d 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -115,12 +115,24 @@ STATIC void emit_write_code_info_qstr(emit_t* emit, qstr qstr) {
#if MICROPY_ENABLE_SOURCE_LINE
STATIC void emit_write_code_info_bytes_lines(emit_t* emit, uint bytes_to_skip, uint lines_to_skip) {
assert(bytes_to_skip > 0 || lines_to_skip > 0);
+ //printf(" %d %d\n", bytes_to_skip, lines_to_skip);
while (bytes_to_skip > 0 || lines_to_skip > 0) {
- uint b = MIN(bytes_to_skip, 31);
- uint l = MIN(lines_to_skip, 7);
+ mp_uint_t b, l;
+ if (lines_to_skip <= 6) {
+ // use 0b0LLBBBBB encoding
+ b = MIN(bytes_to_skip, 0x1f);
+ l = MIN(lines_to_skip, 0x3);
+ *emit_get_cur_to_write_code_info(emit, 1) = b | (l << 5);
+ } else {
+ // use 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte)
+ b = MIN(bytes_to_skip, 0xf);
+ l = MIN(lines_to_skip, 0x7ff);
+ byte *ci = emit_get_cur_to_write_code_info(emit, 2);
+ ci[0] = 0x80 | b | ((l >> 4) & 0x70);
+ ci[1] = l;
+ }
bytes_to_skip -= b;
lines_to_skip -= l;
- *emit_get_cur_to_write_code_info(emit, 1) = b | (l << 5);
}
}
#endif
@@ -363,7 +375,6 @@ STATIC void emit_bc_set_source_line(emit_t *emit, int source_line) {
uint bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset;
uint lines_to_skip = source_line - emit->last_source_line;
emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip);
- //printf(" %d %d\n", bytes_to_skip, lines_to_skip);
emit->last_source_line_offset = emit->bytecode_offset;
emit->last_source_line = source_line;
}
diff --git a/py/showbc.c b/py/showbc.c
index 12400fa7c2..6c10333c9f 100644
--- a/py/showbc.c
+++ b/py/showbc.c
@@ -95,9 +95,18 @@ void mp_bytecode_print(const void *descr, const byte *ip, int len) {
mp_int_t bc = (code_info + code_info_size) - ip;
mp_uint_t source_line = 1;
printf(" bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line);
- for (const byte* ci = code_info + 12; *ci; ci++) {
- bc += *ci & 31;
- source_line += *ci >> 5;
+ for (const byte* ci = code_info + 12; *ci;) {
+ if ((ci[0] & 0x80) == 0) {
+ // 0b0LLBBBBB encoding
+ bc += ci[0] & 0x1f;
+ source_line += ci[0] >> 5;
+ ci += 1;
+ } else {
+ // 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte)
+ bc += ci[0] & 0xf;
+ source_line += ((ci[0] << 4) & 0x700) | ci[1];
+ ci += 2;
+ }
printf(" bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line);
}
}
diff --git a/py/vm.c b/py/vm.c
index ade2ee2b5a..c0116bbeb9 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -931,9 +931,27 @@ exception_handler:
const byte* ci = code_info + 12;
if (*ci) {
source_line = 1;
- for (; *ci && bc >= ((*ci) & 31); ci++) {
- bc -= *ci & 31;
- source_line += *ci >> 5;
+ mp_uint_t c;
+ while ((c = *ci)) {
+ mp_uint_t b, l;
+ if ((c & 0x80) == 0) {
+ // 0b0LLBBBBB encoding
+ b = c & 0x1f;
+ l = c >> 5;
+ ci += 1;
+ } else {
+ // 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte)
+ b = c & 0xf;
+ l = ((c << 4) & 0x700) | ci[1];
+ ci += 2;
+ }
+ if (bc >= b) {
+ bc -= b;
+ source_line += l;
+ } else {
+ // found source line corresponding to bytecode offset
+ break;
+ }
}
}
mp_obj_exception_add_traceback(nlr.ret_val, source_file, source_line, block_name);