diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-09-24 09:21:31 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-09-24 09:26:13 +0200 |
commit | 218e8221a80a8fcf8bfd6cc115d7a0ae00a65ead (patch) | |
tree | 98120146a73bbe413945690e4009e2b8249da01d /vm.c | |
parent | 5b908bdf64a586d27d5bdd1df8c72a7cd63b386a (diff) |
vm: clear exception information before calling managed code functions
If execution in an existing VM that threw an exception was resumed
through uc_vm_call() or uc_vm_invoke(), the exception was never cleared,
causing all subsequent calls to return with an exception status as well.
Ensure that any preexisting exception information is discarded before
executing the requested function in order to start from a clean state.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -731,6 +731,18 @@ uc_vm_exception_new(uc_vm_t *vm, uc_exception_type_t type, const char *message, return exo; } +static void +uc_vm_clear_exception(uc_vm_t *vm) +{ + vm->exception.type = EXCEPTION_NONE; + + ucv_put(vm->exception.stacktrace); + vm->exception.stacktrace = NULL; + + free(vm->exception.message); + vm->exception.message = NULL; +} + static bool uc_vm_handle_exception(uc_vm_t *vm) { @@ -765,10 +777,7 @@ uc_vm_handle_exception(uc_vm_t *vm) uc_vm_stack_push(vm, exo); /* reset exception information */ - free(vm->exception.message); - - vm->exception.type = EXCEPTION_NONE; - vm->exception.message = NULL; + uc_vm_clear_exception(vm); /* jump to exception handler */ if (chunk->ehranges.entries[i].target >= chunk->count) { @@ -2358,6 +2367,8 @@ uc_vm_call(uc_vm_t *vm, bool mcall, size_t nargs) uc_value_t *ctx = mcall ? ucv_get(uc_vm_stack_peek(vm, nargs + 1)) : NULL; uc_value_t *fno = ucv_get(uc_vm_stack_peek(vm, nargs)); + uc_vm_clear_exception(vm); + if (uc_vm_call_function(vm, ctx, fno, mcall, nargs & 0xffff)) { if (ucv_type(fno) != UC_CFUNCTION) uc_vm_execute_chunk(vm); |