diff --git a/src/c/cmpaux.d b/src/c/cmpaux.d index 1033620d9..c2d36f15f 100644 --- a/src/c/cmpaux.d +++ b/src/c/cmpaux.d @@ -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); diff --git a/src/c/eval.d b/src/c/eval.d index 260e7ef5a..730bca7d8 100644 --- a/src/c/eval.d +++ b/src/c/eval.d @@ -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; } diff --git a/src/c/interpreter.d b/src/c/interpreter.d index aa92ba10f..89052edeb 100644 --- a/src/c/interpreter.d +++ b/src/c/interpreter.d @@ -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(); diff --git a/src/c/main.d b/src/c/main.d index 5d8154200..e9e0442b3 100644 --- a/src/c/main.d +++ b/src/c/main.d @@ -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 diff --git a/src/c/stacks.d b/src/c/stacks.d index e6ba2293d..c541f2842 100644 --- a/src/c/stacks.d +++ b/src/c/stacks.d @@ -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) { diff --git a/src/c/symbols_list.h b/src/c/symbols_list.h index 154459c26..1af45c7c5 100644 --- a/src/c/symbols_list.h +++ b/src/c/symbols_list.h @@ -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}, diff --git a/src/c/symbols_list2.h b/src/c/symbols_list2.h index 6783e18f2..f80cafb60 100644 --- a/src/c/symbols_list2.h +++ b/src/c/symbols_list2.h @@ -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}, diff --git a/src/cmp/cmpblock.lsp b/src/cmp/cmpblock.lsp index 2b4e6a760..98fe2eaaa 100644 --- a/src/cmp/cmpblock.lsp +++ b/src/cmp/cmpblock.lsp @@ -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 {") diff --git a/src/cmp/cmpcatch.lsp b/src/cmp/cmpcatch.lsp index ae09ce1a1..0b99e3f21 100644 --- a/src/cmp/cmpcatch.lsp +++ b/src/cmp/cmpcatch.lsp @@ -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)) diff --git a/src/cmp/cmptag.lsp b/src/cmp/cmptag.lsp index a4efef2f0..0155e14dd 100644 --- a/src/cmp/cmptag.lsp +++ b/src/cmp/cmptag.lsp @@ -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))) diff --git a/src/cmp/sysfun.lsp b/src/cmp/sysfun.lsp index 0b402613c..2cb1633c7 100644 --- a/src/cmp/sysfun.lsp +++ b/src/cmp/sysfun.lsp @@ -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) diff --git a/src/h/external.h b/src/h/external.h index 7614fc304..ccbdc4933 100644 --- a/src/h/external.h +++ b/src/h/external.h @@ -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); diff --git a/src/h/stacks.h b/src/h/stacks.h index c9398700a..e784daf4b 100644 --- a/src/h/stacks.h +++ b/src/h/stacks.h @@ -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 {