X-Git-Url: https://git.hcoop.net/bpt/guile.git/blobdiff_plain/705edb959b3093cb1cbe1390110d96ee833b63fc..7f3be1db9949b0566d3a2cb6bd9d0e84287bbb0a:/libguile/__scm.h diff --git a/libguile/__scm.h b/libguile/__scm.h index 55f9f49e2..ed35d531b 100644 --- a/libguile/__scm.h +++ b/libguile/__scm.h @@ -3,7 +3,8 @@ #ifndef SCM___SCM_H #define SCM___SCM_H -/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2006, + * 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 @@ -62,6 +63,15 @@ * additional information to the developers. */ +/* Return true (non-zero) if GCC version MAJ.MIN or later is being used + * (macro taken from glibc.) */ +#if defined __GNUC__ && defined __GNUC_MINOR__ +# define SCM_GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +# define SCM_GNUC_PREREQ(maj, min) 0 +#endif + /* The macro SCM_NORETURN indicates that a function will never return. * Examples: * 1) int foo (char arg) SCM_NORETURN; @@ -89,7 +99,7 @@ /* The SCM_EXPECT macros provide branch prediction hints to the compiler. To * use only in places where the result of the expression under "normal" * circumstances is known. */ -#if defined(__GNUC__) && (__GNUC__ >= 3) +#if SCM_GNUC_PREREQ (3, 0) # define SCM_EXPECT __builtin_expect #else # define SCM_EXPECT(_expr, _value) (_expr) @@ -108,13 +118,32 @@ * or variables. Defining `SCM_BUILDING_DEPRECATED_CODE' allows deprecated * functions to be implemented in terms of deprecated functions, and allows * deprecated functions to be referred to by `scm_c_define_gsubr ()'. */ -#if !defined (SCM_BUILDING_DEPRECATED_CODE) \ - && defined (__GNUC__) && (__GNUC__ >= 3) +#if !defined (SCM_BUILDING_DEPRECATED_CODE) && SCM_GNUC_PREREQ (3, 0) # define SCM_DEPRECATED SCM_API __attribute__ ((__deprecated__)) #else # define SCM_DEPRECATED SCM_API #endif +/* The SCM_ALIGNED macro, when defined, can be used to instruct the compiler + * to honor the given alignment constraint. */ +/* Sun Studio supports alignment since Sun Studio 12 */ +#if defined __GNUC__ || (defined( __SUNPRO_C ) && (__SUNPRO_C - 0 >= 0x590)) +# define SCM_ALIGNED(x) __attribute__ ((aligned (x))) +#elif defined __INTEL_COMPILER +# define SCM_ALIGNED(x) __declspec (align (x)) +#else +/* Don't know how to align things. */ +# undef SCM_ALIGNED +#endif + +/* The SCM_MALLOC macro can be used in function declarations to tell the + * compiler that a function may be treated as if any non-NULL pointer it returns + * cannot alias any other pointer valid when the function returns. */ +#if SCM_GNUC_PREREQ (3, 0) +# define SCM_MALLOC __attribute__ ((__malloc__)) +#else +# define SCM_MALLOC +#endif /* {Supported Options} @@ -124,19 +153,6 @@ /* #define GUILE_DEBUG_FREELIST */ -/* All the number support there is. - */ -#define BIGNUMS - -/* GC should relinquish empty cons-pair arenas. */ -/* cmm:FIXME look at this after done mangling the GC */ -/* #define GC_FREE_SEGMENTS */ - -/* Provide a scheme-accessible count-down timer that - * generates a pseudo-interrupt. - */ -#define TICKS - /* Use engineering notation when converting numbers strings? */ @@ -165,9 +181,9 @@ /* SCM_API is a macro prepended to all function and data definitions which should be exported from libguile. */ -#if BUILDING_LIBGUILE && HAVE_VISIBILITY +#if defined BUILDING_LIBGUILE && defined HAVE_VISIBILITY # define SCM_API extern __attribute__((__visibility__("default"))) -#elif BUILDING_LIBGUILE && defined _MSC_VER +#elif defined BUILDING_LIBGUILE && defined _MSC_VER # define SCM_API __declspec(dllexport) extern #elif defined _MSC_VER # define SCM_API __declspec(dllimport) extern @@ -177,6 +193,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 @@ -359,13 +433,7 @@ #ifdef LONG_BIT # define SCM_LONG_BIT LONG_BIT #else -# define SCM_LONG_BIT (SCM_CHAR_BIT * sizeof (long) / sizeof (char)) -#endif - -#ifdef UCHAR_MAX -# define SCM_CHAR_CODE_LIMIT (UCHAR_MAX + 1L) -#else -# define SCM_CHAR_CODE_LIMIT 256L +# define SCM_LONG_BIT (SCM_SIZEOF_LONG * 8) #endif #define SCM_I_UTYPE_MAX(type) ((type)-1) @@ -384,11 +452,9 @@ #define SCM_T_INT32_MIN SCM_I_TYPE_MIN(scm_t_int32,SCM_T_UINT32_MAX) #define SCM_T_INT32_MAX SCM_I_TYPE_MAX(scm_t_int32,SCM_T_UINT32_MAX) -#if SCM_HAVE_T_INT64 #define SCM_T_UINT64_MAX SCM_I_UTYPE_MAX(scm_t_uint64) #define SCM_T_INT64_MIN SCM_I_TYPE_MIN(scm_t_int64,SCM_T_UINT64_MAX) #define SCM_T_INT64_MAX SCM_I_TYPE_MAX(scm_t_int64,SCM_T_UINT64_MAX) -#endif #if SCM_SIZEOF_LONG_LONG #define SCM_I_ULLONG_MAX SCM_I_UTYPE_MAX(unsigned long long) @@ -400,6 +466,10 @@ #define SCM_T_INTMAX_MIN SCM_I_TYPE_MIN(scm_t_intmax,SCM_T_UINTMAX_MAX) #define SCM_T_INTMAX_MAX SCM_I_TYPE_MAX(scm_t_intmax,SCM_T_UINTMAX_MAX) +#define SCM_T_UINTPTR_MAX SCM_I_UTYPE_MAX(scm_t_uintptr) +#define SCM_T_INTPTR_MIN SCM_I_TYPE_MIN(scm_t_intptr,SCM_T_UINTPTR_MAX) +#define SCM_T_INTPTR_MAX SCM_I_TYPE_MAX(scm_t_intptr,SCM_T_UINTPTR_MAX) + #define SCM_I_SIZE_MAX SCM_I_UTYPE_MAX(size_t) #define SCM_I_SSIZE_MIN SCM_I_TYPE_MIN(ssize_t,SCM_I_SIZE_MAX) #define SCM_I_SSIZE_MAX SCM_I_TYPE_MAX(ssize_t,SCM_I_SIZE_MAX) @@ -408,6 +478,19 @@ #include "libguile/tags.h" + +/* The type of subrs, i.e., Scheme procedures implemented in C. Empty + function declarators are used internally for pointers to functions of + any arity. However, these are equivalent to `(void)' in C++, are + obsolescent as of C99, and trigger `strict-prototypes' GCC warnings + (bug #23681). */ + +#ifdef BUILDING_LIBGUILE +typedef SCM (* scm_t_subr) (); +#else +typedef void *scm_t_subr; +#endif + #ifdef vms # ifndef CHEAP_CONTINUATIONS @@ -497,12 +580,24 @@ SCM_API void scm_async_tick (void); #ifdef BUILDING_LIBGUILE /* FIXME: should change names */ -# define SCM_ASYNC_TICK \ - do \ - { \ - if (SCM_I_CURRENT_THREAD->pending_asyncs) \ - scm_async_click (); \ - } \ +# define SCM_ASYNC_TICK \ + do \ + { \ + if (SCM_UNLIKELY (SCM_I_CURRENT_THREAD->pending_asyncs)) \ + scm_async_click (); \ + } \ + while (0) + +/* SCM_ASYNC_TICK_WITH_CODE is only available to Guile itself */ +# define SCM_ASYNC_TICK_WITH_CODE(thr, stmt) \ + do \ + { \ + if (SCM_UNLIKELY (thr->pending_asyncs)) \ + { \ + stmt; \ + scm_async_click (); \ + } \ + } \ while (0) #else /* !BUILDING_LIBGUILE */ @@ -551,7 +646,6 @@ do { \ #ifdef SCM_RECKLESS #define SCM_ASSERT(_cond, _arg, _pos, _subr) #define SCM_ASSERT_TYPE(_cond, _arg, _pos, _subr, _msg) -#define SCM_ASRTGO(_cond, _label) #else #define SCM_ASSERT(_cond, _arg, _pos, _subr) \ do { if (SCM_UNLIKELY (!(_cond))) \ @@ -559,9 +653,6 @@ do { \ #define SCM_ASSERT_TYPE(_cond, _arg, _pos, _subr, _msg) \ do { if (SCM_UNLIKELY (!(_cond))) \ scm_wrong_type_arg_msg(_subr, _pos, _arg, _msg); } while (0) -#define SCM_ASRTGO(_cond, _label) \ - do { if (SCM_UNLIKELY (!(_cond))) \ - goto _label; } while (0) #endif /*