refactor pic_try/catch
This commit is contained in:
parent
4751131b4f
commit
10aae770c9
|
@ -5,9 +5,32 @@
|
|||
#include "picrin.h"
|
||||
#include "picrin/object.h"
|
||||
|
||||
struct pic_cont {
|
||||
PIC_JMPBUF *jmp;
|
||||
|
||||
int id;
|
||||
|
||||
struct pic_checkpoint *cp;
|
||||
ptrdiff_t sp_offset;
|
||||
ptrdiff_t ci_offset;
|
||||
ptrdiff_t xp_offset;
|
||||
size_t arena_idx;
|
||||
pic_value ptable;
|
||||
pic_code *ip;
|
||||
|
||||
int retc;
|
||||
pic_value *retv;
|
||||
|
||||
struct pic_cont *prev;
|
||||
};
|
||||
|
||||
static const pic_data_type cont_type = { "pic_cont", NULL, NULL };
|
||||
|
||||
void
|
||||
pic_save_point(pic_state *pic, struct pic_cont *cont)
|
||||
pic_save_point(pic_state *pic, struct pic_cont *cont, PIC_JMPBUF *jmp)
|
||||
{
|
||||
cont->jmp = jmp;
|
||||
|
||||
/* save runtime context */
|
||||
cont->cp = pic->cp;
|
||||
cont->sp_offset = pic->sp - pic->stbase;
|
||||
|
@ -86,9 +109,6 @@ pic_dynamic_wind(pic_state *pic, pic_value in, pic_value thunk, pic_value out)
|
|||
return val;
|
||||
}
|
||||
|
||||
#define CV_ID 0
|
||||
#define CV_ESCAPE 1
|
||||
|
||||
static pic_value
|
||||
cont_call(pic_state *pic)
|
||||
{
|
||||
|
@ -99,7 +119,9 @@ cont_call(pic_state *pic)
|
|||
|
||||
pic_get_args(pic, "*", &argc, &argv);
|
||||
|
||||
id = pic_int(pic, pic_closure_ref(pic, CV_ID));
|
||||
cont = pic_data(pic, pic_closure_ref(pic, 0));
|
||||
|
||||
id = cont->id;
|
||||
|
||||
/* check if continuation is alive */
|
||||
for (cc = pic->cc; cc != NULL; cc = cc->prev) {
|
||||
|
@ -111,13 +133,12 @@ cont_call(pic_state *pic)
|
|||
pic_errorf(pic, "calling dead escape continuation");
|
||||
}
|
||||
|
||||
cont = pic_data(pic, pic_closure_ref(pic, CV_ESCAPE));
|
||||
cont->retc = argc;
|
||||
cont->retv = argv;
|
||||
|
||||
pic_load_point(pic, cont);
|
||||
|
||||
PIC_LONGJMP(pic, cont->jmp, 1);
|
||||
PIC_LONGJMP(pic, *cont->jmp, 1);
|
||||
|
||||
PIC_UNREACHABLE();
|
||||
}
|
||||
|
@ -125,26 +146,30 @@ cont_call(pic_state *pic)
|
|||
pic_value
|
||||
pic_make_cont(pic_state *pic, struct pic_cont *cont)
|
||||
{
|
||||
static const pic_data_type cont_type = { "cont", NULL, NULL };
|
||||
return pic_lambda(pic, cont_call, 1, pic_data_value(pic, cont, &cont_type));
|
||||
}
|
||||
|
||||
/* save the escape continuation in proc */
|
||||
return pic_lambda(pic, cont_call, 2, pic_int_value(pic, cont->id), pic_data_value(pic, cont, &cont_type));
|
||||
struct pic_cont *
|
||||
pic_alloca_cont(pic_state *pic)
|
||||
{
|
||||
return pic_alloca(pic, sizeof(struct pic_cont));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_callcc(pic_state *pic, pic_value proc)
|
||||
{
|
||||
struct pic_cont cont;
|
||||
PIC_JMPBUF jmp;
|
||||
struct pic_cont *cont = pic_alloca_cont(pic);
|
||||
|
||||
pic_save_point(pic, &cont);
|
||||
|
||||
if (PIC_SETJMP(pic, cont.jmp)) {
|
||||
return pic_valuesk(pic, cont.retc, cont.retv);
|
||||
if (PIC_SETJMP(pic, jmp)) {
|
||||
return pic_valuesk(pic, cont->retc, cont->retv);
|
||||
}
|
||||
else {
|
||||
pic_value val;
|
||||
|
||||
val = pic_call(pic, proc, 1, pic_make_cont(pic, &cont));
|
||||
pic_save_point(pic, cont, &jmp);
|
||||
|
||||
val = pic_call(pic, proc, 1, pic_make_cont(pic, cont));
|
||||
|
||||
pic_exit_point(pic);
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ pic_errorf(pic_state *pic, const char *fmt, ...)
|
|||
pic_error(pic, "", msg, pic_nil_value(pic));
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_native_exception_handler(pic_state *pic)
|
||||
static pic_value
|
||||
native_exception_handler(pic_state *pic)
|
||||
{
|
||||
pic_value err;
|
||||
|
||||
|
@ -61,6 +61,16 @@ pic_native_exception_handler(pic_state *pic)
|
|||
PIC_UNREACHABLE();
|
||||
}
|
||||
|
||||
void
|
||||
pic_push_native_handler(pic_state *pic, struct pic_cont *cont)
|
||||
{
|
||||
pic_value handler;
|
||||
|
||||
handler = pic_lambda(pic, native_exception_handler, 1, pic_make_cont(pic, cont));
|
||||
|
||||
pic_push_handler(pic, handler);
|
||||
}
|
||||
|
||||
void
|
||||
pic_push_handler(pic_state *pic, pic_value handler)
|
||||
{
|
||||
|
|
|
@ -345,6 +345,14 @@ void pic_load_cstr(pic_state *, const char *);
|
|||
pic_in_library(pic, lib); \
|
||||
} while (0)
|
||||
|
||||
struct pic_cont *pic_alloca_cont(pic_state *);
|
||||
pic_value pic_make_cont(pic_state *, struct pic_cont *);
|
||||
void pic_push_native_handler(pic_state *, struct pic_cont *);
|
||||
void pic_push_handler(pic_state *, pic_value);
|
||||
pic_value pic_pop_handler(pic_state *);
|
||||
void pic_save_point(pic_state *, struct pic_cont *, PIC_JMPBUF *);
|
||||
void pic_exit_point(pic_state *);
|
||||
|
||||
/* do not return from try block! */
|
||||
|
||||
#define pic_try \
|
||||
|
@ -353,22 +361,13 @@ void pic_load_cstr(pic_state *, const char *);
|
|||
pic_catch_(PIC_GENSYM(label))
|
||||
#define pic_try_(cont, handler) \
|
||||
do { \
|
||||
extern pic_value pic_make_cont(pic_state *, struct pic_cont *); \
|
||||
extern void pic_push_handler(pic_state *, pic_value proc); \
|
||||
extern pic_value pic_pop_handler(pic_state *); \
|
||||
extern pic_value pic_native_exception_handler(pic_state *); \
|
||||
extern void pic_save_point(pic_state *, struct pic_cont *); \
|
||||
extern void pic_exit_point(pic_state *); \
|
||||
struct pic_cont cont; \
|
||||
pic_save_point(pic, &cont); \
|
||||
if (PIC_SETJMP(pic, cont.jmp) == 0) { \
|
||||
pic_value handler; \
|
||||
handler = pic_lambda(pic, pic_native_exception_handler, 1, pic_make_cont(pic, &cont)); \
|
||||
do { \
|
||||
pic_push_handler(pic, handler);
|
||||
PIC_JMPBUF jmp; \
|
||||
struct pic_cont *cont = pic_alloca_cont(pic); \
|
||||
if (PIC_SETJMP(pic, jmp) == 0) { \
|
||||
pic_save_point(pic, cont, &jmp); \
|
||||
pic_push_native_handler(pic, cont);
|
||||
#define pic_catch_(label) \
|
||||
pic_pop_handler(pic); \
|
||||
} while (0); \
|
||||
pic_pop_handler(pic); \
|
||||
pic_exit_point(pic); \
|
||||
} else { \
|
||||
goto label; \
|
||||
|
|
|
@ -22,25 +22,6 @@ struct pic_lib {
|
|||
struct pic_dict *exports;
|
||||
};
|
||||
|
||||
struct pic_cont {
|
||||
PIC_JMPBUF jmp;
|
||||
|
||||
int id;
|
||||
|
||||
struct pic_checkpoint *cp;
|
||||
ptrdiff_t sp_offset;
|
||||
ptrdiff_t ci_offset;
|
||||
ptrdiff_t xp_offset;
|
||||
size_t arena_idx;
|
||||
pic_value ptable;
|
||||
pic_code *ip;
|
||||
|
||||
int retc;
|
||||
pic_value *retv;
|
||||
|
||||
struct pic_cont *prev;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int argc, retc;
|
||||
pic_code *ip;
|
||||
|
|
Loading…
Reference in New Issue