Optimize number-to-string conversion
* Make constants static in `ecma_number_to_utf8_string`. * Make `ecma_number_to_utf8_string` use early returns, and rewrite its self-recursion in case of negative numbers. * Make the stringification of decimal exponent in `ecma_number_to_utf8_string` use `ecma_uint32_to_utf8_string`. * Changed ERROL0 dtoa implementation to use the `double` type instead of `ecma_number_t`. Thus, even is `ecma_number_t` is 32 bit wide, the algorithm works the same. * Changed `ecma_number_to_decimal` to use the ERROL0 dtoa algorithm for 32-bit floats as well. * Changed `ecma_number_to_decimal` to generate the decimal string representation of the mantissa instead of an `uint64_t` number. * Changed `ecma_number_to_utf8_string` to make use of the already available string representation of the mantissa, generated now by `ecma_number_to_decimal`. * Changed `ecma_number_to_utf8_string` not to use static arrays and variables for digit, "e", etc. generation. * Changed all `Number.prototype.toXXX` implementations and the `ecma_builtin_number_prototype_helper_round` helper to make use of the already available string representation of the mantissa, generated now by `ecma_number_to_decimal`. * Factored out the common stringification parts of all `Number.prototype.toXXX` implementations into a new helper `ecma_builtin_number_prototype_helper_to_string`. JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
This commit is contained in:
committed by
Zoltan Herczeg
parent
65542549af
commit
30fd549e7f
@@ -49,8 +49,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
|
||||
|
||||
/**
|
||||
* Printing Floating-Point Numbers
|
||||
*
|
||||
@@ -70,8 +68,8 @@
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_number_t value; /**< value */
|
||||
ecma_number_t offset; /**< offset */
|
||||
double value; /**< value */
|
||||
double offset; /**< offset */
|
||||
} ecma_high_prec_t;
|
||||
|
||||
/**
|
||||
@@ -80,7 +78,7 @@ typedef struct
|
||||
static inline void __attr_always_inline___
|
||||
ecma_normalize_high_prec_data (ecma_high_prec_t *hp_data_p) /**< [in, out] float pair */
|
||||
{
|
||||
ecma_number_t val = hp_data_p->value;
|
||||
double val = hp_data_p->value;
|
||||
|
||||
hp_data_p->value += hp_data_p->offset;
|
||||
hp_data_p->offset += val - hp_data_p->value;
|
||||
@@ -92,12 +90,12 @@ ecma_normalize_high_prec_data (ecma_high_prec_t *hp_data_p) /**< [in, out] float
|
||||
static inline void __attr_always_inline___
|
||||
ecma_multiply_high_prec_by_10 (ecma_high_prec_t *hp_data_p) /**< [in, out] high-precision number */
|
||||
{
|
||||
ecma_number_t value = hp_data_p->value;
|
||||
double value = hp_data_p->value;
|
||||
|
||||
hp_data_p->value *= 10.0;
|
||||
hp_data_p->offset *= 10.0;
|
||||
|
||||
ecma_number_t offset = hp_data_p->value;
|
||||
double offset = hp_data_p->value;
|
||||
|
||||
offset -= value * 8.0;
|
||||
offset -= value * 2.0;
|
||||
@@ -113,7 +111,7 @@ ecma_multiply_high_prec_by_10 (ecma_high_prec_t *hp_data_p) /**< [in, out] high-
|
||||
static void
|
||||
ecma_divide_high_prec_by_10 (ecma_high_prec_t *hp_data_p) /**< [in, out] high-precision number */
|
||||
{
|
||||
ecma_number_t value = hp_data_p->value;
|
||||
double value = hp_data_p->value;
|
||||
|
||||
hp_data_p->value /= 10.0;
|
||||
hp_data_p->offset /= 10.0;
|
||||
@@ -129,15 +127,13 @@ ecma_divide_high_prec_by_10 (ecma_high_prec_t *hp_data_p) /**< [in, out] high-pr
|
||||
/**
|
||||
* Errol0 double to ASCII conversion, guaranteed correct but possibly not optimal.
|
||||
*
|
||||
* @return digits
|
||||
* @return number of generated digits
|
||||
*/
|
||||
inline uint64_t __attr_always_inline___
|
||||
ecma_errol0_dtoa (ecma_number_t val, /**< ecma number */
|
||||
int32_t *num_of_digits_p, /**< [out] number of digits */
|
||||
inline lit_utf8_size_t __attr_always_inline___
|
||||
ecma_errol0_dtoa (double val, /**< ecma number */
|
||||
lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
|
||||
int32_t *exp_p) /**< [out] exponent */
|
||||
{
|
||||
uint64_t digits = 0u;
|
||||
int32_t num_of_digits = 0;
|
||||
double power_of_10 = 1.0;
|
||||
int32_t exp = 1;
|
||||
|
||||
@@ -195,6 +191,8 @@ ecma_errol0_dtoa (ecma_number_t val, /**< ecma number */
|
||||
|
||||
/* digit generation */
|
||||
|
||||
lit_utf8_byte_t *dst_p = buffer_p;
|
||||
|
||||
while (high_bound.value != 0.0 || high_bound.offset != 0.0)
|
||||
{
|
||||
uint8_t high_digit = (uint8_t) high_bound.value;
|
||||
@@ -216,9 +214,7 @@ ecma_errol0_dtoa (ecma_number_t val, /**< ecma number */
|
||||
break;
|
||||
}
|
||||
|
||||
digits *= 10;
|
||||
digits += (uint64_t) high_digit;
|
||||
num_of_digits++;
|
||||
*dst_p++ = (lit_utf8_byte_t) ('0' + high_digit);
|
||||
|
||||
high_bound.value -= high_digit;
|
||||
ecma_multiply_high_prec_by_10 (&high_bound);
|
||||
@@ -228,16 +224,13 @@ ecma_errol0_dtoa (ecma_number_t val, /**< ecma number */
|
||||
}
|
||||
|
||||
double mdig = (high_bound.value + low_bound.value) / 2.0 + 0.5;
|
||||
*dst_p++ = (lit_utf8_byte_t) ('0' + (uint8_t) mdig);
|
||||
|
||||
*num_of_digits_p = num_of_digits + 1;
|
||||
*exp_p = exp;
|
||||
digits *= 10;
|
||||
|
||||
return digits + (uint64_t) mdig;
|
||||
return (lit_utf8_size_t) (dst_p - buffer_p);
|
||||
} /* ecma_errol0_dtoa */
|
||||
|
||||
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
Reference in New Issue
Block a user