Fix gc with exceptions

This commit is contained in:
2026-09-03 21:04:46 -07:00
parent 2533b0db7d
commit 3b2ecf2b16
10 changed files with 139 additions and 275 deletions
+9 -26
View File
@@ -27,7 +27,7 @@ void *lisp_alloc_object_no_gc(size_t size, LispValType type) {
LispObject *obj = lisp_aligned_alloc(LISP_OBJECT_ALIGNMENT, size);
memset(obj, 0, size);
obj->type = type;
tss_create(&obj->gc.lowest_local_ref, NULL);
obj->gc.lowest_local_ref = NULL;
return obj;
}
@@ -45,8 +45,6 @@ void *lisp_alloc_object(size_t size, LispValType type) {
void lisp_release_object(LispVal *val) {
assert(OBJECTP(val));
LispObject *obj = val;
tss_delete(obj->gc.lowest_local_ref);
lisp_free(val);
}
@@ -294,35 +292,20 @@ static void check_handler_bind_handlers(LispVal *handlers) {
}
}
static void lisp_handler_bind_handler(LispVal *name, LispVal *data,
LispVal *lisp_handler) {
CALL(lisp_handler, CONS(name, data));
}
DEFUN(handler_bind, "handler-bind", (LispVal * thunk, LispVal *handlers),
"(thunk &rest handlers)", "") {
check_handler_bind_handlers(handlers);
StackFrame *stack_ref = LISP_STACK_REF();
jmp_buf jmp_target;
size_t nhandlers = list_length(handlers);
LispVal **handler_vec = lisp_malloc(sizeof(LispVal *) * nhandlers);
bool **enabled_vec = lisp_malloc(sizeof(bool *) * nhandlers);
size_t idx = 0;
DOLIST(handler, handlers) {
handler_vec[idx] = XCDR(handler);
enabled_vec[idx] =
push_handler_bind_frame(&jmp_target, XCAR(handler), idx);
++idx;
}
if (setjmp(jmp_target) == 0) {
return UNWIND_AND_RETURN(stack_ref, CALL0(thunk));
} else {
size_t handler_idx = EXCEPTION_HANDLER_FRAME()->handler_bind.datum;
for (size_t i = 0; i < nhandlers; ++i) {
*enabled_vec[i] = false;
}
CALL(handler_vec[handler_idx],
CONS(EXCEPTION_NAME(), EXCEPTION_DATA()));
for (size_t i = 0; i < nhandlers; ++i) {
*enabled_vec[i] = true;
}
continue_unwinding();
push_handler_bind_frame(FIRST(handler), lisp_handler_bind_handler,
SECOND(handler), NULL);
}
return UNWIND_AND_RETURN(stack_ref, CALL0(thunk));
}
DEFUN(error, "error", (LispVal * data), "(data)", "") {