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