1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_CONVERSIONS_INL_H_ 6 #define V8_CONVERSIONS_INL_H_ 7 8 #include <float.h> // Required for DBL_MAX and on Win32 for finite() 9 #include <limits.h> // Required for INT_MAX etc. 10 #include <stdarg.h> 11 #include <cmath> 12 #include "src/globals.h" // Required for V8_INFINITY 13 #include "src/unicode-cache-inl.h" 14 15 // ---------------------------------------------------------------------------- 16 // Extra POSIX/ANSI functions for Win32/MSVC. 17 18 #include "src/base/bits.h" 19 #include "src/base/platform/platform.h" 20 #include "src/conversions.h" 21 #include "src/double.h" 22 #include "src/objects-inl.h" 23 #include "src/strtod.h" 24 25 namespace v8 { 26 namespace internal { 27 28 inline double JunkStringValue() { 29 return bit_cast<double, uint64_t>(kQuietNaNMask); 30 } 31 32 33 inline double SignedZero(bool negative) { 34 return negative ? uint64_to_double(Double::kSignMask) : 0.0; 35 } 36 37 38 // The fast double-to-unsigned-int conversion routine does not guarantee 39 // rounding towards zero, or any reasonable value if the argument is larger 40 // than what fits in an unsigned 32-bit integer. 41 inline unsigned int FastD2UI(double x) { 42 // There is no unsigned version of lrint, so there is no fast path 43 // in this function as there is in FastD2I. Using lrint doesn't work 44 // for values of 2^31 and above. 45 46 // Convert "small enough" doubles to uint32_t by fixing the 32 47 // least significant non-fractional bits in the low 32 bits of the 48 // double, and reading them from there. 49 const double k2Pow52 = 4503599627370496.0; 50 bool negative = x < 0; 51 if (negative) { 52 x = -x; 53 } 54 if (x < k2Pow52) { 55 x += k2Pow52; 56 uint32_t result; 57 #ifndef V8_TARGET_BIG_ENDIAN 58 Address mantissa_ptr = reinterpret_cast<Address>(&x); 59 #else 60 Address mantissa_ptr = reinterpret_cast<Address>(&x) + kInt32Size; 61 #endif 62 // Copy least significant 32 bits of mantissa. 63 memcpy(&result, mantissa_ptr, sizeof(result)); 64 return negative ? ~result + 1 : result; 65 } 66 // Large number (outside uint32 range), Infinity or NaN. 67 return 0x80000000u; // Return integer indefinite. 68 } 69 70 71 inline float DoubleToFloat32(double x) { 72 // TODO(yangguo): This static_cast is implementation-defined behaviour in C++, 73 // so we may need to do the conversion manually instead to match the spec. 74 volatile float f = static_cast<float>(x); 75 return f; 76 } 77 78 79 inline double DoubleToInteger(double x) { 80 if (std::isnan(x)) return 0; 81 if (!std::isfinite(x) || x == 0) return x; 82 return (x >= 0) ? std::floor(x) : std::ceil(x); 83 } 84 85 86 int32_t DoubleToInt32(double x) { 87 int32_t i = FastD2I(x); 88 if (FastI2D(i) == x) return i; 89 Double d(x); 90 int exponent = d.Exponent(); 91 if (exponent < 0) { 92 if (exponent <= -Double::kSignificandSize) return 0; 93 return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent); 94 } else { 95 if (exponent > 31) return 0; 96 return d.Sign() * static_cast<int32_t>(d.Significand() << exponent); 97 } 98 } 99 100 bool DoubleToSmiInteger(double value, int* smi_int_value) { 101 if (IsMinusZero(value)) return false; 102 int i = FastD2IChecked(value); 103 if (value != i || !Smi::IsValid(i)) return false; 104 *smi_int_value = i; 105 return true; 106 } 107 108 bool IsSmiDouble(double value) { 109 return !IsMinusZero(value) && value >= Smi::kMinValue && 110 value <= Smi::kMaxValue && value == FastI2D(FastD2I(value)); 111 } 112 113 114 bool IsInt32Double(double value) { 115 return !IsMinusZero(value) && value >= kMinInt && value <= kMaxInt && 116 value == FastI2D(FastD2I(value)); 117 } 118 119 120 bool IsUint32Double(double value) { 121 return !IsMinusZero(value) && value >= 0 && value <= kMaxUInt32 && 122 value == FastUI2D(FastD2UI(value)); 123 } 124 125 bool DoubleToUint32IfEqualToSelf(double value, uint32_t* uint32_value) { 126 const double k2Pow52 = 4503599627370496.0; 127 const uint32_t kValidTopBits = 0x43300000; 128 const uint64_t kBottomBitMask = V8_2PART_UINT64_C(0x00000000, FFFFFFFF); 129 130 // Add 2^52 to the double, to place valid uint32 values in the low-significant 131 // bits of the exponent, by effectively setting the (implicit) top bit of the 132 // significand. Note that this addition also normalises 0.0 and -0.0. 133 double shifted_value = value + k2Pow52; 134 135 // At this point, a valid uint32 valued double will be represented as: 136 // 137 // sign = 0 138 // exponent = 52 139 // significand = 1. 00...00 <value> 140 // implicit^ ^^^^^^^ 32 bits 141 // ^^^^^^^^^^^^^^^ 52 bits 142 // 143 // Therefore, we can first check the top 32 bits to make sure that the sign, 144 // exponent and remaining significand bits are valid, and only then check the 145 // value in the bottom 32 bits. 146 147 uint64_t result = bit_cast<uint64_t>(shifted_value); 148 if ((result >> 32) == kValidTopBits) { 149 *uint32_value = result & kBottomBitMask; 150 return FastUI2D(result & kBottomBitMask) == value; 151 } 152 return false; 153 } 154 155 int32_t NumberToInt32(Object* number) { 156 if (number->IsSmi()) return Smi::cast(number)->value(); 157 return DoubleToInt32(number->Number()); 158 } 159 160 uint32_t NumberToUint32(Object* number) { 161 if (number->IsSmi()) return Smi::cast(number)->value(); 162 return DoubleToUint32(number->Number()); 163 } 164 165 uint32_t PositiveNumberToUint32(Object* number) { 166 if (number->IsSmi()) { 167 int value = Smi::cast(number)->value(); 168 if (value <= 0) return 0; 169 return value; 170 } 171 DCHECK(number->IsHeapNumber()); 172 double value = number->Number(); 173 // Catch all values smaller than 1 and use the double-negation trick for NANs. 174 if (!(value >= 1)) return 0; 175 uint32_t max = std::numeric_limits<uint32_t>::max(); 176 if (value < max) return static_cast<uint32_t>(value); 177 return max; 178 } 179 180 int64_t NumberToInt64(Object* number) { 181 if (number->IsSmi()) return Smi::cast(number)->value(); 182 return static_cast<int64_t>(number->Number()); 183 } 184 185 bool TryNumberToSize(Object* number, size_t* result) { 186 // Do not create handles in this function! Don't use SealHandleScope because 187 // the function can be used concurrently. 188 if (number->IsSmi()) { 189 int value = Smi::cast(number)->value(); 190 DCHECK(static_cast<unsigned>(Smi::kMaxValue) <= 191 std::numeric_limits<size_t>::max()); 192 if (value >= 0) { 193 *result = static_cast<size_t>(value); 194 return true; 195 } 196 return false; 197 } else { 198 DCHECK(number->IsHeapNumber()); 199 double value = HeapNumber::cast(number)->value(); 200 // If value is compared directly to the limit, the limit will be 201 // casted to a double and could end up as limit + 1, 202 // because a double might not have enough mantissa bits for it. 203 // So we might as well cast the limit first, and use < instead of <=. 204 double maxSize = static_cast<double>(std::numeric_limits<size_t>::max()); 205 if (value >= 0 && value < maxSize) { 206 *result = static_cast<size_t>(value); 207 return true; 208 } else { 209 return false; 210 } 211 } 212 } 213 214 size_t NumberToSize(Object* number) { 215 size_t result = 0; 216 bool is_valid = TryNumberToSize(number, &result); 217 CHECK(is_valid); 218 return result; 219 } 220 221 222 uint32_t DoubleToUint32(double x) { 223 return static_cast<uint32_t>(DoubleToInt32(x)); 224 } 225 226 227 template <class Iterator, class EndMark> 228 bool SubStringEquals(Iterator* current, 229 EndMark end, 230 const char* substring) { 231 DCHECK(**current == *substring); 232 for (substring++; *substring != '\0'; substring++) { 233 ++*current; 234 if (*current == end || **current != *substring) return false; 235 } 236 ++*current; 237 return true; 238 } 239 240 241 // Returns true if a nonspace character has been found and false if the 242 // end was been reached before finding a nonspace character. 243 template <class Iterator, class EndMark> 244 inline bool AdvanceToNonspace(UnicodeCache* unicode_cache, 245 Iterator* current, 246 EndMark end) { 247 while (*current != end) { 248 if (!unicode_cache->IsWhiteSpaceOrLineTerminator(**current)) return true; 249 ++*current; 250 } 251 return false; 252 } 253 254 255 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. 256 template <int radix_log_2, class Iterator, class EndMark> 257 double InternalStringToIntDouble(UnicodeCache* unicode_cache, 258 Iterator current, 259 EndMark end, 260 bool negative, 261 bool allow_trailing_junk) { 262 DCHECK(current != end); 263 264 // Skip leading 0s. 265 while (*current == '0') { 266 ++current; 267 if (current == end) return SignedZero(negative); 268 } 269 270 int64_t number = 0; 271 int exponent = 0; 272 const int radix = (1 << radix_log_2); 273 274 do { 275 int digit; 276 if (*current >= '0' && *current <= '9' && *current < '0' + radix) { 277 digit = static_cast<char>(*current) - '0'; 278 } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { 279 digit = static_cast<char>(*current) - 'a' + 10; 280 } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { 281 digit = static_cast<char>(*current) - 'A' + 10; 282 } else { 283 if (allow_trailing_junk || 284 !AdvanceToNonspace(unicode_cache, ¤t, end)) { 285 break; 286 } else { 287 return JunkStringValue(); 288 } 289 } 290 291 number = number * radix + digit; 292 int overflow = static_cast<int>(number >> 53); 293 if (overflow != 0) { 294 // Overflow occurred. Need to determine which direction to round the 295 // result. 296 int overflow_bits_count = 1; 297 while (overflow > 1) { 298 overflow_bits_count++; 299 overflow >>= 1; 300 } 301 302 int dropped_bits_mask = ((1 << overflow_bits_count) - 1); 303 int dropped_bits = static_cast<int>(number) & dropped_bits_mask; 304 number >>= overflow_bits_count; 305 exponent = overflow_bits_count; 306 307 bool zero_tail = true; 308 while (true) { 309 ++current; 310 if (current == end || !isDigit(*current, radix)) break; 311 zero_tail = zero_tail && *current == '0'; 312 exponent += radix_log_2; 313 } 314 315 if (!allow_trailing_junk && 316 AdvanceToNonspace(unicode_cache, ¤t, end)) { 317 return JunkStringValue(); 318 } 319 320 int middle_value = (1 << (overflow_bits_count - 1)); 321 if (dropped_bits > middle_value) { 322 number++; // Rounding up. 323 } else if (dropped_bits == middle_value) { 324 // Rounding to even to consistency with decimals: half-way case rounds 325 // up if significant part is odd and down otherwise. 326 if ((number & 1) != 0 || !zero_tail) { 327 number++; // Rounding up. 328 } 329 } 330 331 // Rounding up may cause overflow. 332 if ((number & (static_cast<int64_t>(1) << 53)) != 0) { 333 exponent++; 334 number >>= 1; 335 } 336 break; 337 } 338 ++current; 339 } while (current != end); 340 341 DCHECK(number < ((int64_t)1 << 53)); 342 DCHECK(static_cast<int64_t>(static_cast<double>(number)) == number); 343 344 if (exponent == 0) { 345 if (negative) { 346 if (number == 0) return -0.0; 347 number = -number; 348 } 349 return static_cast<double>(number); 350 } 351 352 DCHECK(number != 0); 353 return std::ldexp(static_cast<double>(negative ? -number : number), exponent); 354 } 355 356 // ES6 18.2.5 parseInt(string, radix) 357 template <class Iterator, class EndMark> 358 double InternalStringToInt(UnicodeCache* unicode_cache, 359 Iterator current, 360 EndMark end, 361 int radix) { 362 const bool allow_trailing_junk = true; 363 const double empty_string_val = JunkStringValue(); 364 365 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { 366 return empty_string_val; 367 } 368 369 bool negative = false; 370 bool leading_zero = false; 371 372 if (*current == '+') { 373 // Ignore leading sign; skip following spaces. 374 ++current; 375 if (current == end) { 376 return JunkStringValue(); 377 } 378 } else if (*current == '-') { 379 ++current; 380 if (current == end) { 381 return JunkStringValue(); 382 } 383 negative = true; 384 } 385 386 if (radix == 0) { 387 // Radix detection. 388 radix = 10; 389 if (*current == '0') { 390 ++current; 391 if (current == end) return SignedZero(negative); 392 if (*current == 'x' || *current == 'X') { 393 radix = 16; 394 ++current; 395 if (current == end) return JunkStringValue(); 396 } else { 397 leading_zero = true; 398 } 399 } 400 } else if (radix == 16) { 401 if (*current == '0') { 402 // Allow "0x" prefix. 403 ++current; 404 if (current == end) return SignedZero(negative); 405 if (*current == 'x' || *current == 'X') { 406 ++current; 407 if (current == end) return JunkStringValue(); 408 } else { 409 leading_zero = true; 410 } 411 } 412 } 413 414 if (radix < 2 || radix > 36) return JunkStringValue(); 415 416 // Skip leading zeros. 417 while (*current == '0') { 418 leading_zero = true; 419 ++current; 420 if (current == end) return SignedZero(negative); 421 } 422 423 if (!leading_zero && !isDigit(*current, radix)) { 424 return JunkStringValue(); 425 } 426 427 if (base::bits::IsPowerOfTwo32(radix)) { 428 switch (radix) { 429 case 2: 430 return InternalStringToIntDouble<1>( 431 unicode_cache, current, end, negative, allow_trailing_junk); 432 case 4: 433 return InternalStringToIntDouble<2>( 434 unicode_cache, current, end, negative, allow_trailing_junk); 435 case 8: 436 return InternalStringToIntDouble<3>( 437 unicode_cache, current, end, negative, allow_trailing_junk); 438 439 case 16: 440 return InternalStringToIntDouble<4>( 441 unicode_cache, current, end, negative, allow_trailing_junk); 442 443 case 32: 444 return InternalStringToIntDouble<5>( 445 unicode_cache, current, end, negative, allow_trailing_junk); 446 default: 447 UNREACHABLE(); 448 } 449 } 450 451 if (radix == 10) { 452 // Parsing with strtod. 453 const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308. 454 // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero 455 // end. 456 const int kBufferSize = kMaxSignificantDigits + 2; 457 char buffer[kBufferSize]; 458 int buffer_pos = 0; 459 while (*current >= '0' && *current <= '9') { 460 if (buffer_pos <= kMaxSignificantDigits) { 461 // If the number has more than kMaxSignificantDigits it will be parsed 462 // as infinity. 463 DCHECK(buffer_pos < kBufferSize); 464 buffer[buffer_pos++] = static_cast<char>(*current); 465 } 466 ++current; 467 if (current == end) break; 468 } 469 470 if (!allow_trailing_junk && 471 AdvanceToNonspace(unicode_cache, ¤t, end)) { 472 return JunkStringValue(); 473 } 474 475 SLOW_DCHECK(buffer_pos < kBufferSize); 476 buffer[buffer_pos] = '\0'; 477 Vector<const char> buffer_vector(buffer, buffer_pos); 478 return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); 479 } 480 481 // The following code causes accumulating rounding error for numbers greater 482 // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, 483 // 16, or 32, then mathInt may be an implementation-dependent approximation to 484 // the mathematical integer value" (15.1.2.2). 485 486 int lim_0 = '0' + (radix < 10 ? radix : 10); 487 int lim_a = 'a' + (radix - 10); 488 int lim_A = 'A' + (radix - 10); 489 490 // NOTE: The code for computing the value may seem a bit complex at 491 // first glance. It is structured to use 32-bit multiply-and-add 492 // loops as long as possible to avoid loosing precision. 493 494 double v = 0.0; 495 bool done = false; 496 do { 497 // Parse the longest part of the string starting at index j 498 // possible while keeping the multiplier, and thus the part 499 // itself, within 32 bits. 500 unsigned int part = 0, multiplier = 1; 501 while (true) { 502 int d; 503 if (*current >= '0' && *current < lim_0) { 504 d = *current - '0'; 505 } else if (*current >= 'a' && *current < lim_a) { 506 d = *current - 'a' + 10; 507 } else if (*current >= 'A' && *current < lim_A) { 508 d = *current - 'A' + 10; 509 } else { 510 done = true; 511 break; 512 } 513 514 // Update the value of the part as long as the multiplier fits 515 // in 32 bits. When we can't guarantee that the next iteration 516 // will not overflow the multiplier, we stop parsing the part 517 // by leaving the loop. 518 const unsigned int kMaximumMultiplier = 0xffffffffU / 36; 519 uint32_t m = multiplier * radix; 520 if (m > kMaximumMultiplier) break; 521 part = part * radix + d; 522 multiplier = m; 523 DCHECK(multiplier > part); 524 525 ++current; 526 if (current == end) { 527 done = true; 528 break; 529 } 530 } 531 532 // Update the value and skip the part in the string. 533 v = v * multiplier + part; 534 } while (!done); 535 536 if (!allow_trailing_junk && 537 AdvanceToNonspace(unicode_cache, ¤t, end)) { 538 return JunkStringValue(); 539 } 540 541 return negative ? -v : v; 542 } 543 544 545 // Converts a string to a double value. Assumes the Iterator supports 546 // the following operations: 547 // 1. current == end (other ops are not allowed), current != end. 548 // 2. *current - gets the current character in the sequence. 549 // 3. ++current (advances the position). 550 template <class Iterator, class EndMark> 551 double InternalStringToDouble(UnicodeCache* unicode_cache, 552 Iterator current, 553 EndMark end, 554 int flags, 555 double empty_string_val) { 556 // To make sure that iterator dereferencing is valid the following 557 // convention is used: 558 // 1. Each '++current' statement is followed by check for equality to 'end'. 559 // 2. If AdvanceToNonspace returned false then current == end. 560 // 3. If 'current' becomes be equal to 'end' the function returns or goes to 561 // 'parsing_done'. 562 // 4. 'current' is not dereferenced after the 'parsing_done' label. 563 // 5. Code before 'parsing_done' may rely on 'current != end'. 564 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { 565 return empty_string_val; 566 } 567 568 const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0; 569 570 // The longest form of simplified number is: "-<significant digits>'.1eXXX\0". 571 const int kBufferSize = kMaxSignificantDigits + 10; 572 char buffer[kBufferSize]; // NOLINT: size is known at compile time. 573 int buffer_pos = 0; 574 575 // Exponent will be adjusted if insignificant digits of the integer part 576 // or insignificant leading zeros of the fractional part are dropped. 577 int exponent = 0; 578 int significant_digits = 0; 579 int insignificant_digits = 0; 580 bool nonzero_digit_dropped = false; 581 582 enum Sign { 583 NONE, 584 NEGATIVE, 585 POSITIVE 586 }; 587 588 Sign sign = NONE; 589 590 if (*current == '+') { 591 // Ignore leading sign. 592 ++current; 593 if (current == end) return JunkStringValue(); 594 sign = POSITIVE; 595 } else if (*current == '-') { 596 ++current; 597 if (current == end) return JunkStringValue(); 598 sign = NEGATIVE; 599 } 600 601 static const char kInfinityString[] = "Infinity"; 602 if (*current == kInfinityString[0]) { 603 if (!SubStringEquals(¤t, end, kInfinityString)) { 604 return JunkStringValue(); 605 } 606 607 if (!allow_trailing_junk && 608 AdvanceToNonspace(unicode_cache, ¤t, end)) { 609 return JunkStringValue(); 610 } 611 612 DCHECK(buffer_pos == 0); 613 return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY; 614 } 615 616 bool leading_zero = false; 617 if (*current == '0') { 618 ++current; 619 if (current == end) return SignedZero(sign == NEGATIVE); 620 621 leading_zero = true; 622 623 // It could be hexadecimal value. 624 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { 625 ++current; 626 if (current == end || !isDigit(*current, 16) || sign != NONE) { 627 return JunkStringValue(); // "0x". 628 } 629 630 return InternalStringToIntDouble<4>(unicode_cache, 631 current, 632 end, 633 false, 634 allow_trailing_junk); 635 636 // It could be an explicit octal value. 637 } else if ((flags & ALLOW_OCTAL) && (*current == 'o' || *current == 'O')) { 638 ++current; 639 if (current == end || !isDigit(*current, 8) || sign != NONE) { 640 return JunkStringValue(); // "0o". 641 } 642 643 return InternalStringToIntDouble<3>(unicode_cache, 644 current, 645 end, 646 false, 647 allow_trailing_junk); 648 649 // It could be a binary value. 650 } else if ((flags & ALLOW_BINARY) && (*current == 'b' || *current == 'B')) { 651 ++current; 652 if (current == end || !isBinaryDigit(*current) || sign != NONE) { 653 return JunkStringValue(); // "0b". 654 } 655 656 return InternalStringToIntDouble<1>(unicode_cache, 657 current, 658 end, 659 false, 660 allow_trailing_junk); 661 } 662 663 // Ignore leading zeros in the integer part. 664 while (*current == '0') { 665 ++current; 666 if (current == end) return SignedZero(sign == NEGATIVE); 667 } 668 } 669 670 bool octal = leading_zero && (flags & ALLOW_IMPLICIT_OCTAL) != 0; 671 672 // Copy significant digits of the integer part (if any) to the buffer. 673 while (*current >= '0' && *current <= '9') { 674 if (significant_digits < kMaxSignificantDigits) { 675 DCHECK(buffer_pos < kBufferSize); 676 buffer[buffer_pos++] = static_cast<char>(*current); 677 significant_digits++; 678 // Will later check if it's an octal in the buffer. 679 } else { 680 insignificant_digits++; // Move the digit into the exponential part. 681 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 682 } 683 octal = octal && *current < '8'; 684 ++current; 685 if (current == end) goto parsing_done; 686 } 687 688 if (significant_digits == 0) { 689 octal = false; 690 } 691 692 if (*current == '.') { 693 if (octal && !allow_trailing_junk) return JunkStringValue(); 694 if (octal) goto parsing_done; 695 696 ++current; 697 if (current == end) { 698 if (significant_digits == 0 && !leading_zero) { 699 return JunkStringValue(); 700 } else { 701 goto parsing_done; 702 } 703 } 704 705 if (significant_digits == 0) { 706 // octal = false; 707 // Integer part consists of 0 or is absent. Significant digits start after 708 // leading zeros (if any). 709 while (*current == '0') { 710 ++current; 711 if (current == end) return SignedZero(sign == NEGATIVE); 712 exponent--; // Move this 0 into the exponent. 713 } 714 } 715 716 // There is a fractional part. We don't emit a '.', but adjust the exponent 717 // instead. 718 while (*current >= '0' && *current <= '9') { 719 if (significant_digits < kMaxSignificantDigits) { 720 DCHECK(buffer_pos < kBufferSize); 721 buffer[buffer_pos++] = static_cast<char>(*current); 722 significant_digits++; 723 exponent--; 724 } else { 725 // Ignore insignificant digits in the fractional part. 726 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 727 } 728 ++current; 729 if (current == end) goto parsing_done; 730 } 731 } 732 733 if (!leading_zero && exponent == 0 && significant_digits == 0) { 734 // If leading_zeros is true then the string contains zeros. 735 // If exponent < 0 then string was [+-]\.0*... 736 // If significant_digits != 0 the string is not equal to 0. 737 // Otherwise there are no digits in the string. 738 return JunkStringValue(); 739 } 740 741 // Parse exponential part. 742 if (*current == 'e' || *current == 'E') { 743 if (octal) return JunkStringValue(); 744 ++current; 745 if (current == end) { 746 if (allow_trailing_junk) { 747 goto parsing_done; 748 } else { 749 return JunkStringValue(); 750 } 751 } 752 char sign = '+'; 753 if (*current == '+' || *current == '-') { 754 sign = static_cast<char>(*current); 755 ++current; 756 if (current == end) { 757 if (allow_trailing_junk) { 758 goto parsing_done; 759 } else { 760 return JunkStringValue(); 761 } 762 } 763 } 764 765 if (current == end || *current < '0' || *current > '9') { 766 if (allow_trailing_junk) { 767 goto parsing_done; 768 } else { 769 return JunkStringValue(); 770 } 771 } 772 773 const int max_exponent = INT_MAX / 2; 774 DCHECK(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); 775 int num = 0; 776 do { 777 // Check overflow. 778 int digit = *current - '0'; 779 if (num >= max_exponent / 10 780 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { 781 num = max_exponent; 782 } else { 783 num = num * 10 + digit; 784 } 785 ++current; 786 } while (current != end && *current >= '0' && *current <= '9'); 787 788 exponent += (sign == '-' ? -num : num); 789 } 790 791 if (!allow_trailing_junk && 792 AdvanceToNonspace(unicode_cache, ¤t, end)) { 793 return JunkStringValue(); 794 } 795 796 parsing_done: 797 exponent += insignificant_digits; 798 799 if (octal) { 800 return InternalStringToIntDouble<3>(unicode_cache, 801 buffer, 802 buffer + buffer_pos, 803 sign == NEGATIVE, 804 allow_trailing_junk); 805 } 806 807 if (nonzero_digit_dropped) { 808 buffer[buffer_pos++] = '1'; 809 exponent--; 810 } 811 812 SLOW_DCHECK(buffer_pos < kBufferSize); 813 buffer[buffer_pos] = '\0'; 814 815 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); 816 return (sign == NEGATIVE) ? -converted : converted; 817 } 818 819 } // namespace internal 820 } // namespace v8 821 822 #endif // V8_CONVERSIONS_INL_H_ 823