summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib.c7
-rw-r--r--main.c4
-rw-r--r--types.h3
-rw-r--r--vm.c11
-rw-r--r--vm.h1
5 files changed, 23 insertions, 3 deletions
diff --git a/lib.c b/lib.c
index 750acfb..cd0f582 100644
--- a/lib.c
+++ b/lib.c
@@ -502,12 +502,15 @@ uc_exists(uc_vm *vm, size_t nargs)
return ucv_boolean_new(found);
}
-__attribute__((noreturn)) static uc_value_t *
+static uc_value_t *
uc_exit(uc_vm *vm, size_t nargs)
{
int64_t n = uc_cast_int64(uc_get_arg(0));
- exit(n);
+ vm->arg.s32 = (int32_t)n;
+ uc_vm_raise_exception(vm, EXCEPTION_EXIT, "Terminated");
+
+ return NULL;
}
static uc_value_t *
diff --git a/main.c b/main.c
index 6c763cd..b420051 100644
--- a/main.c
+++ b/main.c
@@ -132,6 +132,10 @@ parse(uc_parse_config *config, uc_source *src,
rc = 0;
break;
+ case STATUS_EXIT:
+ rc = (int)ucv_int64_get(res);
+ break;
+
case ERROR_COMPILE:
rc = -1;
break;
diff --git a/types.h b/types.h
index 710f6fc..b4c33fc 100644
--- a/types.h
+++ b/types.h
@@ -217,7 +217,8 @@ typedef enum {
EXCEPTION_RUNTIME,
EXCEPTION_TYPE,
EXCEPTION_REFERENCE,
- EXCEPTION_USER
+ EXCEPTION_USER,
+ EXCEPTION_EXIT
} uc_exception_type_t;
typedef struct {
diff --git a/vm.c b/vm.c
index 15e510d..f4c56db 100644
--- a/vm.c
+++ b/vm.c
@@ -77,6 +77,7 @@ static const char *exception_type_strings[] = {
[EXCEPTION_TYPE] = "Type error",
[EXCEPTION_REFERENCE] = "Reference error",
[EXCEPTION_USER] = "Error",
+ [EXCEPTION_EXIT] = "Exit"
};
@@ -2256,6 +2257,16 @@ uc_vm_execute_chunk(uc_vm *vm, uc_value_t **retvalp)
/* previous instruction raised exception */
if (vm->exception.type != EXCEPTION_NONE) {
+ /* VM termination was requested */
+ if (vm->exception.type == EXCEPTION_EXIT) {
+ uc_vm_reset_callframes(vm);
+
+ if (retvalp)
+ *retvalp = ucv_int64_new(vm->arg.s32);
+
+ return STATUS_EXIT;
+ }
+
/* walk up callframes until something handles the exception or the root is reached */
while (!uc_vm_handle_exception(vm)) {
/* no further callframe to pop, report unhandled exception and terminate */
diff --git a/vm.h b/vm.h
index 520cf62..c4952a0 100644
--- a/vm.h
+++ b/vm.h
@@ -103,6 +103,7 @@ enum insn_type {
typedef enum {
STATUS_OK,
+ STATUS_EXIT,
ERROR_COMPILE,
ERROR_RUNTIME
} uc_vm_status_t;