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 */
41typedef 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 */
52static uint64_t
53ecma_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 */
218static inline int JERRY_ATTR_ALWAYS_INLINE
219ecma_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 */
236static 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 */
293static ecma_number_t
294ecma_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 */
365ecma_number_t
366ecma_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 */
722lit_utf8_size_t
723ecma_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 */
759uint32_t
760ecma_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 */
816int32_t
817ecma_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  */
867lit_utf8_size_t
868ecma_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 */
885inline static int32_t JERRY_ATTR_ALWAYS_INLINE
886ecma_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 */
903inline static void JERRY_ATTR_ALWAYS_INLINE
904ecma_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 */
937static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
938ecma_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 */
1003lit_utf8_size_t
1004ecma_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 */
1025lit_utf8_size_t
1026ecma_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