• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <math.h>
17 
18 #include "ecma-globals.h"
19 #include "ecma-helpers.h"
20 #include "jrt-libc-includes.h"
21 #include "lit-char-helpers.h"
22 #include "lit-magic-strings.h"
23 
24 /** \addtogroup ecma ECMA
25  * @{
26  *
27  * \addtogroup ecmahelpers Helpers for operations with ECMA data types
28  * @{
29  */
30 
31 #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
32 
33 /**
34  * \addtogroup ecmahelpersbigintegers Helpers for operations intermediate 128-bit integers
35  * @{
36  */
37 
38 /**
39  * 128-bit integer type
40  */
41 typedef struct
42 {
43   uint64_t lo; /**< low 64 bits */
44   uint64_t hi; /**< high 64 bits */
45 } ecma_uint128_t;
46 
47 /**
48  * Round high part of 128-bit integer to uint64_t
49  *
50  * @return rounded high to uint64_t
51  */
52 static uint64_t
ecma_round_high_to_uint64(ecma_uint128_t * num_p)53 ecma_round_high_to_uint64 (ecma_uint128_t *num_p)
54 {
55   uint64_t masked_lo = num_p->lo & ~(1ULL << 63u);
56   uint64_t masked_hi = num_p->hi & 0x1;
57 
58   if ((num_p->lo >> 63u != 0)
59       && (masked_lo > 0 || masked_hi != 0))
60   {
61     return (num_p->hi + 1);
62   }
63   return num_p->hi;
64 } /* ecma_round_high_to_uint64 */
65 
66 /**
67  * Check if 128-bit integer is zero
68  */
69 #define ECMA_UINT128_IS_ZERO(name) \
70   (name.hi == 0 && name.lo == 0)
71 
72 /**
73  * Left shift 128-bit integer by max 63 bits
74  */
75 #define ECMA_UINT128_LEFT_SHIFT_MAX63(name, shift) \
76 { \
77   name.hi = (name.hi << (shift)) | (name.lo >> (64 - (shift))); \
78   name.lo <<= (shift); \
79 }
80 
81 /**
82  * Right shift 128-bit integer by max 63 bits
83  */
84 #define ECMA_UINT128_RIGHT_SHIFT_MAX63(name, shift) \
85 { \
86   name.lo = (name.lo >> (shift)) | (name.hi << (64 - (shift))); \
87   name.hi >>= (shift); \
88 }
89 
90 /**
91  * Add 128-bit integer
92  */
93 #define ECMA_UINT128_ADD(name_add_to, name_to_add) \
94 { \
95   name_add_to.hi += name_to_add.hi; \
96   name_add_to.lo += name_to_add.lo; \
97   if (name_add_to.lo < name_to_add.lo) \
98   { \
99     name_add_to.hi++; \
100   } \
101 }
102 
103 /**
104  * Multiply 128-bit integer by 10
105  */
106 #define ECMA_UINT128_MUL10(name) \
107 { \
108   ECMA_UINT128_LEFT_SHIFT_MAX63 (name, 1u); \
109   \
110   ecma_uint128_t name ## _tmp = name; \
111   \
112   ECMA_UINT128_LEFT_SHIFT_MAX63 (name ## _tmp, 2u); \
113   \
114   ECMA_UINT128_ADD (name, name ## _tmp); \
115 }
116 
117 /**
118  * Divide 128-bit integer by 10
119  *
120  * N = N3 *2^96  + N2 *2^64  + N1 *2^32  + N0 *2^0     // 128-bit dividend
121  * T = T3 *2^-32 + T2 *2^-64 + T1 *2^-96 + T0 *2^-128  // 128-bit divisor reciprocal, 1/10 * 2^-128
122  *
123  * N * T    = N3*T3 *2^64 + N2*T3 *2^32 + N1*T3 *2^0 + N0*T3 *2^-32
124  *          +               N3*T2 *2^32 + N2*T2 *2^0 + N1*T2 *2^-32 + N0*T2 *2^-64
125  *          +                             N3*T1 *2^0 + N2*T1 *2^-32 + N1*T1 *2^-64 + N0*T1 *2^-96
126  *          +                                          N3*T0 *2^-32 + N2*T0 *2^-64 + N1*T0 *2^-96 + N0*T0 *2^-128
127  *
128  *  Q3=carry  Q2=^+carry    Q1=^+carry    Q0=^+carry   fraction=^...
129  *
130  * Q = Q3 *2^96  + Q2 *2^64  + Q1 *2^32  + Q0 *2^0     // 128-bit quotient
131  */
132 #define ECMA_UINT128_DIV10(name) \
133 { \
134   /* estimation of reciprocal of 10, 128 bits right of the binary point (T1 == T2) */ \
135   const uint64_t tenth_l = 0x9999999aul; \
136   const uint64_t tenth_m = 0x99999999ul; \
137   const uint64_t tenth_h = 0x19999999ul; \
138   \
139   uint64_t l0 = ((uint32_t) name.lo) * tenth_l; \
140   uint64_t l1 = (name.lo >> 32u) * tenth_l; \
141   uint64_t l2 = ((uint32_t) name.hi) * tenth_l; \
142   uint64_t l3 = (name.hi >> 32u) * tenth_l; \
143   uint64_t m0 = ((uint32_t) name.lo) * tenth_m; \
144   uint64_t m1 = (name.lo >> 32u) * tenth_m; \
145   uint64_t m2 = ((uint32_t) name.hi) * tenth_m; \
146   uint64_t m3 = (name.hi >> 32u) * tenth_m; \
147   uint64_t h0 = ((uint32_t) name.lo) * tenth_h; \
148   uint64_t h1 = (name.lo >> 32u) * tenth_h; \
149   uint64_t h2 = ((uint32_t) name.hi) * tenth_h; \
150   uint64_t h3 = (name.hi >> 32u) * tenth_h; \
151   \
152   uint64_t q0 = l0 >> 32u; \
153   q0 += (uint32_t) l1; \
154   q0 += (uint32_t) m0; \
155   \
156   q0 >>= 32u; \
157   q0 += l1 >> 32u; \
158   q0 += m0 >> 32u; \
159   q0 += (uint32_t) l2; \
160   q0 += (uint32_t) m1; \
161   q0 += (uint32_t) m0; \
162   \
163   q0 >>= 32u; \
164   q0 += l2 >> 32u; \
165   q0 += m1 >> 32u; \
166   q0 += m0 >> 32u; \
167   q0 += (uint32_t) l3; \
168   q0 += (uint32_t) m2; \
169   q0 += (uint32_t) m1; \
170   q0 += (uint32_t) h0; \
171   \
172   q0 >>=32u; \
173   q0 += l3 >> 32u; \
174   q0 += m2 >> 32u; \
175   q0 += m1 >> 32u; \
176   q0 += h0 >> 32u; \
177   q0 += (uint32_t) m3; \
178   q0 += (uint32_t) m2; \
179   q0 += (uint32_t) h1; \
180   \
181   uint64_t q1 = q0 >> 32u; \
182   q1 += m3 >> 32u; \
183   q1 += m2 >> 32u; \
184   q1 += h1 >> 32u; \
185   q1 += (uint32_t) m3; \
186   q1 += (uint32_t) h2; \
187   \
188   uint64_t q32 = q1 >> 32u; \
189   q32 += m3 >> 32u; \
190   q32 += h2 >> 32u; \
191   q32 += h3; \
192   \
193   name.lo = (q1 << 32u) | ((uint32_t) q0); \
194   name.hi = q32; \
195 }
196 
197 #if defined (__GNUC__) || defined (__clang__)
198 
199 /**
200  * Count leading zeros in the topmost 64 bits of a 128-bit integer.
201  */
202 #define ECMA_UINT128_CLZ_MAX63(name) \
203   __builtin_clzll (name.hi)
204 
205 /**
206  * Count leading zeros in the topmost 4 bits of a 128-bit integer.
207  */
208 #define ECMA_UINT128_CLZ_MAX4(name) \
209   __builtin_clzll (name.hi)
210 
211 #else /* !__GNUC__ && !__clang__ */
212 
213 /**
214  * Count leading zeros in a 64-bit integer. The behaviour is undefined for 0.
215  *
216  * @return number of leading zeros.
217  */
218 static inline int JERRY_ATTR_ALWAYS_INLINE
ecma_uint64_clz(uint64_t n)219 ecma_uint64_clz (uint64_t n) /**< integer to count leading zeros in */
220 {
221   JERRY_ASSERT (n != 0);
222 
223   int cnt = 0;
224   uint64_t one = 0x8000000000000000ull;
225   while ((n & one) == 0)
226   {
227     cnt++;
228     one >>= 1;
229   }
230   return cnt;
231 } /* ecma_uint64_clz */
232 
233 /**
234  * Number of leading zeros in 4-bit integers.
235  */
236 static const uint8_t ecma_uint4_clz[] = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
237 
238 /**
239  * Count leading zeros in the topmost 64 bits of a 128-bit integer.
240  */
241 #define ECMA_UINT128_CLZ_MAX63(name) \
242   ecma_uint64_clz (name.hi)
243 
244 /**
245  * Count leading zeros in the topmost 4 bits of a 128-bit integer.
246  */
247 #define ECMA_UINT128_CLZ_MAX4(name) \
248   ecma_uint4_clz[name.hi >> 60]
249 
250 #endif /* __GNUC__ || __clang__ */
251 
252 /**
253  * @}
254  */
255 
256 /**
257  * Number.MAX_VALUE exponent part when using 64 bit float representation.
258  */
259 #define NUMBER_MAX_DECIMAL_EXPONENT 308
260 /**
261  * Number.MIN_VALUE exponent part when using 64 bit float representation.
262  */
263 #define NUMBER_MIN_DECIMAL_EXPONENT -324
264 
265 #elif !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
266 
267 /**
268  * Number.MAX_VALUE exponent part when using 32 bit float representation.
269  */
270 #define NUMBER_MAX_DECIMAL_EXPONENT 38
271 /**
272  * Number.MIN_VALUE exponent part when using 32 bit float representation.
273  */
274 #define NUMBER_MIN_DECIMAL_EXPONENT -45
275 
276 #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
277 
278 /**
279  * Value of epsilon
280  */
281 #define EPSILON 0.0000001
282 
283 /**
284  * ECMA-defined conversion from string to number for different radixes (2, 8, 16).
285  *
286  * See also:
287  *          ECMA-262 v5 9.3.1
288  *          ECMA-262 v6 7.1.3.1
289  *
290  * @return NaN - if the conversion fails
291  *         converted number - otherwise
292  */
293 static ecma_number_t
ecma_utf8_string_to_number_by_radix(const lit_utf8_byte_t * str_p,const lit_utf8_byte_t * end_p,uint32_t radix)294 ecma_utf8_string_to_number_by_radix (const lit_utf8_byte_t *str_p, /**< utf-8 string */
295                                      const lit_utf8_byte_t *end_p, /**< end of utf-8 string  */
296                                      uint32_t radix) /**< radix */
297 {
298   JERRY_ASSERT (radix == 2 || radix == 8 || radix == 16);
299   ecma_number_t num = ECMA_NUMBER_ZERO;
300 
301 #if ENABLED (JERRY_ES2015)
302   if (radix <= 8)
303   {
304     lit_code_point_t upper_limit = LIT_CHAR_0 + radix;
305 
306     for (const lit_utf8_byte_t * iter_p = str_p;  iter_p <= end_p; iter_p++)
307     {
308       int32_t digit_value;
309 
310       if (*iter_p >= LIT_CHAR_0 && *iter_p < upper_limit)
311       {
312         digit_value = (*iter_p - LIT_CHAR_0);
313       }
314       else
315       {
316         return ecma_number_make_nan ();
317       }
318 
319       num = num * radix + (ecma_number_t) digit_value;
320     }
321 
322     return num;
323   }
324 #endif /* ENABLED (JERRY_ES2015) */
325 
326   for (const lit_utf8_byte_t * iter_p = str_p; iter_p <= end_p; iter_p++)
327   {
328     int32_t digit_value;
329 
330     if (*iter_p >= LIT_CHAR_0
331         && *iter_p <= LIT_CHAR_9)
332     {
333       digit_value = (*iter_p - LIT_CHAR_0);
334     }
335     else if (*iter_p >= LIT_CHAR_LOWERCASE_A
336             && *iter_p <= LIT_CHAR_LOWERCASE_F)
337     {
338       digit_value = 10 + (*iter_p - LIT_CHAR_LOWERCASE_A);
339     }
340     else if (*iter_p >= LIT_CHAR_UPPERCASE_A
341             && *iter_p <= LIT_CHAR_UPPERCASE_F)
342     {
343       digit_value = 10 + (*iter_p - LIT_CHAR_UPPERCASE_A);
344     }
345     else
346     {
347       return ecma_number_make_nan ();
348     }
349 
350     num = num * radix + (ecma_number_t) digit_value;
351   }
352 
353   return num;
354 } /* ecma_utf8_string_to_number_by_radix */
355 
356 /**
357  * ECMA-defined conversion of string to Number.
358  *
359  * See also:
360  *          ECMA-262 v5, 9.3.1
361  *
362  * @return NaN - if the conversion fails
363  *         converted number - otherwise
364  */
365 ecma_number_t
ecma_utf8_string_to_number(const lit_utf8_byte_t * str_p,lit_utf8_size_t str_size)366 ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
367                             lit_utf8_size_t str_size) /**< string size */
368 {
369   /* TODO: Check license issues */
370 
371   if (str_size == 0)
372   {
373     return ECMA_NUMBER_ZERO;
374   }
375 
376   ecma_string_trim_helper (&str_p, &str_size);
377   const lit_utf8_byte_t *end_p = str_p + (str_size - 1);
378 
379   if (str_size < 1)
380   {
381     return ECMA_NUMBER_ZERO;
382   }
383 
384   if (end_p >= str_p + 2
385       && str_p[0] == LIT_CHAR_0)
386   {
387     switch (LEXER_TO_ASCII_LOWERCASE (str_p[1]))
388     {
389       case LIT_CHAR_LOWERCASE_X :
390       {
391         return ecma_utf8_string_to_number_by_radix (str_p + 2, end_p, 16);
392       }
393       case LIT_CHAR_LOWERCASE_O :
394       {
395         return ecma_utf8_string_to_number_by_radix (str_p + 2, end_p, 8);
396       }
397       case LIT_CHAR_LOWERCASE_B :
398       {
399         return ecma_utf8_string_to_number_by_radix (str_p + 2, end_p, 2);
400       }
401       default:
402       {
403         break;
404       }
405     }
406   }
407 
408   bool sign = false; /* positive */
409 
410   if (*str_p == LIT_CHAR_PLUS)
411   {
412     str_p++;
413   }
414   else if (*str_p == LIT_CHAR_MINUS)
415   {
416     sign = true; /* negative */
417 
418     str_p++;
419   }
420 
421   if (str_p > end_p)
422   {
423     return ecma_number_make_nan ();
424   }
425 
426   /* Checking if significant part of parse string is equal to "Infinity" */
427   const lit_utf8_byte_t *infinity_zt_str_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING_INFINITY_UL);
428 
429   JERRY_ASSERT (strlen ((const char *) infinity_zt_str_p) == 8);
430 
431   if ((end_p - str_p) == (8 - 1) && memcmp (infinity_zt_str_p, str_p, 8) == 0)
432   {
433     return ecma_number_make_infinity (sign);
434   }
435 
436   uint64_t fraction_uint64 = 0;
437   uint32_t digits = 0;
438   int32_t e = 0;
439   bool digit_seen = false;
440 
441   /* Parsing digits before dot (or before end of digits part if there is no dot in number) */
442   while (str_p <= end_p)
443   {
444     int32_t digit_value;
445 
446     if (*str_p >= LIT_CHAR_0
447         && *str_p <= LIT_CHAR_9)
448     {
449       digit_seen = true;
450       digit_value = (*str_p - LIT_CHAR_0);
451     }
452     else
453     {
454       break;
455     }
456 
457     if (digits != 0 || digit_value != 0)
458     {
459       if (digits < ECMA_NUMBER_MAX_DIGITS)
460       {
461         fraction_uint64 = fraction_uint64 * 10 + (uint32_t) digit_value;
462         digits++;
463       }
464       else
465       {
466         e++;
467       }
468     }
469 
470     str_p++;
471   }
472 
473   if (str_p <= end_p
474       && *str_p == LIT_CHAR_DOT)
475   {
476     str_p++;
477 
478     if (!digit_seen && str_p > end_p)
479     {
480       return ecma_number_make_nan ();
481     }
482 
483     /* Parsing number's part that is placed after dot */
484     while (str_p <= end_p)
485     {
486       int32_t digit_value;
487 
488       if (*str_p >= LIT_CHAR_0
489           && *str_p <= LIT_CHAR_9)
490       {
491         digit_seen = true;
492         digit_value = (*str_p - LIT_CHAR_0);
493       }
494       else
495       {
496         break;
497       }
498 
499       if (digits < ECMA_NUMBER_MAX_DIGITS)
500       {
501         if (digits != 0 || digit_value != 0)
502         {
503           fraction_uint64 = fraction_uint64 * 10 + (uint32_t) digit_value;
504           digits++;
505         }
506 
507         e--;
508       }
509 
510       str_p++;
511     }
512   }
513 
514   /* Parsing exponent literal */
515   int32_t e_in_lit = 0;
516   bool e_in_lit_sign = false;
517 
518   if (str_p <= end_p
519       && (*str_p == LIT_CHAR_LOWERCASE_E
520           || *str_p == LIT_CHAR_UPPERCASE_E))
521   {
522     str_p++;
523 
524     if (!digit_seen || str_p > end_p)
525     {
526       return ecma_number_make_nan ();
527     }
528 
529     if (*str_p == LIT_CHAR_PLUS)
530     {
531       str_p++;
532     }
533     else if (*str_p == LIT_CHAR_MINUS)
534     {
535       e_in_lit_sign = true;
536       str_p++;
537     }
538 
539     if (str_p > end_p)
540     {
541       return ecma_number_make_nan ();
542     }
543 
544     while (str_p <= end_p)
545     {
546       int32_t digit_value;
547 
548       if (*str_p >= LIT_CHAR_0
549           && *str_p <= LIT_CHAR_9)
550       {
551         digit_value = (*str_p - LIT_CHAR_0);
552       }
553       else
554       {
555         return ecma_number_make_nan ();
556       }
557 
558       e_in_lit = e_in_lit * 10 + digit_value;
559       int32_t e_check = e + (int32_t) digits - 1  + (e_in_lit_sign ? -e_in_lit : e_in_lit);
560 
561       if (e_check > NUMBER_MAX_DECIMAL_EXPONENT)
562       {
563         return ecma_number_make_infinity (sign);
564       }
565       else if (e_check < NUMBER_MIN_DECIMAL_EXPONENT)
566       {
567         return sign ? -ECMA_NUMBER_ZERO : ECMA_NUMBER_ZERO;
568       }
569 
570       str_p++;
571     }
572   }
573 
574   /* Adding value of exponent literal to exponent value */
575   if (e_in_lit_sign)
576   {
577     e -= e_in_lit;
578   }
579   else
580   {
581     e += e_in_lit;
582   }
583 
584   bool e_sign;
585 
586   if (e < 0)
587   {
588     e_sign = true;
589     e = -e;
590   }
591   else
592   {
593     e_sign = false;
594   }
595 
596   if (str_p <= end_p)
597   {
598     return ecma_number_make_nan ();
599   }
600 
601   JERRY_ASSERT (str_p == end_p + 1);
602 
603   if (fraction_uint64 == 0)
604   {
605     return sign ? -ECMA_NUMBER_ZERO : ECMA_NUMBER_ZERO;
606   }
607 
608 #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
609   /*
610    * 128-bit mantissa storage
611    *
612    * Normalized: |4 bits zero|124-bit mantissa with highest bit set to 1|
613    */
614   ecma_uint128_t fraction_uint128 = { 0, fraction_uint64 };
615 
616   /* Normalizing mantissa */
617   int shift = 4 - ECMA_UINT128_CLZ_MAX63 (fraction_uint128);
618   if (shift < 0)
619   {
620     ECMA_UINT128_LEFT_SHIFT_MAX63 (fraction_uint128, -shift);
621   }
622   else
623   {
624     ECMA_UINT128_RIGHT_SHIFT_MAX63 (fraction_uint128, shift);
625   }
626   int32_t binary_exponent = 1 + shift;
627 
628   if (!e_sign)
629   {
630     /* positive or zero decimal exponent */
631     JERRY_ASSERT (e >= 0);
632 
633     while (e > 0)
634     {
635       JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 4);
636 
637       ECMA_UINT128_MUL10 (fraction_uint128);
638 
639       e--;
640 
641       /* Normalizing mantissa */
642       shift = 4 - ECMA_UINT128_CLZ_MAX4 (fraction_uint128);
643       JERRY_ASSERT (shift >= 0);
644       ECMA_UINT128_RIGHT_SHIFT_MAX63 (fraction_uint128, shift);
645       binary_exponent += shift;
646     }
647   }
648   else
649   {
650     /* negative decimal exponent */
651     JERRY_ASSERT (e != 0);
652 
653     while (e > 0)
654     {
655       /* Denormalizing mantissa, moving highest 1 to bit 127 */
656       shift = ECMA_UINT128_CLZ_MAX4 (fraction_uint128);
657       JERRY_ASSERT (shift <= 4);
658       ECMA_UINT128_LEFT_SHIFT_MAX63 (fraction_uint128, shift);
659       binary_exponent -= shift;
660 
661       JERRY_ASSERT (!ECMA_UINT128_IS_ZERO (fraction_uint128));
662 
663       ECMA_UINT128_DIV10 (fraction_uint128);
664 
665       e--;
666     }
667 
668     /* Normalizing mantissa */
669     shift = 4 - ECMA_UINT128_CLZ_MAX4 (fraction_uint128);
670     JERRY_ASSERT (shift >= 0);
671     ECMA_UINT128_RIGHT_SHIFT_MAX63 (fraction_uint128, shift);
672     binary_exponent += shift;
673 
674     JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 4);
675   }
676 
677   JERRY_ASSERT (!ECMA_UINT128_IS_ZERO (fraction_uint128));
678   JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 4);
679 
680   /*
681    * Preparing mantissa for conversion to 52-bit representation, converting it to:
682    *
683    * |11 zero bits|1|116 mantissa bits|
684    */
685   ECMA_UINT128_RIGHT_SHIFT_MAX63 (fraction_uint128, 7u);
686   binary_exponent += 7;
687 
688   JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 11);
689 
690   fraction_uint64 = ecma_round_high_to_uint64 (&fraction_uint128);
691 
692   return ecma_number_make_from_sign_mantissa_and_exponent (sign, fraction_uint64, binary_exponent);
693 #elif !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
694   /* Less precise conversion */
695   ecma_number_t num = (ecma_number_t) (uint32_t) fraction_uint64;
696 
697   ecma_number_t m = e_sign ? (ecma_number_t) 0.1 : (ecma_number_t) 10.0;
698 
699   while (e)
700   {
701     if (e % 2)
702     {
703       num *= m;
704     }
705 
706     m *= m;
707     e /= 2;
708   }
709 
710   return num;
711 #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
712 } /* ecma_utf8_string_to_number */
713 
714 /**
715  * ECMA-defined conversion of UInt32 to String (zero-terminated).
716  *
717  * See also:
718  *          ECMA-262 v5, 9.8.1
719  *
720  * @return number of bytes copied to buffer
721  */
722 lit_utf8_size_t
ecma_uint32_to_utf8_string(uint32_t value,lit_utf8_byte_t * out_buffer_p,lit_utf8_size_t buffer_size)723 ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
724                             lit_utf8_byte_t *out_buffer_p, /**< buffer for string */
725                             lit_utf8_size_t buffer_size) /**< size of buffer */
726 {
727   lit_utf8_byte_t *buf_p = out_buffer_p + buffer_size;
728 
729   do
730   {
731     JERRY_ASSERT (buf_p >= out_buffer_p);
732 
733     buf_p--;
734     *buf_p = (lit_utf8_byte_t) ((value % 10) + LIT_CHAR_0);
735     value /= 10;
736   }
737   while (value != 0);
738 
739   JERRY_ASSERT (buf_p >= out_buffer_p);
740 
741   lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (out_buffer_p + buffer_size - buf_p);
742 
743   if (JERRY_LIKELY (buf_p != out_buffer_p))
744   {
745     memmove (out_buffer_p, buf_p, bytes_copied);
746   }
747 
748   return bytes_copied;
749 } /* ecma_uint32_to_utf8_string */
750 
751 /**
752  * ECMA-defined conversion of Number value to UInt32 value
753  *
754  * See also:
755  *          ECMA-262 v5, 9.6
756  *
757  * @return 32-bit unsigned integer - result of conversion.
758  */
759 uint32_t
ecma_number_to_uint32(ecma_number_t num)760 ecma_number_to_uint32 (ecma_number_t num) /**< ecma-number */
761 {
762   if (JERRY_UNLIKELY (ecma_number_is_zero (num) || !ecma_number_is_finite (num)))
763   {
764     return 0;
765   }
766 
767   const bool sign = ecma_number_is_negative (num);
768   const ecma_number_t abs_num = sign ? -num : num;
769 
770   /* 2 ^ 32 */
771   const uint64_t uint64_2_pow_32 = (1ull << 32);
772 
773   const ecma_number_t num_2_pow_32 = (float) uint64_2_pow_32;
774 
775   ecma_number_t num_in_uint32_range;
776 
777   if (abs_num >= num_2_pow_32)
778   {
779     num_in_uint32_range = ecma_number_calc_remainder (abs_num,
780                                                       num_2_pow_32);
781   }
782   else
783   {
784     num_in_uint32_range = abs_num;
785   }
786 
787   /* Check that the floating point value can be represented with uint32_t. */
788   JERRY_ASSERT (num_in_uint32_range < uint64_2_pow_32);
789   uint32_t uint32_num = (uint32_t) num_in_uint32_range;
790 
791   const uint32_t ret = sign ? -uint32_num : uint32_num;
792 
793 #ifndef JERRY_NDEBUG
794   if (sign
795       && uint32_num != 0)
796   {
797     JERRY_ASSERT (ret == uint64_2_pow_32 - uint32_num);
798   }
799   else
800   {
801     JERRY_ASSERT (ret == uint32_num);
802   }
803 #endif /* !JERRY_NDEBUG */
804 
805   return ret;
806 } /* ecma_number_to_uint32 */
807 
808 /**
809  * ECMA-defined conversion of Number value to Int32 value
810  *
811  * See also:
812  *          ECMA-262 v5, 9.5
813  *
814  * @return 32-bit signed integer - result of conversion.
815  */
816 int32_t
ecma_number_to_int32(ecma_number_t num)817 ecma_number_to_int32 (ecma_number_t num) /**< ecma-number */
818 {
819   uint32_t uint32_num = ecma_number_to_uint32 (num);
820 
821   /* 2 ^ 32 */
822   const int64_t int64_2_pow_32 = (1ll << 32);
823 
824   /* 2 ^ 31 */
825   const uint32_t uint32_2_pow_31 = (1ull << 31);
826 
827   int32_t ret;
828 
829   if (uint32_num >= uint32_2_pow_31)
830   {
831     ret = (int32_t) (uint32_num - int64_2_pow_32);
832   }
833   else
834   {
835     ret = (int32_t) uint32_num;
836   }
837 
838 #ifndef JERRY_NDEBUG
839   int64_t int64_num = uint32_num;
840 
841   JERRY_ASSERT (int64_num >= 0);
842 
843   if (int64_num >= uint32_2_pow_31)
844   {
845     JERRY_ASSERT (ret == int64_num - int64_2_pow_32);
846   }
847   else
848   {
849     JERRY_ASSERT (ret == int64_num);
850   }
851 #endif /* !JERRY_NDEBUG */
852 
853   return ret;
854 } /* ecma_number_to_int32 */
855 
856 /**
857   * Perform conversion of ecma-number to decimal representation with decimal exponent.
858   *
859   * Note:
860   *      The calculated values correspond to s, n, k parameters in ECMA-262 v5, 9.8.1, item 5:
861   *         - parameter out_digits_p corresponds to s, the digits of the number;
862   *         - parameter out_decimal_exp_p corresponds to n, the decimal exponent;
863   *         - return value corresponds to k, the number of digits.
864   *
865   * @return the number of digits
866   */
867 lit_utf8_size_t
ecma_number_to_decimal(ecma_number_t num,lit_utf8_byte_t * out_digits_p,int32_t * out_decimal_exp_p)868 ecma_number_to_decimal (ecma_number_t num, /**< ecma-number */
869                         lit_utf8_byte_t *out_digits_p, /**< [out] buffer to fill with digits */
870                         int32_t *out_decimal_exp_p) /**< [out] decimal exponent */
871 {
872   JERRY_ASSERT (!ecma_number_is_nan (num));
873   JERRY_ASSERT (!ecma_number_is_zero (num));
874   JERRY_ASSERT (!ecma_number_is_infinity (num));
875   JERRY_ASSERT (!ecma_number_is_negative (num));
876 
877   return ecma_errol0_dtoa ((double) num, out_digits_p, out_decimal_exp_p);
878 } /* ecma_number_to_decimal */
879 
880 /**
881  * Calculate the number of digits from the given double value whithout franction part
882  *
883  * @return number of digits
884  */
885 inline static int32_t JERRY_ATTR_ALWAYS_INLINE
ecma_number_of_digits(double val)886 ecma_number_of_digits (double val) /**< ecma number */
887 {
888   JERRY_ASSERT (fabs (fmod (val, 1.0)) < EPSILON);
889   int32_t exponent = 0;
890 
891   while (val >= 1.0)
892   {
893     val /= 10.0;
894     exponent++;
895   }
896 
897   return exponent;
898 } /* ecma_number_of_digits */
899 
900 /**
901  * Convert double value to ASCII
902  */
903 inline static void JERRY_ATTR_ALWAYS_INLINE
ecma_double_to_ascii(double val,lit_utf8_byte_t * buffer_p,int32_t num_of_digits,int32_t * exp_p)904 ecma_double_to_ascii (double val, /**< ecma number */
905                       lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
906                       int32_t num_of_digits, /**< number of digits */
907                       int32_t *exp_p) /**< [out] exponent */
908 {
909   int32_t char_cnt = 0;
910 
911   double divider = 10.0;
912   double prev_residual;
913   double mod_res = fmod (val, divider);
914 
915   buffer_p[num_of_digits - 1 - char_cnt++] = (lit_utf8_byte_t) ((int) mod_res + '0');
916   divider *= 10.0;
917   prev_residual = mod_res;
918 
919   while (char_cnt < num_of_digits)
920   {
921     mod_res = fmod (val, divider);
922     double residual = mod_res - prev_residual;
923     buffer_p[num_of_digits - 1 - char_cnt++] = (lit_utf8_byte_t) ((int) (residual / (divider / 10.0)) + '0');
924 
925     divider *= 10.0;
926     prev_residual = mod_res;
927   }
928 
929   *exp_p = char_cnt;
930 } /* ecma_double_to_ascii */
931 
932 /**
933  * Double to binary floating-point number conversion
934  *
935  * @return number of generated digits
936  */
937 static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
ecma_double_to_binary_floating_point(double val,lit_utf8_byte_t * buffer_p,int32_t * exp_p)938 ecma_double_to_binary_floating_point (double val, /**< ecma number */
939                                       lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
940                                       int32_t *exp_p) /**< [out] exponent */
941 {
942   int32_t char_cnt = 0;
943   double integer_part, fraction_part;
944 
945   fraction_part = fmod (val, 1.0);
946   integer_part = floor (val);
947   int32_t num_of_digits = ecma_number_of_digits (integer_part);
948 
949   if (fabs (integer_part) < EPSILON)
950   {
951     buffer_p[0] = '0';
952     char_cnt++;
953   }
954   else if (num_of_digits <= 16) /* Ensure that integer_part is not rounded */
955   {
956     while (integer_part > 0.0)
957     {
958       buffer_p[num_of_digits - 1 - char_cnt++] = (lit_utf8_byte_t) ((int) fmod (integer_part, 10.0) + '0');
959       integer_part = floor (integer_part / 10.0);
960     }
961   }
962   else if (num_of_digits <= 21)
963   {
964     ecma_double_to_ascii (integer_part, buffer_p, num_of_digits, &char_cnt);
965   }
966   else
967   {
968     /* According to ECMA-262 v5, 15.7.4.5, step 7: if x >= 10^21, then execution will continue with
969      * ToString(x) so in this case no further conversions are required. Number 21 in the else if condition
970      * above must be kept in sync with the number 21 in ecma_builtin_number_prototype_object_to_fixed
971      * method, step 7. */
972     *exp_p = num_of_digits;
973     return 0;
974   }
975 
976   *exp_p = char_cnt;
977 
978   while (fraction_part > 0 && char_cnt < ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER - 1)
979   {
980     fraction_part *= 10;
981     double tmp = fraction_part;
982     fraction_part = fmod (fraction_part, 1.0);
983     integer_part = floor (tmp);
984     buffer_p[char_cnt++] = (lit_utf8_byte_t) ('0' + (int) integer_part);
985   }
986 
987   buffer_p[char_cnt] = '\0';
988 
989   return (lit_utf8_size_t) (char_cnt - *exp_p);
990 } /* ecma_double_to_binary_floating_point */
991 
992 /**
993  * Perform conversion of ecma-number to equivalent binary floating-point number representation with decimal exponent.
994  *
995  * Note:
996  *      The calculated values correspond to s, n, k parameters in ECMA-262 v5, 9.8.1, item 5:
997  *         - parameter out_digits_p corresponds to s, the digits of the number;
998  *         - parameter out_decimal_exp_p corresponds to n, the decimal exponent;
999  *         - return value corresponds to k, the number of digits.
1000  *
1001  * @return the number of digits
1002  */
1003 lit_utf8_size_t
ecma_number_to_binary_floating_point_number(ecma_number_t num,lit_utf8_byte_t * out_digits_p,int32_t * out_decimal_exp_p)1004 ecma_number_to_binary_floating_point_number (ecma_number_t num, /**< ecma-number */
1005                                              lit_utf8_byte_t *out_digits_p, /**< [out] buffer to fill with digits */
1006                                              int32_t *out_decimal_exp_p) /**< [out] decimal exponent */
1007 {
1008   JERRY_ASSERT (!ecma_number_is_nan (num));
1009   JERRY_ASSERT (!ecma_number_is_zero (num));
1010   JERRY_ASSERT (!ecma_number_is_infinity (num));
1011   JERRY_ASSERT (!ecma_number_is_negative (num));
1012 
1013   return ecma_double_to_binary_floating_point ((double) num, out_digits_p, out_decimal_exp_p);
1014 } /* ecma_number_to_binary_floating_point_number */
1015 
1016 /**
1017  * Convert ecma-number to zero-terminated string
1018  *
1019  * See also:
1020  *          ECMA-262 v5, 9.8.1
1021  *
1022  *
1023  * @return size of utf-8 string
1024  */
1025 lit_utf8_size_t
ecma_number_to_utf8_string(ecma_number_t num,lit_utf8_byte_t * buffer_p,lit_utf8_size_t buffer_size)1026 ecma_number_to_utf8_string (ecma_number_t num, /**< ecma-number */
1027                             lit_utf8_byte_t *buffer_p, /**< buffer for utf-8 string */
1028                             lit_utf8_size_t buffer_size) /**< size of buffer */
1029 {
1030   lit_utf8_byte_t *dst_p;
1031 
1032   if (ecma_number_is_nan (num))
1033   {
1034     /* 1. */
1035     dst_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_NAN, buffer_p, buffer_size);
1036     return (lit_utf8_size_t) (dst_p - buffer_p);
1037   }
1038 
1039   if (ecma_number_is_zero (num))
1040   {
1041     /* 2. */
1042     *buffer_p = LIT_CHAR_0;
1043     JERRY_ASSERT (1 <= buffer_size);
1044     return 1;
1045   }
1046 
1047   dst_p = buffer_p;
1048 
1049   if (ecma_number_is_negative (num))
1050   {
1051     /* 3. */
1052     *dst_p++ = LIT_CHAR_MINUS;
1053     num = -num;
1054   }
1055 
1056   if (ecma_number_is_infinity (num))
1057   {
1058     /* 4. */
1059     dst_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_INFINITY_UL, dst_p,
1060                                              (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
1061     JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
1062     return (lit_utf8_size_t) (dst_p - buffer_p);
1063   }
1064 
1065   JERRY_ASSERT (ecma_number_get_next (ecma_number_get_prev (num)) == num);
1066 
1067   /* 5. */
1068   uint32_t num_uint32 = ecma_number_to_uint32 (num);
1069 
1070   if (((ecma_number_t) num_uint32) == num)
1071   {
1072     dst_p += ecma_uint32_to_utf8_string (num_uint32, dst_p, (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
1073     JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
1074     return (lit_utf8_size_t) (dst_p - buffer_p);
1075   }
1076 
1077   /* decimal exponent */
1078   int32_t n;
1079   /* number of digits in mantissa */
1080   int32_t k;
1081 
1082   k = (int32_t) ecma_number_to_decimal (num, dst_p, &n);
1083 
1084   if (k <= n && n <= 21)
1085   {
1086     /* 6. */
1087     dst_p += k;
1088 
1089     memset (dst_p, LIT_CHAR_0, (size_t) (n - k));
1090     dst_p += n - k;
1091 
1092     JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
1093     return (lit_utf8_size_t) (dst_p - buffer_p);
1094   }
1095 
1096   if (0 < n && n <= 21)
1097   {
1098     /* 7. */
1099     memmove (dst_p + n + 1, dst_p + n, (size_t) (k - n));
1100     *(dst_p + n) = LIT_CHAR_DOT;
1101     dst_p += k + 1;
1102 
1103     JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
1104     return (lit_utf8_size_t) (dst_p - buffer_p);
1105   }
1106 
1107   if (-6 < n && n <= 0)
1108   {
1109     /* 8. */
1110     memmove (dst_p + 2 - n, dst_p, (size_t) k);
1111     memset (dst_p + 2, LIT_CHAR_0, (size_t) -n);
1112     *dst_p = LIT_CHAR_0;
1113     *(dst_p + 1) = LIT_CHAR_DOT;
1114     dst_p += k - n + 2;
1115 
1116     JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
1117     return (lit_utf8_size_t) (dst_p - buffer_p);
1118   }
1119 
1120   if (k == 1)
1121   {
1122     /* 9. */
1123     dst_p++;
1124   }
1125   else
1126   {
1127     /* 10. */
1128     memmove (dst_p + 2, dst_p + 1, (size_t) (k - 1));
1129     *(dst_p + 1) = LIT_CHAR_DOT;
1130     dst_p += k + 1;
1131   }
1132 
1133   /* 9., 10. */
1134   *dst_p++ = LIT_CHAR_LOWERCASE_E;
1135   *dst_p++ = (n >= 1) ? LIT_CHAR_PLUS : LIT_CHAR_MINUS;
1136   uint32_t t = (uint32_t) (n >= 1 ? (n - 1) : -(n - 1));
1137 
1138   dst_p += ecma_uint32_to_utf8_string (t, dst_p, (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
1139 
1140   JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
1141 
1142   return (lit_utf8_size_t) (dst_p - buffer_p);
1143 } /* ecma_number_to_utf8_string */
1144 
1145 /**
1146  * @}
1147  * @}
1148  */
1149