From e1777427e3ea254b33badc9df491523d2d0e071a Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Tue, 29 Oct 2013 01:05:19 +0200 Subject: [PATCH] add 32-bit only duk_tval.h handling, fix DUK__DOUBLE_IS_NAN_FULL() middle/other endian mixup --- src/duk_features.h | 6 +++ src/duk_tval.h | 93 +++++++++++++++++++++++++++------------------- 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/duk_features.h b/src/duk_features.h index fdcf35c0..e1352fc4 100644 --- a/src/duk_features.h +++ b/src/duk_features.h @@ -352,7 +352,9 @@ typedef signed int duk_i32; /* indexes of various types with respect to big endian (logical) layout */ #if defined(DUK_USE_DOUBLE_LE) +#ifdef DUK_USE_64BIT_OPS #define DUK_DBL_IDX_ULL0 0 +#endif #define DUK_DBL_IDX_UI0 1 #define DUK_DBL_IDX_UI1 0 #define DUK_DBL_IDX_US0 3 @@ -370,7 +372,9 @@ typedef signed int duk_i32; #define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */ #define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */ #elif defined(DUK_USE_DOUBLE_BE) +#ifdef DUK_USE_64BIT_OPS #define DUK_DBL_IDX_ULL0 0 +#endif #define DUK_DBL_IDX_UI0 0 #define DUK_DBL_IDX_UI1 1 #define DUK_DBL_IDX_US0 0 @@ -388,7 +392,9 @@ typedef signed int duk_i32; #define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */ #define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */ #elif defined(DUK_USE_DOUBLE_ME) +#ifdef DUK_USE_64BIT_OPS #define DUK_DBL_IDX_ULL0 0 /* not directly applicable, byte order differs from a double */ +#endif #define DUK_DBL_IDX_UI0 0 #define DUK_DBL_IDX_UI1 1 #define DUK_DBL_IDX_US0 1 diff --git a/src/duk_tval.h b/src/duk_tval.h index 0d524c11..c804755d 100644 --- a/src/duk_tval.h +++ b/src/duk_tval.h @@ -63,6 +63,9 @@ #ifdef DUK_USE_DOUBLE_BE #define USE__BE_VARIANT #endif +#ifdef DUK_USE_64BIT_OPS +#define USE__64BIT +#endif /* sanity */ #if !defined(USE__LE_VARIANT) && !defined(USE__ME_VARIANT) && !defined(USE__BE_VARIANT) @@ -87,7 +90,10 @@ */ union duk_tval { double d; + /* FIXME: types */ +#ifdef USE__64BIT unsigned long long ull[1]; +#endif unsigned int ui[2]; unsigned short us[4]; unsigned char uc[8]; @@ -111,6 +117,7 @@ typedef union duk_tval duk_tval; /* for convenience */ #define DUK_XTAG_UNDEFINED_ACTUAL 0xfff10000 #define DUK_XTAG_UNDEFINED_UNUSED 0xfff10001 +#define DUK_XTAG_NULL 0xfff20000 #define DUK_XTAG_BOOLEAN_FALSE 0xfff30000 #define DUK_XTAG_BOOLEAN_TRUE 0xfff30001 @@ -124,61 +131,40 @@ typedef union duk_tval duk_tval; */ /* raw setters */ +#ifdef USE__64BIT #ifdef USE__ME_VARIANT -#define DUK__TVAL_SET_UNDEFINED_ACTUAL_FULL(v) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (unsigned long long) DUK_XTAG_UNDEFINED_ACTUAL; \ +#define DUK__TVAL_SET_HIGH32_FULL(v,x) do { \ + (v)->ull[DUK_DBL_IDX_ULL0] = (unsigned long long) (x); \ } while (0) #else -#define DUK__TVAL_SET_UNDEFINED_ACTUAL_FULL(v) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = ((unsigned long long) DUK_XTAG_UNDEFINED_ACTUAL) << 32; \ +#define DUK__TVAL_SET_HIGH32_FULL(v,x) do { \ + (v)->ull[DUK_DBL_IDX_ULL0] = ((unsigned long long) (x)) << 32; \ } while (0) #endif +#else /* USE__64BIT */ +#define DUK__TVAL_SET_HIGH32_FULL(v,x) do { \ + (v)->ui[DUK_DBL_IDX_UI0] = (unsigned int) (x); \ + (v)->ui[DUK_DBL_IDX_UI1] = (unsigned int) 0; \ + } while (0) +#endif /* USE__64BIT */ +#define DUK__TVAL_SET_UNDEFINED_ACTUAL_FULL(v) DUK__TVAL_SET_HIGH32((v), DUK_XTAG_UNDEFINED_ACTUAL) #define DUK__TVAL_SET_UNDEFINED_ACTUAL_NOTFULL(v) do { \ (v)->ui[DUK_DBL_IDX_UI0] = (unsigned int) DUK_XTAG_UNDEFINED_ACTUAL; \ } while (0) -#ifdef USE__ME_VARIANT -#define DUK__TVAL_SET_UNDEFINED_UNUSED_FULL(v) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (unsigned long long) DUK_XTAG_UNDEFINED_UNUSED; \ - } while (0) -#else -#define DUK__TVAL_SET_UNDEFINED_UNUSED_FULL(v) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = ((unsigned long long) DUK_XTAG_UNDEFINED_UNUSED) << 32; \ - } while (0) -#endif - +#define DUK__TVAL_SET_UNDEFINED_UNUSED_FULL(v) DUK__TVAL_SET_HIGH32((v), DUK_XTAG_UNDEFINED_UNUSED) #define DUK__TVAL_SET_UNDEFINED_UNUSED_NOTFULL(v) do { \ (v)->ui[DUK_DBL_IDX_UI0] = (unsigned int) DUK_XTAG_UNDEFINED_UNUSED; \ } while (0) -#ifdef USE__ME_VARIANT -#define DUK__TVAL_SET_NULL_FULL(v) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((unsigned long long) DUK_TAG_NULL) << 16); \ - } while (0) -#else -#define DUK__TVAL_SET_NULL_FULL(v) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((unsigned long long) DUK_TAG_NULL) << 48); \ - } while (0) -#endif - /* Note: 16-bit initializer suffices (unlike for undefined/boolean) */ +#define DUK__TVAL_SET_NULL_FULL(v) DUK__TVAL_SET_HIGH32((v), DUK_XTAG_NULL) #define DUK__TVAL_SET_NULL_NOTFULL(v) do { \ (v)->us[DUK_DBL_IDX_US0] = (unsigned short) DUK_TAG_NULL; \ } while (0) -#ifdef USE__ME_VARIANT -#define DUK__TVAL_SET_BOOLEAN_FULL(v,val) do { \ - DUK_ASSERT((val) == 0 || (val) == 1); \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((unsigned long long) DUK_TAG_BOOLEAN) << 16) | ((unsigned long long) (val)); \ - } while (0) -#else -#define DUK__TVAL_SET_BOOLEAN_FULL(v,val) do { \ - DUK_ASSERT((val) == 0 || (val) == 1); \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((unsigned long long) DUK_TAG_BOOLEAN) << 48) | (((unsigned long long) (val)) << 32); \ - } while (0) -#endif - +#define DUK__TVAL_SET_BOOLEAN_FULL(v,val) DUK__TVAL_SET_HIGH32((v), (((unsigned int) DUK_TAG_BOOLEAN) << 16) | ((unsigned int) val)) #define DUK__TVAL_SET_BOOLEAN_NOTFULL(v,val) do { \ DUK_ASSERT((val) == 0 || (val) == 1); \ (v)->ui[DUK_DBL_IDX_UI0] = (((unsigned int) DUK_TAG_BOOLEAN) << 16) | ((unsigned int) (val)); \ @@ -193,6 +179,7 @@ typedef union duk_tval duk_tval; #define DUK__TVAL_SET_NUMBER_NOTFULL(v,d) DUK__TVAL_SET_NUMBER_FULL(v,d) /* two casts to avoid gcc warning: "warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]" */ +#ifdef USE__64BIT #ifdef USE__ME_VARIANT #define DUK__TVAL_SET_TAGGEDPOINTER(v,h,tag) do { \ (v)->ull[DUK_DBL_IDX_ULL0] = (((unsigned long long) (tag)) << 16) | (((unsigned long long) (unsigned int) (h)) << 32); \ @@ -202,7 +189,14 @@ typedef union duk_tval duk_tval; (v)->ull[DUK_DBL_IDX_ULL0] = (((unsigned long long) (tag)) << 48) | ((unsigned long long) (unsigned int) (h)); \ } while (0) #endif +#else /* USE__64BIT */ +#define DUK__TVAL_SET_TAGGEDPOINTER(v,h,tag) do { \ + (v)->ui[DUK_DBL_IDX_UI0] = ((unsigned int) (tag)) << 16; \ + (v)->ui[DUK_DBL_IDX_UI1] = (unsigned int) (h); \ + } while (0) +#endif /* USE__64BIT */ +#ifdef USE__64BIT #ifdef USE__ME_VARIANT #define DUK__TVAL_SET_NAN_FULL(v) do { \ (v)->ull[DUK_DBL_IDX_ULL0] = 0x000000007ff80000ULL; \ @@ -212,6 +206,12 @@ typedef union duk_tval duk_tval; (v)->ull[DUK_DBL_IDX_ULL0] = 0x7ff8000000000000ULL; \ } while (0) #endif +#else /* USE__64BIT */ +#define DUK__TVAL_SET_NAN_FULL(v) do { \ + (v)->ui[DUK_DBL_IDX_UI0] = (unsigned int) 0x7ff80000; \ + (v)->ui[DUK_DBL_IDX_UI1] = (unsigned int) 0x00000000; \ + } while (0) +#endif /* USE__64BIT */ #define DUK__TVAL_SET_NAN_NOTFULL(v) do { \ (v)->us[DUK_DBL_IDX_US0] = 0x7ff8; \ @@ -285,17 +285,25 @@ typedef union duk_tval duk_tval; */ /* XXX: reading unsigned int instead of unsigned short is one byte shorter on x86 :) */ +#ifdef USE__64BIT #ifdef USE__ME_VARIANT #define DUK__DOUBLE_IS_NAN_FULL(d) \ /* E == 0x7ff, F != 0 => NaN */ \ (((((duk_tval *)(d))->us[DUK_DBL_IDX_US0] & 0x7ff0) == 0x7ff0) && \ - (((((duk_tval *)(d))->ull[DUK_DBL_IDX_ULL0]) & 0x000fffffffffffffULL) != 0)) + (((((duk_tval *)(d))->ull[DUK_DBL_IDX_ULL0]) & 0xffffffff000fffffULL) != 0)) #else #define DUK__DOUBLE_IS_NAN_FULL(d) \ /* E == 0x7ff, F != 0 => NaN */ \ (((((duk_tval *)(d))->us[DUK_DBL_IDX_US0] & 0x7ff0) == 0x7ff0) && \ - (((((duk_tval *)(d))->ull[DUK_DBL_IDX_ULL0]) & 0xffffffff000fffffULL) != 0)) + (((((duk_tval *)(d))->ull[DUK_DBL_IDX_ULL0]) & 0x000fffffffffffffULL) != 0)) #endif +#else /* USE__64BIT */ +#define DUK__DOUBLE_IS_NAN_FULL(d) \ + /* E == 0x7ff, F != 0 => NaN */ \ + (((((duk_tval *)(d))->ui[DUK_DBL_IDX_UI0] & 0x7ff00000) == 0x7ff00000) && \ + ((((duk_tval *)(d))->ui[DUK_DBL_IDX_UI0] & 0x000fffff) != 0 || \ + ((duk_tval *)(d))->ui[DUK_DBL_IDX_UI1] != 0)) +#endif /* USE__64BIT */ /* XXX: avoid possible double read? */ #define DUK__DOUBLE_IS_NAN_NOTFULL(d) \ @@ -315,6 +323,7 @@ typedef union duk_tval duk_tval; } \ } while (0) +#ifdef USE__64BIT #ifdef USE__ME_VARIANT #define DUK__DOUBLE_IS_NORMALIZED_NAN_FULL(d) \ (((duk_tval *)(d))->ull[DUK_DBL_IDX_ULL0] == 0x000000007ff80000ULL) @@ -322,6 +331,11 @@ typedef union duk_tval duk_tval; #define DUK__DOUBLE_IS_NORMALIZED_NAN_FULL(d) \ (((duk_tval *)(d))->ull[DUK_DBL_IDX_ULL0] == 0x7ff8000000000000ULL) #endif +#else /* USE__64BIT */ +#define DUK__DOUBLE_IS_NORMALIZED_NAN_FULL(d) \ + ((((duk_tval *)(d))->ui[DUK_DBL_IDX_UI0] == 0x7ff80000) && \ + (((duk_tval *)(d))->ui[DUK_DBL_IDX_UI1] == 0x00000000)) +#endif /* USE__64BIT */ #define DUK__DOUBLE_IS_NORMALIZED_NAN_NOTFULL(d) \ /* E == 0x7ff, F == 8 => normalized NaN */ \ @@ -496,6 +510,9 @@ struct duk_tval_struct { #ifdef USE__BE_VARIANT #undef USE__BE_VARIANT #endif +#ifdef USE__64BIT +#undef USE__64BIT +#endif #endif /* DUK_TVAL_H_INCLUDED */