Skip to content

Commit 596f41d

Browse files
committed
py: Reuse value stack in VM WITH_CLEANUP opcode to reduce C-stack size.
Saves 8 bytes C-stack on stmhal and 16 bytes on unix x86.
1 parent ea0461d commit 596f41d

1 file changed

Lines changed: 16 additions & 9 deletions

File tree

py/vm.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -587,25 +587,32 @@ mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_o
587587
assert(0);
588588
}
589589
} else if (mp_obj_is_exception_type(TOP())) {
590-
mp_obj_t args[3] = {sp[0], sp[-1], sp[-2]};
591-
mp_obj_t ret_value = mp_call_function_n_kw(sp[-3], 3, 0, args);
592-
// Pop __exit__ boundmethod at sp[-3]
593-
// TODO: Once semantics is proven, optimize for case when ret_value == True
594-
sp[-3] = sp[-2];
595-
sp[-2] = sp[-1];
596-
sp[-1] = sp[0];
597-
sp--;
590+
// Need to pass (sp[0], sp[-1], sp[-2]) as arguments so must reverse the
591+
// order of these on the value stack (don't want to create a temporary
592+
// array because it increases stack footprint of the VM).
593+
mp_obj_t obj = sp[-2];
594+
sp[-2] = sp[0];
595+
sp[0] = obj;
596+
mp_obj_t ret_value = mp_call_function_n_kw(sp[-3], 3, 0, &sp[-2]);
598597
if (mp_obj_is_true(ret_value)) {
599598
// This is what CPython does
600599
//PUSH(MP_OBJ_NEW_SMALL_INT(UNWIND_SILENCED));
601600
// But what we need to do is - pop exception from value stack...
602-
sp -= 3;
601+
sp -= 4;
603602
// ... pop "with" exception handler, and signal END_FINALLY
604603
// to just execute finally handler normally (by pushing None
605604
// on value stack)
606605
assert(exc_sp >= exc_stack);
607606
POP_EXC_BLOCK();
608607
PUSH(mp_const_none);
608+
} else {
609+
// Pop __exit__ boundmethod at sp[-3], remembering that top 3 values
610+
// are reversed.
611+
sp[-3] = sp[0];
612+
obj = sp[-2];
613+
sp[-2] = sp[-1];
614+
sp[-1] = obj;
615+
sp--;
609616
}
610617
} else {
611618
assert(0);

0 commit comments

Comments
 (0)