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