initial raise-continuable support
This commit is contained in:
parent
f52ef27a81
commit
70ace29b7c
|
@ -11,6 +11,7 @@ extern "C" {
|
||||||
|
|
||||||
struct pic_jmpbuf {
|
struct pic_jmpbuf {
|
||||||
jmp_buf here;
|
jmp_buf here;
|
||||||
|
struct pic_proc *handler;
|
||||||
pic_callinfo *ci;
|
pic_callinfo *ci;
|
||||||
pic_value *sp;
|
pic_value *sp;
|
||||||
pic_code *ip;
|
pic_code *ip;
|
||||||
|
@ -20,7 +21,9 @@ struct pic_jmpbuf {
|
||||||
/* do not return from try block! */
|
/* do not return from try block! */
|
||||||
|
|
||||||
#define pic_try \
|
#define pic_try \
|
||||||
pic_push_try(pic); \
|
pic_try_with_handler(NULL)
|
||||||
|
#define pic_try_with_handler(handler) \
|
||||||
|
pic_push_try(pic, handler); \
|
||||||
if (setjmp(*pic->jmp) == 0) \
|
if (setjmp(*pic->jmp) == 0) \
|
||||||
do
|
do
|
||||||
#define pic_catch \
|
#define pic_catch \
|
||||||
|
@ -28,7 +31,7 @@ struct pic_jmpbuf {
|
||||||
else \
|
else \
|
||||||
if (pic_pop_try(pic), 1)
|
if (pic_pop_try(pic), 1)
|
||||||
|
|
||||||
void pic_push_try(pic_state *);
|
void pic_push_try(pic_state *, struct pic_proc *);
|
||||||
void pic_pop_try(pic_state *);
|
void pic_pop_try(pic_state *);
|
||||||
|
|
||||||
noreturn void pic_throw(pic_state *, short, const char *, pic_value);
|
noreturn void pic_throw(pic_state *, short, const char *, pic_value);
|
||||||
|
|
29
src/error.c
29
src/error.c
|
@ -34,7 +34,7 @@ pic_warnf(pic_state *pic, const char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pic_push_try(pic_state *pic)
|
pic_push_try(pic_state *pic, struct pic_proc *handler)
|
||||||
{
|
{
|
||||||
struct pic_jmpbuf *try_jmp;
|
struct pic_jmpbuf *try_jmp;
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ pic_push_try(pic_state *pic)
|
||||||
|
|
||||||
try_jmp = pic->try_jmps + pic->try_jmp_idx++;
|
try_jmp = pic->try_jmps + pic->try_jmp_idx++;
|
||||||
|
|
||||||
|
try_jmp->handler = handler;
|
||||||
|
|
||||||
try_jmp->ci = pic->ci;
|
try_jmp->ci = pic->ci;
|
||||||
try_jmp->sp = pic->sp;
|
try_jmp->sp = pic->sp;
|
||||||
try_jmp->ip = pic->ip;
|
try_jmp->ip = pic->ip;
|
||||||
|
@ -140,7 +142,7 @@ pic_error_with_exception_handler(pic_state *pic)
|
||||||
|
|
||||||
pic_get_args(pic, "ll", &handler, &thunk);
|
pic_get_args(pic, "ll", &handler, &thunk);
|
||||||
|
|
||||||
pic_try {
|
pic_try_with_handler(handler) {
|
||||||
v = pic_apply0(pic, thunk);
|
v = pic_apply0(pic, thunk);
|
||||||
}
|
}
|
||||||
pic_catch {
|
pic_catch {
|
||||||
|
@ -169,6 +171,28 @@ pic_error_raise(pic_state *pic)
|
||||||
pic_throw(pic, PIC_ERROR_RAISED, "object is raised", pic_list1(pic, v));
|
pic_throw(pic, PIC_ERROR_RAISED, "object is raised", pic_list1(pic, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pic_value
|
||||||
|
pic_error_raise_continuable(pic_state *pic)
|
||||||
|
{
|
||||||
|
pic_value v;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
pic_get_args(pic, "o", &v);
|
||||||
|
|
||||||
|
if (pic->try_jmps->handler == NULL) {
|
||||||
|
pic_errorf(pic, "uncontinuable exception handler is on top");
|
||||||
|
}
|
||||||
|
if ((i = pic->try_jmp_idx) == 0) {
|
||||||
|
pic_errorf(pic, "no exception handler registered");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pic->try_jmp_idx--;
|
||||||
|
v = pic_apply1(pic, pic->try_jmps->handler, v);
|
||||||
|
++pic->try_jmp_idx;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
noreturn static pic_value
|
noreturn static pic_value
|
||||||
pic_error_error(pic_state *pic)
|
pic_error_error(pic_state *pic)
|
||||||
{
|
{
|
||||||
|
@ -248,6 +272,7 @@ pic_init_error(pic_state *pic)
|
||||||
{
|
{
|
||||||
pic_defun(pic, "with-exception-handler", pic_error_with_exception_handler);
|
pic_defun(pic, "with-exception-handler", pic_error_with_exception_handler);
|
||||||
pic_defun(pic, "raise", pic_error_raise);
|
pic_defun(pic, "raise", pic_error_raise);
|
||||||
|
pic_defun(pic, "raise-continuable", pic_error_raise_continuable);
|
||||||
pic_defun(pic, "error", pic_error_error);
|
pic_defun(pic, "error", pic_error_error);
|
||||||
pic_defun(pic, "error-object?", pic_error_error_object_p);
|
pic_defun(pic, "error-object?", pic_error_error_object_p);
|
||||||
pic_defun(pic, "error-object-message", pic_error_error_object_message);
|
pic_defun(pic, "error-object-message", pic_error_error_object_message);
|
||||||
|
|
Loading…
Reference in New Issue