From 16734200535ce3275f11cb09e3116807bc2809ff Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 22 Mar 2014 23:20:07 +0200 Subject: [PATCH] vm: Abstract working with tagged pointers in VM using macro accessors. Based on issues raised during recent review and inconsistency of different implementations. --- py/bc.h | 7 ++++++- py/vm.c | 16 ++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/py/bc.h b/py/bc.h index 0709897750..153851be87 100644 --- a/py/bc.h +++ b/py/bc.h @@ -8,7 +8,7 @@ typedef enum { typedef struct _mp_exc_stack { const byte *handler; // bit 0 is saved currently_in_except_block value - machine_uint_t val_sp; + mp_obj_t *val_sp; // 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; @@ -17,3 +17,8 @@ typedef struct _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, uint n_state, 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)) diff --git a/py/vm.c b/py/vm.c index 2042e5a6ee..48c4bdf04b 100644 --- a/py/vm.c +++ b/py/vm.c @@ -118,8 +118,8 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i mp_obj_t obj1, obj2; nlr_buf_t nlr; - volatile machine_uint_t currently_in_except_block = (machine_uint_t)*exc_sp_in_out & 1; // 0 or 1, to detect nested exceptions - mp_exc_stack *volatile exc_sp = (void*)((machine_uint_t)*exc_sp_in_out & ~1); // stack grows up, exc_sp points to top of stack + volatile bool currently_in_except_block = MP_TAGPTR_TAG(*exc_sp_in_out); // 0 or 1, to detect nested exceptions + mp_exc_stack *volatile exc_sp = MP_TAGPTR_PTR(*exc_sp_in_out); // stack grows up, exc_sp points to top of stack const byte *volatile save_ip = ip; // this is so we can access ip in the exception handler without making ip volatile (which means the compiler can't keep it in a register in the main loop) // outer exception handling loop @@ -387,7 +387,7 @@ unwind_jump: ++exc_sp; exc_sp->opcode = op; exc_sp->handler = ip + unum; - exc_sp->val_sp = (((machine_uint_t)sp) | currently_in_except_block); + exc_sp->val_sp = MP_TAGPTR_MAKE(sp, currently_in_except_block); currently_in_except_block = 0; // in a try block now break; @@ -437,7 +437,7 @@ unwind_jump: case MP_BC_POP_BLOCK: // we are exiting an exception handler, so pop the last one of the exception-stack assert(exc_sp >= exc_stack); - currently_in_except_block = (exc_sp->val_sp & 1); // restore previous state + currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); // restore previous state exc_sp--; // pop back to previous exception handler break; @@ -449,7 +449,7 @@ unwind_jump: assert(currently_in_except_block); //sp = (mp_obj_t*)(*exc_sp--); //exc_sp--; // discard ip - currently_in_except_block = (exc_sp->val_sp & 1); // restore previous state + currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); // restore previous state exc_sp--; // pop back to previous exception handler //sp -= 3; // pop 3 exception values break; @@ -607,7 +607,7 @@ unwind_return: nlr_pop(); *ip_in_out = ip; *sp_in_out = sp; - *exc_sp_in_out = (void*)((machine_uint_t)exc_sp | currently_in_except_block); + *exc_sp_in_out = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block); return MP_VM_RETURN_YIELD; case MP_BC_IMPORT_NAME: @@ -663,7 +663,7 @@ unwind_return: // at the moment we are just raising the very last exception (the one that caused the nested exception) // move up to previous exception handler - currently_in_except_block = (exc_sp->val_sp & 1); // restore previous state + currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); // restore previous state exc_sp--; // pop back to previous exception handler } @@ -672,7 +672,7 @@ unwind_return: currently_in_except_block = 1; // catch exception and pass to byte code - sp = (mp_obj_t*)(exc_sp->val_sp & (~((machine_uint_t)1))); + sp = MP_TAGPTR_PTR(exc_sp->val_sp); ip = exc_sp->handler; // push(traceback, exc-val, exc-type) PUSH(mp_const_none);