summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--types.h3
-rw-r--r--vm.c32
-rw-r--r--vm.h3
3 files changed, 31 insertions, 7 deletions
diff --git a/types.h b/types.h
index b4c33fc..349ae7e 100644
--- a/types.h
+++ b/types.h
@@ -241,6 +241,8 @@ uc_declare_vector(uc_stack, uc_value_t *);
typedef struct printbuf uc_stringbuf_t;
+typedef void (uc_exception_handler_t)(uc_vm *, uc_exception *);
+
struct uc_vm {
uc_stack stack;
uc_exception exception;
@@ -262,6 +264,7 @@ struct uc_vm {
size_t spread_values;
uint8_t trace;
uc_stringbuf_t *strbuf;
+ uc_exception_handler_t *exhandler;
FILE *output;
};
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;
+}
diff --git a/vm.h b/vm.h
index c4952a0..84b42fe 100644
--- a/vm.h
+++ b/vm.h
@@ -120,6 +120,9 @@ void uc_vm_stack_push(uc_vm *vm, uc_value_t *value);
uc_value_t *uc_vm_stack_pop(uc_vm *vm);
uc_value_t *uc_vm_stack_peek(uc_vm *vm, size_t offset);
+uc_exception_handler_t *uc_vm_exception_handler_get(uc_vm *vm);
+void uc_vm_exception_handler_set(uc_vm *vm, uc_exception_handler_t *exhandler);
+
uc_exception_type_t uc_vm_call(uc_vm *vm, bool mcall, size_t nargs);
void __attribute__((format(printf, 3, 0)))