1
0
Fork 0
forked from fun/fun

Fixed try/catch to run finally again. exit() in catch if you want to stop execution. (0.37.62)

This commit is contained in:
Johannes Findeisen 2026-01-24 21:17:40 +01:00
commit 869d68b992
4 changed files with 43 additions and 5 deletions

View file

@ -235,6 +235,38 @@ static void fun_vm_exit(int code) {
/* Redirect exit inside this TU (affects included opcode handlers) */
#define exit(code) fun_vm_exit(code)
/* Forward decl for stack push used by vm_raise_error */
static void push_value(VM *vm, Value v);
/* Raise a runtime error that respects try/catch/finally semantics.
* If a handler is installed for the current frame, jump to it and push
* an error string for the catch clause. Otherwise, print and stop VM. */
void vm_raise_error(VM *vm, const char *msg) {
if (!vm || vm->fp < 0) {
fprintf(stderr, "Runtime error: %s\n", msg ? msg : "<error>");
return;
}
Frame *f = &vm->frames[vm->fp];
if (f->try_sp >= 0) {
char buf[256];
if (msg) {
snprintf(buf, sizeof(buf), "Runtime error: %s", msg);
} else {
snprintf(buf, sizeof(buf), "Runtime error");
}
/* push error value and transfer control to handler target */
Value err = make_string(buf);
push_value(vm, err);
int try_idx = f->try_stack[f->try_sp--];
int target = f->fn->instructions[try_idx].operand;
f->ip = target;
return;
}
/* No handler: print annotated message and terminate VM */
fprintf(stderr, "Runtime error: %s\n", msg ? msg : "<error>");
vm->fp = -1; /* stop execution */
}
/*
Opcode case include index (vm_case_*.inc):
- Core/stack/frame:

View file

@ -122,6 +122,12 @@ void vm_dump_globals(VM *vm);
// run entry Bytecode (pushes first frame)
void vm_run(VM *vm, Bytecode *entry);
/* Raise a runtime error that respects try/catch/finally.
* If a try handler is active in the current frame, control jumps to it
* with an error string pushed on the stack. Otherwise, prints the error
* (annotated with location) and terminates execution. */
void vm_raise_error(VM *vm, const char *msg);
/* --- Debugger API --- */
void vm_debug_reset(VM *vm);
int vm_debug_add_breakpoint(VM *vm, const char *file, int line); // returns id >=0 or -1

View file

@ -40,8 +40,8 @@ case OP_DIV: {
double da = (a.type == VAL_FLOAT) ? a.d : (double)a.i;
double db = (b.type == VAL_FLOAT) ? b.d : (double)b.i;
if (db == 0.0) {
fprintf(stderr, "Runtime error: division by zero\n");
exit(1);
vm_raise_error(vm, "division by zero");
break;
}
Value res = make_float(da / db);
free_value(a);
@ -49,8 +49,8 @@ case OP_DIV: {
push_value(vm, res);
} else {
if (b.i == 0) {
fprintf(stderr, "Runtime error: division by zero\n");
exit(1);
vm_raise_error(vm, "division by zero");
break;
}
Value res = make_int(a.i / b.i);
free_value(a);