Remove incorrect comment in read.c
[bpt/guile.git] / libguile / weaks.c
CommitLineData
d3464bb6 1/* Copyright (C) 1995,1996,1998,2000,2001, 2003, 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
0f2d19dd 2 *
d3cf93bc 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
d3cf93bc
NJ
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
0f2d19dd 12 *
d3cf93bc
NJ
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
d3cf93bc 17 */
1bbd0b84 18
1bbd0b84 19
0f2d19dd 20\f
dbb605f5
LC
21#ifdef HAVE_CONFIG_H
22# include <config.h>
23#endif
592996c9 24
06c1d900
MV
25#include <stdio.h>
26
a0599745
MD
27#include "libguile/_scm.h"
28#include "libguile/vectors.h"
f59a096e 29#include "libguile/hashtab.h"
0f2d19dd 30
a0599745
MD
31#include "libguile/validate.h"
32#include "libguile/weaks.h"
0f2d19dd 33
1c44468d 34#include "libguile/bdw-gc.h"
986ec822
LC
35#include <gc/gc_typed.h>
36
37
38\f
39/* Weak pairs for use in weak alist vectors and weak hash tables.
40
41 We have weal-car pairs, weak-cdr pairs, and doubly weak pairs. In weak
42 pairs, the weak component(s) are not scanned for pointers and are
43 registered as disapperaring links; therefore, the weak component may be
44 set to NULL by the garbage collector when no other reference to that word
45 exist. Thus, users should only access weak pairs via the
46 `SCM_WEAK_PAIR_C[AD]R ()' macros. See also `scm_fixup_weak_alist ()' in
47 `hashtab.c'. */
48
49/* Type descriptors for weak-c[ad]r pairs. */
50static GC_descr wcar_pair_descr, wcdr_pair_descr;
51
52
53SCM
54scm_weak_car_pair (SCM car, SCM cdr)
55{
56 scm_t_cell *cell;
57
58 cell = (scm_t_cell *)GC_malloc_explicitly_typed (sizeof (*cell),
59 wcar_pair_descr);
60
61 cell->word_0 = car;
62 cell->word_1 = cdr;
63
64 if (SCM_NIMP (car))
d3464bb6
AW
65 /* Weak car cells make sense iff the car is non-immediate. */
66 SCM_I_REGISTER_DISAPPEARING_LINK ((GC_PTR) &cell->word_0,
67 (GC_PTR) SCM2PTR (car));
986ec822
LC
68
69 return (SCM_PACK (cell));
70}
71
72SCM
73scm_weak_cdr_pair (SCM car, SCM cdr)
74{
75 scm_t_cell *cell;
76
77 cell = (scm_t_cell *)GC_malloc_explicitly_typed (sizeof (*cell),
78 wcdr_pair_descr);
79
80 cell->word_0 = car;
81 cell->word_1 = cdr;
82
83 if (SCM_NIMP (cdr))
d3464bb6
AW
84 /* Weak cdr cells make sense iff the cdr is non-immediate. */
85 SCM_I_REGISTER_DISAPPEARING_LINK ((GC_PTR) &cell->word_1,
86 (GC_PTR) SCM2PTR (cdr));
986ec822
LC
87
88 return (SCM_PACK (cell));
89}
90
91SCM
92scm_doubly_weak_pair (SCM car, SCM cdr)
93{
94 /* Doubly weak cells shall not be scanned at all for pointers. */
95 scm_t_cell *cell = (scm_t_cell *)scm_gc_malloc_pointerless (sizeof (*cell),
96 "weak cell");
97
98 cell->word_0 = car;
99 cell->word_1 = cdr;
100
101 if (SCM_NIMP (car))
d3464bb6
AW
102 SCM_I_REGISTER_DISAPPEARING_LINK ((GC_PTR) &cell->word_0,
103 (GC_PTR) SCM2PTR (car));
986ec822 104 if (SCM_NIMP (cdr))
d3464bb6
AW
105 SCM_I_REGISTER_DISAPPEARING_LINK ((GC_PTR) &cell->word_1,
106 (GC_PTR) SCM2PTR (cdr));
986ec822
LC
107
108 return (SCM_PACK (cell));
109}
110
111
592996c9 112\f
0f2d19dd 113
c35738c1
MD
114/* 1. The current hash table implementation in hashtab.c uses weak alist
115 * vectors (formerly called weak hash tables) internally.
116 *
117 * 2. All hash table operations still work on alist vectors.
118 *
119 * 3. The weak vector and alist vector Scheme API is accessed through
120 * the module (ice-9 weak-vector).
121 */
122
123
0f2d19dd
JB
124/* {Weak Vectors}
125 */
126
127
3b3b36dd 128SCM_DEFINE (scm_make_weak_vector, "make-weak-vector", 1, 1, 0,
1e6808ea 129 (SCM size, SCM fill),
b380b885 130 "Return a weak vector with @var{size} elements. If the optional\n"
1e6808ea
MG
131 "argument @var{fill} is given, all entries in the vector will be\n"
132 "set to @var{fill}. The default value for @var{fill} is the\n"
133 "empty list.")
1bbd0b84 134#define FUNC_NAME s_scm_make_weak_vector
0f2d19dd 135{
d525e4f9 136 return scm_i_make_weak_vector (0, size, fill);
0f2d19dd 137}
1bbd0b84 138#undef FUNC_NAME
0f2d19dd
JB
139
140
1bbd0b84 141SCM_REGISTER_PROC(s_list_to_weak_vector, "list->weak-vector", 1, 0, 0, scm_weak_vector);
1cc91f1b 142
3b3b36dd 143SCM_DEFINE (scm_weak_vector, "weak-vector", 0, 0, 1,
1bbd0b84 144 (SCM l),
8f85c0c6 145 "@deffnx {Scheme Procedure} list->weak-vector l\n"
1e6808ea
MG
146 "Construct a weak vector from a list: @code{weak-vector} uses\n"
147 "the list of its arguments while @code{list->weak-vector} uses\n"
148 "its only argument @var{l} (a list) to construct a weak vector\n"
149 "the same way @code{list->vector} would.")
1bbd0b84 150#define FUNC_NAME s_scm_weak_vector
0f2d19dd 151{
d525e4f9 152 return scm_i_make_weak_vector_from_list (0, l);
0f2d19dd 153}
1bbd0b84 154#undef FUNC_NAME
0f2d19dd
JB
155
156
3b3b36dd 157SCM_DEFINE (scm_weak_vector_p, "weak-vector?", 1, 0, 0,
1e6808ea 158 (SCM obj),
5352393c
MG
159 "Return @code{#t} if @var{obj} is a weak vector. Note that all\n"
160 "weak hashes are also weak vectors.")
1bbd0b84 161#define FUNC_NAME s_scm_weak_vector_p
0f2d19dd 162{
6e708ef2 163 return scm_from_bool (SCM_I_WVECTP (obj) && !SCM_IS_WHVEC (obj));
0f2d19dd 164}
1bbd0b84 165#undef FUNC_NAME
0f2d19dd 166
0f2d19dd 167\f
3a2de079
LC
168/* Weak alist vectors, i.e., vectors of alists.
169
170 The alist vector themselves are _not_ weak. The `car' (or `cdr', or both)
171 of the pairs within it are weak. See `hashtab.c' for details. */
0f2d19dd 172
4650cdd2
LC
173
174/* FIXME: We used to have two implementations of weak hash tables: the one in
175 here and the one in `hashtab.c'. The difference is that weak alist
176 vectors could be used as vectors while (weak) hash tables can't. We need
177 to unify that. */
178
c35738c1 179SCM_DEFINE (scm_make_weak_key_alist_vector, "make-weak-key-alist-vector", 0, 1, 0,
1e6808ea 180 (SCM size),
c35738c1
MD
181 "@deffnx {Scheme Procedure} make-weak-value-alist-vector size\n"
182 "@deffnx {Scheme Procedure} make-doubly-weak-alist-vector size\n"
1e6808ea
MG
183 "Return a weak hash table with @var{size} buckets. As with any\n"
184 "hash table, choosing a good size for the table requires some\n"
185 "caution.\n"
186 "\n"
187 "You can modify weak hash tables in exactly the same way you\n"
188 "would modify regular hash tables. (@pxref{Hash Tables})")
c35738c1 189#define FUNC_NAME s_scm_make_weak_key_alist_vector
0f2d19dd 190{
4650cdd2 191 return scm_make_weak_key_hash_table (size);
0f2d19dd 192}
1bbd0b84 193#undef FUNC_NAME
0f2d19dd
JB
194
195
c35738c1 196SCM_DEFINE (scm_make_weak_value_alist_vector, "make-weak-value-alist-vector", 0, 1, 0,
1e6808ea 197 (SCM size),
e3239868
DH
198 "Return a hash table with weak values with @var{size} buckets.\n"
199 "(@pxref{Hash Tables})")
c35738c1 200#define FUNC_NAME s_scm_make_weak_value_alist_vector
0f2d19dd 201{
4650cdd2 202 return scm_make_weak_value_hash_table (size);
0f2d19dd 203}
1bbd0b84 204#undef FUNC_NAME
0f2d19dd
JB
205
206
c35738c1 207SCM_DEFINE (scm_make_doubly_weak_alist_vector, "make-doubly-weak-alist-vector", 1, 0, 0,
1e6808ea 208 (SCM size),
e3239868
DH
209 "Return a hash table with weak keys and values with @var{size}\n"
210 "buckets. (@pxref{Hash Tables})")
c35738c1 211#define FUNC_NAME s_scm_make_doubly_weak_alist_vector
0f2d19dd 212{
b6ed39c4 213 return scm_make_doubly_weak_hash_table (size);
0f2d19dd 214}
1bbd0b84 215#undef FUNC_NAME
0f2d19dd 216
592996c9 217
c35738c1 218SCM_DEFINE (scm_weak_key_alist_vector_p, "weak-key-alist-vector?", 1, 0, 0,
1e6808ea 219 (SCM obj),
c35738c1
MD
220 "@deffnx {Scheme Procedure} weak-value-alist-vector? obj\n"
221 "@deffnx {Scheme Procedure} doubly-weak-alist-vector? obj\n"
5352393c
MG
222 "Return @code{#t} if @var{obj} is the specified weak hash\n"
223 "table. Note that a doubly weak hash table is neither a weak key\n"
224 "nor a weak value hash table.")
c35738c1 225#define FUNC_NAME s_scm_weak_key_alist_vector_p
0f2d19dd 226{
6e708ef2 227 return scm_from_bool (SCM_I_WVECTP (obj) && SCM_IS_WHVEC (obj));
0f2d19dd 228}
1bbd0b84 229#undef FUNC_NAME
0f2d19dd
JB
230
231
c35738c1 232SCM_DEFINE (scm_weak_value_alist_vector_p, "weak-value-alist-vector?", 1, 0, 0,
1e6808ea
MG
233 (SCM obj),
234 "Return @code{#t} if @var{obj} is a weak value hash table.")
c35738c1 235#define FUNC_NAME s_scm_weak_value_alist_vector_p
0f2d19dd 236{
6e708ef2 237 return scm_from_bool (SCM_I_WVECTP (obj) && SCM_IS_WHVEC_V (obj));
0f2d19dd 238}
1bbd0b84 239#undef FUNC_NAME
0f2d19dd
JB
240
241
c35738c1 242SCM_DEFINE (scm_doubly_weak_alist_vector_p, "doubly-weak-alist-vector?", 1, 0, 0,
1e6808ea
MG
243 (SCM obj),
244 "Return @code{#t} if @var{obj} is a doubly weak hash table.")
c35738c1 245#define FUNC_NAME s_scm_doubly_weak_alist_vector_p
0f2d19dd 246{
6e708ef2 247 return scm_from_bool (SCM_I_WVECTP (obj) && SCM_IS_WHVEC_B (obj));
0f2d19dd 248}
1bbd0b84 249#undef FUNC_NAME
0f2d19dd 250
592996c9 251
592996c9 252
06c1d900 253\f
c35738c1
MD
254SCM
255scm_init_weaks_builtins ()
256{
257#include "libguile/weaks.x"
258 return SCM_UNSPECIFIED;
259}
260
986ec822
LC
261void
262scm_weaks_prehistory ()
263{
264 /* Initialize weak pairs. */
265 GC_word wcar_pair_bitmap[GC_BITMAP_SIZE (scm_t_cell)] = { 0 };
266 GC_word wcdr_pair_bitmap[GC_BITMAP_SIZE (scm_t_cell)] = { 0 };
267
268 /* In a weak-car pair, only the second word must be scanned for
269 pointers. */
270 GC_set_bit (wcar_pair_bitmap, GC_WORD_OFFSET (scm_t_cell, word_1));
271 wcar_pair_descr = GC_make_descriptor (wcar_pair_bitmap,
272 GC_WORD_LEN (scm_t_cell));
273
274 /* Conversely, in a weak-cdr pair, only the first word must be scanned for
275 pointers. */
276 GC_set_bit (wcdr_pair_bitmap, GC_WORD_OFFSET (scm_t_cell, word_0));
277 wcdr_pair_descr = GC_make_descriptor (wcdr_pair_bitmap,
278 GC_WORD_LEN (scm_t_cell));
279
280}
281
0f2d19dd
JB
282void
283scm_init_weaks ()
0f2d19dd 284{
c35738c1
MD
285 scm_c_define_gsubr ("%init-weaks-builtins", 0, 0, 0,
286 scm_init_weaks_builtins);
0f2d19dd
JB
287}
288
89e00824
ML
289
290/*
291 Local Variables:
292 c-file-style: "gnu"
293 End:
294*/