py: Only store the exception instance on Py stack in bytecode try block.
When an exception is raised and is to be handled by the VM, it is stored on the Python value stack so the bytecode can access it. CPython stores 3 objects on the stack for each exception: exc type, exc instance and traceback. uPy followed this approach, but it turns out not to be necessary. Instead, it is enough to store just the exception instance on the Python value stack. The only place where the 3 values are needed explicitly is for the __exit__ handler of a with-statement context, but for these cases the 3 values can be extracted from the single exception instance. This patch removes the need to store 3 values on the stack, and instead just stores the exception instance. Code size is reduced by about 50-100 bytes, the compiler and VM are slightly simpler, generate bytecode is smaller (by 2 bytes for each try block), and the Python value stack is reduced in size for functions that handle exceptions.
This commit is contained in:
@@ -1495,6 +1495,8 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
|
||||
EMIT_ARG(label_assign, l1); // start of exception handler
|
||||
EMIT(start_except_handler);
|
||||
|
||||
// at this point the top of the stack contains the exception instance that was raised
|
||||
|
||||
uint l2 = comp_next_label(comp);
|
||||
|
||||
for (int i = 0; i < n_except; i++) {
|
||||
@@ -1528,16 +1530,13 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
|
||||
EMIT_ARG(pop_jump_if, false, end_finally_label);
|
||||
}
|
||||
|
||||
EMIT(pop_top);
|
||||
|
||||
// either discard or store the exception instance
|
||||
if (qstr_exception_local == 0) {
|
||||
EMIT(pop_top);
|
||||
} else {
|
||||
compile_store_id(comp, qstr_exception_local);
|
||||
}
|
||||
|
||||
EMIT(pop_top);
|
||||
|
||||
uint l3 = 0;
|
||||
if (qstr_exception_local != 0) {
|
||||
l3 = comp_next_label(comp);
|
||||
@@ -1561,7 +1560,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
|
||||
}
|
||||
EMIT_ARG(jump, l2);
|
||||
EMIT_ARG(label_assign, end_finally_label);
|
||||
EMIT_ARG(adjust_stack_size, 3); // stack adjust for the 3 exception items
|
||||
EMIT_ARG(adjust_stack_size, 1); // stack adjust for the exception instance
|
||||
}
|
||||
|
||||
compile_decrease_except_level(comp);
|
||||
|
||||
Reference in New Issue
Block a user