>From 5d4c4b5b70e65af4be5c5d53a9f7e7c7f764326c Mon Sep 17 00:00:00 2001 From: felix Date: Fri, 28 Dec 2012 00:13:27 +0100 Subject: [PATCH] Corrected behaviour for "C_i_foreign_[unsigned]_integer64_argumentp" Extract floating-point values from argument and compare with MIN/MAX for the associated C type). Added limits to chicken.h, which uses stdint.h now (or inttypes.h on SunOS). Disabled compiler-test added by Peter for #955 for 32-bit platforms. Signed-off-by: Peter Bex --- chicken.h | 55 +++++++++++++++++++++++++++++++++++++++++++------------ runtime.c | 19 ++++++++++++------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/chicken.h b/chicken.h index e128332..082c318 100644 --- a/chicken.h +++ b/chicken.h @@ -502,9 +502,17 @@ static inline int isinf_ld (long double x) #define C_F32_LOCATIVE 8 #define C_F64_LOCATIVE 9 +#if defined (__MINGW32__) +# define C_s64 __int64 +# define C_u64 unsigned __int64 +#else +# define C_s64 int64_t +# define C_u64 uint64_t +#endif + #ifdef C_SIXTY_FOUR # ifdef C_LLP -# define C_word __int64 +# define C_word C_s64 # else # define C_word long # endif @@ -516,24 +524,47 @@ static inline int isinf_ld (long double x) # define C_s32 int #endif -#if defined (__MINGW32__) -# define C_s64 __int64 -# define C_u64 unsigned __int64 -#else -# define C_s64 int64_t -# define C_u64 uint64_t -#endif - #define C_char char #define C_uchar unsigned C_char #define C_byte char #define C_uword unsigned C_word #define C_header C_uword +#if defined(__sun__) && !defined(__svr4__) +/* SunOS is supposed not to have stdint.h */ +# include +#else +# include +#endif + +/* if all else fails, use these: + #define UINT64_MAX (18446744073709551615ULL) + #define INT64_MAX (9223372036854775807LL) + #define INT64_MIN (-INT64_MAX - 1) + #define UINT32_MAX (4294967295U) + #define INT32_MAX (2147483647) + #define INT32_MIN (-INT32_MAX - 1) + #define UINT16_MAX (65535U) + #define INT16_MAX (32767) + #define INT16_MIN (-INT16_MAX - 1) + #define UINT8_MAX (255) + #define INT8_MAX (127) + #define INT8_MIN (-INT8_MAX - 1) +*/ + +#define C_U64_MAX UINT64_MAX +#define C_S64_MIN INT64_MIN +#define C_S64_MAX INT64_MAX + #if defined(C_LLP) && defined(C_SIXTY_FOUR) -# define C_long __int64 -# define C_LONG_MAX LONG_LONG_MAX -# define C_LONG_MIN LONG_LONG_MIN +# define C_long C_s64 +# ifndef LONG_LONG_MAX +# define C_LONG_MAX LLONG_MAX +# define C_LONG_MIN LLONG_MIN +# else +# define C_LONG_MAX LONG_LONG_MAX +# define C_LONG_MIN LONG_LONG_MIN +# endif #else # define C_long long # define C_LONG_MAX LONG_MAX diff --git a/runtime.c b/runtime.c index 63e553c..0b89361 100644 --- a/runtime.c +++ b/runtime.c @@ -5879,10 +5879,15 @@ C_regparm C_word C_fcall C_i_foreign_integer_argumentp(C_word x) C_regparm C_word C_fcall C_i_foreign_integer64_argumentp(C_word x) { - double m; + double m, r; - if((x & C_FIXNUM_BIT) != 0 || (!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG)) - return x; + if((x & C_FIXNUM_BIT) != 0) return x; + + if(!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG) { + m = C_flonum_magnitude(x); + + if(m >= C_S64_MIN && m <= C_S64_MAX && C_modf(m, &r) == 0.0) return x; + } barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, NULL, x); return C_SCHEME_UNDEFINED; @@ -5891,14 +5896,14 @@ C_regparm C_word C_fcall C_i_foreign_integer64_argumentp(C_word x) C_regparm C_word C_fcall C_i_foreign_unsigned_integer_argumentp(C_word x) { - double m; + double m ,r; if((x & C_FIXNUM_BIT) != 0) return x; if(!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG) { m = C_flonum_magnitude(x); - if(m >= 0 && m <= C_UWORD_MAX) return x; + if(m >= 0 && m <= C_UWORD_MAX && C_modf(m, &r) == 0.0) return x; } barf(C_BAD_ARGUMENT_TYPE_NO_UINTEGER_ERROR, NULL, x); @@ -5908,14 +5913,14 @@ C_regparm C_word C_fcall C_i_foreign_unsigned_integer_argumentp(C_word x) C_regparm C_word C_fcall C_i_foreign_unsigned_integer64_argumentp(C_word x) { - double m; + double m, r; if((x & C_FIXNUM_BIT) != 0) return x; if(!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG) { m = C_flonum_magnitude(x); - if(m >= 0 && m <= C_UWORD_MAX) return x; + if(m >= 0 && m <= C_U64_MAX && C_modf(m, &r) == 0.0) return x; } barf(C_BAD_ARGUMENT_TYPE_NO_UINTEGER_ERROR, NULL, x); -- 1.8.0.1