Skip to content
Snippets Groups Projects
  • Paul Sokolovsky's avatar
    0c904df8
    vm: Save current active exception on opening new try block. · 0c904df8
    Paul Sokolovsky authored
    Required to reraise correct exceptions in except block, regardless if more
    try blocks with active exceptions happen in the same except block.
    
    P.S. This "automagic reraise" appears to be quite wasteful feature of Python
    - we need to save pending exception just in case it *might* be reraised.
    Instead, programmer could explcitly capture exception to a variable using
    "except ... as var", and reraise that. So, consider disabling argless raise
    support as an optimization.
    0c904df8
    History
    vm: Save current active exception on opening new try block.
    Paul Sokolovsky authored
    Required to reraise correct exceptions in except block, regardless if more
    try blocks with active exceptions happen in the same except block.
    
    P.S. This "automagic reraise" appears to be quite wasteful feature of Python
    - we need to save pending exception just in case it *might* be reraised.
    Instead, programmer could explcitly capture exception to a variable using
    "except ... as var", and reraise that. So, consider disabling argless raise
    support as an optimization.
bc.h 1.21 KiB
typedef enum {
    MP_VM_RETURN_NORMAL,
    MP_VM_RETURN_YIELD,
    MP_VM_RETURN_EXCEPTION,
} mp_vm_return_kind_t;

// Exception stack entry
typedef struct _mp_exc_stack {
    const byte *handler;
    // bit 0 is saved currently_in_except_block value
    mp_obj_t *val_sp;
    // Saved exception, valid if currently_in_except_block bit is 1
    mp_obj_t prev_exc;
    // We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY,
    // consider storing it in bit 1 of val_sp. TODO: SETUP_WITH?
    byte opcode;
} mp_exc_stack;

mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret);
mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out, mp_exc_stack *exc_stack, mp_exc_stack **exc_sp_in_out, volatile mp_obj_t inject_exc);
void mp_byte_code_print(const byte *code, int len);

// Helper macros to access pointer with least significant bit holding a flag
#define MP_TAGPTR_PTR(x) ((void*)((machine_uint_t)(x) & ~((machine_uint_t)1)))
#define MP_TAGPTR_TAG(x) ((machine_uint_t)(x) & 1)
#define MP_TAGPTR_MAKE(ptr, tag) ((void*)((machine_uint_t)(ptr) | tag))