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-conversion.h"
19#include "lit-char-helpers.h"
20
21/** \addtogroup ecma ECMA
22 * @{
23 *
24 * \addtogroup ecmahelpers Helpers for operations with ECMA data types
25 * @{
26 */
27
28JERRY_STATIC_ASSERT (sizeof (ecma_value_t) == sizeof (ecma_integer_value_t),
29                     size_of_ecma_value_t_must_be_equal_to_the_size_of_ecma_integer_value_t);
30
31JERRY_STATIC_ASSERT (ECMA_DIRECT_SHIFT == ECMA_VALUE_SHIFT + 1,
32                     currently_directly_encoded_values_has_one_extra_flag);
33
34JERRY_STATIC_ASSERT (((1 << (ECMA_DIRECT_SHIFT - 1)) | ECMA_TYPE_DIRECT) == ECMA_DIRECT_TYPE_SIMPLE_VALUE,
35                     currently_directly_encoded_values_start_after_direct_type_simple_value);
36/**
37 * Position of the sign bit in ecma-numbers
38 */
39#define ECMA_NUMBER_SIGN_POS (ECMA_NUMBER_FRACTION_WIDTH + \
40                              ECMA_NUMBER_BIASED_EXP_WIDTH)
41
42#if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
43JERRY_STATIC_ASSERT (sizeof (ecma_number_t) == sizeof (uint32_t),
44                     size_of_ecma_number_t_must_be_equal_to_4_bytes);
45
46/**
47 * Packing sign, fraction and biased exponent to ecma-number
48 *
49 * @return ecma-number with specified sign, biased_exponent and fraction
50 */
51static ecma_number_t
52ecma_number_pack (bool sign, /**< sign */
53                  uint32_t biased_exp, /**< biased exponent */
54                  uint64_t fraction) /**< fraction */
55{
56  JERRY_ASSERT ((biased_exp & ~((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)) == 0);
57  JERRY_ASSERT ((fraction & ~((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1)) == 0);
58
59  uint32_t packed_value = (((sign ? 1u : 0u) << ECMA_NUMBER_SIGN_POS) |
60                           (biased_exp << ECMA_NUMBER_FRACTION_WIDTH) |
61                           ((uint32_t) fraction));
62
63  ecma_number_accessor_t u;
64  u.as_uint32_t = packed_value;
65  return u.as_ecma_number_t;
66} /* ecma_number_pack */
67
68/**
69 * Unpacking sign, fraction and biased exponent from ecma-number
70 */
71static void
72ecma_number_unpack (ecma_number_t num, /**< ecma-number */
73                    bool *sign_p, /**< [out] sign (optional) */
74                    uint32_t *biased_exp_p, /**< [out] biased exponent (optional) */
75                    uint64_t *fraction_p) /**< [out] fraction (optional) */
76{
77  ecma_number_accessor_t u;
78  u.as_ecma_number_t = num;
79  uint32_t packed_value = u.as_uint32_t;
80
81  if (sign_p != NULL)
82  {
83    *sign_p = ((packed_value >> ECMA_NUMBER_SIGN_POS) != 0);
84  }
85
86  if (biased_exp_p != NULL)
87  {
88    *biased_exp_p = (((packed_value) & ~(1u << ECMA_NUMBER_SIGN_POS)) >> ECMA_NUMBER_FRACTION_WIDTH);
89  }
90
91  if (fraction_p != NULL)
92  {
93    *fraction_p = (packed_value & ((1u << ECMA_NUMBER_FRACTION_WIDTH) - 1));
94  }
95} /* ecma_number_unpack */
96
97/**
98 * Value used to calculate exponent from biased exponent
99 *
100 * See also:
101 *          IEEE-754 2008, 3.6, Table 3.5
102 */
103const int32_t ecma_number_exponent_bias = 127;
104
105#elif ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
106JERRY_STATIC_ASSERT (sizeof (ecma_number_t) == sizeof (uint64_t),
107                     size_of_ecma_number_t_must_be_equal_to_8_bytes);
108
109/**
110 * Packing sign, fraction and biased exponent to ecma-number
111 *
112 * @return ecma-number with specified sign, biased_exponent and fraction
113 */
114static ecma_number_t
115ecma_number_pack (bool sign, /**< sign */
116                  uint32_t biased_exp, /**< biased exponent */
117                  uint64_t fraction) /**< fraction */
118{
119  uint64_t packed_value = (((sign ? 1ull : 0ull) << ECMA_NUMBER_SIGN_POS) |
120                           (((uint64_t) biased_exp) << ECMA_NUMBER_FRACTION_WIDTH) |
121                           fraction);
122
123  JERRY_ASSERT ((biased_exp & ~((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)) == 0);
124  JERRY_ASSERT ((fraction & ~((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1)) == 0);
125
126  ecma_number_accessor_t u;
127  u.as_uint64_t = packed_value;
128  return u.as_ecma_number_t;
129} /* ecma_number_pack */
130
131/**
132 * Unpacking sign, fraction and biased exponent from ecma-number
133 */
134static void
135ecma_number_unpack (ecma_number_t num, /**< ecma-number */
136                    bool *sign_p, /**< [out] sign (optional) */
137                    uint32_t *biased_exp_p, /**< [out] biased exponent (optional) */
138                    uint64_t *fraction_p) /**< [out] fraction (optional) */
139{
140  ecma_number_accessor_t u;
141  u.as_ecma_number_t = num;
142  uint64_t packed_value = u.as_uint64_t;
143
144  if (sign_p != NULL)
145  {
146    *sign_p = ((packed_value >> ECMA_NUMBER_SIGN_POS) != 0);
147  }
148
149  if (biased_exp_p != NULL)
150  {
151    *biased_exp_p = (uint32_t) (((packed_value) & ~(1ull << ECMA_NUMBER_SIGN_POS)) >> ECMA_NUMBER_FRACTION_WIDTH);
152  }
153
154  if (fraction_p != NULL)
155  {
156    *fraction_p = (packed_value & ((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1));
157  }
158} /* ecma_number_unpack */
159
160/**
161 * Value used to calculate exponent from biased exponent
162 *
163 * See also:
164 *          IEEE-754 2008, 3.6, Table 3.5
165 */
166const int32_t ecma_number_exponent_bias = 1023;
167
168#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
169
170/**
171 * Get fraction of number
172 *
173 * @return normalized fraction field of number
174 */
175static uint64_t
176ecma_number_get_fraction_field (ecma_number_t num) /**< ecma-number */
177{
178  uint64_t fraction;
179
180  ecma_number_unpack (num, NULL, NULL, &fraction);
181
182  return fraction;
183} /* ecma_number_get_fraction_field */
184
185/**
186 * Get exponent of number
187 *
188 * @return exponent corresponding to normalized fraction of number
189 */
190static uint32_t
191ecma_number_get_biased_exponent_field (ecma_number_t num) /**< ecma-number */
192{
193  uint32_t biased_exp;
194
195  ecma_number_unpack (num, NULL, &biased_exp, NULL);
196
197  return biased_exp;
198} /* ecma_number_get_biased_exponent_field */
199
200/**
201 * Get sign bit of number
202 *
203 * @return 0 or 1 - value of sign bit
204 */
205static uint32_t
206ecma_number_get_sign_field (ecma_number_t num) /**< ecma-number */
207{
208  bool sign;
209
210  ecma_number_unpack (num, &sign, NULL, NULL);
211
212  return sign;
213} /* ecma_number_get_sign_field */
214
215/**
216 * Check if ecma-number is NaN
217 *
218 * @return true - if biased exponent is filled with 1 bits and
219                  fraction is filled with anything but not all zero bits,
220 *         false - otherwise
221 */
222extern inline bool JERRY_ATTR_ALWAYS_INLINE
223ecma_number_is_nan (ecma_number_t num) /**< ecma-number */
224{
225  bool is_nan = (num != num);
226
227#ifndef JERRY_NDEBUG
228  uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
229  uint64_t fraction = ecma_number_get_fraction_field (num);
230
231   /* IEEE-754 2008, 3.4, a */
232  bool is_nan_ieee754 = ((biased_exp == (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)
233                         && (fraction != 0));
234
235  JERRY_ASSERT (is_nan == is_nan_ieee754);
236#endif /* !JERRY_NDEBUG */
237
238  return is_nan;
239} /* ecma_number_is_nan */
240
241/**
242 * Make a NaN.
243 *
244 * @return NaN value
245 */
246ecma_number_t
247ecma_number_make_nan (void)
248{
249  /* IEEE754 QNaN = sign bit: 0, exponent: all 1 bits, fraction: 1....0 */
250  ecma_number_accessor_t f;
251#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
252  f.as_uint64_t = 0x7ff8000000000000ull; /* double QNaN, same as the C99 nan("") returns. */
253#else /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
254  f.as_uint32_t = 0x7fc00000u;  /* float QNaN, same as the C99 nanf("") returns. */
255#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
256  return f.as_ecma_number_t;
257} /* ecma_number_make_nan */
258
259/**
260 * Make an Infinity.
261 *
262 * @return if !sign - +Infinity value,
263 *         else - -Infinity value.
264 */
265ecma_number_t
266ecma_number_make_infinity (bool sign) /**< true - for negative Infinity,
267                                           false - for positive Infinity */
268{
269  /* IEEE754 INF = sign bit: sign, exponent: all 1 bits, fraction: 0....0 */
270  ecma_number_accessor_t f;
271#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
272  f.as_uint64_t = sign ? 0xfff0000000000000ull : 0x7ff0000000000000ull;
273#else /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
274  f.as_uint32_t = sign ? 0xff800000u : 0x7f800000u;
275#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
276  return f.as_ecma_number_t;
277} /* ecma_number_make_infinity */
278
279/**
280 * Check if ecma-number is negative
281 *
282 * @return true - if sign bit of ecma-number is set
283 *         false - otherwise
284 */
285inline bool JERRY_ATTR_ALWAYS_INLINE
286ecma_number_is_negative (ecma_number_t num) /**< ecma-number */
287{
288  JERRY_ASSERT (!ecma_number_is_nan (num));
289
290  /* IEEE-754 2008, 3.4 */
291  return (ecma_number_get_sign_field (num) != 0);
292} /* ecma_number_is_negative */
293
294/**
295 * Check if ecma-number is zero
296 *
297 * @return true - if fraction is zero and biased exponent is zero,
298 *         false - otherwise
299 */
300bool
301ecma_number_is_zero (ecma_number_t num) /**< ecma-number */
302{
303  bool is_zero = (num == ECMA_NUMBER_ZERO);
304
305#ifndef JERRY_NDEBUG
306  /* IEEE-754 2008, 3.4, e */
307  bool is_zero_ieee754 = (ecma_number_get_fraction_field (num) == 0
308                          && ecma_number_get_biased_exponent_field (num) == 0);
309
310  JERRY_ASSERT (is_zero == is_zero_ieee754);
311#endif /* !JERRY_NDEBUG */
312
313  return is_zero;
314} /* ecma_number_is_zero */
315
316/**
317 * Check if number is infinity
318 *
319 * @return true - if biased exponent is filled with 1 bits and
320 *                fraction is filled with zero bits,
321 *         false - otherwise
322 */
323bool
324ecma_number_is_infinity (ecma_number_t num) /**< ecma-number */
325{
326  uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
327  uint64_t fraction = ecma_number_get_fraction_field (num);
328
329  /* IEEE-754 2008, 3.4, b */
330  return ((biased_exp  == (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)
331          && (fraction == 0));
332} /* ecma_number_is_infinity */
333
334/**
335 * Check if number is finite
336 *
337 * @return true  - if number is finite
338 *         false - if number is NaN or infinity
339 */
340extern inline bool JERRY_ATTR_ALWAYS_INLINE
341ecma_number_is_finite (ecma_number_t num) /**< ecma-number */
342{
343#if defined (__GNUC__) || defined (__clang__)
344  return __builtin_isfinite (num);
345#elif defined (WIN32)
346  return isfinite (num);
347#else
348  return !ecma_number_is_nan (num) && !ecma_number_is_infinity (num);
349#endif /* defined (__GNUC__) || defined (__clang__) */
350} /* ecma_number_is_finite */
351
352/**
353 * Get fraction and exponent of the number
354 *
355 * @return shift of dot in the fraction
356 */
357static int32_t
358ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */
359                                       uint64_t *out_fraction_p, /**< [out] fraction of the number */
360                                       int32_t *out_exponent_p) /**< [out] exponent of the number */
361{
362  JERRY_ASSERT (!ecma_number_is_nan (num));
363
364  uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
365  uint64_t fraction = ecma_number_get_fraction_field (num);
366  int32_t exponent;
367
368  if (JERRY_UNLIKELY (biased_exp == 0))
369  {
370    /* IEEE-754 2008, 3.4, d */
371    if (ecma_number_is_zero (num))
372    {
373      exponent = -ecma_number_exponent_bias;
374    }
375    else
376    {
377      exponent = 1 - ecma_number_exponent_bias;
378
379      while (!(fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)))
380      {
381        JERRY_ASSERT (fraction != 0);
382
383        fraction <<= 1;
384        exponent--;
385      }
386    }
387  }
388  else if (ecma_number_is_infinity (num))
389  {
390    /* The fraction and exponent should round to infinity */
391    exponent = (int32_t) biased_exp - ecma_number_exponent_bias;
392
393    JERRY_ASSERT ((fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) == 0);
394    fraction |= 1ull << ECMA_NUMBER_FRACTION_WIDTH;
395  }
396  else
397  {
398    /* IEEE-754 2008, 3.4, c */
399    exponent = (int32_t) biased_exp - ecma_number_exponent_bias;
400
401    JERRY_ASSERT (biased_exp > 0 && biased_exp < (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1);
402    JERRY_ASSERT ((fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) == 0);
403    fraction |= 1ull << ECMA_NUMBER_FRACTION_WIDTH;
404  }
405
406  *out_fraction_p = fraction;
407  *out_exponent_p = exponent;
408  return ECMA_NUMBER_FRACTION_WIDTH;
409} /* ecma_number_get_fraction_and_exponent */
410
411/**
412 * Make normalised positive Number from given fraction and exponent
413 *
414 * @return ecma-number
415 */
416static ecma_number_t
417ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t fraction, /**< fraction */
418                                                             int32_t exponent) /**< exponent */
419{
420  uint32_t biased_exp = (uint32_t) (exponent + ecma_number_exponent_bias);
421  JERRY_ASSERT (biased_exp > 0 && biased_exp < (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1);
422  JERRY_ASSERT ((fraction & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1)) == 0);
423  JERRY_ASSERT ((fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) != 0);
424
425  return ecma_number_pack (false,
426                           biased_exp,
427                           fraction & ~(1ull << ECMA_NUMBER_FRACTION_WIDTH));
428} /* ecma_number_make_normal_positive_from_fraction_and_exponent */
429
430/**
431 * Make Number of given sign from given mantissa value and binary exponent
432 *
433 * @return ecma-number (possibly Infinity of specified sign)
434 */
435ecma_number_t
436ecma_number_make_from_sign_mantissa_and_exponent (bool sign, /**< true - for negative sign,
437                                                                  false - for positive sign */
438                                                  uint64_t mantissa, /**< mantissa */
439                                                  int32_t exponent) /**< binary exponent */
440{
441  /* Rounding mantissa to fit into fraction field width */
442  if (mantissa & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1))
443  {
444    /* Rounded mantissa looks like the following: |00...0|1|fraction_width mantissa bits| */
445    while ((mantissa & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1)) != 0)
446    {
447      uint64_t rightmost_bit = (mantissa & 1);
448
449      exponent++;
450      mantissa >>= 1;
451
452      if ((mantissa & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1)) == 0)
453      {
454        /* Rounding to nearest value */
455        mantissa += rightmost_bit;
456
457        /* In the first case loop is finished,
458           and in the second - just one shift follows and then loop finishes */
459        JERRY_ASSERT (((mantissa & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1)) == 0)
460                      || (mantissa == (1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1))));
461      }
462    }
463  }
464
465  /* Normalizing mantissa */
466  while (mantissa != 0
467         && ((mantissa & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) == 0))
468  {
469    exponent--;
470    mantissa <<= 1;
471  }
472
473  /* Moving floating point */
474  exponent += ECMA_NUMBER_FRACTION_WIDTH - 1;
475
476  int32_t biased_exp_signed = exponent + ecma_number_exponent_bias;
477
478  if (biased_exp_signed < 1)
479  {
480    /* Denormalizing mantissa if biased_exponent is less than zero */
481    while (biased_exp_signed < 0)
482    {
483      biased_exp_signed++;
484      mantissa >>= 1;
485    }
486
487    /* Rounding to nearest value */
488    mantissa += 1;
489    mantissa >>= 1;
490
491    /* Encoding denormalized exponent */
492    biased_exp_signed = 0;
493  }
494  else
495  {
496    /* Clearing highest mantissa bit that should have been non-zero if mantissa is non-zero */
497    mantissa &= ~(1ull << ECMA_NUMBER_FRACTION_WIDTH);
498  }
499
500  uint32_t biased_exp = (uint32_t) biased_exp_signed;
501
502  if (biased_exp >= ((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1))
503  {
504    return ecma_number_make_infinity (sign);
505  }
506
507  JERRY_ASSERT (biased_exp < (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1);
508  JERRY_ASSERT ((mantissa & ~((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1)) == 0);
509
510  return ecma_number_pack (sign,
511                           biased_exp,
512                           mantissa);
513} /* ecma_number_make_from_sign_mantissa_and_exponent */
514
515/**
516 * Get previous representable ecma-number
517 *
518 * @return maximum ecma-number that is less compared to passed argument
519 */
520ecma_number_t
521ecma_number_get_prev (ecma_number_t num) /**< ecma-number */
522{
523  JERRY_ASSERT (!ecma_number_is_nan (num));
524  JERRY_ASSERT (!ecma_number_is_zero (num));
525
526  if (ecma_number_is_negative (num))
527  {
528    return -ecma_number_get_next (num);
529  }
530
531  uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
532  uint64_t fraction = ecma_number_get_fraction_field (num);
533
534  if (fraction == 0 && biased_exp != 0)
535  {
536    fraction = (1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1;
537
538    biased_exp--;
539  }
540  else
541  {
542    fraction--;
543  }
544
545  return ecma_number_pack (false,
546                           biased_exp,
547                           fraction);
548} /* ecma_number_get_prev */
549
550/**
551 * Get next representable ecma-number
552 *
553 * @return minimum ecma-number that is greater compared to passed argument
554 */
555ecma_number_t
556ecma_number_get_next (ecma_number_t num) /**< ecma-number */
557{
558  JERRY_ASSERT (!ecma_number_is_nan (num));
559  JERRY_ASSERT (!ecma_number_is_infinity (num));
560
561  if (ecma_number_is_negative (num))
562  {
563    return -ecma_number_get_prev (num);
564  }
565
566  uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
567  uint64_t fraction = ecma_number_get_fraction_field (num);
568
569  fraction |= (1ull << ECMA_NUMBER_FRACTION_WIDTH);
570
571  fraction++;
572
573  if ((fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) == 0)
574  {
575    fraction >>= 1;
576
577    biased_exp++;
578  }
579
580  JERRY_ASSERT (fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH));
581
582  fraction &= ~(1ull << ECMA_NUMBER_FRACTION_WIDTH);
583
584  return ecma_number_pack (false,
585                           biased_exp,
586                           fraction);
587} /* ecma_number_get_next */
588
589/**
590 * Truncate fractional part of the number
591 *
592 * @return integer part of the number
593 */
594ecma_number_t
595ecma_number_trunc (ecma_number_t num) /**< ecma-number */
596{
597  JERRY_ASSERT (!ecma_number_is_nan (num));
598
599  uint64_t fraction;
600  int32_t exponent;
601  const int32_t dot_shift = ecma_number_get_fraction_and_exponent (num, &fraction, &exponent);
602  const bool sign = ecma_number_is_negative (num);
603
604  if (exponent < 0)
605  {
606    return ECMA_NUMBER_ZERO;
607  }
608  else if (exponent < dot_shift)
609  {
610    fraction &= ~((1ull << (dot_shift - exponent)) - 1);
611
612    ecma_number_t tmp = ecma_number_make_normal_positive_from_fraction_and_exponent (fraction,
613                                                                                     exponent);
614    if (sign)
615    {
616      return -tmp;
617    }
618    else
619    {
620      return tmp;
621    }
622  }
623  else
624  {
625    return num;
626  }
627} /* ecma_number_trunc */
628
629/**
630 * Calculate remainder of division of two numbers,
631 * as specified in ECMA-262 v5, 11.5.3, item 6.
632 *
633 * Note:
634 *      operands shouldn't contain NaN, Infinity, or zero.
635 *
636 * @return number - calculated remainder.
637 */
638ecma_number_t
639ecma_number_calc_remainder (ecma_number_t left_num, /**< left operand */
640                            ecma_number_t right_num) /**< right operand */
641{
642  JERRY_ASSERT (!ecma_number_is_nan (left_num)
643                && !ecma_number_is_zero (left_num)
644                && !ecma_number_is_infinity (left_num));
645  JERRY_ASSERT (!ecma_number_is_nan (right_num)
646                && !ecma_number_is_zero (right_num)
647                && !ecma_number_is_infinity (right_num));
648
649  const ecma_number_t q = ecma_number_trunc (left_num / right_num);
650  ecma_number_t r = left_num - right_num * q;
651
652  if (ecma_number_is_zero (r)
653      && ecma_number_is_negative (left_num))
654  {
655    r = -r;
656  }
657
658  return r;
659} /* ecma_number_calc_remainder */
660
661/**
662 * Compute power operation according to the ES standard.
663 *
664 * @return x ** y
665 */
666ecma_number_t
667ecma_number_pow (ecma_number_t x, /**< left operand */
668                 ecma_number_t y) /**< right operand */
669{
670  if (ecma_number_is_nan (y) ||
671      (ecma_number_is_infinity (y) && (x == 1.0 || x == -1.0)))
672  {
673    /* Handle differences between ES5.1 and ISO C standards for pow. */
674    return ecma_number_make_nan ();
675  }
676
677  if (ecma_number_is_zero (y))
678  {
679    /* Handle differences between ES5.1 and ISO C standards for pow. */
680    return (ecma_number_t) 1.0;
681  }
682
683  return DOUBLE_TO_ECMA_NUMBER_T (pow (x, y));
684} /* ecma_number_pow */
685
686/**
687 * ECMA-integer number multiplication.
688 *
689 * @return number - result of multiplication.
690 */
691inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
692ecma_integer_multiply (ecma_integer_value_t left_integer, /**< left operand */
693                       ecma_integer_value_t right_integer) /**< right operand */
694{
695#if defined (__GNUC__) || defined (__clang__)
696  /* Check if left_integer is power of 2 */
697  if (JERRY_UNLIKELY ((left_integer & (left_integer - 1)) == 0))
698  {
699    /* Right shift right_integer with log2 (left_integer) */
700    return ecma_make_integer_value (right_integer << (__builtin_ctz ((unsigned int) left_integer)));
701  }
702  else if (JERRY_UNLIKELY ((right_integer & (right_integer - 1)) == 0))
703  {
704    /* Right shift left_integer with log2 (right_integer) */
705    return ecma_make_integer_value (left_integer << (__builtin_ctz ((unsigned int) right_integer)));
706  }
707#endif /* defined (__GNUC__) || defined (__clang__) */
708  return ecma_make_integer_value (left_integer * right_integer);
709} /* ecma_integer_multiply */
710
711/**
712 * The Number object's 'parseInt' routine
713 *
714 * See also:
715 *          ECMA-262 v5, 15.1.2.2
716 *
717 * @return ecma value
718 *         Returned value must be freed with ecma_free_value.
719 */
720ecma_value_t
721ecma_number_parse_int (const lit_utf8_byte_t *string_buff, /**< routine's first argument's
722                                                            *   string buffer */
723                        lit_utf8_size_t string_buff_size, /**< routine's first argument's
724                                                           *   string buffer's size */
725                        ecma_value_t radix) /**< routine's second argument */
726{
727  if (string_buff_size == 0)
728  {
729    return ecma_make_nan_value ();
730  }
731
732  const lit_utf8_byte_t *string_curr_p = string_buff;
733
734  /* 2. Remove leading whitespace. */
735  ecma_string_trim_helper (&string_curr_p, &string_buff_size);
736
737  const lit_utf8_byte_t *string_end_p = string_curr_p + string_buff_size;
738  const lit_utf8_byte_t *start_p = string_curr_p;
739  const lit_utf8_byte_t *end_p = string_end_p;
740
741  if (string_curr_p >= string_end_p)
742  {
743    return ecma_make_nan_value ();
744  }
745
746  /* 3. */
747  int sign = 1;
748
749  /* 4. */
750  ecma_char_t current = lit_cesu8_read_next (&string_curr_p);
751  if (current == LIT_CHAR_MINUS)
752  {
753    sign = -1;
754  }
755
756  /* 5. */
757  if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
758  {
759    start_p = string_curr_p;
760    if (string_curr_p < string_end_p)
761    {
762      current = lit_cesu8_read_next (&string_curr_p);
763    }
764  }
765
766  /* 6. */
767  ecma_number_t radix_num;
768  radix = ecma_get_number (radix, &radix_num);
769
770  if (!ecma_is_value_empty (radix))
771  {
772    return radix;
773  }
774
775  int32_t rad = ecma_number_to_int32 (radix_num);
776
777  /* 7.*/
778  bool strip_prefix = true;
779
780  /* 8. */
781  if (rad != 0)
782  {
783    /* 8.a */
784    if (rad < 2 || rad > 36)
785    {
786      return ecma_make_nan_value ();
787    }
788    /* 8.b */
789    else if (rad != 16)
790    {
791      strip_prefix = false;
792    }
793  }
794  /* 9. */
795  else
796  {
797    rad = 10;
798  }
799
800  /* 10. */
801  if (strip_prefix
802      && ((end_p - start_p) >= 2)
803      && (current == LIT_CHAR_0))
804  {
805    ecma_char_t next = *string_curr_p;
806    if (next == LIT_CHAR_LOWERCASE_X || next == LIT_CHAR_UPPERCASE_X)
807    {
808      /* Skip the 'x' or 'X' characters. */
809      start_p = ++string_curr_p;
810      rad = 16;
811    }
812  }
813
814  /* 11. Check if characters are in [0, Radix - 1]. We also convert them to number values in the process. */
815  string_curr_p = start_p;
816  while (string_curr_p < string_end_p)
817  {
818    ecma_char_t current_char = *string_curr_p++;
819    int32_t current_number;
820
821    if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
822    {
823      current_number = current_char - LIT_CHAR_LOWERCASE_A + 10;
824    }
825    else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
826    {
827      current_number = current_char - LIT_CHAR_UPPERCASE_A + 10;
828    }
829    else if (lit_char_is_decimal_digit (current_char))
830    {
831      current_number = current_char - LIT_CHAR_0;
832    }
833    else
834    {
835      /* Not a valid number char, set value to radix so it fails to pass as a valid character. */
836      current_number = rad;
837    }
838
839    if (!(current_number < rad))
840    {
841      end_p = --string_curr_p;
842      break;
843    }
844  }
845
846  /* 12. */
847  if (end_p == start_p)
848  {
849    return ecma_make_nan_value ();
850  }
851
852  ecma_number_t value = ECMA_NUMBER_ZERO;
853  ecma_number_t multiplier = 1.0f;
854
855  /* 13. and 14. */
856  string_curr_p = end_p;
857
858  while (string_curr_p > start_p)
859  {
860    ecma_char_t current_char = *(--string_curr_p);
861    ecma_number_t current_number = ECMA_NUMBER_MINUS_ONE;
862
863    if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
864    {
865      current_number = (ecma_number_t) current_char - LIT_CHAR_LOWERCASE_A + 10;
866    }
867    else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
868    {
869      current_number = (ecma_number_t) current_char - LIT_CHAR_UPPERCASE_A + 10;
870    }
871    else
872    {
873      JERRY_ASSERT (lit_char_is_decimal_digit (current_char));
874      current_number = (ecma_number_t) current_char - LIT_CHAR_0;
875    }
876
877    value += current_number * multiplier;
878    multiplier *= (ecma_number_t) rad;
879  }
880
881  /* 15. */
882  if (sign < 0)
883  {
884    value *= (ecma_number_t) sign;
885  }
886  return ecma_make_number_value (value);
887} /* ecma_number_parse_int */
888
889/**
890 * The Number object's 'parseFloat' routine
891 *
892 * See also:
893 *          ECMA-262 v5, 15.1.2.2
894 *
895 * @return ecma value
896 *         Returned value must be freed with ecma_free_value.
897 */
898ecma_value_t
899ecma_number_parse_float (const lit_utf8_byte_t *string_buff, /**< routine's first argument's
900                                                              *   string buffer */
901                          lit_utf8_size_t string_buff_size) /**< routine's first argument's
902                                                             *   string buffer's size */
903{
904  if (string_buff_size == 0)
905  {
906    return ecma_make_nan_value ();
907  }
908
909  const lit_utf8_byte_t *str_curr_p = string_buff;
910
911  /* 2. Remove leading whitespace. */
912  ecma_string_trim_helper (&str_curr_p, &string_buff_size);
913
914  const lit_utf8_byte_t *str_end_p = str_curr_p + string_buff_size;
915  const lit_utf8_byte_t *start_p = str_curr_p;
916  const lit_utf8_byte_t *end_p = str_end_p;
917
918  bool sign = false;
919  ecma_char_t current;
920
921  if (str_curr_p < str_end_p)
922  {
923    /* Check if sign is present. */
924    current = *str_curr_p;
925    if (current == LIT_CHAR_MINUS)
926    {
927      sign = true;
928    }
929
930    if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
931    {
932      /* Set starting position to be after the sign character. */
933      start_p = ++str_curr_p;
934    }
935  }
936
937  /* Check if string is equal to "Infinity". */
938  const lit_utf8_byte_t *infinity_str_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING_INFINITY_UL);
939  const lit_utf8_size_t infinity_length = lit_get_magic_string_size (LIT_MAGIC_STRING_INFINITY_UL);
940
941  /* The input string should be at least the length of "Infinity" to be correctly processed as
942   * the infinity value.
943   */
944  if ((str_end_p - str_curr_p) >= (int) infinity_length
945      && memcmp (infinity_str_p, str_curr_p, infinity_length) == 0)
946  {
947    /* String matched Infinity. */
948    return ecma_make_number_value (ecma_number_make_infinity (sign));
949  }
950
951  /* Reset to starting position. */
952  str_curr_p = start_p;
953
954  /* String ended after sign character, or was empty after removing leading whitespace. */
955  if (str_curr_p >= str_end_p)
956  {
957    return ecma_make_nan_value ();
958  }
959
960  /* Reset to starting position. */
961  str_curr_p = start_p;
962
963  current = *str_curr_p;
964
965  bool has_whole_part = false;
966  bool has_fraction_part = false;
967
968  /* Check digits of whole part. */
969  if (lit_char_is_decimal_digit (current))
970  {
971    has_whole_part = true;
972    str_curr_p++;
973
974    while (str_curr_p < str_end_p)
975    {
976      current = *str_curr_p++;
977      if (!lit_char_is_decimal_digit (current))
978      {
979        str_curr_p--;
980        break;
981      }
982    }
983  }
984
985  /* Set end position to the end of whole part. */
986  end_p = str_curr_p;
987  if (str_curr_p < str_end_p)
988  {
989    current = *str_curr_p;
990
991    /* Check decimal point. */
992    if (current == LIT_CHAR_DOT)
993    {
994      str_curr_p++;
995
996      if (str_curr_p < str_end_p)
997      {
998        current = *str_curr_p;
999
1000        if (lit_char_is_decimal_digit (current))
1001        {
1002          has_fraction_part = true;
1003
1004          /* Check digits of fractional part. */
1005          while (str_curr_p < str_end_p)
1006          {
1007            current = *str_curr_p++;
1008            if (!lit_char_is_decimal_digit (current))
1009            {
1010              str_curr_p--;
1011              break;
1012            }
1013          }
1014
1015          /* Set end position to end of fraction part. */
1016          end_p = str_curr_p;
1017        }
1018      }
1019    }
1020  }
1021
1022  if (str_curr_p < str_end_p)
1023  {
1024    current = *str_curr_p++;
1025  }
1026
1027  /* Check exponent. */
1028  if ((current == LIT_CHAR_LOWERCASE_E || current == LIT_CHAR_UPPERCASE_E)
1029      && (has_whole_part || has_fraction_part)
1030      && str_curr_p < str_end_p)
1031  {
1032    current = *str_curr_p++;
1033
1034    /* Check sign of exponent. */
1035    if ((current == LIT_CHAR_PLUS || current == LIT_CHAR_MINUS)
1036         && str_curr_p < str_end_p)
1037    {
1038      current = *str_curr_p++;
1039    }
1040
1041    if (lit_char_is_decimal_digit (current))
1042    {
1043      /* Check digits of exponent part. */
1044      while (str_curr_p < str_end_p)
1045      {
1046        current = *str_curr_p++;
1047        if (!lit_char_is_decimal_digit (current))
1048        {
1049          str_curr_p--;
1050          break;
1051        }
1052      }
1053
1054      /* Set end position to end of exponent part. */
1055      end_p = str_curr_p;
1056    }
1057  }
1058
1059  /* String did not contain a valid number. */
1060  if (start_p == end_p)
1061  {
1062    return ecma_make_nan_value ();
1063  }
1064
1065  /* 5. */
1066  ecma_number_t ret_num = ecma_utf8_string_to_number (start_p, (lit_utf8_size_t) (end_p - start_p));
1067
1068  if (sign)
1069  {
1070    ret_num *= ECMA_NUMBER_MINUS_ONE;
1071  }
1072
1073  return ecma_make_number_value (ret_num);
1074} /* ecma_number_parse_float */
1075
1076/**
1077 * @}
1078 * @}
1079 */
1080