summaryrefslogtreecommitdiffhomepage
path: root/vm.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-09-24 09:21:31 +0200
committerJo-Philipp Wich <jo@mein.io>2021-09-24 09:26:13 +0200
commit218e8221a80a8fcf8bfd6cc115d7a0ae00a65ead (patch)
tree98120146a73bbe413945690e4009e2b8249da01d /vm.c
parent5b908bdf64a586d27d5bdd1df8c72a7cd63b386a (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.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/vm.c b/vm.c
index d5d3feb..2c8f524 100644
--- a/vm.c
+++ b/vm.c
@@ -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);