Merge branch 'master' of ssh://civodul@git.sv.gnu.org/srv/git/guile
[bpt/guile.git] / libguile / inline.h
CommitLineData
16ea9620
MV
1/* classes: h_files */
2
3#ifndef SCM_INLINE_H
4#define SCM_INLINE_H
5
3f520967 6/* Copyright (C) 2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, Inc.
16ea9620 7 *
73be1d9e
MV
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
16ea9620 12 *
73be1d9e 13 * This library is distributed in the hope that it will be useful,
16ea9620 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
16ea9620 17 *
73be1d9e
MV
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
92205699 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
73be1d9e 21 */
16ea9620
MV
22
23/* This file is for inline functions. On platforms that don't support
24 inlining functions, they are turned into ordinary functions. See
25 "inline.c".
26*/
27
60e7529a 28#include "libguile/__scm.h"
c8a1bdc4 29
1e71eafb
HWN
30#if (SCM_DEBUG_CELL_ACCESSES == 1)
31#include <stdio.h>
1e71eafb
HWN
32#endif
33
16ea9620
MV
34#include "libguile/pairs.h"
35#include "libguile/gc.h"
9bc4701c 36#include "libguile/threads.h"
9598a406 37#include "libguile/unif.h"
d5ad4aa6 38#include "libguile/pairs.h"
16ea9620 39
c8a1bdc4 40
979eade6
LC
41#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
42
43/* GCC has `__inline__' in all modes, including strict ansi. GCC 4.3 and
44 above with `-std=c99' or `-std=gnu99' implements ISO C99 inline semantics,
45 unless `-fgnu89-inline' is used. Here we want GNU "extern inline"
46 semantics, hence the `__gnu_inline__' attribute, in accordance with:
47 http://gcc.gnu.org/gcc-4.3/porting_to.html .
48
49 With GCC 4.2, `__GNUC_STDC_INLINE__' is never defined (because C99 inline
50 semantics are not supported), but a warning is issued in C99 mode if
7dc9ae71 51 `__gnu_inline__' is not used.
979eade6 52
7dc9ae71
LC
53 Apple's GCC build >5400 (since Xcode 3.0) doesn't support GNU inline in
54 C99 mode and doesn't define `__GNUC_STDC_INLINE__'. Fall back to "static
55 inline" in that case. */
56
57# if (defined __GNUC__) && (!(__APPLE_CC__ > 5400 && __STDC_VERSION__ >= 199901L))
07db6fcd 58# define SCM_C_USE_EXTERN_INLINE 1
979eade6
LC
59# if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2)
60# define SCM_C_EXTERN_INLINE \
61 extern __inline__ __attribute__ ((__gnu_inline__))
62# else
63# define SCM_C_EXTERN_INLINE extern __inline__
64# endif
65# elif (defined SCM_C_INLINE)
66# define SCM_C_EXTERN_INLINE static SCM_C_INLINE
67# endif
68
69#endif /* SCM_INLINE_C_INCLUDING_INLINE_H */
70
71
07db6fcd
LC
72#if (!defined SCM_C_INLINE) || (defined SCM_INLINE_C_INCLUDING_INLINE_H) \
73 || (defined SCM_C_USE_EXTERN_INLINE)
3f520967
LC
74
75/* The `extern' declarations. They should only appear when used from
07db6fcd
LC
76 "inline.c", when `inline' is not supported at all or when "extern inline"
77 is used. */
3f520967 78
c8a1bdc4
HWN
79SCM_API SCM scm_cell (scm_t_bits car, scm_t_bits cdr);
80SCM_API SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr,
81 scm_t_bits ccr, scm_t_bits cdr);
82
9598a406
MV
83SCM_API SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t pos);
84SCM_API void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val);
16ea9620 85
3f520967
LC
86SCM_API int scm_is_pair (SCM x);
87
88#endif
89
60e7529a 90
9dca8935 91#if defined SCM_C_EXTERN_INLINE || defined SCM_INLINE_C_INCLUDING_INLINE_H
60e7529a
RB
92/* either inlining, or being included from inline.c. We use (and
93 repeat) this long #if test here and below so that we don't have to
94 introduce any extraneous symbols into the public namespace. We
95 only need SCM_C_INLINE to be seen publically . */
c8a1bdc4
HWN
96
97extern unsigned scm_newcell2_count;
98extern unsigned scm_newcell_count;
99
979eade6 100
9dca8935 101#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
979eade6 102SCM_C_EXTERN_INLINE
60e7529a 103#endif
c8a1bdc4 104SCM
228a24ef 105scm_cell (scm_t_bits car, scm_t_bits cdr)
16ea9620
MV
106{
107 SCM z;
9bc4701c 108 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist);
16ea9620 109
d2e53ed6 110 if (scm_is_null (*freelist))
9bc4701c 111 z = scm_gc_for_newcell (&scm_i_master_freelist, freelist);
c8a1bdc4 112 else
16ea9620 113 {
9bc4701c
MD
114 z = *freelist;
115 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620 116 }
c8a1bdc4
HWN
117
118 /*
119 We update scm_cells_allocated from this function. If we don't
120 update this explicitly, we will have to walk a freelist somewhere
121 later on, which seems a lot more expensive.
122 */
123 scm_cells_allocated += 1;
124
125#if (SCM_DEBUG_CELL_ACCESSES == 1)
126 if (scm_debug_cell_accesses_p)
1e71eafb
HWN
127 {
128 if (SCM_GC_MARK_P (z))
129 {
130 fprintf(stderr, "scm_cell tried to allocate a marked cell.\n");
131 abort();
132 }
6b69393d 133 else if (SCM_GC_CELL_WORD(z, 0) != scm_tc_free_cell)
1e71eafb
HWN
134 {
135 fprintf(stderr, "cell from freelist is not a free cell.\n");
136 abort();
137 }
138 }
139
140 /*
141 Always set mark. Otherwise cells that are alloced before
142 scm_debug_cell_accesses_p is toggled seem invalid.
143 */
144 SCM_SET_GC_MARK (z);
145
146 /*
147 TODO: figure out if this use of mark bits is valid with
148 threading. What if another thread is doing GC at this point
149 ... ?
150 */
c8a1bdc4 151
c8a1bdc4 152#endif
16ea9620 153
c8a1bdc4 154
16ea9620
MV
155 /* Initialize the type slot last so that the cell is ignored by the
156 GC until it is completely initialized. This is only relevant
b2a339f6
MV
157 when the GC can actually run during this code, which it can't
158 since the GC only runs when all other threads are stopped.
16ea9620 159 */
1fc8902f
DH
160 SCM_GC_SET_CELL_WORD (z, 1, cdr);
161 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 162
eab1b259
HWN
163#if (SCM_DEBUG_CELL_ACCESSES == 1)
164 if (scm_expensive_debug_cell_accesses_p )
165 scm_i_expensive_validation_check (z);
166#endif
c8a1bdc4 167
16ea9620
MV
168 return z;
169}
170
9dca8935 171#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
979eade6 172SCM_C_EXTERN_INLINE
60e7529a 173#endif
c8a1bdc4 174SCM
228a24ef
DH
175scm_double_cell (scm_t_bits car, scm_t_bits cbr,
176 scm_t_bits ccr, scm_t_bits cdr)
16ea9620 177{
5e1e20c8
MV
178 SCM z;
179 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist2);
180
d2e53ed6 181 if (scm_is_null (*freelist))
9bc4701c 182 z = scm_gc_for_newcell (&scm_i_master_freelist2, freelist);
16ea9620
MV
183 else
184 {
9bc4701c
MD
185 z = *freelist;
186 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620
MV
187 }
188
c8a1bdc4
HWN
189 scm_cells_allocated += 2;
190
16ea9620
MV
191 /* Initialize the type slot last so that the cell is ignored by the
192 GC until it is completely initialized. This is only relevant
b2a339f6
MV
193 when the GC can actually run during this code, which it can't
194 since the GC only runs when all other threads are stopped.
16ea9620 195 */
1fc8902f
DH
196 SCM_GC_SET_CELL_WORD (z, 1, cbr);
197 SCM_GC_SET_CELL_WORD (z, 2, ccr);
198 SCM_GC_SET_CELL_WORD (z, 3, cdr);
199 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 200
c8a1bdc4
HWN
201#if (SCM_DEBUG_CELL_ACCESSES == 1)
202 if (scm_debug_cell_accesses_p)
203 {
204 if (SCM_GC_MARK_P (z))
205 {
206 fprintf(stderr,
207 "scm_double_cell tried to allocate a marked cell.\n");
208 abort();
209 }
c8a1bdc4 210 }
4ad0814a
HWN
211
212 /* see above. */
213 SCM_SET_GC_MARK (z);
214
3553e1d1
GH
215#endif
216
217 /* When this function is inlined, it's possible that the last
218 SCM_GC_SET_CELL_WORD above will be adjacent to a following
219 initialization of z. E.g., it occurred in scm_make_real. GCC
220 from around version 3 (e.g., certainly 3.2) began taking
221 advantage of strict C aliasing rules which say that it's OK to
222 interchange the initialization above and the one below when the
223 pointer types appear to differ sufficiently. We don't want that,
224 of course. GCC allows this behaviour to be disabled with the
225 -fno-strict-aliasing option, but would also need to be supplied
226 by Guile users. Instead, the following statements prevent the
227 reordering.
228 */
229#ifdef __GNUC__
cb975c21 230 __asm__ volatile ("" : : : "memory");
3553e1d1
GH
231#else
232 /* portable version, just in case any other compiler does the same
233 thing. */
234 scm_remember_upto_here_1 (z);
c8a1bdc4 235#endif
6253f3f1 236
c8a1bdc4
HWN
237 return z;
238}
6253f3f1 239
9dca8935 240#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
979eade6 241SCM_C_EXTERN_INLINE
9598a406
MV
242#endif
243SCM
244scm_array_handle_ref (scm_t_array_handle *h, ssize_t p)
245{
246 return h->ref (h, p);
247}
eab1b259 248
9dca8935 249#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
979eade6 250SCM_C_EXTERN_INLINE
9598a406
MV
251#endif
252void
253scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v)
254{
255 h->set (h, p, v);
256}
eab1b259 257
9dca8935 258#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
979eade6 259SCM_C_EXTERN_INLINE
d5ad4aa6
MV
260#endif
261int
262scm_is_pair (SCM x)
263{
23f2b9a3
KR
264 /* The following "workaround_for_gcc_295" avoids bad code generated by
265 i386 gcc 2.95.4 (the Debian packaged 2.95.4-24 at least).
266
267 Under the default -O2 the inlined SCM_I_CONSP test gets "optimized" so
268 the fetch of the tag word from x is done before confirming it's a
269 non-immediate (SCM_NIMP). Needless to say that bombs badly if x is a
270 immediate. This was seen to afflict scm_srfi1_split_at and something
271 deep in the bowels of ceval(). In both cases segvs resulted from
272 deferencing a random immediate value. srfi-1.test exposes the problem
273 through a short list, the immediate being SCM_EOL in that case.
274 Something in syntax.test exposed the ceval() problem.
275
276 Just "volatile SCM workaround_for_gcc_295 = lst" is enough to avoid the
277 problem, without even using that variable. The "w=w" is just to
278 prevent a warning about it being unused.
279 */
280#if defined (__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 95
281 volatile SCM workaround_for_gcc_295 = x;
282 workaround_for_gcc_295 = workaround_for_gcc_295;
283#endif
284
d5ad4aa6
MV
285 return SCM_I_CONSP (x);
286}
287
16ea9620 288#endif
16ea9620 289#endif