1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-30 08:50:23 +02:00

* throw.h, throw.c: Use SCM_P instead of #if hair.

Remove special support for uncaught throws; see throw.c for
rationale.
* throw.c (unhandled_throw): New function.
(scm_ithrow): Call unhandled_throw if we don't find a throw
target; don't mess with scm_bad_throw_vcell.
(scm_bad_throw_vcell): Variable deleted.
(scm_init_throw): Don't initialize it.

* throw.c (scm_ithrow): Don't let outer key matches shadow inner
#t catches.
This commit is contained in:
Jim Blandy 1996-09-28 00:01:40 +00:00
parent b59b97ba3a
commit 32f7b3a1b1

View file

@ -53,15 +53,12 @@
#include "continuations.h" #include "continuations.h"
#include "throw.h" #include "throw.h"
/* {Catch and Throw} /* {Catch and Throw}
*/ */
static int scm_tc16_jmpbuffer; static int scm_tc16_jmpbuffer;
SCM scm_bad_throw_vcell;
#define SCM_JMPBUFP(O) (SCM_TYP16(O) == scm_tc16_jmpbuffer) #define SCM_JMPBUFP(O) (SCM_TYP16(O) == scm_tc16_jmpbuffer)
#define JBACTIVE(O) (SCM_CAR (O) & (1L << 16L)) #define JBACTIVE(O) (SCM_CAR (O) & (1L << 16L))
#define ACTIVATEJB(O) (SCM_CAR (O) |= (1L << 16L)) #define ACTIVATEJB(O) (SCM_CAR (O) |= (1L << 16L))
@ -76,30 +73,23 @@ SCM scm_bad_throw_vcell;
#define SCM_SETJBDFRAME(O,X) SCM_CAR(SCM_CDR (O)) = (SCM)(X) #define SCM_SETJBDFRAME(O,X) SCM_CAR(SCM_CDR (O)) = (SCM)(X)
#define SETJBJMPBUF(O,X) SCM_SETCDR(SCM_CDR (O), X) #define SETJBJMPBUF(O,X) SCM_SETCDR(SCM_CDR (O), X)
#ifdef __STDC__ static scm_sizet freejb SCM_P ((SCM jbsmob));
static scm_sizet
freejb (SCM jbsmob)
#else
static scm_sizet static scm_sizet
freejb (jbsmob) freejb (jbsmob)
SCM jbsmob; SCM jbsmob;
#endif
{ {
scm_must_free ((char *) SCM_CDR (jbsmob)); scm_must_free ((char *) SCM_CDR (jbsmob));
return sizeof (scm_cell); return sizeof (scm_cell);
} }
#endif #endif
#ifdef __STDC__ static int printjb SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
static int
printjb (SCM exp, SCM port, scm_print_state *pstate)
#else
static int static int
printjb (exp, port, pstate) printjb (exp, port, pstate)
SCM exp; SCM exp;
SCM port; SCM port;
scm_print_state *pstate; scm_print_state *pstate;
#endif
{ {
scm_gen_puts (scm_regular_string, "#<jmpbuffer ", port); scm_gen_puts (scm_regular_string, "#<jmpbuffer ", port);
scm_gen_puts (scm_regular_string, JBACTIVE(exp) ? "(active) " : "(inactive) ", port); scm_gen_puts (scm_regular_string, JBACTIVE(exp) ? "(active) " : "(inactive) ", port);
@ -119,13 +109,9 @@ static scm_smobfuns jbsmob = {
0 0
}; };
#ifdef __STDC__ static SCM make_jmpbuf SCM_P ((void));
static SCM
make_jmpbuf (void)
#else
static SCM static SCM
make_jmpbuf () make_jmpbuf ()
#endif
{ {
SCM answer; SCM answer;
SCM_NEWCELL (answer); SCM_NEWCELL (answer);
@ -152,16 +138,11 @@ struct jmp_buf_and_retval /* use only on the stack, in scm_catch */
}; };
SCM_PROC(s_catch, "catch", 3, 0, 0, scm_catch); SCM_PROC(s_catch, "catch", 3, 0, 0, scm_catch);
#ifdef __STDC__
SCM
scm_catch (SCM tag, SCM thunk, SCM handler)
#else
SCM SCM
scm_catch (tag, thunk, handler) scm_catch (tag, thunk, handler)
SCM tag; SCM tag;
SCM thunk; SCM thunk;
SCM handler; SCM handler;
#endif
{ {
struct jmp_buf_and_retval jbr; struct jmp_buf_and_retval jbr;
SCM jmpbuf; SCM jmpbuf;
@ -206,17 +187,37 @@ scm_catch (tag, thunk, handler)
} }
/* The user has thrown to an uncaught key --- print a message and die.
1) If the user wants something different, they can use (catch #t
...) to do what they like.
2) Outside the context of a read-eval-print loop, there isn't
anything else good to do; libguile should not assume the existence
of a read-eval-print loop.
3) Given that we shouldn't do anything complex, it's much more
robust to do it in C code. */
static SCM unhandled_throw SCM_P ((SCM key, SCM args));
static SCM
unhandled_throw (key, args)
SCM key;
SCM args;
{
SCM p = scm_def_errp;
scm_gen_puts (scm_regular_string, "guile: uncaught throw to ", p);
scm_prin1 (key, p, 0);
scm_gen_puts (scm_regular_string, ": ", p);
scm_prin1 (args, p, 1);
scm_gen_putc ('\n', p);
exit (2);
}
static char s_throw[]; static char s_throw[];
#ifdef __STDC__
SCM
scm_ithrow (SCM key, SCM args, int noreturn)
#else
SCM SCM
scm_ithrow (key, args, noreturn) scm_ithrow (key, args, noreturn)
SCM key; SCM key;
SCM args; SCM args;
int noreturn; int noreturn;
#endif
{ {
SCM jmpbuf; SCM jmpbuf;
SCM wind_goal; SCM wind_goal;
@ -236,28 +237,36 @@ scm_ithrow (key, args, noreturn)
else else
{ {
SCM dynpair; SCM dynpair;
SCM hook; SCM winds;
if (noreturn) if (noreturn)
{ {
SCM_ASSERT (SCM_NIMP (key) && SCM_SYMBOLP (key), key, SCM_ARG1, s_throw); SCM_ASSERT (SCM_NIMP (key) && SCM_SYMBOLP (key), key, SCM_ARG1,
s_throw);
} }
else if (!(SCM_NIMP (key) && SCM_SYMBOLP (key))) else if (!(SCM_NIMP (key) && SCM_SYMBOLP (key)))
return SCM_UNSPECIFIED; return SCM_UNSPECIFIED;
dynpair = scm_sloppy_assq (key, scm_dynwinds); /* Search the wind list for an appropriate catch.
"Waiter, please bring us the wind list." */
if (dynpair == SCM_BOOL_F) for (winds = scm_dynwinds;
dynpair = scm_sloppy_assq (SCM_BOOL_T, scm_dynwinds); SCM_NIMP (winds) && SCM_CONSP (winds);
winds = SCM_CDR (winds))
hook = SCM_CDR (scm_bad_throw_vcell);
if ((dynpair == SCM_BOOL_F)
&& (SCM_BOOL_T == scm_procedure_p (hook)))
{ {
SCM answer; dynpair = SCM_CAR (winds);
answer = scm_apply (hook, scm_cons (key, args), SCM_EOL); if (SCM_NIMP (winds) && SCM_CONSP (winds))
{
SCM this_key = SCM_CAR (dynpair);
if (this_key == SCM_BOOL_T || this_key == key)
break;
}
} }
/* If we didn't find anything, print a message and exit Guile. */
if (SCM_IMP (winds) || SCM_NCONSP (winds))
unhandled_throw (key, args);
if (dynpair != SCM_BOOL_F) if (dynpair != SCM_BOOL_F)
jmpbuf = SCM_CDR (dynpair); jmpbuf = SCM_CDR (dynpair);
else else
@ -294,31 +303,19 @@ scm_ithrow (key, args, noreturn)
SCM_PROC(s_throw, "throw", 1, 0, 1, scm_throw); SCM_PROC(s_throw, "throw", 1, 0, 1, scm_throw);
#ifdef __STDC__
SCM
scm_throw (SCM key, SCM args)
#else
SCM SCM
scm_throw (key, args) scm_throw (key, args)
SCM key; SCM key;
SCM args; SCM args;
#endif
{ {
scm_ithrow (key, args, 1); scm_ithrow (key, args, 1);
return SCM_BOOL_F; /* never really returns */ return SCM_BOOL_F; /* never really returns */
} }
#ifdef __STDC__
void
scm_init_throw (void)
#else
void void
scm_init_throw () scm_init_throw ()
#endif
{ {
scm_tc16_jmpbuffer = scm_newsmob (&jbsmob); scm_tc16_jmpbuffer = scm_newsmob (&jbsmob);
scm_bad_throw_vcell = scm_sysintern ("%%bad-throw", SCM_BOOL_F);
#include "throw.x" #include "throw.x"
} }