summaryrefslogtreecommitdiff
path: root/libguile/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/eval.c')
-rw-r--r--libguile/eval.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/libguile/eval.c b/libguile/eval.c
index d9129dcbc..1869051f0 100644
--- a/libguile/eval.c
+++ b/libguile/eval.c
@@ -1158,6 +1158,34 @@ scm_eval_args (l, env)
}
return res;
}
+
+
+/* The SCM_CEVAL and SCM_APPLY functions use this function instead of
+ calling setjmp directly, to make sure that local variables don't
+ have their values clobbered by a longjmp.
+
+ According to Harbison & Steele, "Automatic variables local to the
+ function containing setjmp are guaranteed to have their correct
+ value in ANSI C only if they have a volatile-qualified type or if
+ their values were not changed between the original call to setjmp
+ and the corresponding longjmp call."
+
+ SCM_CEVAL and SCM_APPLY are too complex for me to see how to meet
+ the second condition, and making x and env volatile would be a
+ speed problem, so we'll just trivially meet the first, by having no
+ "automatic variables local to the function containing setjmp." */
+static int
+safe_setjmp (jmp_buf env)
+{
+ /* I think ANSI requires us to write the function this way, instead
+ of just saying "return setjmp (env)". Maybe I'm being silly.
+ See Harbison & Steele, third edition, p. 353. */
+ int val;
+ val = setjmp (env);
+ return val;
+}
+
+
#endif /* !DEVAL */
@@ -1204,7 +1232,7 @@ scm_eval_args (l, env)
else\
{\
scm_make_cont (&tmp);\
- if (!setjmp (SCM_JMPBUF (tmp)))\
+ if (!safe_setjmp (SCM_JMPBUF (tmp)))\
scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
}\
}\
@@ -1371,7 +1399,7 @@ loop:
SCM_RESET_DEBUG_MODE;
SCM_CLEAR_TRACED_FRAME (debug);
scm_make_cont (&t.arg1);
- if (!setjmp (SCM_JMPBUF (t.arg1)))
+ if (!safe_setjmp (SCM_JMPBUF (t.arg1)))
scm_ithrow (scm_i_exit_tail, scm_cons (t.arg1, SCM_EOL), 0);
}
}
@@ -1400,7 +1428,7 @@ start:
else
{
scm_make_cont (&t.arg1);
- if (setjmp (SCM_JMPBUF (t.arg1)))
+ if (safe_setjmp (SCM_JMPBUF (t.arg1)))
{
x = SCM_THROW_VALUE (t.arg1);
if (SCM_IMP (x))
@@ -1726,7 +1754,7 @@ dispatch:
case (SCM_ISYMNUM (SCM_IM_CONT)):
scm_make_cont (&t.arg1);
- if (setjmp (SCM_JMPBUF (t.arg1)))
+ if (safe_setjmp (SCM_JMPBUF (t.arg1)))
{
SCM val;
val = SCM_THROW_VALUE (t.arg1);
@@ -2185,7 +2213,7 @@ exit:
else
{
scm_make_cont (&t.arg1);
- if (setjmp (SCM_JMPBUF (t.arg1)))
+ if (safe_setjmp (SCM_JMPBUF (t.arg1)))
{
proc = SCM_THROW_VALUE (t.arg1);
goto ret;
@@ -2345,7 +2373,7 @@ SCM_APPLY (proc, arg1, args)
else
{
scm_make_cont (&tmp);
- if (setjmp (SCM_JMPBUF (tmp)))
+ if (safe_setjmp (SCM_JMPBUF (tmp)))
goto entap;
}
scm_ithrow (scm_i_enter_frame, scm_cons (tmp, SCM_EOL), 0);
@@ -2492,7 +2520,7 @@ exit:
else
{
scm_make_cont (&arg1);
- if (setjmp (SCM_JMPBUF (arg1)))
+ if (safe_setjmp (SCM_JMPBUF (arg1)))
{
proc = SCM_THROW_VALUE (arg1);
goto ret;