diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 50ccaabb6..f321958fe 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -1024,6 +1024,15 @@ typedef struct */ typedef float ecma_number_t; +/** + * It makes possible to read/write an ecma_number_t as uint32_t without strict aliasing rule violation. + */ +typedef union +{ + ecma_number_t as_ecma_number_t; + uint32_t as_uint32_t; +} ecma_number_accessor_t; + #define DOUBLE_TO_ECMA_NUMBER_T(value) (ecma_number_t) (value) /** @@ -1060,6 +1069,15 @@ typedef float ecma_number_t; */ typedef double ecma_number_t; +/** + * It makes possible to read/write an ecma_number_t as uint64_t without strict aliasing rule violation. + */ +typedef union +{ + ecma_number_t as_ecma_number_t; + uint64_t as_uint64_t; +} ecma_number_accessor_t; + #define DOUBLE_TO_ECMA_NUMBER_T(value) value /** diff --git a/jerry-core/ecma/base/ecma-helpers-number.c b/jerry-core/ecma/base/ecma-helpers-number.c index f905c3c08..ca0d5d527 100644 --- a/jerry-core/ecma/base/ecma-helpers-number.c +++ b/jerry-core/ecma/base/ecma-helpers-number.c @@ -58,15 +58,9 @@ ecma_number_pack (bool sign, /**< sign */ (biased_exp << ECMA_NUMBER_FRACTION_WIDTH) | ((uint32_t) fraction)); - union - { - uint32_t u32_value; - ecma_number_t float_value; - } u; - - u.u32_value = packed_value; - - return u.float_value; + ecma_number_accessor_t u; + u.as_uint32_t = packed_value; + return u.as_ecma_number_t; } /* ecma_number_pack */ /** @@ -78,15 +72,9 @@ ecma_number_unpack (ecma_number_t num, /**< ecma-number */ uint32_t *biased_exp_p, /**< [out] biased exponent (optional) */ uint64_t *fraction_p) /**< [out] fraction (optional) */ { - union - { - uint32_t u32_value; - ecma_number_t float_value; - } u; - - u.float_value = num; - - uint32_t packed_value = u.u32_value; + ecma_number_accessor_t u; + u.as_ecma_number_t = num; + uint32_t packed_value = u.as_uint32_t; if (sign_p != NULL) { @@ -133,15 +121,9 @@ ecma_number_pack (bool sign, /**< sign */ JERRY_ASSERT ((biased_exp & ~((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)) == 0); JERRY_ASSERT ((fraction & ~((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1)) == 0); - union - { - uint64_t u64_value; - ecma_number_t float_value; - } u; - - u.u64_value = packed_value; - - return u.float_value; + ecma_number_accessor_t u; + u.as_uint64_t = packed_value; + return u.as_ecma_number_t; } /* ecma_number_pack */ /** @@ -153,14 +135,9 @@ ecma_number_unpack (ecma_number_t num, /**< ecma-number */ uint32_t *biased_exp_p, /**< [out] biased exponent (optional) */ uint64_t *fraction_p) /**< [out] fraction (optional) */ { - union - { - uint64_t u64_value; - ecma_number_t float_value; - } u; - u.float_value = num; - - uint64_t packed_value = u.u64_value; + ecma_number_accessor_t u; + u.as_ecma_number_t = num; + uint64_t packed_value = u.as_uint64_t; if (sign_p != NULL) { @@ -267,9 +244,14 @@ ecma_number_is_nan (ecma_number_t num) /**< ecma-number */ ecma_number_t ecma_number_make_nan (void) { - return ecma_number_pack (false, - (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1u, - 1u); + /* IEEE754 QNaN = sign bit: 0, exponent: all 1 bits, fraction: 1....0 */ + ecma_number_accessor_t f; +#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) + f.as_uint64_t = 0x7ff8000000000000ull; /* double QNaN, same as the C99 nan("") returns. */ +#else /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ + f.as_uint32_t = 0x7fc00000u; /* float QNaN, same as the C99 nanf("") returns. */ +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ + return f.as_ecma_number_t; } /* ecma_number_make_nan */ /** @@ -282,9 +264,14 @@ ecma_number_t ecma_number_make_infinity (bool sign) /**< true - for negative Infinity, false - for positive Infinity */ { - return ecma_number_pack (sign, - (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1u, - 0u); + /* IEEE754 INF = sign bit: sign, exponent: all 1 bits, fraction: 0....0 */ + ecma_number_accessor_t f; +#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) + f.as_uint64_t = sign ? 0xfff0000000000000ull : 0x7ff0000000000000ull; +#else /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ + f.as_uint32_t = sign ? 0xff800000u : 0x7f800000u; +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ + return f.as_ecma_number_t; } /* ecma_number_make_infinity */ /** diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c index 8180f424b..7e0a7f855 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.c +++ b/jerry-core/ecma/base/ecma-helpers-value.c @@ -477,26 +477,12 @@ ecma_make_nan_value (void) static inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE ecma_is_number_equal_to_positive_zero (ecma_number_t ecma_number) /**< number */ { + ecma_number_accessor_t u; + u.as_ecma_number_t = ecma_number; #if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - union - { - uint32_t u32_value; - ecma_number_t float_value; - } u; - - u.float_value = ecma_number; - - return u.u32_value == 0; + return u.as_uint32_t == 0; #else /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - union - { - uint64_t u64_value; - ecma_number_t float_value; - } u; - - u.float_value = ecma_number; - - return u.u64_value == 0; + return u.as_uint64_t == 0; #endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ } /* ecma_is_number_equal_to_positive_zero */