1 /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003, 2004, 2006, 2008, 2010, 2011, 2012 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 #include "libguile/_scm.h"
29 #include "libguile/dynstack.h"
30 #include "libguile/eval.h"
31 #include "libguile/ports.h"
33 #include "libguile/dynwind.h"
39 scm_dynamic_wind (SCM in_guard
, SCM thunk
, SCM out_guard
)
40 #define FUNC_NAME "dynamic-wind"
43 scm_i_thread
*thread
= SCM_I_CURRENT_THREAD
;
45 SCM_ASSERT (scm_is_true (scm_thunk_p (out_guard
)), out_guard
,
48 scm_call_0 (in_guard
);
49 scm_dynstack_push_dynwind (&thread
->dynstack
, in_guard
, out_guard
);
51 ans
= scm_call_0 (thunk
);
53 scm_dynstack_pop (&thread
->dynstack
);
54 scm_call_0 (out_guard
);
62 scm_dynwind_begin (scm_t_dynwind_flags flags
)
64 scm_i_thread
*thread
= SCM_I_CURRENT_THREAD
;
66 scm_dynstack_push_frame (&thread
->dynstack
, flags
);
70 scm_dynwind_end (void)
72 scm_dynstack_unwind_frame (&SCM_I_CURRENT_THREAD
->dynstack
);
76 scm_dynwind_unwind_handler (void (*proc
) (void *), void *data
,
77 scm_t_wind_flags flags
)
79 scm_i_thread
*thread
= SCM_I_CURRENT_THREAD
;
80 scm_t_dynstack
*dynstack
= &thread
->dynstack
;
82 scm_dynstack_push_unwinder (dynstack
, flags
, proc
, data
);
86 scm_dynwind_rewind_handler (void (*proc
) (void *), void *data
,
87 scm_t_wind_flags flags
)
89 scm_i_thread
*thread
= SCM_I_CURRENT_THREAD
;
90 scm_t_dynstack
*dynstack
= &thread
->dynstack
;
92 scm_dynstack_push_rewinder (dynstack
, 0, proc
, data
);
94 if (flags
& SCM_F_WIND_EXPLICITLY
)
99 scm_dynwind_unwind_handler_with_scm (void (*proc
) (SCM
), SCM data
,
100 scm_t_wind_flags flags
)
102 /* FIXME: This is not a safe cast. */
103 scm_dynwind_unwind_handler ((scm_t_guard
) proc
, SCM2PTR (data
), flags
);
107 scm_dynwind_rewind_handler_with_scm (void (*proc
) (SCM
), SCM data
,
108 scm_t_wind_flags flags
)
110 /* FIXME: This is not a safe cast. */
111 scm_dynwind_rewind_handler ((scm_t_guard
) proc
, SCM2PTR (data
), flags
);
115 scm_dynwind_free (void *mem
)
117 scm_dynwind_unwind_handler (free
, mem
, SCM_F_WIND_EXPLICITLY
);
121 scm_swap_bindings (SCM vars
, SCM vals
)
124 while (scm_is_pair (vals
))
126 tmp
= SCM_VARIABLE_REF (SCM_CAR (vars
));
127 SCM_VARIABLE_SET (SCM_CAR (vars
), SCM_CAR (vals
));
128 SCM_SETCAR (vals
, tmp
);
129 vars
= SCM_CDR (vars
);
130 vals
= SCM_CDR (vals
);
137 #include "libguile/dynwind.x"