initial raise-continuable support
This commit is contained in:
parent
f52ef27a81
commit
70ace29b7c
|
@ -11,6 +11,7 @@ extern "C" {
|
|||
|
||||
struct pic_jmpbuf {
|
||||
jmp_buf here;
|
||||
struct pic_proc *handler;
|
||||
pic_callinfo *ci;
|
||||
pic_value *sp;
|
||||
pic_code *ip;
|
||||
|
@ -20,7 +21,9 @@ struct pic_jmpbuf {
|
|||
/* do not return from try block! */
|
||||
|
||||
#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) \
|
||||
do
|
||||
#define pic_catch \
|
||||
|
@ -28,7 +31,7 @@ struct pic_jmpbuf {
|
|||
else \
|
||||
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 *);
|
||||
|
||||
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
|
||||
pic_push_try(pic_state *pic)
|
||||
pic_push_try(pic_state *pic, struct pic_proc *handler)
|
||||
{
|
||||
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->handler = handler;
|
||||
|
||||
try_jmp->ci = pic->ci;
|
||||
try_jmp->sp = pic->sp;
|
||||
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_try {
|
||||
pic_try_with_handler(handler) {
|
||||
v = pic_apply0(pic, thunk);
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
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, "raise", pic_error_raise);
|
||||
pic_defun(pic, "raise-continuable", pic_error_raise_continuable);
|
||||
pic_defun(pic, "error", pic_error_error);
|
||||
pic_defun(pic, "error-object?", pic_error_error_object_p);
|
||||
pic_defun(pic, "error-object-message", pic_error_error_object_message);
|
||||
|
|
Loading…
Reference in New Issue