• 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-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 
28 JERRY_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 
31 JERRY_STATIC_ASSERT (ECMA_DIRECT_SHIFT == ECMA_VALUE_SHIFT + 1,
32                      currently_directly_encoded_values_has_one_extra_flag);
33 
34 JERRY_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)
43 JERRY_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  */
51 static ecma_number_t
ecma_number_pack(bool sign,uint32_t biased_exp,uint64_t fraction)52 ecma_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  */
71 static void
ecma_number_unpack(ecma_number_t num,bool * sign_p,uint32_t * biased_exp_p,uint64_t * fraction_p)72 ecma_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  */
103 const int32_t ecma_number_exponent_bias = 127;
104 
105 #elif ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
106 JERRY_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  */
114 static ecma_number_t
ecma_number_pack(bool sign,uint32_t biased_exp,uint64_t fraction)115 ecma_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  */
134 static void
ecma_number_unpack(ecma_number_t num,bool * sign_p,uint32_t * biased_exp_p,uint64_t * fraction_p)135 ecma_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  */
166 const 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  */
175 static uint64_t
ecma_number_get_fraction_field(ecma_number_t num)176 ecma_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  */
190 static uint32_t
ecma_number_get_biased_exponent_field(ecma_number_t num)191 ecma_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  */
205 static uint32_t
ecma_number_get_sign_field(ecma_number_t num)206 ecma_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  */
222 extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_number_is_nan(ecma_number_t num)223 ecma_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  */
246 ecma_number_t
ecma_number_make_nan(void)247 ecma_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  */
265 ecma_number_t
ecma_number_make_infinity(bool sign)266 ecma_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  */
285 inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_number_is_negative(ecma_number_t num)286 ecma_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  */
300 bool
ecma_number_is_zero(ecma_number_t num)301 ecma_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  */
323 bool
ecma_number_is_infinity(ecma_number_t num)324 ecma_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  */
340 extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_number_is_finite(ecma_number_t num)341 ecma_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  */
357 static int32_t
ecma_number_get_fraction_and_exponent(ecma_number_t num,uint64_t * out_fraction_p,int32_t * out_exponent_p)358 ecma_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  */
416 static ecma_number_t
ecma_number_make_normal_positive_from_fraction_and_exponent(uint64_t fraction,int32_t exponent)417 ecma_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  */
435 ecma_number_t
ecma_number_make_from_sign_mantissa_and_exponent(bool sign,uint64_t mantissa,int32_t exponent)436 ecma_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  */
520 ecma_number_t
ecma_number_get_prev(ecma_number_t num)521 ecma_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  */
555 ecma_number_t
ecma_number_get_next(ecma_number_t num)556 ecma_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  */
594 ecma_number_t
ecma_number_trunc(ecma_number_t num)595 ecma_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  */
638 ecma_number_t
ecma_number_calc_remainder(ecma_number_t left_num,ecma_number_t right_num)639 ecma_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  */
666 ecma_number_t
ecma_number_pow(ecma_number_t x,ecma_number_t y)667 ecma_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  */
691 inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
ecma_integer_multiply(ecma_integer_value_t left_integer,ecma_integer_value_t right_integer)692 ecma_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  */
720 ecma_value_t
ecma_number_parse_int(const lit_utf8_byte_t * string_buff,lit_utf8_size_t string_buff_size,ecma_value_t radix)721 ecma_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  */
898 ecma_value_t
ecma_number_parse_float(const lit_utf8_byte_t * string_buff,lit_utf8_size_t string_buff_size)899 ecma_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