1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include <stdarg.h> 29 #include <limits.h> 30 31 #include "v8.h" 32 33 #include "conversions-inl.h" 34 #include "dtoa.h" 35 #include "factory.h" 36 #include "scanner-base.h" 37 #include "strtod.h" 38 39 namespace v8 { 40 namespace internal { 41 42 namespace { 43 44 // C++-style iterator adaptor for StringInputBuffer 45 // (unlike C++ iterators the end-marker has different type). 46 class StringInputBufferIterator { 47 public: 48 class EndMarker {}; 49 50 explicit StringInputBufferIterator(StringInputBuffer* buffer); 51 52 int operator*() const; 53 void operator++(); 54 bool operator==(EndMarker const&) const { return end_; } 55 bool operator!=(EndMarker const& m) const { return !end_; } 56 57 private: 58 StringInputBuffer* const buffer_; 59 int current_; 60 bool end_; 61 }; 62 63 64 StringInputBufferIterator::StringInputBufferIterator( 65 StringInputBuffer* buffer) : buffer_(buffer) { 66 ++(*this); 67 } 68 69 int StringInputBufferIterator::operator*() const { 70 return current_; 71 } 72 73 74 void StringInputBufferIterator::operator++() { 75 end_ = !buffer_->has_more(); 76 if (!end_) { 77 current_ = buffer_->GetNext(); 78 } 79 } 80 } 81 82 83 template <class Iterator, class EndMark> 84 static bool SubStringEquals(Iterator* current, 85 EndMark end, 86 const char* substring) { 87 ASSERT(**current == *substring); 88 for (substring++; *substring != '\0'; substring++) { 89 ++*current; 90 if (*current == end || **current != *substring) return false; 91 } 92 ++*current; 93 return true; 94 } 95 96 97 // Maximum number of significant digits in decimal representation. 98 // The longest possible double in decimal representation is 99 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 100 // (768 digits). If we parse a number whose first digits are equal to a 101 // mean of 2 adjacent doubles (that could have up to 769 digits) the result 102 // must be rounded to the bigger one unless the tail consists of zeros, so 103 // we don't need to preserve all the digits. 104 const int kMaxSignificantDigits = 772; 105 106 107 static const double JUNK_STRING_VALUE = OS::nan_value(); 108 109 110 // Returns true if a nonspace found and false if the end has reached. 111 template <class Iterator, class EndMark> 112 static inline bool AdvanceToNonspace(UnicodeCache* unicode_cache, 113 Iterator* current, 114 EndMark end) { 115 while (*current != end) { 116 if (!unicode_cache->IsWhiteSpace(**current)) return true; 117 ++*current; 118 } 119 return false; 120 } 121 122 123 static bool isDigit(int x, int radix) { 124 return (x >= '0' && x <= '9' && x < '0' + radix) 125 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) 126 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); 127 } 128 129 130 static double SignedZero(bool negative) { 131 return negative ? -0.0 : 0.0; 132 } 133 134 135 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. 136 template <int radix_log_2, class Iterator, class EndMark> 137 static double InternalStringToIntDouble(UnicodeCache* unicode_cache, 138 Iterator current, 139 EndMark end, 140 bool negative, 141 bool allow_trailing_junk) { 142 ASSERT(current != end); 143 144 // Skip leading 0s. 145 while (*current == '0') { 146 ++current; 147 if (current == end) return SignedZero(negative); 148 } 149 150 int64_t number = 0; 151 int exponent = 0; 152 const int radix = (1 << radix_log_2); 153 154 do { 155 int digit; 156 if (*current >= '0' && *current <= '9' && *current < '0' + radix) { 157 digit = static_cast<char>(*current) - '0'; 158 } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { 159 digit = static_cast<char>(*current) - 'a' + 10; 160 } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { 161 digit = static_cast<char>(*current) - 'A' + 10; 162 } else { 163 if (allow_trailing_junk || 164 !AdvanceToNonspace(unicode_cache, ¤t, end)) { 165 break; 166 } else { 167 return JUNK_STRING_VALUE; 168 } 169 } 170 171 number = number * radix + digit; 172 int overflow = static_cast<int>(number >> 53); 173 if (overflow != 0) { 174 // Overflow occurred. Need to determine which direction to round the 175 // result. 176 int overflow_bits_count = 1; 177 while (overflow > 1) { 178 overflow_bits_count++; 179 overflow >>= 1; 180 } 181 182 int dropped_bits_mask = ((1 << overflow_bits_count) - 1); 183 int dropped_bits = static_cast<int>(number) & dropped_bits_mask; 184 number >>= overflow_bits_count; 185 exponent = overflow_bits_count; 186 187 bool zero_tail = true; 188 while (true) { 189 ++current; 190 if (current == end || !isDigit(*current, radix)) break; 191 zero_tail = zero_tail && *current == '0'; 192 exponent += radix_log_2; 193 } 194 195 if (!allow_trailing_junk && 196 AdvanceToNonspace(unicode_cache, ¤t, end)) { 197 return JUNK_STRING_VALUE; 198 } 199 200 int middle_value = (1 << (overflow_bits_count - 1)); 201 if (dropped_bits > middle_value) { 202 number++; // Rounding up. 203 } else if (dropped_bits == middle_value) { 204 // Rounding to even to consistency with decimals: half-way case rounds 205 // up if significant part is odd and down otherwise. 206 if ((number & 1) != 0 || !zero_tail) { 207 number++; // Rounding up. 208 } 209 } 210 211 // Rounding up may cause overflow. 212 if ((number & ((int64_t)1 << 53)) != 0) { 213 exponent++; 214 number >>= 1; 215 } 216 break; 217 } 218 ++current; 219 } while (current != end); 220 221 ASSERT(number < ((int64_t)1 << 53)); 222 ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); 223 224 if (exponent == 0) { 225 if (negative) { 226 if (number == 0) return -0.0; 227 number = -number; 228 } 229 return static_cast<double>(number); 230 } 231 232 ASSERT(number != 0); 233 // The double could be constructed faster from number (mantissa), exponent 234 // and sign. Assuming it's a rare case more simple code is used. 235 return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); 236 } 237 238 239 template <class Iterator, class EndMark> 240 static double InternalStringToInt(UnicodeCache* unicode_cache, 241 Iterator current, 242 EndMark end, 243 int radix) { 244 const bool allow_trailing_junk = true; 245 const double empty_string_val = JUNK_STRING_VALUE; 246 247 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { 248 return empty_string_val; 249 } 250 251 bool negative = false; 252 bool leading_zero = false; 253 254 if (*current == '+') { 255 // Ignore leading sign; skip following spaces. 256 ++current; 257 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { 258 return JUNK_STRING_VALUE; 259 } 260 } else if (*current == '-') { 261 ++current; 262 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { 263 return JUNK_STRING_VALUE; 264 } 265 negative = true; 266 } 267 268 if (radix == 0) { 269 // Radix detection. 270 if (*current == '0') { 271 ++current; 272 if (current == end) return SignedZero(negative); 273 if (*current == 'x' || *current == 'X') { 274 radix = 16; 275 ++current; 276 if (current == end) return JUNK_STRING_VALUE; 277 } else { 278 radix = 8; 279 leading_zero = true; 280 } 281 } else { 282 radix = 10; 283 } 284 } else if (radix == 16) { 285 if (*current == '0') { 286 // Allow "0x" prefix. 287 ++current; 288 if (current == end) return SignedZero(negative); 289 if (*current == 'x' || *current == 'X') { 290 ++current; 291 if (current == end) return JUNK_STRING_VALUE; 292 } else { 293 leading_zero = true; 294 } 295 } 296 } 297 298 if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; 299 300 // Skip leading zeros. 301 while (*current == '0') { 302 leading_zero = true; 303 ++current; 304 if (current == end) return SignedZero(negative); 305 } 306 307 if (!leading_zero && !isDigit(*current, radix)) { 308 return JUNK_STRING_VALUE; 309 } 310 311 if (IsPowerOf2(radix)) { 312 switch (radix) { 313 case 2: 314 return InternalStringToIntDouble<1>( 315 unicode_cache, current, end, negative, allow_trailing_junk); 316 case 4: 317 return InternalStringToIntDouble<2>( 318 unicode_cache, current, end, negative, allow_trailing_junk); 319 case 8: 320 return InternalStringToIntDouble<3>( 321 unicode_cache, current, end, negative, allow_trailing_junk); 322 323 case 16: 324 return InternalStringToIntDouble<4>( 325 unicode_cache, current, end, negative, allow_trailing_junk); 326 327 case 32: 328 return InternalStringToIntDouble<5>( 329 unicode_cache, current, end, negative, allow_trailing_junk); 330 default: 331 UNREACHABLE(); 332 } 333 } 334 335 if (radix == 10) { 336 // Parsing with strtod. 337 const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308. 338 // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero 339 // end. 340 const int kBufferSize = kMaxSignificantDigits + 2; 341 char buffer[kBufferSize]; 342 int buffer_pos = 0; 343 while (*current >= '0' && *current <= '9') { 344 if (buffer_pos <= kMaxSignificantDigits) { 345 // If the number has more than kMaxSignificantDigits it will be parsed 346 // as infinity. 347 ASSERT(buffer_pos < kBufferSize); 348 buffer[buffer_pos++] = static_cast<char>(*current); 349 } 350 ++current; 351 if (current == end) break; 352 } 353 354 if (!allow_trailing_junk && 355 AdvanceToNonspace(unicode_cache, ¤t, end)) { 356 return JUNK_STRING_VALUE; 357 } 358 359 ASSERT(buffer_pos < kBufferSize); 360 buffer[buffer_pos] = '\0'; 361 Vector<const char> buffer_vector(buffer, buffer_pos); 362 return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); 363 } 364 365 // The following code causes accumulating rounding error for numbers greater 366 // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, 367 // 16, or 32, then mathInt may be an implementation-dependent approximation to 368 // the mathematical integer value" (15.1.2.2). 369 370 int lim_0 = '0' + (radix < 10 ? radix : 10); 371 int lim_a = 'a' + (radix - 10); 372 int lim_A = 'A' + (radix - 10); 373 374 // NOTE: The code for computing the value may seem a bit complex at 375 // first glance. It is structured to use 32-bit multiply-and-add 376 // loops as long as possible to avoid loosing precision. 377 378 double v = 0.0; 379 bool done = false; 380 do { 381 // Parse the longest part of the string starting at index j 382 // possible while keeping the multiplier, and thus the part 383 // itself, within 32 bits. 384 unsigned int part = 0, multiplier = 1; 385 while (true) { 386 int d; 387 if (*current >= '0' && *current < lim_0) { 388 d = *current - '0'; 389 } else if (*current >= 'a' && *current < lim_a) { 390 d = *current - 'a' + 10; 391 } else if (*current >= 'A' && *current < lim_A) { 392 d = *current - 'A' + 10; 393 } else { 394 done = true; 395 break; 396 } 397 398 // Update the value of the part as long as the multiplier fits 399 // in 32 bits. When we can't guarantee that the next iteration 400 // will not overflow the multiplier, we stop parsing the part 401 // by leaving the loop. 402 const unsigned int kMaximumMultiplier = 0xffffffffU / 36; 403 uint32_t m = multiplier * radix; 404 if (m > kMaximumMultiplier) break; 405 part = part * radix + d; 406 multiplier = m; 407 ASSERT(multiplier > part); 408 409 ++current; 410 if (current == end) { 411 done = true; 412 break; 413 } 414 } 415 416 // Update the value and skip the part in the string. 417 v = v * multiplier + part; 418 } while (!done); 419 420 if (!allow_trailing_junk && 421 AdvanceToNonspace(unicode_cache, ¤t, end)) { 422 return JUNK_STRING_VALUE; 423 } 424 425 return negative ? -v : v; 426 } 427 428 429 // Converts a string to a double value. Assumes the Iterator supports 430 // the following operations: 431 // 1. current == end (other ops are not allowed), current != end. 432 // 2. *current - gets the current character in the sequence. 433 // 3. ++current (advances the position). 434 template <class Iterator, class EndMark> 435 static double InternalStringToDouble(UnicodeCache* unicode_cache, 436 Iterator current, 437 EndMark end, 438 int flags, 439 double empty_string_val) { 440 // To make sure that iterator dereferencing is valid the following 441 // convention is used: 442 // 1. Each '++current' statement is followed by check for equality to 'end'. 443 // 2. If AdvanceToNonspace returned false then current == end. 444 // 3. If 'current' becomes be equal to 'end' the function returns or goes to 445 // 'parsing_done'. 446 // 4. 'current' is not dereferenced after the 'parsing_done' label. 447 // 5. Code before 'parsing_done' may rely on 'current != end'. 448 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { 449 return empty_string_val; 450 } 451 452 const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0; 453 454 // The longest form of simplified number is: "-<significant digits>'.1eXXX\0". 455 const int kBufferSize = kMaxSignificantDigits + 10; 456 char buffer[kBufferSize]; // NOLINT: size is known at compile time. 457 int buffer_pos = 0; 458 459 // Exponent will be adjusted if insignificant digits of the integer part 460 // or insignificant leading zeros of the fractional part are dropped. 461 int exponent = 0; 462 int significant_digits = 0; 463 int insignificant_digits = 0; 464 bool nonzero_digit_dropped = false; 465 bool fractional_part = false; 466 467 bool negative = false; 468 469 if (*current == '+') { 470 // Ignore leading sign. 471 ++current; 472 if (current == end) return JUNK_STRING_VALUE; 473 } else if (*current == '-') { 474 ++current; 475 if (current == end) return JUNK_STRING_VALUE; 476 negative = true; 477 } 478 479 static const char kInfinitySymbol[] = "Infinity"; 480 if (*current == kInfinitySymbol[0]) { 481 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { 482 return JUNK_STRING_VALUE; 483 } 484 485 if (!allow_trailing_junk && 486 AdvanceToNonspace(unicode_cache, ¤t, end)) { 487 return JUNK_STRING_VALUE; 488 } 489 490 ASSERT(buffer_pos == 0); 491 return negative ? -V8_INFINITY : V8_INFINITY; 492 } 493 494 bool leading_zero = false; 495 if (*current == '0') { 496 ++current; 497 if (current == end) return SignedZero(negative); 498 499 leading_zero = true; 500 501 // It could be hexadecimal value. 502 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { 503 ++current; 504 if (current == end || !isDigit(*current, 16)) { 505 return JUNK_STRING_VALUE; // "0x". 506 } 507 508 return InternalStringToIntDouble<4>(unicode_cache, 509 current, 510 end, 511 negative, 512 allow_trailing_junk); 513 } 514 515 // Ignore leading zeros in the integer part. 516 while (*current == '0') { 517 ++current; 518 if (current == end) return SignedZero(negative); 519 } 520 } 521 522 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; 523 524 // Copy significant digits of the integer part (if any) to the buffer. 525 while (*current >= '0' && *current <= '9') { 526 if (significant_digits < kMaxSignificantDigits) { 527 ASSERT(buffer_pos < kBufferSize); 528 buffer[buffer_pos++] = static_cast<char>(*current); 529 significant_digits++; 530 // Will later check if it's an octal in the buffer. 531 } else { 532 insignificant_digits++; // Move the digit into the exponential part. 533 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 534 } 535 octal = octal && *current < '8'; 536 ++current; 537 if (current == end) goto parsing_done; 538 } 539 540 if (significant_digits == 0) { 541 octal = false; 542 } 543 544 if (*current == '.') { 545 if (octal && !allow_trailing_junk) return JUNK_STRING_VALUE; 546 if (octal) goto parsing_done; 547 548 ++current; 549 if (current == end) { 550 if (significant_digits == 0 && !leading_zero) { 551 return JUNK_STRING_VALUE; 552 } else { 553 goto parsing_done; 554 } 555 } 556 557 if (significant_digits == 0) { 558 // octal = false; 559 // Integer part consists of 0 or is absent. Significant digits start after 560 // leading zeros (if any). 561 while (*current == '0') { 562 ++current; 563 if (current == end) return SignedZero(negative); 564 exponent--; // Move this 0 into the exponent. 565 } 566 } 567 568 // We don't emit a '.', but adjust the exponent instead. 569 fractional_part = true; 570 571 // There is a fractional part. 572 while (*current >= '0' && *current <= '9') { 573 if (significant_digits < kMaxSignificantDigits) { 574 ASSERT(buffer_pos < kBufferSize); 575 buffer[buffer_pos++] = static_cast<char>(*current); 576 significant_digits++; 577 exponent--; 578 } else { 579 // Ignore insignificant digits in the fractional part. 580 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 581 } 582 ++current; 583 if (current == end) goto parsing_done; 584 } 585 } 586 587 if (!leading_zero && exponent == 0 && significant_digits == 0) { 588 // If leading_zeros is true then the string contains zeros. 589 // If exponent < 0 then string was [+-]\.0*... 590 // If significant_digits != 0 the string is not equal to 0. 591 // Otherwise there are no digits in the string. 592 return JUNK_STRING_VALUE; 593 } 594 595 // Parse exponential part. 596 if (*current == 'e' || *current == 'E') { 597 if (octal) return JUNK_STRING_VALUE; 598 ++current; 599 if (current == end) { 600 if (allow_trailing_junk) { 601 goto parsing_done; 602 } else { 603 return JUNK_STRING_VALUE; 604 } 605 } 606 char sign = '+'; 607 if (*current == '+' || *current == '-') { 608 sign = static_cast<char>(*current); 609 ++current; 610 if (current == end) { 611 if (allow_trailing_junk) { 612 goto parsing_done; 613 } else { 614 return JUNK_STRING_VALUE; 615 } 616 } 617 } 618 619 if (current == end || *current < '0' || *current > '9') { 620 if (allow_trailing_junk) { 621 goto parsing_done; 622 } else { 623 return JUNK_STRING_VALUE; 624 } 625 } 626 627 const int max_exponent = INT_MAX / 2; 628 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); 629 int num = 0; 630 do { 631 // Check overflow. 632 int digit = *current - '0'; 633 if (num >= max_exponent / 10 634 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { 635 num = max_exponent; 636 } else { 637 num = num * 10 + digit; 638 } 639 ++current; 640 } while (current != end && *current >= '0' && *current <= '9'); 641 642 exponent += (sign == '-' ? -num : num); 643 } 644 645 if (!allow_trailing_junk && 646 AdvanceToNonspace(unicode_cache, ¤t, end)) { 647 return JUNK_STRING_VALUE; 648 } 649 650 parsing_done: 651 exponent += insignificant_digits; 652 653 if (octal) { 654 return InternalStringToIntDouble<3>(unicode_cache, 655 buffer, 656 buffer + buffer_pos, 657 negative, 658 allow_trailing_junk); 659 } 660 661 if (nonzero_digit_dropped) { 662 buffer[buffer_pos++] = '1'; 663 exponent--; 664 } 665 666 ASSERT(buffer_pos < kBufferSize); 667 buffer[buffer_pos] = '\0'; 668 669 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); 670 return negative ? -converted : converted; 671 } 672 673 674 double StringToDouble(UnicodeCache* unicode_cache, 675 String* str, int flags, double empty_string_val) { 676 StringShape shape(str); 677 if (shape.IsSequentialAscii()) { 678 const char* begin = SeqAsciiString::cast(str)->GetChars(); 679 const char* end = begin + str->length(); 680 return InternalStringToDouble(unicode_cache, begin, end, flags, 681 empty_string_val); 682 } else if (shape.IsSequentialTwoByte()) { 683 const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); 684 const uc16* end = begin + str->length(); 685 return InternalStringToDouble(unicode_cache, begin, end, flags, 686 empty_string_val); 687 } else { 688 StringInputBuffer buffer(str); 689 return InternalStringToDouble(unicode_cache, 690 StringInputBufferIterator(&buffer), 691 StringInputBufferIterator::EndMarker(), 692 flags, 693 empty_string_val); 694 } 695 } 696 697 698 double StringToInt(UnicodeCache* unicode_cache, 699 String* str, 700 int radix) { 701 StringShape shape(str); 702 if (shape.IsSequentialAscii()) { 703 const char* begin = SeqAsciiString::cast(str)->GetChars(); 704 const char* end = begin + str->length(); 705 return InternalStringToInt(unicode_cache, begin, end, radix); 706 } else if (shape.IsSequentialTwoByte()) { 707 const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); 708 const uc16* end = begin + str->length(); 709 return InternalStringToInt(unicode_cache, begin, end, radix); 710 } else { 711 StringInputBuffer buffer(str); 712 return InternalStringToInt(unicode_cache, 713 StringInputBufferIterator(&buffer), 714 StringInputBufferIterator::EndMarker(), 715 radix); 716 } 717 } 718 719 720 double StringToDouble(UnicodeCache* unicode_cache, 721 const char* str, int flags, double empty_string_val) { 722 const char* end = str + StrLength(str); 723 return InternalStringToDouble(unicode_cache, str, end, flags, 724 empty_string_val); 725 } 726 727 728 double StringToDouble(UnicodeCache* unicode_cache, 729 Vector<const char> str, 730 int flags, 731 double empty_string_val) { 732 const char* end = str.start() + str.length(); 733 return InternalStringToDouble(unicode_cache, str.start(), end, flags, 734 empty_string_val); 735 } 736 737 738 const char* DoubleToCString(double v, Vector<char> buffer) { 739 switch (fpclassify(v)) { 740 case FP_NAN: return "NaN"; 741 case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity"); 742 case FP_ZERO: return "0"; 743 default: { 744 StringBuilder builder(buffer.start(), buffer.length()); 745 int decimal_point; 746 int sign; 747 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; 748 char decimal_rep[kV8DtoaBufferCapacity]; 749 int length; 750 751 DoubleToAscii(v, DTOA_SHORTEST, 0, 752 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), 753 &sign, &length, &decimal_point); 754 755 if (sign) builder.AddCharacter('-'); 756 757 if (length <= decimal_point && decimal_point <= 21) { 758 // ECMA-262 section 9.8.1 step 6. 759 builder.AddString(decimal_rep); 760 builder.AddPadding('0', decimal_point - length); 761 762 } else if (0 < decimal_point && decimal_point <= 21) { 763 // ECMA-262 section 9.8.1 step 7. 764 builder.AddSubstring(decimal_rep, decimal_point); 765 builder.AddCharacter('.'); 766 builder.AddString(decimal_rep + decimal_point); 767 768 } else if (decimal_point <= 0 && decimal_point > -6) { 769 // ECMA-262 section 9.8.1 step 8. 770 builder.AddString("0."); 771 builder.AddPadding('0', -decimal_point); 772 builder.AddString(decimal_rep); 773 774 } else { 775 // ECMA-262 section 9.8.1 step 9 and 10 combined. 776 builder.AddCharacter(decimal_rep[0]); 777 if (length != 1) { 778 builder.AddCharacter('.'); 779 builder.AddString(decimal_rep + 1); 780 } 781 builder.AddCharacter('e'); 782 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); 783 int exponent = decimal_point - 1; 784 if (exponent < 0) exponent = -exponent; 785 builder.AddFormatted("%d", exponent); 786 } 787 return builder.Finalize(); 788 } 789 } 790 } 791 792 793 const char* IntToCString(int n, Vector<char> buffer) { 794 bool negative = false; 795 if (n < 0) { 796 // We must not negate the most negative int. 797 if (n == kMinInt) return DoubleToCString(n, buffer); 798 negative = true; 799 n = -n; 800 } 801 // Build the string backwards from the least significant digit. 802 int i = buffer.length(); 803 buffer[--i] = '\0'; 804 do { 805 buffer[--i] = '0' + (n % 10); 806 n /= 10; 807 } while (n); 808 if (negative) buffer[--i] = '-'; 809 return buffer.start() + i; 810 } 811 812 813 char* DoubleToFixedCString(double value, int f) { 814 const int kMaxDigitsBeforePoint = 21; 815 const double kFirstNonFixed = 1e21; 816 const int kMaxDigitsAfterPoint = 20; 817 ASSERT(f >= 0); 818 ASSERT(f <= kMaxDigitsAfterPoint); 819 820 bool negative = false; 821 double abs_value = value; 822 if (value < 0) { 823 abs_value = -value; 824 negative = true; 825 } 826 827 // If abs_value has more than kMaxDigitsBeforePoint digits before the point 828 // use the non-fixed conversion routine. 829 if (abs_value >= kFirstNonFixed) { 830 char arr[100]; 831 Vector<char> buffer(arr, ARRAY_SIZE(arr)); 832 return StrDup(DoubleToCString(value, buffer)); 833 } 834 835 // Find a sufficiently precise decimal representation of n. 836 int decimal_point; 837 int sign; 838 // Add space for the '\0' byte. 839 const int kDecimalRepCapacity = 840 kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1; 841 char decimal_rep[kDecimalRepCapacity]; 842 int decimal_rep_length; 843 DoubleToAscii(value, DTOA_FIXED, f, 844 Vector<char>(decimal_rep, kDecimalRepCapacity), 845 &sign, &decimal_rep_length, &decimal_point); 846 847 // Create a representation that is padded with zeros if needed. 848 int zero_prefix_length = 0; 849 int zero_postfix_length = 0; 850 851 if (decimal_point <= 0) { 852 zero_prefix_length = -decimal_point + 1; 853 decimal_point = 1; 854 } 855 856 if (zero_prefix_length + decimal_rep_length < decimal_point + f) { 857 zero_postfix_length = decimal_point + f - decimal_rep_length - 858 zero_prefix_length; 859 } 860 861 unsigned rep_length = 862 zero_prefix_length + decimal_rep_length + zero_postfix_length; 863 StringBuilder rep_builder(rep_length + 1); 864 rep_builder.AddPadding('0', zero_prefix_length); 865 rep_builder.AddString(decimal_rep); 866 rep_builder.AddPadding('0', zero_postfix_length); 867 char* rep = rep_builder.Finalize(); 868 869 // Create the result string by appending a minus and putting in a 870 // decimal point if needed. 871 unsigned result_size = decimal_point + f + 2; 872 StringBuilder builder(result_size + 1); 873 if (negative) builder.AddCharacter('-'); 874 builder.AddSubstring(rep, decimal_point); 875 if (f > 0) { 876 builder.AddCharacter('.'); 877 builder.AddSubstring(rep + decimal_point, f); 878 } 879 DeleteArray(rep); 880 return builder.Finalize(); 881 } 882 883 884 static char* CreateExponentialRepresentation(char* decimal_rep, 885 int exponent, 886 bool negative, 887 int significant_digits) { 888 bool negative_exponent = false; 889 if (exponent < 0) { 890 negative_exponent = true; 891 exponent = -exponent; 892 } 893 894 // Leave room in the result for appending a minus, for a period, the 895 // letter 'e', a minus or a plus depending on the exponent, and a 896 // three digit exponent. 897 unsigned result_size = significant_digits + 7; 898 StringBuilder builder(result_size + 1); 899 900 if (negative) builder.AddCharacter('-'); 901 builder.AddCharacter(decimal_rep[0]); 902 if (significant_digits != 1) { 903 builder.AddCharacter('.'); 904 builder.AddString(decimal_rep + 1); 905 int rep_length = StrLength(decimal_rep); 906 builder.AddPadding('0', significant_digits - rep_length); 907 } 908 909 builder.AddCharacter('e'); 910 builder.AddCharacter(negative_exponent ? '-' : '+'); 911 builder.AddFormatted("%d", exponent); 912 return builder.Finalize(); 913 } 914 915 916 917 char* DoubleToExponentialCString(double value, int f) { 918 const int kMaxDigitsAfterPoint = 20; 919 // f might be -1 to signal that f was undefined in JavaScript. 920 ASSERT(f >= -1 && f <= kMaxDigitsAfterPoint); 921 922 bool negative = false; 923 if (value < 0) { 924 value = -value; 925 negative = true; 926 } 927 928 // Find a sufficiently precise decimal representation of n. 929 int decimal_point; 930 int sign; 931 // f corresponds to the digits after the point. There is always one digit 932 // before the point. The number of requested_digits equals hence f + 1. 933 // And we have to add one character for the null-terminator. 934 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; 935 // Make sure that the buffer is big enough, even if we fall back to the 936 // shortest representation (which happens when f equals -1). 937 ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); 938 char decimal_rep[kV8DtoaBufferCapacity]; 939 int decimal_rep_length; 940 941 if (f == -1) { 942 DoubleToAscii(value, DTOA_SHORTEST, 0, 943 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), 944 &sign, &decimal_rep_length, &decimal_point); 945 f = decimal_rep_length - 1; 946 } else { 947 DoubleToAscii(value, DTOA_PRECISION, f + 1, 948 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), 949 &sign, &decimal_rep_length, &decimal_point); 950 } 951 ASSERT(decimal_rep_length > 0); 952 ASSERT(decimal_rep_length <= f + 1); 953 954 int exponent = decimal_point - 1; 955 char* result = 956 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); 957 958 return result; 959 } 960 961 962 char* DoubleToPrecisionCString(double value, int p) { 963 const int kMinimalDigits = 1; 964 const int kMaximalDigits = 21; 965 ASSERT(p >= kMinimalDigits && p <= kMaximalDigits); 966 USE(kMinimalDigits); 967 968 bool negative = false; 969 if (value < 0) { 970 value = -value; 971 negative = true; 972 } 973 974 // Find a sufficiently precise decimal representation of n. 975 int decimal_point; 976 int sign; 977 // Add one for the terminating null character. 978 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; 979 char decimal_rep[kV8DtoaBufferCapacity]; 980 int decimal_rep_length; 981 982 DoubleToAscii(value, DTOA_PRECISION, p, 983 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), 984 &sign, &decimal_rep_length, &decimal_point); 985 ASSERT(decimal_rep_length <= p); 986 987 int exponent = decimal_point - 1; 988 989 char* result = NULL; 990 991 if (exponent < -6 || exponent >= p) { 992 result = 993 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); 994 } else { 995 // Use fixed notation. 996 // 997 // Leave room in the result for appending a minus, a period and in 998 // the case where decimal_point is not positive for a zero in 999 // front of the period. 1000 unsigned result_size = (decimal_point <= 0) 1001 ? -decimal_point + p + 3 1002 : p + 2; 1003 StringBuilder builder(result_size + 1); 1004 if (negative) builder.AddCharacter('-'); 1005 if (decimal_point <= 0) { 1006 builder.AddString("0."); 1007 builder.AddPadding('0', -decimal_point); 1008 builder.AddString(decimal_rep); 1009 builder.AddPadding('0', p - decimal_rep_length); 1010 } else { 1011 const int m = Min(decimal_rep_length, decimal_point); 1012 builder.AddSubstring(decimal_rep, m); 1013 builder.AddPadding('0', decimal_point - decimal_rep_length); 1014 if (decimal_point < p) { 1015 builder.AddCharacter('.'); 1016 const int extra = negative ? 2 : 1; 1017 if (decimal_rep_length > decimal_point) { 1018 const int len = StrLength(decimal_rep + decimal_point); 1019 const int n = Min(len, p - (builder.position() - extra)); 1020 builder.AddSubstring(decimal_rep + decimal_point, n); 1021 } 1022 builder.AddPadding('0', extra + (p - builder.position())); 1023 } 1024 } 1025 result = builder.Finalize(); 1026 } 1027 1028 return result; 1029 } 1030 1031 1032 char* DoubleToRadixCString(double value, int radix) { 1033 ASSERT(radix >= 2 && radix <= 36); 1034 1035 // Character array used for conversion. 1036 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 1037 1038 // Buffer for the integer part of the result. 1024 chars is enough 1039 // for max integer value in radix 2. We need room for a sign too. 1040 static const int kBufferSize = 1100; 1041 char integer_buffer[kBufferSize]; 1042 integer_buffer[kBufferSize - 1] = '\0'; 1043 1044 // Buffer for the decimal part of the result. We only generate up 1045 // to kBufferSize - 1 chars for the decimal part. 1046 char decimal_buffer[kBufferSize]; 1047 decimal_buffer[kBufferSize - 1] = '\0'; 1048 1049 // Make sure the value is positive. 1050 bool is_negative = value < 0.0; 1051 if (is_negative) value = -value; 1052 1053 // Get the integer part and the decimal part. 1054 double integer_part = floor(value); 1055 double decimal_part = value - integer_part; 1056 1057 // Convert the integer part starting from the back. Always generate 1058 // at least one digit. 1059 int integer_pos = kBufferSize - 2; 1060 do { 1061 integer_buffer[integer_pos--] = 1062 chars[static_cast<int>(modulo(integer_part, radix))]; 1063 integer_part /= radix; 1064 } while (integer_part >= 1.0); 1065 // Sanity check. 1066 ASSERT(integer_pos > 0); 1067 // Add sign if needed. 1068 if (is_negative) integer_buffer[integer_pos--] = '-'; 1069 1070 // Convert the decimal part. Repeatedly multiply by the radix to 1071 // generate the next char. Never generate more than kBufferSize - 1 1072 // chars. 1073 // 1074 // TODO(1093998): We will often generate a full decimal_buffer of 1075 // chars because hitting zero will often not happen. The right 1076 // solution would be to continue until the string representation can 1077 // be read back and yield the original value. To implement this 1078 // efficiently, we probably have to modify dtoa. 1079 int decimal_pos = 0; 1080 while ((decimal_part > 0.0) && (decimal_pos < kBufferSize - 1)) { 1081 decimal_part *= radix; 1082 decimal_buffer[decimal_pos++] = 1083 chars[static_cast<int>(floor(decimal_part))]; 1084 decimal_part -= floor(decimal_part); 1085 } 1086 decimal_buffer[decimal_pos] = '\0'; 1087 1088 // Compute the result size. 1089 int integer_part_size = kBufferSize - 2 - integer_pos; 1090 // Make room for zero termination. 1091 unsigned result_size = integer_part_size + decimal_pos; 1092 // If the number has a decimal part, leave room for the period. 1093 if (decimal_pos > 0) result_size++; 1094 // Allocate result and fill in the parts. 1095 StringBuilder builder(result_size + 1); 1096 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); 1097 if (decimal_pos > 0) builder.AddCharacter('.'); 1098 builder.AddSubstring(decimal_buffer, decimal_pos); 1099 return builder.Finalize(); 1100 } 1101 1102 1103 static Mutex* dtoa_lock_one = OS::CreateMutex(); 1104 static Mutex* dtoa_lock_zero = OS::CreateMutex(); 1105 1106 1107 } } // namespace v8::internal 1108 1109 1110 extern "C" { 1111 void ACQUIRE_DTOA_LOCK(int n) { 1112 ASSERT(n == 0 || n == 1); 1113 (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock(); 1114 } 1115 1116 1117 void FREE_DTOA_LOCK(int n) { 1118 ASSERT(n == 0 || n == 1); 1119 (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)-> 1120 Unlock(); 1121 } 1122 } 1123