mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 19:50:24 +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}
|
/* {Debugging Options}
|
||||||
*
|
*
|
||||||
* These compile time options determine whether to include code that is only
|
* 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_API char *scm_gc_strndup (const char *str, size_t n, const char *what)
|
||||||
SCM_MALLOC;
|
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_1 (SCM obj);
|
||||||
SCM_API void scm_remember_upto_here_2 (SCM obj1, SCM obj2);
|
SCM_API void scm_remember_upto_here_2 (SCM obj1, SCM obj2);
|
||||||
SCM_API void scm_remember_upto_here (SCM obj1, ...);
|
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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -20,5 +20,6 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#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"
|
#include "libguile/inline.h"
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This file is for inline functions. On platforms that don't support
|
/* This file is for inline functions. On platforms that don't support
|
||||||
inlining functions, they are turned into ordinary functions. See
|
inlining functions, they are turned into ordinary functions. On
|
||||||
"inline.c".
|
platforms that do support inline functions, the definitions are still
|
||||||
*/
|
compiled into the library, once, in inline.c. */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -41,80 +41,33 @@
|
||||||
#include "libguile/error.h"
|
#include "libguile/error.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
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,
|
||||||
/* 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_t_bits ccr, scm_t_bits cdr);
|
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_INLINE 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 void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val);
|
||||||
|
|
||||||
SCM_API int scm_is_pair (SCM x);
|
SCM_INLINE int scm_is_pair (SCM x);
|
||||||
SCM_API int scm_is_string (SCM x);
|
SCM_INLINE int scm_is_string (SCM x);
|
||||||
|
|
||||||
SCM_API int scm_get_byte_or_eof (SCM port);
|
SCM_INLINE int scm_get_byte_or_eof (SCM port);
|
||||||
SCM_API int scm_peek_byte_or_eof (SCM port);
|
SCM_INLINE int scm_peek_byte_or_eof (SCM port);
|
||||||
SCM_API void scm_putc (char c, SCM port);
|
SCM_INLINE void scm_putc (char c, SCM port);
|
||||||
SCM_API void scm_puts (const char *str_data, SCM port);
|
SCM_INLINE void scm_puts (const char *str_data, SCM port);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#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
|
/* 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
|
repeat) this long #if test here and below so that we don't have to
|
||||||
introduce any extraneous symbols into the public namespace. We
|
introduce any extraneous symbols into the public namespace. We
|
||||||
only need SCM_C_INLINE to be seen publically . */
|
only need SCM_C_INLINE to be seen publically . */
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION SCM
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SCM
|
|
||||||
scm_cell (scm_t_bits car, scm_t_bits cdr)
|
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
|
/* 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
|
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;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION SCM
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
SCM
|
|
||||||
scm_double_cell (scm_t_bits car, scm_t_bits cbr,
|
scm_double_cell (scm_t_bits car, scm_t_bits cbr,
|
||||||
scm_t_bits ccr, scm_t_bits cdr)
|
scm_t_bits ccr, scm_t_bits cdr)
|
||||||
{
|
{
|
||||||
SCM z;
|
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
|
/* Initialize the type slot last so that the cell is ignored by the
|
||||||
GC until it is completely initialized. This is only relevant
|
GC until it is completely initialized. This is only relevant
|
||||||
when the GC can actually run during this code, which it can't
|
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;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION SCM
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
SCM
|
|
||||||
scm_words (scm_t_bits car, scm_t_uint16 n_words)
|
scm_words (scm_t_bits car, scm_t_uint16 n_words)
|
||||||
{
|
{
|
||||||
SCM z;
|
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);
|
SCM_GC_SET_CELL_WORD (z, 0, car);
|
||||||
|
|
||||||
/* FIXME: is the following concern even relevant with BDW-GC? */
|
/* 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;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION SCM
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
SCM
|
|
||||||
scm_array_handle_ref (scm_t_array_handle *h, ssize_t p)
|
scm_array_handle_ref (scm_t_array_handle *h, ssize_t p)
|
||||||
{
|
{
|
||||||
if (SCM_UNLIKELY (p < 0 && ((size_t)-p) > h->base))
|
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);
|
return h->impl->vref (h, h->base + p);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION void
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
void
|
|
||||||
scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v)
|
scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v)
|
||||||
{
|
{
|
||||||
if (SCM_UNLIKELY (p < 0 && ((size_t)-p) > h->base))
|
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);
|
h->impl->vset (h, h->base + p, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION int
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
int
|
|
||||||
scm_is_pair (SCM x)
|
scm_is_pair (SCM x)
|
||||||
{
|
{
|
||||||
/* The following "workaround_for_gcc_295" avoids bad code generated by
|
/* 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);
|
return SCM_I_CONSP (x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION int
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
int
|
|
||||||
scm_is_string (SCM x)
|
scm_is_string (SCM x)
|
||||||
{
|
{
|
||||||
return SCM_NIMP (x) && (SCM_TYP7 (x) == scm_tc7_string);
|
return SCM_NIMP (x) && (SCM_TYP7 (x) == scm_tc7_string);
|
||||||
|
@ -272,10 +207,7 @@ scm_is_string (SCM x)
|
||||||
|
|
||||||
/* Port I/O. */
|
/* Port I/O. */
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION int
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
int
|
|
||||||
scm_get_byte_or_eof (SCM port)
|
scm_get_byte_or_eof (SCM port)
|
||||||
{
|
{
|
||||||
int c;
|
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'. */
|
/* Like `scm_get_byte_or_eof' but does not change PORT's `read_pos'. */
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION int
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
int
|
|
||||||
scm_peek_byte_or_eof (SCM port)
|
scm_peek_byte_or_eof (SCM port)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
@ -327,20 +256,14 @@ scm_peek_byte_or_eof (SCM port)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION void
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
void
|
|
||||||
scm_putc (char c, SCM port)
|
scm_putc (char c, SCM port)
|
||||||
{
|
{
|
||||||
SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
|
SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
|
||||||
scm_lfwrite (&c, 1, port);
|
scm_lfwrite (&c, 1, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
|
SCM_INLINE_IMPLEMENTATION void
|
||||||
SCM_C_EXTERN_INLINE
|
|
||||||
#endif
|
|
||||||
void
|
|
||||||
scm_puts (const char *s, SCM port)
|
scm_puts (const char *s, SCM port)
|
||||||
{
|
{
|
||||||
SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
|
SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue