Browse Source

add 32-bit only duk_tval.h handling, fix DUK__DOUBLE_IS_NAN_FULL() middle/other endian mixup

pull/1/head
Sami Vaarala 11 years ago
parent
commit
e1777427e3
  1. 6
      src/duk_features.h
  2. 93
      src/duk_tval.h

6
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

93
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 */

Loading…
Cancel
Save