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:
parent
b59b97ba3a
commit
32f7b3a1b1
1 changed files with 50 additions and 53 deletions
103
libguile/throw.c
103
libguile/throw.c
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue