Skip to content

Commit 02db91a

Browse files
committed
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).
1 parent 870e900 commit 02db91a

File tree

6 files changed

+50
-43
lines changed

6 files changed

+50
-43
lines changed

py/bc0.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
#define MP_BC_BASE_VINT_O (0x30) // UUMMCCCC--------
4747
#define MP_BC_BASE_JUMP_E (0x40) // J-JJJJJEEEEF----
4848
#define MP_BC_BASE_BYTE_O (0x50) // LLLLSSDTTTTTEEFF
49-
#define MP_BC_BASE_BYTE_E (0x60) // E-BRYYI---------
49+
#define MP_BC_BASE_BYTE_E (0x60) // --BREEEYYI------
5050
#define MP_BC_LOAD_CONST_SMALL_INT_MULTI (0x70) // LLLLLLLLLLLLLLLL
5151
// (0x80) // LLLLLLLLLLLLLLLL
5252
// (0x90) // LLLLLLLLLLLLLLLL
@@ -128,9 +128,11 @@
128128
#define MP_BC_UNPACK_EX (MP_BC_BASE_VINT_O + 0x01) // uint
129129

130130
#define MP_BC_RETURN_VALUE (MP_BC_BASE_BYTE_E + 0x03)
131-
#define MP_BC_RAISE_VARARGS (MP_BC_BASE_BYTE_E + 0x00) // extra byte
132-
#define MP_BC_YIELD_VALUE (MP_BC_BASE_BYTE_E + 0x04)
133-
#define MP_BC_YIELD_FROM (MP_BC_BASE_BYTE_E + 0x05)
131+
#define MP_BC_RAISE_LAST (MP_BC_BASE_BYTE_E + 0x04)
132+
#define MP_BC_RAISE_OBJ (MP_BC_BASE_BYTE_E + 0x05)
133+
#define MP_BC_RAISE_FROM (MP_BC_BASE_BYTE_E + 0x06)
134+
#define MP_BC_YIELD_VALUE (MP_BC_BASE_BYTE_E + 0x07)
135+
#define MP_BC_YIELD_FROM (MP_BC_BASE_BYTE_E + 0x08)
134136

135137
#define MP_BC_MAKE_FUNCTION (MP_BC_BASE_VINT_O + 0x02) // uint
136138
#define MP_BC_MAKE_FUNCTION_DEFARGS (MP_BC_BASE_VINT_O + 0x03) // uint
@@ -143,6 +145,6 @@
143145

144146
#define MP_BC_IMPORT_NAME (MP_BC_BASE_QSTR_O + 0x0b) // qstr
145147
#define MP_BC_IMPORT_FROM (MP_BC_BASE_QSTR_O + 0x0c) // qstr
146-
#define MP_BC_IMPORT_STAR (MP_BC_BASE_BYTE_E + 0x06)
148+
#define MP_BC_IMPORT_STAR (MP_BC_BASE_BYTE_E + 0x09)
147149

148150
#endif // MICROPY_INCLUDED_PY_BC0_H

py/emitbc.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,6 @@ STATIC void emit_write_bytecode_byte(emit_t *emit, int stack_adj, byte b1) {
193193
c[0] = b1;
194194
}
195195

196-
STATIC void emit_write_bytecode_byte_byte(emit_t* emit, int stack_adj, byte b1, byte b2) {
197-
mp_emit_bc_adjust_stack_size(emit, stack_adj);
198-
byte *c = emit_get_cur_to_write_bytecode(emit, 2);
199-
c[0] = b1;
200-
c[1] = b2;
201-
}
202-
203196
// Similar to emit_write_bytecode_uint(), just some extra handling to encode sign
204197
STATIC void emit_write_bytecode_byte_int(emit_t *emit, int stack_adj, byte b1, mp_int_t num) {
205198
emit_write_bytecode_byte(emit, stack_adj, b1);
@@ -848,8 +841,10 @@ void mp_emit_bc_return_value(emit_t *emit) {
848841
}
849842

850843
void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) {
844+
MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 1 == MP_BC_RAISE_OBJ);
845+
MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 2 == MP_BC_RAISE_FROM);
851846
assert(n_args <= 2);
852-
emit_write_bytecode_byte_byte(emit, -n_args, MP_BC_RAISE_VARARGS, n_args);
847+
emit_write_bytecode_byte(emit, -n_args, MP_BC_RAISE_LAST + n_args);
853848
}
854849

