diff options
Diffstat (limited to 'py/emitbc.c')
-rw-r--r-- | py/emitbc.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/py/emitbc.c b/py/emitbc.c index e11c9ae94f..ec12a62c6c 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -144,10 +144,15 @@ STATIC void emit_write_code_info_bytes_lines(emit_t *emit, mp_uint_t bytes_to_sk //printf(" %d %d\n", bytes_to_skip, lines_to_skip); while (bytes_to_skip > 0 || lines_to_skip > 0) { mp_uint_t b, l; - if (lines_to_skip <= 6) { + if (lines_to_skip <= 6 || bytes_to_skip > 0xf) { // use 0b0LLBBBBB encoding b = MIN(bytes_to_skip, 0x1f); - l = MIN(lines_to_skip, 0x3); + if (b < bytes_to_skip) { + // we can't skip any lines until we skip all the bytes + l = 0; + } else { + 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) @@ -443,7 +448,19 @@ bool mp_emit_bc_last_emit_was_return_value(emit_t *emit) { } void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) { + if (emit->pass == MP_PASS_SCOPE) { + return; + } + assert((mp_int_t)emit->stack_size + delta >= 0); emit->stack_size += delta; + if (emit->stack_size > emit->scope->stack_size) { + emit->scope->stack_size = emit->stack_size; + } + emit->last_emit_was_return_value = false; +} + +static inline void emit_bc_pre(emit_t *emit, mp_int_t stack_size_delta) { + mp_emit_bc_adjust_stack_size(emit, stack_size_delta); } void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) { @@ -466,18 +483,6 @@ void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) { #endif } -STATIC void emit_bc_pre(emit_t *emit, mp_int_t stack_size_delta) { - if (emit->pass == MP_PASS_SCOPE) { - return; - } - assert((mp_int_t)emit->stack_size + stack_size_delta >= 0); - emit->stack_size += stack_size_delta; - if (emit->stack_size > emit->scope->stack_size) { - emit->scope->stack_size = emit->stack_size; - } - emit->last_emit_was_return_value = false; -} - void mp_emit_bc_label_assign(emit_t *emit, mp_uint_t l) { emit_bc_pre(emit, 0); if (emit->pass == MP_PASS_SCOPE) { @@ -589,9 +594,9 @@ void mp_emit_bc_load_attr(emit_t *emit, qstr qst) { } } -void mp_emit_bc_load_method(emit_t *emit, qstr qst) { - emit_bc_pre(emit, 1); - emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_METHOD, qst); +void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) { + emit_bc_pre(emit, 1 - 2 * is_super); + emit_write_bytecode_byte_qstr(emit, is_super ? MP_BC_LOAD_SUPER_METHOD : MP_BC_LOAD_METHOD, qst); } void mp_emit_bc_load_build_class(emit_t *emit) { @@ -729,6 +734,10 @@ void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_dept if (label & MP_EMIT_BREAK_FROM_FOR) { // need to pop the iterator if we are breaking out of a for loop emit_write_bytecode_byte(emit, MP_BC_POP_TOP); + // also pop the iter_buf + for (size_t i = 0; i < MP_OBJ_ITER_BUF_NSLOTS - 1; ++i) { + emit_write_bytecode_byte(emit, MP_BC_POP_TOP); + } } emit_write_bytecode_byte_signed_label(emit, MP_BC_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR); } else { @@ -768,9 +777,9 @@ void mp_emit_bc_end_finally(emit_t *emit) { emit_write_bytecode_byte(emit, MP_BC_END_FINALLY); } -void mp_emit_bc_get_iter(emit_t *emit) { - emit_bc_pre(emit, 0); - emit_write_bytecode_byte(emit, MP_BC_GET_ITER); +void mp_emit_bc_get_iter(emit_t *emit, bool use_stack) { + emit_bc_pre(emit, use_stack ? MP_OBJ_ITER_BUF_NSLOTS - 1 : 0); + emit_write_bytecode_byte(emit, use_stack ? MP_BC_GET_ITER_STACK : MP_BC_GET_ITER); } void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) { @@ -779,7 +788,7 @@ void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) { } void mp_emit_bc_for_iter_end(emit_t *emit) { - emit_bc_pre(emit, -1); + emit_bc_pre(emit, -MP_OBJ_ITER_BUF_NSLOTS); } void mp_emit_bc_pop_block(emit_t *emit) { |