summaryrefslogtreecommitdiffhomepage
path: root/vm.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-07-09 19:06:29 +0200
committerJo-Philipp Wich <jo@mein.io>2021-07-11 15:49:14 +0200
commit48f33ad70bf584a97a2e2d3870b04bbc970194b7 (patch)
tree96158523674777c7990c41cc948c88bfee5ecb34 /vm.c
parent0f69f099dba58e23e6438023619c002cd82eacf2 (diff)
vm: make root exception handler configurable
So far, the VM simply printed exception information to stderr if the exception was not catched in managed code. Host programs embedding ucode might want to customize that behaviour, so refactor the current defualt behaviour into a callback function and add a public getter and setter to allow changing the exception handler callback. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/vm.c b/vm.c
index a5c4b8c..99e07bb 100644
--- a/vm.c
+++ b/vm.c
@@ -132,6 +132,9 @@ uc_vm_alloc_global_scope(uc_vm *vm)
return scope;
}
+static void
+uc_vm_output_exception(uc_vm *vm, uc_exception *ex);
+
void uc_vm_init(uc_vm *vm, uc_parse_config *config)
{
char *s = getenv("TRACE");
@@ -155,6 +158,8 @@ void uc_vm_init(uc_vm *vm, uc_parse_config *config)
uc_vm_reset_stack(vm);
uc_vm_alloc_global_scope(vm);
+
+ uc_vm_exception_handler_set(vm, uc_vm_output_exception);
}
void uc_vm_free(uc_vm *vm)
@@ -2010,18 +2015,18 @@ uc_vm_callframe_pop(uc_vm *vm)
}
static void
-uc_vm_output_exception(uc_vm *vm)
+uc_vm_output_exception(uc_vm *vm, uc_exception *ex)
{
uc_value_t *ctx;
- if (vm->exception.type == EXCEPTION_USER)
- fprintf(stderr, "%s\n", vm->exception.message);
+ if (ex->type == EXCEPTION_USER)
+ fprintf(stderr, "%s\n", ex->message);
else
fprintf(stderr, "%s: %s\n",
- exception_type_strings[vm->exception.type] ? exception_type_strings[vm->exception.type] : "Error",
- vm->exception.message);
+ exception_type_strings[ex->type] ? exception_type_strings[ex->type] : "Error",
+ ex->message);
- ctx = ucv_object_get(ucv_array_get(vm->exception.stacktrace, 0), "context", NULL);
+ ctx = ucv_object_get(ucv_array_get(ex->stacktrace, 0), "context", NULL);
if (ctx)
fprintf(stderr, "%s\n", ucv_string_get(ctx));
@@ -2276,7 +2281,8 @@ uc_vm_execute_chunk(uc_vm *vm, uc_value_t **retvalp)
while (!uc_vm_handle_exception(vm)) {
/* no further callframe to pop, report unhandled exception and terminate */
if (vm->callframes.count <= 1) {
- uc_vm_output_exception(vm);
+ if (vm->exhandler)
+ vm->exhandler(vm, &vm->exception);
return ERROR_RUNTIME;
}
@@ -2391,3 +2397,15 @@ uc_vm_invoke(uc_vm *vm, const char *fname, size_t nargs, ...)
return uc_vm_stack_pop(vm);
}
+
+uc_exception_handler_t *
+uc_vm_exception_handler_get(uc_vm *vm)
+{
+ return vm->exhandler;
+}
+
+void
+uc_vm_exception_handler_set(uc_vm *vm, uc_exception_handler_t *exhandler)
+{
+ vm->exhandler = exhandler;
+}