mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
simplify inline function infrastructure
* libguile/__scm.h (SCM_C_EXTERN_INLINE): Move this definition here, from inline.h. We'd like to support inline function definitions in more header files: not just inline.h. (SCM_CAN_INLINE, SCM_INLINE, SCM_INLINE_IMPLEMENTATION): New definitions. * libguile/gc.h (SCM_GC_MALLOC, SCM_GC_MALLOC_POINTERLESS): Define these wrappers, which redirect to the GC_MALLOC macros when building Guile, and the scm_gc_malloc functions otherwise. A step towards getting BDW-GC out of Guile's API. * libguile/inline.h: Simplify, using SCM_INLINE, SCM_INLINE_IMPLEMENTATION, and SCM_IMPLEMENT_INLINES. Also use the new SCM_GC_MALLOC macros.
This commit is contained in:
parent
be79627c21
commit
46163e52e5
4 changed files with 101 additions and 108 deletions
|
@ -192,6 +192,64 @@
|
|||
|
||||
|
||||
|
||||
/* We would like gnu89 extern inline semantics, not C99 extern inline
|
||||
semantics, so that we can be sure to avoid reifying definitions of
|
||||
inline functions in all compilation units, which is a possibility at
|
||||
low optimization levels, or if a user takes the address of an inline
|
||||
function.
|
||||
|
||||
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))
|
||||
# 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
|
||||
# endif
|
||||
|
||||
/* SCM_INLINE is a macro prepended to all public inline function
|
||||
declarations. Implementations of those functions should also be in
|
||||
the header file, prefixed by SCM_INLINE_IMPLEMENTATION, and protected
|
||||
by SCM_CAN_INLINE and a CPP define for the C file in question, like
|
||||
SCM_INLINE_C_INCLUDING_INLINE_H. See inline.h for an example
|
||||
usage. */
|
||||
|
||||
#if defined SCM_IMPLEMENT_INLINES
|
||||
/* Reifying functions to a file, whether or not inlining is available. */
|
||||
# define SCM_CAN_INLINE 0
|
||||
# define SCM_INLINE SCM_API
|
||||
# define SCM_INLINE_IMPLEMENTATION
|
||||
#elif defined SCM_C_INLINE
|
||||
/* Declarations when inlining is available. */
|
||||
# define SCM_CAN_INLINE 1
|
||||
# ifdef SCM_C_EXTERN_INLINE
|
||||
# define SCM_INLINE SCM_C_EXTERN_INLINE
|
||||
# else
|
||||
/* Fall back to static inline if GNU "extern inline" is unavailable. */
|
||||
# define SCM_INLINE static SCM_C_INLINE
|
||||
# endif
|
||||
# define SCM_INLINE_IMPLEMENTATION SCM_INLINE
|
||||
#else
|
||||
/* Declarations when inlining is not available. */
|
||||
# define SCM_CAN_INLINE 0
|
||||
# define SCM_INLINE SCM_API
|
||||
/* Don't define SCM_INLINE_IMPLEMENTATION; it should never be seen in
|
||||
this case. */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* {Debugging Options}
|
||||
*
|
||||
* These compile time options determine whether to include code that is only
|
||||
|
|
|
@ -207,6 +207,17 @@ SCM_API char *scm_gc_strdup (const char *str, const char *what)
|
|||
SCM_API char *scm_gc_strndup (const char *str, size_t n, const char *what)
|
||||
SCM_MALLOC;
|
||||
|
||||
|
||||
#ifdef BUILDING_LIBGUILE
|
||||
#include "libguile/bdw-gc.h"
|
||||
#define SCM_GC_MALLOC(size) GC_MALLOC (size)
|
||||
#define SCM_GC_MALLOC_POINTERLESS(size) GC_MALLOC_ATOMIC (size)
|
||||
#else
|
||||
#define SCM_GC_MALLOC(size) scm_gc_malloc (size, NULL)
|
||||
#define SCM_GC_MALLOC_POINTERLESS(size) scm_gc_malloc_pointerless (size, NULL)
|
||||
#endif
|
||||
|
||||
|
||||
SCM_API void scm_remember_upto_here_1 (SCM obj);
|
||||
SCM_API void scm_remember_upto_here_2 (SCM obj1, SCM obj2);
|
||||
SCM_API void scm_remember_upto_here (SCM obj1, ...);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001, 2006, 2008, 2011 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
|
@ -20,5 +20,6 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#define SCM_INLINE_C_INCLUDING_INLINE_H 1
|
||||
#define SCM_IMPLEMENT_INLINES 1
|
||||
#define SCM_INLINE_C_IMPLEMENTING_INLINES 1
|
||||
#include "libguile/inline.h"
|
||||
|
|
|
@ -23,9 +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".
|
||||
*/
|
||||
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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -41,80 +41,33 @@
|
|||
#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. */
|
||||
|
||||
#include "libguile/bdw-gc.h"
|
||||
|
||||
|
||||
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_INLINE 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_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);
|
||||
|
||||
SCM_API int scm_is_pair (SCM x);
|
||||
SCM_API int scm_is_string (SCM x);
|
||||
SCM_INLINE int scm_is_pair (SCM x);
|
||||
SCM_INLINE 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
|
||||
SCM_INLINE int scm_get_byte_or_eof (SCM port);
|
||||
SCM_INLINE int scm_peek_byte_or_eof (SCM port);
|
||||
SCM_INLINE void scm_putc (char c, SCM port);
|
||||
SCM_INLINE void scm_puts (const char *str_data, SCM port);
|
||||
|
||||
|
||||
#if defined SCM_C_EXTERN_INLINE || defined SCM_INLINE_C_INCLUDING_INLINE_H
|
||||
#if SCM_CAN_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_INLINE_IMPLEMENTATION SCM
|
||||
scm_cell (scm_t_bits car, scm_t_bits cdr)
|
||||
{
|
||||
SCM cell = PTR2SCM (GC_MALLOC (sizeof (scm_t_cell)));
|
||||
SCM cell = PTR2SCM (SCM_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
|
||||
|
@ -126,16 +79,13 @@ scm_cell (scm_t_bits car, scm_t_bits cdr)
|
|||
return cell;
|
||||
}
|
||||
|
||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
||||
SCM_C_EXTERN_INLINE
|
||||
#endif
|
||||
SCM
|
||||
SCM_INLINE_IMPLEMENTATION 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)));
|
||||
z = PTR2SCM (SCM_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
|
||||
|
@ -169,15 +119,12 @@ scm_double_cell (scm_t_bits car, scm_t_bits cbr,
|
|||
return z;
|
||||
}
|
||||
|
||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
||||
SCM_C_EXTERN_INLINE
|
||||
#endif
|
||||
SCM
|
||||
SCM_INLINE_IMPLEMENTATION SCM
|
||||
scm_words (scm_t_bits car, scm_t_uint16 n_words)
|
||||
{
|
||||
SCM z;
|
||||
|
||||
z = PTR2SCM (GC_MALLOC (sizeof (scm_t_bits) * n_words));
|
||||
z = PTR2SCM (SCM_GC_MALLOC (sizeof (scm_t_bits) * n_words));
|
||||
SCM_GC_SET_CELL_WORD (z, 0, car);
|
||||
|
||||
/* FIXME: is the following concern even relevant with BDW-GC? */
|
||||
|
@ -205,10 +152,7 @@ scm_words (scm_t_bits car, scm_t_uint16 n_words)
|
|||
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 +162,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 +172,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,10 +199,7 @@ 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);
|
||||
|
@ -272,10 +207,7 @@ scm_is_string (SCM x)
|
|||
|
||||
/* Port I/O. */
|
||||
|
||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
||||
SCM_C_EXTERN_INLINE
|
||||
#endif
|
||||
int
|
||||
SCM_INLINE_IMPLEMENTATION int
|
||||
scm_get_byte_or_eof (SCM port)
|
||||
{
|
||||
int c;
|
||||
|
@ -300,10 +232,7 @@ scm_get_byte_or_eof (SCM port)
|
|||
}
|
||||
|
||||
/* 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_INLINE_IMPLEMENTATION int
|
||||
scm_peek_byte_or_eof (SCM port)
|
||||
{
|
||||
int c;
|
||||
|
@ -327,20 +256,14 @@ scm_peek_byte_or_eof (SCM port)
|
|||
return c;
|
||||
}
|
||||
|
||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
||||
SCM_C_EXTERN_INLINE
|
||||
#endif
|
||||
void
|
||||
SCM_INLINE_IMPLEMENTATION void
|
||||
scm_putc (char c, SCM port)
|
||||
{
|
||||
SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
|
||||
scm_lfwrite (&c, 1, port);
|
||||
}
|
||||
|
||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
||||
SCM_C_EXTERN_INLINE
|
||||
#endif
|
||||
void
|
||||
SCM_INLINE_IMPLEMENTATION void
|
||||
scm_puts (const char *s, SCM port)
|
||||
{
|
||||
SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue