Simplified the frame stack by replacing the frame class with a particular tag.

This commit is contained in:
jjgarcia 2005-08-30 14:38:04 +00:00
parent 93cf73b8d5
commit a5b4834caf
13 changed files with 47 additions and 88 deletions

View file

@ -166,7 +166,7 @@ aset_bv(cl_object x, cl_index index, int value)
void
cl_throw(cl_object tag)
{
ecl_frame_ptr fr = frs_sch_catch(tag);
ecl_frame_ptr fr = frs_sch(tag);
if (fr == NULL)
FEcontrol_error("THROW: The catch ~S is undefined.", 1, tag);
unwind(fr);

View file

@ -252,14 +252,13 @@ cl_safe_eval(cl_object form, cl_object env, cl_object err_value)
{
cl_object output;
if (frs_push(FRS_CATCHALL, Cnil)) {
output = err_value;
} else {
CL_CATCH_ALL_BEGIN
bds_bind(@'si::*ignore-errors*', Ct);
output = si_eval_with_env(2, form, env);
bds_unwind1();
}
frs_pop();
CL_CATCH_ALL_IF_CAUGHT
output = err_value;
CL_CATCH_ALL_END;
return output;
}

View file

@ -1096,7 +1096,7 @@ interpret(cl_object bytecodes, void *pc) {
name = GET_DATA(vector, bytecodes);
GET_LABEL(exit, vector);
cl_stack_push((cl_object)exit);
if (frs_push(FRS_CATCH, id) == 0) {
if (frs_push(id) == 0) {
bind_block(name, id);
} else {
reg0 = VALUES(0);
@ -1120,7 +1120,7 @@ interpret(cl_object bytecodes, void *pc) {
/* FIXME! */
GET_LABEL(exit, vector);
cl_stack_push((cl_object)exit);
if (frs_push(FRS_CATCH, id) == 0) {
if (frs_push(id) == 0) {
bind_block(name, id);
} else {
reg0 = VALUES(0);
@ -1142,7 +1142,7 @@ interpret(cl_object bytecodes, void *pc) {
cl_opcode *exit;
GET_LABEL(exit, vector);
cl_stack_push((cl_object)exit);
if (frs_push(FRS_CATCH, reg0) != 0) {
if (frs_push(reg0) != 0) {
reg0 = VALUES(0);
cl_env.lex_env = cl_env.frs_top->frs_lex;
frs_pop();
@ -1166,7 +1166,7 @@ interpret(cl_object bytecodes, void *pc) {
int n = GET_OPARG(vector);
/* Here we save the location of the jump table */
cl_stack_push((cl_object)vector); /* FIXME! */
if (frs_push(FRS_CATCH, bind_tagbody()) == 0) {
if (frs_push(bind_tagbody()) == 0) {
/* The first time, we "name" the tagbody and
* skip the jump table */
vector += n * OPARG_SIZE;
@ -1309,7 +1309,7 @@ interpret(cl_object bytecodes, void *pc) {
cl_opcode *exit;
GET_LABEL(exit, vector);
cl_stack_push((cl_object)exit);
if (frs_push(FRS_PROTECT,Cnil) != 0) {
if (frs_push(ECL_PROTECT_TAG) != 0) {
cl_env.lex_env = cl_env.frs_top->frs_lex;
frs_pop();
vector = (cl_opcode *)cl_stack_pop();

View file

@ -128,12 +128,11 @@ cl_shutdown(void)
{
cl_object l = SYM_VAL(@'si::*exit-hooks*');
while (CONSP(l)) {
if (!frs_push(FRS_CATCHALL, Cnil)) {
CL_CATCH_ALL_BEGIN
bds_bind(@'si::*ignore-errors*', Ct);
funcall(1, CAR(l));
bds_unwind1();
}
frs_pop();
CL_CATCH_ALL_END;
l = CDR(l);
}
#ifdef ENABLE_DLOPEN

View file

@ -255,13 +255,12 @@ frs_overflow(void) /* used as condition in list.d */
}
ecl_frame_ptr
_frs_push(register enum fr_class clas, register cl_object val)
_frs_push(register cl_object val)
{
ecl_frame_ptr output = ++cl_env.frs_top;
if (output >= cl_env.frs_limit) frs_overflow();
output->frs_lex = cl_env.lex_env;
output->frs_bds_top = cl_env.bds_top;
output->frs_class = clas;
output->frs_val = val;
output->frs_ihs = cl_env.ihs_top;
output->frs_sp = cl_stack_index();
@ -272,7 +271,7 @@ void
unwind(ecl_frame_ptr fr)
{
cl_env.nlj_fr = fr;
while (cl_env.frs_top != fr && cl_env.frs_top->frs_class == FRS_CATCH)
while (cl_env.frs_top != fr && cl_env.frs_top->frs_val != ECL_PROTECT_TAG)
--cl_env.frs_top;
cl_env.lex_env = cl_env.frs_top->frs_lex;
cl_env.ihs_top = cl_env.frs_top->frs_ihs;
@ -288,23 +287,11 @@ frs_sch (cl_object frame_id)
ecl_frame_ptr top;
for (top = cl_env.frs_top; top >= cl_env.frs_org; top--)
if (top->frs_val == frame_id && top->frs_class == FRS_CATCH)
if (top->frs_val == frame_id)
return(top);
return(NULL);
}
ecl_frame_ptr
frs_sch_catch(cl_object frame_id)
{
ecl_frame_ptr top;
for(top = cl_env.frs_top; top >= cl_env.frs_org ;top--)
if ((top->frs_val == frame_id && top->frs_class == FRS_CATCH)
|| top->frs_class == FRS_CATCHALL)
return(top);
return(NULL);
}
static ecl_frame_ptr
get_frame_ptr(cl_object x)
{
@ -330,20 +317,6 @@ si_frs_bds(cl_object arg)
@(return MAKE_FIXNUM(get_frame_ptr(arg)->frs_bds_top - cl_env.bds_org))
}
cl_object
si_frs_class(cl_object arg)
{
enum fr_class c;
cl_object output;
c = get_frame_ptr(arg)->frs_class;
if (c == FRS_CATCH) output = @':catch';
else if (c == FRS_PROTECT) output = @':protect';
else if (c == FRS_CATCHALL) output = @':catchall';
else FEerror("Unknown frs class was detected.", 0);
@(return output)
}
cl_object
si_frs_tag(cl_object arg)
{

View file

@ -1098,7 +1098,6 @@ cl_symbols[] = {
{SYS_ "FORMATTER-AUX", SI_ORDINARY, si_formatter_aux, -1, OBJNULL},
#endif
{SYS_ "FRS-BDS", SI_ORDINARY, si_frs_bds, 1, OBJNULL},
{SYS_ "FRS-CLASS", SI_ORDINARY, si_frs_class, 1, OBJNULL},
{SYS_ "FRS-IHS", SI_ORDINARY, si_frs_ihs, 1, OBJNULL},
{SYS_ "FRS-TAG", SI_ORDINARY, si_frs_tag, 1, OBJNULL},
{SYS_ "FRS-TOP", SI_ORDINARY, si_frs_top, 0, OBJNULL},
@ -1300,8 +1299,6 @@ cl_symbols[] = {
{KEY_ "BLOCK", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "CAPITALIZE", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "CASE", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "CATCH", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "CATCHALL", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "CIRCLE", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "COMPILE-TOPLEVEL", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "COMMON",KEYWORD,NULL,-1,OBJNULL},
@ -1387,7 +1384,6 @@ cl_symbols[] = {
{KEY_ "PRINT-FUNCTION", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "PRINT-OBJECT", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "PROBE", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "PROTECT", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "RADIX", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "READABLY", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "REHASH-SIZE", KEYWORD, NULL, -1, OBJNULL},

View file

@ -1098,7 +1098,6 @@ cl_symbols[] = {
{SYS_ "FORMATTER-AUX","si_formatter_aux"},
#endif
{SYS_ "FRS-BDS","si_frs_bds"},
{SYS_ "FRS-CLASS","si_frs_class"},
{SYS_ "FRS-IHS","si_frs_ihs"},
{SYS_ "FRS-TAG","si_frs_tag"},
{SYS_ "FRS-TOP","si_frs_top"},
@ -1300,8 +1299,6 @@ cl_symbols[] = {
{KEY_ "BLOCK",NULL},
{KEY_ "CAPITALIZE",NULL},
{KEY_ "CASE",NULL},
{KEY_ "CATCH",NULL},
{KEY_ "CATCHALL",NULL},
{KEY_ "CIRCLE",NULL},
{KEY_ "COMPILE-TOPLEVEL",NULL},
{KEY_ "COMMON",NULL},
@ -1387,7 +1384,6 @@ cl_symbols[] = {
{KEY_ "PRINT-FUNCTION",NULL},
{KEY_ "PRINT-OBJECT",NULL},
{KEY_ "PROBE",NULL},
{KEY_ "PROTECT",NULL},
{KEY_ "RADIX",NULL},
{KEY_ "READABLY",NULL},
{KEY_ "REHASH-SIZE",NULL},

View file

@ -62,7 +62,7 @@
(wt-nl "volatile cl_object env" (incf *env-lvl*)
" = env" env-lvl ";")))
(bind "new_frame_id()" blk-var)
(wt-nl "if (frs_push(FRS_CATCH," blk-var ")!=0) {")
(wt-nl "if (frs_push(" blk-var ")!=0) {")
(let ((*unwind-exit* (cons 'FRAME *unwind-exit*)))
(unwind-exit 'VALUES)
(wt-nl "} else {")

View file

@ -28,12 +28,12 @@
(*unwind-exit* (list* *exit* 'FRAME *unwind-exit*)))
(if (member new-destination '(TRASH VALUES))
(progn
(wt-nl "if (frs_push(FRS_CATCH," 'VALUE0 ")==0) {")
(wt-nl "if (frs_push(" 'VALUE0 ")==0) {")
(wt-comment "BEGIN CATCH " code nil)
(c2expr body)
(wt-nl "}"))
(progn
(wt-nl "if (frs_push(FRS_CATCH," 'VALUE0 ")) {")
(wt-nl "if (frs_push(" 'VALUE0 ")) {")
(wt-comment "BEGIN CATCH " code nil)
(unwind-exit 'VALUES t)
(wt-nl "}")
@ -60,7 +60,7 @@
(wt-nl "ecl_frame_ptr next_fr; cl_object next_tag;")
;; Here we compile the form which is protected. When this form
;; is aborted, it continues at the frs_pop() with unwinding=TRUE.
(wt-nl "if (frs_push(FRS_PROTECT,Cnil)) {")
(wt-nl "if (frs_push(ECL_PROTECT_TAG)) {")
(wt-nl "unwinding = TRUE; next_fr=cl_env.nlj_fr; } else {")
(let ((*unwind-exit* (cons 'FRAME *unwind-exit*))
(*destination* 'VALUES))

View file

@ -132,7 +132,7 @@
(wt-nl "{ cl_object " tag-loc ";")
(setq env-grows t)) ; just to ensure closing the block
(bind "new_frame_id()" tag-loc)
(wt-nl "if (frs_push(FRS_CATCH," tag-loc ")) {")
(wt-nl "if (frs_push(" tag-loc ")) {")
;; Allocate labels.
(dolist (tag body)
(when (and (tag-p tag) (plusp (tag-ref tag)))

View file

@ -306,7 +306,6 @@
(proclaim-function si:frs-top (*) t)
(proclaim-function si::frs-vs (*) t)
(proclaim-function si:frs-bds (*) t)
(proclaim-function si:frs-class (*) t)
(proclaim-function si:frs-tag (*) t)
(proclaim-function si:frs-ihs (*) t)
(proclaim-function si:bds-top (*) t)

View file

@ -1229,7 +1229,6 @@ extern cl_object si_ihs_next(cl_object arg);
extern cl_object si_ihs_prev(cl_object arg);
extern cl_object si_frs_top(void);
extern cl_object si_frs_bds(cl_object arg);
extern cl_object si_frs_class(cl_object arg);
extern cl_object si_frs_tag(cl_object arg);
extern cl_object si_frs_ihs(cl_object arg);
extern cl_object si_bds_top(void);

View file

@ -92,40 +92,38 @@ extern cl_object ihs_top_function_name(void);
/***************
* FRAME STACK
***************/
/*
frs_class | frs_value | frs_prev
----------+--------------------------------------+--------------
CATCH | frame-id, i.e. |
| throw-tag, |
| block-id (uninterned symbol), or | value of ihs_top
| tagbody-id (uninterned symbol) | when the frame
----------+--------------------------------------| was pushed
CATCHALL | NIL |
----------+--------------------------------------|
PROTECT | NIL |
----------------------------------------------------------------
*/
enum fr_class {
FRS_CATCH, /* for catch,block,tabbody */
FRS_CATCHALL, /* for catchall */
FRS_PROTECT /* for protect-all */
};
/* Frames signal points in the code to which we can at any time jump.
* Frames are established, for instance, by CATCH, BLOCK, TAGBODY,
* LAMBDA, UNWIND-PROTECT, etc.
*
* Frames are established by frs_push(). For each call to frs_push()
* there must be a corresponding frs_pop(). More precisely, since our
* frame mechanism relies on the C stack and on the setjmp/longjmp
* functions, any function that creates a frame must also destroy it
* with frs_pop() before returning.
*
* Frames are identified by a value frs_val. This can be either a
* unique identifier, created for each CATCH, BLOCK, etc, or a common
* one ECL_PROTECT_TAG, used by UNWIND-PROTECT forms. The first type
* of frames can be target of a search frs_sch() and thus one can jump
* to them. The second type of frames are like barriers designed to
* intercept the jumps to the outer frames and are called
* automatically by the function unwind() whenever it jumps to a frame
* which is beyond one of these barriers.
*/
typedef struct ecl_frame {
jmp_buf frs_jmpbuf;
cl_object frs_val;
cl_object frs_lex;
bds_ptr frs_bds_top;
enum fr_class frs_class;
cl_object frs_val;
ihs_ptr frs_ihs;
cl_index frs_sp;
} *ecl_frame_ptr;
extern ecl_frame_ptr _frs_push(register enum fr_class clas, register cl_object val);
#define frs_push(class, val) ecl_setjmp(_frs_push(class, val)->frs_jmpbuf)
#define ECL_PROTECT_TAG OBJNULL
extern ecl_frame_ptr _frs_push(register cl_object val);
#define frs_push(val) ecl_setjmp(_frs_push(val)->frs_jmpbuf)
#define frs_pop() (cl_env.frs_top--)
/*******************
@ -178,7 +176,7 @@ cl_env.lex_env ------> ( tag0 value0 tag1 value1 ... )
#define CL_UNWIND_PROTECT_BEGIN {\
bool __unwinding; ecl_frame_ptr __next_fr; \
cl_index __nr; \
if (frs_push(FRS_PROTECT,Cnil)) { \
if (frs_push(ECL_PROTECT_TAG)) { \
__unwinding=1; __next_fr=cl_env.nlj_fr; \
} else {
@ -193,19 +191,19 @@ cl_env.lex_env ------> ( tag0 value0 tag1 value1 ... )
#define CL_BLOCK_BEGIN(id) { \
cl_object id = new_frame_id(); \
if (frs_push(FRS_CATCH,id) == 0)
if (frs_push(id) == 0)
#define CL_BLOCK_END } \
frs_pop()
#define CL_CATCH_BEGIN(tag) \
if (frs_push(FRS_CATCH,tag) == 0) {
if (frs_push(tag) == 0) {
#define CL_CATCH_END } \
frs_pop();
#define CL_CATCH_ALL_BEGIN \
if (frs_push(FRS_CATCH,Cnil) == 0) {
if (frs_push(ECL_PROTECT_TAG) == 0) {
#define CL_CATCH_ALL_IF_CAUGHT } else {