diff options
author | Damien George <damien.p.george@gmail.com> | 2019-08-22 12:39:07 +1000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2019-09-26 15:39:50 +1000 |
commit | 02db91a7a311a96dd82a497cf513137e04191b29 (patch) | |
tree | 781991a3b87530077bef6199aea8ff0ede034643 /py/vm.c | |
parent | 870e900d02937918187a4e4ef75a1e38880bae62 (diff) |
py: Split RAISE_VARARGS opcode into 3 separate ones.
From the beginning of this project the RAISE_VARARGS opcode was named and
implemented following CPython, where it has an argument (to the opcode)
counting how many args the raise takes:
raise # 0 args (re-raise previous exception)
raise exc # 1 arg
raise exc from exc2 # 2 args (chained raise)
In the bytecode this operation therefore takes 2 bytes, one for
RAISE_VARARGS and one for the number of args.
This patch splits this opcode into 3, where each is now a single byte.
This reduces bytecode size by 1 byte for each use of raise. Every byte
counts! It also has the benefit of reducing code size (on all ports except
nanbox).
Diffstat (limited to 'py/vm.c')
-rw-r--r-- | py/vm.c | 49 |
1 files changed, 25 insertions, 24 deletions
@@ -1162,32 +1162,33 @@ unwind_return: FRAME_LEAVE(); return MP_VM_RETURN_NORMAL; - ENTRY(MP_BC_RAISE_VARARGS): { + ENTRY(MP_BC_RAISE_LAST): { MARK_EXC_IP_SELECTIVE(); - mp_uint_t unum = *ip; - mp_obj_t obj; - if (unum == 2) { - mp_warning(NULL, "exception chaining not supported"); - // ignore (pop) "from" argument - sp--; - } - if (unum == 0) { - // search for the inner-most previous exception, to reraise it - obj = MP_OBJ_NULL; - for (mp_exc_stack_t *e = exc_sp; e >= exc_stack; e--) { - if (e->prev_exc != NULL) { - obj = MP_OBJ_FROM_PTR(e->prev_exc); - break; - } - } - if (obj == MP_OBJ_NULL) { - obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, "no active exception to reraise"); - RAISE(obj); + // search for the inner-most previous exception, to reraise it + mp_obj_t obj = MP_OBJ_NULL; + for (mp_exc_stack_t *e = exc_sp; e >= exc_stack; --e) { + if (e->prev_exc != NULL) { + obj = MP_OBJ_FROM_PTR(e->prev_exc); + break; } - } else { - obj = TOP(); } - obj = mp_make_raise_obj(obj); + if (obj == MP_OBJ_NULL) { + obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, "no active exception to reraise"); + } + RAISE(obj); + } + + ENTRY(MP_BC_RAISE_OBJ): { + MARK_EXC_IP_SELECTIVE(); + mp_obj_t obj = mp_make_raise_obj(TOP()); + RAISE(obj); + } + + ENTRY(MP_BC_RAISE_FROM): { + MARK_EXC_IP_SELECTIVE(); + mp_warning(NULL, "exception chaining not supported"); + sp--; // ignore (pop) "from" argument + mp_obj_t obj = mp_make_raise_obj(TOP()); RAISE(obj); } @@ -1437,7 +1438,7 @@ unwind_loop: // - exceptions re-raised explicitly by "raise" if (nlr.ret_val != &mp_const_GeneratorExit_obj && *code_state->ip != MP_BC_END_FINALLY - && !(*code_state->ip == MP_BC_RAISE_VARARGS && code_state->ip[1] == 0)) { + && *code_state->ip != MP_BC_RAISE_LAST) { const byte *ip = code_state->fun_bc->bytecode; ip = mp_decode_uint_skip(ip); // skip n_state ip = mp_decode_uint_skip(ip); // skip n_exc_stack |