Commit | Line | Data |
---|---|---|
9ede013f AW |
1 | /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003, 2004, 2006, 2008, 2010, 2011, 2012 Free Software Foundation, Inc. |
2 | * | |
73be1d9e | 3 | * This library is free software; you can redistribute it and/or |
53befeb7 NJ |
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. | |
0f2d19dd | 7 | * |
53befeb7 NJ |
8 | * This library is distributed in the hope that it will be useful, but |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
73be1d9e MV |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | * Lesser General Public License for more details. | |
0f2d19dd | 12 | * |
73be1d9e MV |
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 | |
53befeb7 NJ |
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
16 | * 02110-1301 USA | |
73be1d9e | 17 | */ |
1bbd0b84 | 18 | |
1bbd0b84 | 19 | |
0f2d19dd JB |
20 | \f |
21 | ||
dbb605f5 LC |
22 | #ifdef HAVE_CONFIG_H |
23 | # include <config.h> | |
24 | #endif | |
25 | ||
4845bbae MV |
26 | #include <assert.h> |
27 | ||
a0599745 | 28 | #include "libguile/_scm.h" |
9ede013f | 29 | #include "libguile/dynstack.h" |
a0599745 | 30 | #include "libguile/eval.h" |
a0599745 | 31 | #include "libguile/ports.h" |
0f2d19dd | 32 | |
a0599745 | 33 | #include "libguile/dynwind.h" |
0f2d19dd JB |
34 | |
35 | ||
9ede013f | 36 | \f |
0f2d19dd | 37 | |
d69531e2 AW |
38 | SCM |
39 | scm_dynamic_wind (SCM in_guard, SCM thunk, SCM out_guard) | |
40 | #define FUNC_NAME "dynamic-wind" | |
0f2d19dd | 41 | { |
9ede013f AW |
42 | SCM ans; |
43 | scm_i_thread *thread = SCM_I_CURRENT_THREAD; | |
44 | ||
45 | SCM_ASSERT (scm_is_true (scm_thunk_p (out_guard)), out_guard, | |
1bbd0b84 | 46 | SCM_ARG3, FUNC_NAME); |
9ede013f | 47 | |
fdc28395 | 48 | scm_call_0 (in_guard); |
9ede013f AW |
49 | scm_dynstack_push_dynwind (&thread->dynstack, in_guard, out_guard); |
50 | ||
fdc28395 | 51 | ans = scm_call_0 (thunk); |
9ede013f AW |
52 | |
53 | scm_dynstack_pop (&thread->dynstack); | |
fdc28395 | 54 | scm_call_0 (out_guard); |
9ede013f | 55 | |
0f2d19dd JB |
56 | return ans; |
57 | } | |
1bbd0b84 | 58 | #undef FUNC_NAME |
0f2d19dd | 59 | |
4845bbae MV |
60 | |
61 | void | |
98241dc5 | 62 | scm_dynwind_begin (scm_t_dynwind_flags flags) |
4845bbae | 63 | { |
9ede013f AW |
64 | scm_i_thread *thread = SCM_I_CURRENT_THREAD; |
65 | ||
66 | scm_dynstack_push_frame (&thread->dynstack, flags); | |
4845bbae MV |
67 | } |
68 | ||
69 | void | |
661ae7ab | 70 | scm_dynwind_end (void) |
4845bbae | 71 | { |
9ede013f | 72 | scm_dynstack_unwind_frame (&SCM_I_CURRENT_THREAD->dynstack); |
4845bbae MV |
73 | } |
74 | ||
75 | void | |
98241dc5 NJ |
76 | scm_dynwind_unwind_handler (void (*proc) (void *), void *data, |
77 | scm_t_wind_flags flags) | |
4845bbae | 78 | { |
9ede013f AW |
79 | scm_i_thread *thread = SCM_I_CURRENT_THREAD; |
80 | scm_t_dynstack *dynstack = &thread->dynstack; | |
81 | ||
82 | scm_dynstack_push_unwinder (dynstack, flags, proc, data); | |
4845bbae MV |
83 | } |
84 | ||
85 | void | |
98241dc5 NJ |
86 | scm_dynwind_rewind_handler (void (*proc) (void *), void *data, |
87 | scm_t_wind_flags flags) | |
4845bbae | 88 | { |
9ede013f AW |
89 | scm_i_thread *thread = SCM_I_CURRENT_THREAD; |
90 | scm_t_dynstack *dynstack = &thread->dynstack; | |
91 | ||
92 | scm_dynstack_push_rewinder (dynstack, 0, proc, data); | |
93 | ||
a520e4f0 MV |
94 | if (flags & SCM_F_WIND_EXPLICITLY) |
95 | proc (data); | |
96 | } | |
97 | ||
98 | void | |
98241dc5 NJ |
99 | scm_dynwind_unwind_handler_with_scm (void (*proc) (SCM), SCM data, |
100 | scm_t_wind_flags flags) | |
a520e4f0 | 101 | { |
9ede013f AW |
102 | /* FIXME: This is not a safe cast. */ |
103 | scm_dynwind_unwind_handler ((scm_t_guard) proc, SCM2PTR (data), flags); | |
a520e4f0 MV |
104 | } |
105 | ||
106 | void | |
98241dc5 NJ |
107 | scm_dynwind_rewind_handler_with_scm (void (*proc) (SCM), SCM data, |
108 | scm_t_wind_flags flags) | |
a520e4f0 | 109 | { |
9ede013f AW |
110 | /* FIXME: This is not a safe cast. */ |
111 | scm_dynwind_rewind_handler ((scm_t_guard) proc, SCM2PTR (data), flags); | |
4845bbae MV |
112 | } |
113 | ||
6d5649b7 | 114 | void |
661ae7ab | 115 | scm_dynwind_free (void *mem) |
6d5649b7 | 116 | { |
661ae7ab | 117 | scm_dynwind_unwind_handler (free, mem, SCM_F_WIND_EXPLICITLY); |
6d5649b7 MV |
118 | } |
119 | ||
2e171178 | 120 | void |
904a077d | 121 | scm_swap_bindings (SCM vars, SCM vals) |
6778caf9 MD |
122 | { |
123 | SCM tmp; | |
62fdadb0 | 124 | while (scm_is_pair (vals)) |
6778caf9 | 125 | { |
904a077d MV |
126 | tmp = SCM_VARIABLE_REF (SCM_CAR (vars)); |
127 | SCM_VARIABLE_SET (SCM_CAR (vars), SCM_CAR (vals)); | |
6778caf9 | 128 | SCM_SETCAR (vals, tmp); |
904a077d | 129 | vars = SCM_CDR (vars); |
6778caf9 MD |
130 | vals = SCM_CDR (vals); |
131 | } | |
132 | } | |
c2654ef0 | 133 | |
0f2d19dd JB |
134 | void |
135 | scm_init_dynwind () | |
0f2d19dd | 136 | { |
a0599745 | 137 | #include "libguile/dynwind.x" |
0f2d19dd | 138 | } |
89e00824 ML |
139 | |
140 | /* | |
141 | Local Variables: | |
142 | c-file-style: "gnu" | |
143 | End: | |
144 | */ |