Fix gc with exceptions
This commit is contained in:
+34
-32
@@ -1,8 +1,33 @@
|
||||
#include "lisp.h"
|
||||
#include "read.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static jmp_buf toplevel_error_jmp_buf;
|
||||
|
||||
static void toplevel_error_handler(LispVal *name, LispVal *data,
|
||||
void *ignored) {
|
||||
fprintf(stderr, "Caught exception: ");
|
||||
Fprint_condition(name, data, Qerror_write_byte);
|
||||
fprintf(stderr, "\nBacktrace (toplevel comes last):\n");
|
||||
LispVal *backtrace = Fbacktrace();
|
||||
DOLIST(frame, backtrace) {
|
||||
LispVal *name = FIRST(frame);
|
||||
bool evaled = !NILP(THIRD(frame));
|
||||
LispVal *args = FOURTH(frame);
|
||||
fprintf(stderr, " %c ", evaled ? '-' : '*');
|
||||
Fprinc(name, Qerror_write_byte);
|
||||
if (NILP(args)) {
|
||||
fprintf(stderr, "()\n");
|
||||
} else {
|
||||
Fprinc(args, Qerror_write_byte);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
longjmp(toplevel_error_jmp_buf, 1);
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
FILE *in = fopen(argv[1], "r");
|
||||
fseek(in, 0, SEEK_END);
|
||||
@@ -17,38 +42,15 @@ int main(int argc, const char **argv) {
|
||||
ReadStream s;
|
||||
read_stream_init(&s, src, src_len);
|
||||
LispVal *r;
|
||||
bool had_toplevel_error = false;
|
||||
HANDLER_BIND1(
|
||||
LIST(Qt),
|
||||
{
|
||||
while ((r = read(&s))) {
|
||||
Feval(r, Qnil);
|
||||
}
|
||||
},
|
||||
{
|
||||
fprintf(stderr, "Caught exception: ");
|
||||
Fprint_condition(EXCEPTION_NAME(), EXCEPTION_DATA(),
|
||||
Qerror_write_byte); //
|
||||
fprintf(stderr, "\nBacktrace (toplevel comes last):\n");
|
||||
LispVal *backtrace = Fbacktrace();
|
||||
DOLIST(frame, backtrace) {
|
||||
LispVal *name = FIRST(frame);
|
||||
bool evaled = !NILP(THIRD(frame));
|
||||
LispVal *args = FOURTH(frame);
|
||||
fprintf(stderr, " %c ", evaled ? '-' : '*');
|
||||
Fprinc(name, Qerror_write_byte);
|
||||
if (NILP(args)) {
|
||||
fprintf(stderr, "()\n");
|
||||
} else {
|
||||
Fprinc(args, Qerror_write_byte);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
CLEAR_EXCEPTION();
|
||||
had_toplevel_error = true;
|
||||
goto toplevel_error;
|
||||
});
|
||||
toplevel_error:
|
||||
push_handler_bind_frame(LIST(Qt), toplevel_error_handler, NULL, NULL);
|
||||
volatile bool had_toplevel_error = false;
|
||||
if (setjmp(toplevel_error_jmp_buf) == 0) {
|
||||
while ((r = read(&s))) {
|
||||
Feval(r, Qnil);
|
||||
}
|
||||
} else {
|
||||
had_toplevel_error = true;
|
||||
}
|
||||
unwind_to(toplevel);
|
||||
lisp_shutdown();
|
||||
free(src);
|
||||
|
||||
Reference in New Issue
Block a user