summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2010-03-04 11:37:03 +0100
committerAndy Wingo <wingo@pobox.com>2010-03-04 13:14:43 +0100
commit2b2746a831b5f74773d6eec91d2c30d43831e826 (patch)
tree0bc8698bfb45292a7ba9d4b33601fc27e228dfc9
parentbbb2ecd1d1966766aa5f3fed7d5084b46cf1e8a7 (diff)
tighten up scm_i_dowinds, fixing invalid SCM_CAR (prompt)
* libguile/dynwind.c: Update comment regarding what can be on the wind stack. (scm_i_dowinds): Clean up to remove @bind and catch/throw-handler cases, to add a case for prompts, and to be more strict in general regarding the set of things that can be on the wind stack. Fixes a bug whereby prompts were accessed via SCM_CAR; thanks to Ken Raeburn for the report.
-rw-r--r--libguile/dynwind.c47
1 files changed, 15 insertions, 32 deletions
diff --git a/libguile/dynwind.c b/libguile/dynwind.c
index 18e38b995..f4d19bd0a 100644
--- a/libguile/dynwind.c
+++ b/libguile/dynwind.c
@@ -26,6 +26,7 @@
#include <assert.h>
#include "libguile/_scm.h"
+#include "libguile/control.h"
#include "libguile/eval.h"
#include "libguile/alist.h"
#include "libguile/fluids.h"
@@ -41,10 +42,9 @@
#<frame>
#<winder>
+ #<with-fluids>
+ #<prompt>
(enter-proc . leave-proc) dynamic-wind
- (tag . jmpbuf) catch
- (tag . pre-unwind-data) throw-handler / lazy-catch
- tag is either a symbol or a boolean
*/
@@ -240,7 +240,6 @@ scm_i_dowinds (SCM to, long delta, void (*turn_func) (void *), void *data)
else if (delta < 0)
{
SCM wind_elt;
- SCM wind_key;
scm_i_dowinds (SCM_CDR (to), 1 + delta, turn_func, data);
wind_elt = SCM_CAR (to);
@@ -262,21 +261,13 @@ scm_i_dowinds (SCM to, long delta, void (*turn_func) (void *), void *data)
scm_i_swap_with_fluids (wind_elt,
SCM_I_CURRENT_THREAD->dynamic_state);
}
+ else if (SCM_PROMPT_P (wind_elt))
+ ; /* pass -- see vm_reinstate_partial_continuation */
+ else if (scm_is_pair (wind_elt))
+ scm_call_0 (SCM_CAR (wind_elt));
else
- {
- wind_key = SCM_CAR (wind_elt);
- /* key = #t | symbol | thunk | list of variables */
- if (SCM_NIMP (wind_key))
- {
- if (scm_is_pair (wind_key))
- {
- if (SCM_VARIABLEP (SCM_CAR (wind_key)))
- scm_swap_bindings (wind_key, SCM_CDR (wind_elt));
- }
- else if (scm_is_true (scm_thunk_p (wind_key)))
- scm_call_0 (wind_key);
- }
- }
+ /* trash on the wind list */
+ abort ();
scm_i_set_dynwinds (to);
}
@@ -284,7 +275,6 @@ scm_i_dowinds (SCM to, long delta, void (*turn_func) (void *), void *data)
{
SCM wind;
SCM wind_elt;
- SCM wind_key;
wind = scm_i_dynwinds ();
wind_elt = SCM_CAR (wind);
@@ -304,20 +294,13 @@ scm_i_dowinds (SCM to, long delta, void (*turn_func) (void *), void *data)
scm_i_swap_with_fluids (wind_elt,
SCM_I_CURRENT_THREAD->dynamic_state);
}
+ else if (SCM_PROMPT_P (wind_elt))
+ ; /* pass -- though we could invalidate the prompt */
+ else if (scm_is_pair (wind_elt))
+ scm_call_0 (SCM_CDR (wind_elt));
else
- {
- wind_key = SCM_CAR (wind_elt);
- if (SCM_NIMP (wind_key))
- {
- if (scm_is_pair (wind_key))
- {
- if (SCM_VARIABLEP (SCM_CAR (wind_key)))
- scm_swap_bindings (wind_key, SCM_CDR (wind_elt));
- }
- else if (scm_is_true (scm_thunk_p (wind_key)))
- scm_call_0 (SCM_CDR (wind_elt));
- }
- }
+ /* trash on the wind list */
+ abort ();
delta--;
goto tail; /* scm_dowinds(to, delta-1); */