diff options
Diffstat (limited to 'libguile/inline.h')
-rw-r--r-- | libguile/inline.h | 277 |
1 files changed, 17 insertions, 260 deletions
diff --git a/libguile/inline.h b/libguile/inline.h index a78cac515..fe9cac70f 100644 --- a/libguile/inline.h +++ b/libguile/inline.h @@ -23,12 +23,9 @@ */ /* This file is for inline functions. On platforms that don't support - inlining functions, they are turned into ordinary functions. See - "inline.c". -*/ - -#include <stdio.h> -#include <string.h> + inlining functions, they are turned into ordinary functions. On + platforms that do support inline functions, the definitions are still + compiled into the library, once, in inline.c. */ #include "libguile/__scm.h" @@ -41,174 +38,21 @@ #include "libguile/error.h" -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H - -/* GCC has `__inline__' in all modes, including strict ansi. GCC 4.3 and - above with `-std=c99' or `-std=gnu99' implements ISO C99 inline semantics, - unless `-fgnu89-inline' is used. Here we want GNU "extern inline" - semantics, hence the `__gnu_inline__' attribute, in accordance with: - http://gcc.gnu.org/gcc-4.3/porting_to.html . - - With GCC 4.2, `__GNUC_STDC_INLINE__' is never defined (because C99 inline - semantics are not supported), but a warning is issued in C99 mode if - `__gnu_inline__' is not used. - - Apple's GCC build >5400 (since Xcode 3.0) doesn't support GNU inline in - C99 mode and doesn't define `__GNUC_STDC_INLINE__'. Fall back to "static - inline" in that case. */ - -# if (defined __GNUC__) && (!(((defined __APPLE_CC__) && (__APPLE_CC__ > 5400)) && __STDC_VERSION__ >= 199901L)) -# define SCM_C_USE_EXTERN_INLINE 1 -# if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2) -# define SCM_C_EXTERN_INLINE \ - extern __inline__ __attribute__ ((__gnu_inline__)) -# else -# define SCM_C_EXTERN_INLINE extern __inline__ -# endif -# elif (defined SCM_C_INLINE) -# define SCM_C_EXTERN_INLINE static SCM_C_INLINE -# endif - -#endif /* SCM_INLINE_C_INCLUDING_INLINE_H */ - - -#if (!defined SCM_C_INLINE) || (defined SCM_INLINE_C_INCLUDING_INLINE_H) \ - || (defined SCM_C_USE_EXTERN_INLINE) - -/* The `extern' declarations. They should only appear when used from - "inline.c", when `inline' is not supported at all or when "extern inline" - is used. */ +SCM_INLINE SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t pos); +SCM_INLINE void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val); -#include "libguile/bdw-gc.h" +SCM_INLINE int scm_is_pair (SCM x); +SCM_INLINE int scm_is_string (SCM x); - -SCM_API SCM scm_cell (scm_t_bits car, scm_t_bits cdr); -SCM_API SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr, +SCM_INLINE SCM scm_cell (scm_t_bits car, scm_t_bits cdr); +SCM_INLINE SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr, scm_t_bits ccr, scm_t_bits cdr); -SCM_API SCM scm_words (scm_t_bits car, scm_t_uint16 n_words); - -SCM_API SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t pos); -SCM_API void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val); - -SCM_API int scm_is_pair (SCM x); -SCM_API int scm_is_string (SCM x); - -SCM_API int scm_get_byte_or_eof (SCM port); -SCM_API int scm_peek_byte_or_eof (SCM port); -SCM_API void scm_putc (char c, SCM port); -SCM_API void scm_puts (const char *str_data, SCM port); - -#endif - - -#if defined SCM_C_EXTERN_INLINE || defined SCM_INLINE_C_INCLUDING_INLINE_H -/* either inlining, or being included from inline.c. We use (and - repeat) this long #if test here and below so that we don't have to - introduce any extraneous symbols into the public namespace. We - only need SCM_C_INLINE to be seen publically . */ - -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif - -SCM -scm_cell (scm_t_bits car, scm_t_bits cdr) -{ - SCM cell = PTR2SCM (GC_MALLOC (sizeof (scm_t_cell))); - - /* Initialize the type slot last so that the cell is ignored by the GC - until it is completely initialized. This is only relevant when the GC - can actually run during this code, which it can't since the GC only runs - when all other threads are stopped. */ - SCM_GC_SET_CELL_WORD (cell, 1, cdr); - SCM_GC_SET_CELL_WORD (cell, 0, car); - - return cell; -} - -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -SCM -scm_double_cell (scm_t_bits car, scm_t_bits cbr, - scm_t_bits ccr, scm_t_bits cdr) -{ - SCM z; - - z = PTR2SCM (GC_MALLOC (2 * sizeof (scm_t_cell))); - /* Initialize the type slot last so that the cell is ignored by the - GC until it is completely initialized. This is only relevant - when the GC can actually run during this code, which it can't - since the GC only runs when all other threads are stopped. - */ - SCM_GC_SET_CELL_WORD (z, 1, cbr); - SCM_GC_SET_CELL_WORD (z, 2, ccr); - SCM_GC_SET_CELL_WORD (z, 3, cdr); - SCM_GC_SET_CELL_WORD (z, 0, car); - - /* When this function is inlined, it's possible that the last - SCM_GC_SET_CELL_WORD above will be adjacent to a following - initialization of z. E.g., it occurred in scm_make_real. GCC - from around version 3 (e.g., certainly 3.2) began taking - advantage of strict C aliasing rules which say that it's OK to - interchange the initialization above and the one below when the - pointer types appear to differ sufficiently. We don't want that, - of course. GCC allows this behaviour to be disabled with the - -fno-strict-aliasing option, but would also need to be supplied - by Guile users. Instead, the following statements prevent the - reordering. - */ -#ifdef __GNUC__ - __asm__ volatile ("" : : : "memory"); -#else - /* portable version, just in case any other compiler does the same - thing. */ - scm_remember_upto_here_1 (z); -#endif - - return z; -} - -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -SCM -scm_words (scm_t_bits car, scm_t_uint16 n_words) -{ - SCM z; - - z = PTR2SCM (GC_MALLOC (sizeof (scm_t_bits) * n_words)); - SCM_GC_SET_CELL_WORD (z, 0, car); +SCM_INLINE SCM scm_words (scm_t_bits car, scm_t_uint16 n_words); - /* FIXME: is the following concern even relevant with BDW-GC? */ +#if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES +/* Either inlining, or being included from inline.c. */ - /* When this function is inlined, it's possible that the last - SCM_GC_SET_CELL_WORD above will be adjacent to a following - initialization of z. E.g., it occurred in scm_make_real. GCC - from around version 3 (e.g., certainly 3.2) began taking - advantage of strict C aliasing rules which say that it's OK to - interchange the initialization above and the one below when the - pointer types appear to differ sufficiently. We don't want that, - of course. GCC allows this behaviour to be disabled with the - -fno-strict-aliasing option, but would also need to be supplied - by Guile users. Instead, the following statements prevent the - reordering. - */ -#ifdef __GNUC__ - __asm__ volatile ("" : : : "memory"); -#else - /* portable version, just in case any other compiler does the same - thing. */ - scm_remember_upto_here_1 (z); -#endif - - return z; -} - -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -SCM +SCM_INLINE_IMPLEMENTATION SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t p) { if (SCM_UNLIKELY (p < 0 && ((size_t)-p) > h->base)) @@ -218,10 +62,7 @@ scm_array_handle_ref (scm_t_array_handle *h, ssize_t p) return h->impl->vref (h, h->base + p); } -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -void +SCM_INLINE_IMPLEMENTATION void scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v) { if (SCM_UNLIKELY (p < 0 && ((size_t)-p) > h->base)) @@ -231,10 +72,7 @@ scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v) h->impl->vset (h, h->base + p, v); } -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -int +SCM_INLINE_IMPLEMENTATION int scm_is_pair (SCM x) { /* The following "workaround_for_gcc_295" avoids bad code generated by @@ -261,92 +99,11 @@ scm_is_pair (SCM x) return SCM_I_CONSP (x); } -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -int +SCM_INLINE_IMPLEMENTATION int scm_is_string (SCM x) { - return SCM_NIMP (x) && (SCM_TYP7 (x) == scm_tc7_string); -} - -/* Port I/O. */ - -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -int -scm_get_byte_or_eof (SCM port) -{ - int c; - scm_t_port *pt = SCM_PTAB_ENTRY (port); - - if (pt->rw_active == SCM_PORT_WRITE) - /* may be marginally faster than calling scm_flush. */ - scm_ptobs[SCM_PTOBNUM (port)].flush (port); - - if (pt->rw_random) - pt->rw_active = SCM_PORT_READ; - - if (pt->read_pos >= pt->read_end) - { - if (SCM_UNLIKELY (scm_fill_input (port) == EOF)) - return EOF; - } - - c = *(pt->read_pos++); - - return c; -} - -/* Like `scm_get_byte_or_eof' but does not change PORT's `read_pos'. */ -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -int -scm_peek_byte_or_eof (SCM port) -{ - int c; - scm_t_port *pt = SCM_PTAB_ENTRY (port); - - if (pt->rw_active == SCM_PORT_WRITE) - /* may be marginally faster than calling scm_flush. */ - scm_ptobs[SCM_PTOBNUM (port)].flush (port); - - if (pt->rw_random) - pt->rw_active = SCM_PORT_READ; - - if (pt->read_pos >= pt->read_end) - { - if (SCM_UNLIKELY (scm_fill_input (port) == EOF)) - return EOF; - } - - c = *pt->read_pos; - - return c; -} - -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -void -scm_putc (char c, SCM port) -{ - SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port"); - scm_lfwrite (&c, 1, port); + return SCM_HAS_TYP7 (x, scm_tc7_string); } -#ifndef SCM_INLINE_C_INCLUDING_INLINE_H -SCM_C_EXTERN_INLINE -#endif -void -scm_puts (const char *s, SCM port) -{ - SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port"); - scm_lfwrite (s, strlen (s), port); -} - - #endif #endif |