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