855850
void mp_emit_bc_yield(emit_t *emit, int kind) {

py/showbc.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,16 @@ const byte *mp_bytecode_print_str(const byte *ip) {
500500
printf("RETURN_VALUE");
501501
break;
502502

503-
case MP_BC_RAISE_VARARGS:
504-
unum = *ip++;
505-
printf("RAISE_VARARGS " UINT_FMT, unum);
503+
case MP_BC_RAISE_LAST:
504+
printf("RAISE_LAST");
505+
break;
506+
507+
case MP_BC_RAISE_OBJ:
508+
printf("RAISE_OBJ");
509+
break;
510+
511+
case MP_BC_RAISE_FROM:
512+
printf("RAISE_FROM");
506513
break;
507514

508515
case MP_BC_YIELD_VALUE:

py/vm.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,32 +1162,33 @@ unwind_jump:;
11621162
FRAME_LEAVE();
11631163
return MP_VM_RETURN_NORMAL;
11641164

1165-
ENTRY(MP_BC_RAISE_VARARGS): {
1165+
ENTRY(MP_BC_RAISE_LAST): {
11661166
MARK_EXC_IP_SELECTIVE();
1167-
mp_uint_t unum = *ip;
1168-
mp_obj_t obj;
1169-
if (unum == 2) {
1170-
mp_warning(NULL, "exception chaining not supported");
1171-
// ignore (pop) "from" argument
1172-
sp--;
1173-
}
1174-
if (unum == 0) {
1175-
// search for the inner-most previous exception, to reraise it
1176-
obj = MP_OBJ_NULL;
1177-
for (mp_exc_stack_t *e = exc_sp; e >= exc_stack; e--) {
1178-
if (e->prev_exc != NULL) {
1179-
obj = MP_OBJ_FROM_PTR(e->prev_exc);
1180-
break;
1181-
}
1182-
}
1183-
if (obj == MP_OBJ_NULL) {
1184-
obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, "no active exception to reraise");
1185-
RAISE(obj);
1167+
// search for the inner-most previous exception, to reraise it
1168+
mp_obj_t obj = MP_OBJ_NULL;
1169+
for (mp_exc_stack_t *e = exc_sp; e >= exc_stack; --e) {
1170+
if (e->prev_exc != NULL) {
1171+
obj = MP_OBJ_FROM_PTR(e->prev_exc);
1172+
break;
11861173
}
1187-
} else {
1188-
obj = TOP();
11891174
}
1190-
obj = mp_make_raise_obj(obj);
1175+
if (obj == MP_OBJ_NULL) {
1176+
obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, "no active exception to reraise");
1177+
}
1178+
RAISE(obj);
1179+
}
1180+
1181+
ENTRY(MP_BC_RAISE_OBJ): {
1182+
MARK_EXC_IP_SELECTIVE();
1183+
mp_obj_t obj = mp_make_raise_obj(TOP());
1184+
RAISE(obj);
1185+
}
1186+
1187+
ENTRY(MP_BC_RAISE_FROM): {
1188+
MARK_EXC_IP_SELECTIVE();
1189+
mp_warning(NULL, "exception chaining not supported");
1190+
sp--; // ignore (pop) "from" argument
1191+
mp_obj_t obj = mp_make_raise_obj(TOP());
11911192
RAISE(obj);
11921193
}
11931194

@@ -1437,7 +1438,7 @@ unwind_jump:;
14371438
// - exceptions re-raised explicitly by "raise"
14381439
if (nlr.ret_val != &mp_const_GeneratorExit_obj
14391440
&& *code_state->ip != MP_BC_END_FINALLY
1440-
&& !(*code_state->ip == MP_BC_RAISE_VARARGS && code_state->ip[1] == 0)) {
1441+
&& *code_state->ip != MP_BC_RAISE_LAST) {
14411442
const byte *ip = code_state->fun_bc->bytecode;
14421443
ip = mp_decode_uint_skip(ip); // skip n_state
14431444
ip = mp_decode_uint_skip(ip); // skip n_exc_stack

py/vmentrytable.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ static const void *const entry_table[256] = {
9999
[MP_BC_CALL_METHOD] = &&entry_MP_BC_CALL_METHOD,
100100
[MP_BC_CALL_METHOD_VAR_KW] = &&entry_MP_BC_CALL_METHOD_VAR_KW,
101101
[MP_BC_RETURN_VALUE] = &&entry_MP_BC_RETURN_VALUE,
102-
[MP_BC_RAISE_VARARGS] = &&entry_MP_BC_RAISE_VARARGS,
102+
[MP_BC_RAISE_LAST] = &&entry_MP_BC_RAISE_LAST,
103+
[MP_BC_RAISE_OBJ] = &&entry_MP_BC_RAISE_OBJ,
104+
[MP_BC_RAISE_FROM] = &&entry_MP_BC_RAISE_FROM,
103105
[MP_BC_YIELD_VALUE] = &&entry_MP_BC_YIELD_VALUE,
104106
[MP_BC_YIELD_FROM] = &&entry_MP_BC_YIELD_FROM,
105107
[MP_BC_IMPORT_NAME] = &&entry_MP_BC_IMPORT_NAME,

tests/cmdline/cmd_showbc.py.exp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,9 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
305305
\\d\+ BUILD_TUPLE 1
306306
\\d\+ IMPORT_NAME 'a'
307307
\\d\+ IMPORT_STAR
308-
\\d\+ RAISE_VARARGS 0
308+
\\d\+ RAISE_LAST
309309
\\d\+ LOAD_CONST_SMALL_INT 1
310-
\\d\+ RAISE_VARARGS 1
310+
\\d\+ RAISE_OBJ
311311
\\d\+ LOAD_CONST_NONE
312312
\\d\+ RETURN_VALUE
313313
\\d\+ LOAD_CONST_SMALL_INT 1

0 commit comments

Comments
 (0)