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