diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-07-09 19:06:29 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-07-11 15:49:14 +0200 |
commit | 48f33ad70bf584a97a2e2d3870b04bbc970194b7 (patch) | |
tree | 96158523674777c7990c41cc948c88bfee5ecb34 /vm.c | |
parent | 0f69f099dba58e23e6438023619c002cd82eacf2 (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.c | 32 |
1 files changed, 25 insertions, 7 deletions
@@ -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; +} |