| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 // ---------------------------------------------------------------------------- | 36 // ---------------------------------------------------------------------------- |
| 37 // Extra POSIX/ANSI functions for Win32/MSVC. | 37 // Extra POSIX/ANSI functions for Win32/MSVC. |
| 38 | 38 |
| 39 #include "conversions.h" | 39 #include "conversions.h" |
| 40 #include "strtod.h" | 40 #include "strtod.h" |
| 41 #include "platform.h" | 41 #include "platform.h" |
| 42 | 42 |
| 43 namespace v8 { | 43 namespace v8 { |
| 44 namespace internal { | 44 namespace internal { |
| 45 | 45 |
| 46 static inline double JunkStringValue() { |
| 47 return std::numeric_limits<double>::quiet_NaN(); |
| 48 } |
| 49 |
| 50 |
| 46 // The fast double-to-unsigned-int conversion routine does not guarantee | 51 // The fast double-to-unsigned-int conversion routine does not guarantee |
| 47 // rounding towards zero, or any reasonable value if the argument is larger | 52 // rounding towards zero, or any reasonable value if the argument is larger |
| 48 // than what fits in an unsigned 32-bit integer. | 53 // than what fits in an unsigned 32-bit integer. |
| 49 static inline unsigned int FastD2UI(double x) { | 54 static inline unsigned int FastD2UI(double x) { |
| 50 // There is no unsigned version of lrint, so there is no fast path | 55 // There is no unsigned version of lrint, so there is no fast path |
| 51 // in this function as there is in FastD2I. Using lrint doesn't work | 56 // in this function as there is in FastD2I. Using lrint doesn't work |
| 52 // for values of 2^31 and above. | 57 // for values of 2^31 and above. |
| 53 | 58 |
| 54 // Convert "small enough" doubles to uint32_t by fixing the 32 | 59 // Convert "small enough" doubles to uint32_t by fixing the 32 |
| 55 // least significant non-fractional bits in the low 32 bits of the | 60 // least significant non-fractional bits in the low 32 bits of the |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 digit = static_cast<char>(*current) - '0'; | 149 digit = static_cast<char>(*current) - '0'; |
| 145 } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { | 150 } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { |
| 146 digit = static_cast<char>(*current) - 'a' + 10; | 151 digit = static_cast<char>(*current) - 'a' + 10; |
| 147 } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { | 152 } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { |
| 148 digit = static_cast<char>(*current) - 'A' + 10; | 153 digit = static_cast<char>(*current) - 'A' + 10; |
| 149 } else { | 154 } else { |
| 150 if (allow_trailing_junk || | 155 if (allow_trailing_junk || |
| 151 !AdvanceToNonspace(unicode_cache, ¤t, end)) { | 156 !AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 152 break; | 157 break; |
| 153 } else { | 158 } else { |
| 154 return JUNK_STRING_VALUE; | 159 return JunkStringValue(); |
| 155 } | 160 } |
| 156 } | 161 } |
| 157 | 162 |
| 158 number = number * radix + digit; | 163 number = number * radix + digit; |
| 159 int overflow = static_cast<int>(number >> 53); | 164 int overflow = static_cast<int>(number >> 53); |
| 160 if (overflow != 0) { | 165 if (overflow != 0) { |
| 161 // Overflow occurred. Need to determine which direction to round the | 166 // Overflow occurred. Need to determine which direction to round the |
| 162 // result. | 167 // result. |
| 163 int overflow_bits_count = 1; | 168 int overflow_bits_count = 1; |
| 164 while (overflow > 1) { | 169 while (overflow > 1) { |
| 165 overflow_bits_count++; | 170 overflow_bits_count++; |
| 166 overflow >>= 1; | 171 overflow >>= 1; |
| 167 } | 172 } |
| 168 | 173 |
| 169 int dropped_bits_mask = ((1 << overflow_bits_count) - 1); | 174 int dropped_bits_mask = ((1 << overflow_bits_count) - 1); |
| 170 int dropped_bits = static_cast<int>(number) & dropped_bits_mask; | 175 int dropped_bits = static_cast<int>(number) & dropped_bits_mask; |
| 171 number >>= overflow_bits_count; | 176 number >>= overflow_bits_count; |
| 172 exponent = overflow_bits_count; | 177 exponent = overflow_bits_count; |
| 173 | 178 |
| 174 bool zero_tail = true; | 179 bool zero_tail = true; |
| 175 while (true) { | 180 while (true) { |
| 176 ++current; | 181 ++current; |
| 177 if (current == end || !isDigit(*current, radix)) break; | 182 if (current == end || !isDigit(*current, radix)) break; |
| 178 zero_tail = zero_tail && *current == '0'; | 183 zero_tail = zero_tail && *current == '0'; |
| 179 exponent += radix_log_2; | 184 exponent += radix_log_2; |
| 180 } | 185 } |
| 181 | 186 |
| 182 if (!allow_trailing_junk && | 187 if (!allow_trailing_junk && |
| 183 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 188 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 184 return JUNK_STRING_VALUE; | 189 return JunkStringValue(); |
| 185 } | 190 } |
| 186 | 191 |
| 187 int middle_value = (1 << (overflow_bits_count - 1)); | 192 int middle_value = (1 << (overflow_bits_count - 1)); |
| 188 if (dropped_bits > middle_value) { | 193 if (dropped_bits > middle_value) { |
| 189 number++; // Rounding up. | 194 number++; // Rounding up. |
| 190 } else if (dropped_bits == middle_value) { | 195 } else if (dropped_bits == middle_value) { |
| 191 // Rounding to even to consistency with decimals: half-way case rounds | 196 // Rounding to even to consistency with decimals: half-way case rounds |
| 192 // up if significant part is odd and down otherwise. | 197 // up if significant part is odd and down otherwise. |
| 193 if ((number & 1) != 0 || !zero_tail) { | 198 if ((number & 1) != 0 || !zero_tail) { |
| 194 number++; // Rounding up. | 199 number++; // Rounding up. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 222 return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); | 227 return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); |
| 223 } | 228 } |
| 224 | 229 |
| 225 | 230 |
| 226 template <class Iterator, class EndMark> | 231 template <class Iterator, class EndMark> |
| 227 static double InternalStringToInt(UnicodeCache* unicode_cache, | 232 static double InternalStringToInt(UnicodeCache* unicode_cache, |
| 228 Iterator current, | 233 Iterator current, |
| 229 EndMark end, | 234 EndMark end, |
| 230 int radix) { | 235 int radix) { |
| 231 const bool allow_trailing_junk = true; | 236 const bool allow_trailing_junk = true; |
| 232 const double empty_string_val = JUNK_STRING_VALUE; | 237 const double empty_string_val = JunkStringValue(); |
| 233 | 238 |
| 234 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { | 239 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 235 return empty_string_val; | 240 return empty_string_val; |
| 236 } | 241 } |
| 237 | 242 |
| 238 bool negative = false; | 243 bool negative = false; |
| 239 bool leading_zero = false; | 244 bool leading_zero = false; |
| 240 | 245 |
| 241 if (*current == '+') { | 246 if (*current == '+') { |
| 242 // Ignore leading sign; skip following spaces. | 247 // Ignore leading sign; skip following spaces. |
| 243 ++current; | 248 ++current; |
| 244 if (current == end) { | 249 if (current == end) { |
| 245 return JUNK_STRING_VALUE; | 250 return JunkStringValue(); |
| 246 } | 251 } |
| 247 } else if (*current == '-') { | 252 } else if (*current == '-') { |
| 248 ++current; | 253 ++current; |
| 249 if (current == end) { | 254 if (current == end) { |
| 250 return JUNK_STRING_VALUE; | 255 return JunkStringValue(); |
| 251 } | 256 } |
| 252 negative = true; | 257 negative = true; |
| 253 } | 258 } |
| 254 | 259 |
| 255 if (radix == 0) { | 260 if (radix == 0) { |
| 256 // Radix detection. | 261 // Radix detection. |
| 257 if (*current == '0') { | 262 if (*current == '0') { |
| 258 ++current; | 263 ++current; |
| 259 if (current == end) return SignedZero(negative); | 264 if (current == end) return SignedZero(negative); |
| 260 if (*current == 'x' || *current == 'X') { | 265 if (*current == 'x' || *current == 'X') { |
| 261 radix = 16; | 266 radix = 16; |
| 262 ++current; | 267 ++current; |
| 263 if (current == end) return JUNK_STRING_VALUE; | 268 if (current == end) return JunkStringValue(); |
| 264 } else { | 269 } else { |
| 265 radix = 8; | 270 radix = 8; |
| 266 leading_zero = true; | 271 leading_zero = true; |
| 267 } | 272 } |
| 268 } else { | 273 } else { |
| 269 radix = 10; | 274 radix = 10; |
| 270 } | 275 } |
| 271 } else if (radix == 16) { | 276 } else if (radix == 16) { |
| 272 if (*current == '0') { | 277 if (*current == '0') { |
| 273 // Allow "0x" prefix. | 278 // Allow "0x" prefix. |
| 274 ++current; | 279 ++current; |
| 275 if (current == end) return SignedZero(negative); | 280 if (current == end) return SignedZero(negative); |
| 276 if (*current == 'x' || *current == 'X') { | 281 if (*current == 'x' || *current == 'X') { |
| 277 ++current; | 282 ++current; |
| 278 if (current == end) return JUNK_STRING_VALUE; | 283 if (current == end) return JunkStringValue(); |
| 279 } else { | 284 } else { |
| 280 leading_zero = true; | 285 leading_zero = true; |
| 281 } | 286 } |
| 282 } | 287 } |
| 283 } | 288 } |
| 284 | 289 |
| 285 if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; | 290 if (radix < 2 || radix > 36) return JunkStringValue(); |
| 286 | 291 |
| 287 // Skip leading zeros. | 292 // Skip leading zeros. |
| 288 while (*current == '0') { | 293 while (*current == '0') { |
| 289 leading_zero = true; | 294 leading_zero = true; |
| 290 ++current; | 295 ++current; |
| 291 if (current == end) return SignedZero(negative); | 296 if (current == end) return SignedZero(negative); |
| 292 } | 297 } |
| 293 | 298 |
| 294 if (!leading_zero && !isDigit(*current, radix)) { | 299 if (!leading_zero && !isDigit(*current, radix)) { |
| 295 return JUNK_STRING_VALUE; | 300 return JunkStringValue(); |
| 296 } | 301 } |
| 297 | 302 |
| 298 if (IsPowerOf2(radix)) { | 303 if (IsPowerOf2(radix)) { |
| 299 switch (radix) { | 304 switch (radix) { |
| 300 case 2: | 305 case 2: |
| 301 return InternalStringToIntDouble<1>( | 306 return InternalStringToIntDouble<1>( |
| 302 unicode_cache, current, end, negative, allow_trailing_junk); | 307 unicode_cache, current, end, negative, allow_trailing_junk); |
| 303 case 4: | 308 case 4: |
| 304 return InternalStringToIntDouble<2>( | 309 return InternalStringToIntDouble<2>( |
| 305 unicode_cache, current, end, negative, allow_trailing_junk); | 310 unicode_cache, current, end, negative, allow_trailing_junk); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 333 // as infinity. | 338 // as infinity. |
| 334 ASSERT(buffer_pos < kBufferSize); | 339 ASSERT(buffer_pos < kBufferSize); |
| 335 buffer[buffer_pos++] = static_cast<char>(*current); | 340 buffer[buffer_pos++] = static_cast<char>(*current); |
| 336 } | 341 } |
| 337 ++current; | 342 ++current; |
| 338 if (current == end) break; | 343 if (current == end) break; |
| 339 } | 344 } |
| 340 | 345 |
| 341 if (!allow_trailing_junk && | 346 if (!allow_trailing_junk && |
| 342 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 347 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 343 return JUNK_STRING_VALUE; | 348 return JunkStringValue(); |
| 344 } | 349 } |
| 345 | 350 |
| 346 ASSERT(buffer_pos < kBufferSize); | 351 ASSERT(buffer_pos < kBufferSize); |
| 347 buffer[buffer_pos] = '\0'; | 352 buffer[buffer_pos] = '\0'; |
| 348 Vector<const char> buffer_vector(buffer, buffer_pos); | 353 Vector<const char> buffer_vector(buffer, buffer_pos); |
| 349 return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); | 354 return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); |
| 350 } | 355 } |
| 351 | 356 |
| 352 // The following code causes accumulating rounding error for numbers greater | 357 // The following code causes accumulating rounding error for numbers greater |
| 353 // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, | 358 // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 break; | 404 break; |
| 400 } | 405 } |
| 401 } | 406 } |
| 402 | 407 |
| 403 // Update the value and skip the part in the string. | 408 // Update the value and skip the part in the string. |
| 404 v = v * multiplier + part; | 409 v = v * multiplier + part; |
| 405 } while (!done); | 410 } while (!done); |
| 406 | 411 |
| 407 if (!allow_trailing_junk && | 412 if (!allow_trailing_junk && |
| 408 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 413 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 409 return JUNK_STRING_VALUE; | 414 return JunkStringValue(); |
| 410 } | 415 } |
| 411 | 416 |
| 412 return negative ? -v : v; | 417 return negative ? -v : v; |
| 413 } | 418 } |
| 414 | 419 |
| 415 | 420 |
| 416 // Converts a string to a double value. Assumes the Iterator supports | 421 // Converts a string to a double value. Assumes the Iterator supports |
| 417 // the following operations: | 422 // the following operations: |
| 418 // 1. current == end (other ops are not allowed), current != end. | 423 // 1. current == end (other ops are not allowed), current != end. |
| 419 // 2. *current - gets the current character in the sequence. | 424 // 2. *current - gets the current character in the sequence. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 449 int significant_digits = 0; | 454 int significant_digits = 0; |
| 450 int insignificant_digits = 0; | 455 int insignificant_digits = 0; |
| 451 bool nonzero_digit_dropped = false; | 456 bool nonzero_digit_dropped = false; |
| 452 bool fractional_part = false; | 457 bool fractional_part = false; |
| 453 | 458 |
| 454 bool negative = false; | 459 bool negative = false; |
| 455 | 460 |
| 456 if (*current == '+') { | 461 if (*current == '+') { |
| 457 // Ignore leading sign. | 462 // Ignore leading sign. |
| 458 ++current; | 463 ++current; |
| 459 if (current == end) return JUNK_STRING_VALUE; | 464 if (current == end) return JunkStringValue(); |
| 460 } else if (*current == '-') { | 465 } else if (*current == '-') { |
| 461 ++current; | 466 ++current; |
| 462 if (current == end) return JUNK_STRING_VALUE; | 467 if (current == end) return JunkStringValue(); |
| 463 negative = true; | 468 negative = true; |
| 464 } | 469 } |
| 465 | 470 |
| 466 static const char kInfinitySymbol[] = "Infinity"; | 471 static const char kInfinitySymbol[] = "Infinity"; |
| 467 if (*current == kInfinitySymbol[0]) { | 472 if (*current == kInfinitySymbol[0]) { |
| 468 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { | 473 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { |
| 469 return JUNK_STRING_VALUE; | 474 return JunkStringValue(); |
| 470 } | 475 } |
| 471 | 476 |
| 472 if (!allow_trailing_junk && | 477 if (!allow_trailing_junk && |
| 473 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 478 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 474 return JUNK_STRING_VALUE; | 479 return JunkStringValue(); |
| 475 } | 480 } |
| 476 | 481 |
| 477 ASSERT(buffer_pos == 0); | 482 ASSERT(buffer_pos == 0); |
| 478 return negative ? -V8_INFINITY : V8_INFINITY; | 483 return negative ? -V8_INFINITY : V8_INFINITY; |
| 479 } | 484 } |
| 480 | 485 |
| 481 bool leading_zero = false; | 486 bool leading_zero = false; |
| 482 if (*current == '0') { | 487 if (*current == '0') { |
| 483 ++current; | 488 ++current; |
| 484 if (current == end) return SignedZero(negative); | 489 if (current == end) return SignedZero(negative); |
| 485 | 490 |
| 486 leading_zero = true; | 491 leading_zero = true; |
| 487 | 492 |
| 488 // It could be hexadecimal value. | 493 // It could be hexadecimal value. |
| 489 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 494 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { |
| 490 ++current; | 495 ++current; |
| 491 if (current == end || !isDigit(*current, 16)) { | 496 if (current == end || !isDigit(*current, 16)) { |
| 492 return JUNK_STRING_VALUE; // "0x". | 497 return JunkStringValue(); // "0x". |
| 493 } | 498 } |
| 494 | 499 |
| 495 return InternalStringToIntDouble<4>(unicode_cache, | 500 return InternalStringToIntDouble<4>(unicode_cache, |
| 496 current, | 501 current, |
| 497 end, | 502 end, |
| 498 negative, | 503 negative, |
| 499 allow_trailing_junk); | 504 allow_trailing_junk); |
| 500 } | 505 } |
| 501 | 506 |
| 502 // Ignore leading zeros in the integer part. | 507 // Ignore leading zeros in the integer part. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 522 octal = octal && *current < '8'; | 527 octal = octal && *current < '8'; |
| 523 ++current; | 528 ++current; |
| 524 if (current == end) goto parsing_done; | 529 if (current == end) goto parsing_done; |
| 525 } | 530 } |
| 526 | 531 |
| 527 if (significant_digits == 0) { | 532 if (significant_digits == 0) { |
| 528 octal = false; | 533 octal = false; |
| 529 } | 534 } |
| 530 | 535 |
| 531 if (*current == '.') { | 536 if (*current == '.') { |
| 532 if (octal && !allow_trailing_junk) return JUNK_STRING_VALUE; | 537 if (octal && !allow_trailing_junk) return JunkStringValue(); |
| 533 if (octal) goto parsing_done; | 538 if (octal) goto parsing_done; |
| 534 | 539 |
| 535 ++current; | 540 ++current; |
| 536 if (current == end) { | 541 if (current == end) { |
| 537 if (significant_digits == 0 && !leading_zero) { | 542 if (significant_digits == 0 && !leading_zero) { |
| 538 return JUNK_STRING_VALUE; | 543 return JunkStringValue(); |
| 539 } else { | 544 } else { |
| 540 goto parsing_done; | 545 goto parsing_done; |
| 541 } | 546 } |
| 542 } | 547 } |
| 543 | 548 |
| 544 if (significant_digits == 0) { | 549 if (significant_digits == 0) { |
| 545 // octal = false; | 550 // octal = false; |
| 546 // Integer part consists of 0 or is absent. Significant digits start after | 551 // Integer part consists of 0 or is absent. Significant digits start after |
| 547 // leading zeros (if any). | 552 // leading zeros (if any). |
| 548 while (*current == '0') { | 553 while (*current == '0') { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 569 ++current; | 574 ++current; |
| 570 if (current == end) goto parsing_done; | 575 if (current == end) goto parsing_done; |
| 571 } | 576 } |
| 572 } | 577 } |
| 573 | 578 |
| 574 if (!leading_zero && exponent == 0 && significant_digits == 0) { | 579 if (!leading_zero && exponent == 0 && significant_digits == 0) { |
| 575 // If leading_zeros is true then the string contains zeros. | 580 // If leading_zeros is true then the string contains zeros. |
| 576 // If exponent < 0 then string was [+-]\.0*... | 581 // If exponent < 0 then string was [+-]\.0*... |
| 577 // If significant_digits != 0 the string is not equal to 0. | 582 // If significant_digits != 0 the string is not equal to 0. |
| 578 // Otherwise there are no digits in the string. | 583 // Otherwise there are no digits in the string. |
| 579 return JUNK_STRING_VALUE; | 584 return JunkStringValue(); |
| 580 } | 585 } |
| 581 | 586 |
| 582 // Parse exponential part. | 587 // Parse exponential part. |
| 583 if (*current == 'e' || *current == 'E') { | 588 if (*current == 'e' || *current == 'E') { |
| 584 if (octal) return JUNK_STRING_VALUE; | 589 if (octal) return JunkStringValue(); |
| 585 ++current; | 590 ++current; |
| 586 if (current == end) { | 591 if (current == end) { |
| 587 if (allow_trailing_junk) { | 592 if (allow_trailing_junk) { |
| 588 goto parsing_done; | 593 goto parsing_done; |
| 589 } else { | 594 } else { |
| 590 return JUNK_STRING_VALUE; | 595 return JunkStringValue(); |
| 591 } | 596 } |
| 592 } | 597 } |
| 593 char sign = '+'; | 598 char sign = '+'; |
| 594 if (*current == '+' || *current == '-') { | 599 if (*current == '+' || *current == '-') { |
| 595 sign = static_cast<char>(*current); | 600 sign = static_cast<char>(*current); |
| 596 ++current; | 601 ++current; |
| 597 if (current == end) { | 602 if (current == end) { |
| 598 if (allow_trailing_junk) { | 603 if (allow_trailing_junk) { |
| 599 goto parsing_done; | 604 goto parsing_done; |
| 600 } else { | 605 } else { |
| 601 return JUNK_STRING_VALUE; | 606 return JunkStringValue(); |
| 602 } | 607 } |
| 603 } | 608 } |
| 604 } | 609 } |
| 605 | 610 |
| 606 if (current == end || *current < '0' || *current > '9') { | 611 if (current == end || *current < '0' || *current > '9') { |
| 607 if (allow_trailing_junk) { | 612 if (allow_trailing_junk) { |
| 608 goto parsing_done; | 613 goto parsing_done; |
| 609 } else { | 614 } else { |
| 610 return JUNK_STRING_VALUE; | 615 return JunkStringValue(); |
| 611 } | 616 } |
| 612 } | 617 } |
| 613 | 618 |
| 614 const int max_exponent = INT_MAX / 2; | 619 const int max_exponent = INT_MAX / 2; |
| 615 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); | 620 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); |
| 616 int num = 0; | 621 int num = 0; |
| 617 do { | 622 do { |
| 618 // Check overflow. | 623 // Check overflow. |
| 619 int digit = *current - '0'; | 624 int digit = *current - '0'; |
| 620 if (num >= max_exponent / 10 | 625 if (num >= max_exponent / 10 |
| 621 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { | 626 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { |
| 622 num = max_exponent; | 627 num = max_exponent; |
| 623 } else { | 628 } else { |
| 624 num = num * 10 + digit; | 629 num = num * 10 + digit; |
| 625 } | 630 } |
| 626 ++current; | 631 ++current; |
| 627 } while (current != end && *current >= '0' && *current <= '9'); | 632 } while (current != end && *current >= '0' && *current <= '9'); |
| 628 | 633 |
| 629 exponent += (sign == '-' ? -num : num); | 634 exponent += (sign == '-' ? -num : num); |
| 630 } | 635 } |
| 631 | 636 |
| 632 if (!allow_trailing_junk && | 637 if (!allow_trailing_junk && |
| 633 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 638 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 634 return JUNK_STRING_VALUE; | 639 return JunkStringValue(); |
| 635 } | 640 } |
| 636 | 641 |
| 637 parsing_done: | 642 parsing_done: |
| 638 exponent += insignificant_digits; | 643 exponent += insignificant_digits; |
| 639 | 644 |
| 640 if (octal) { | 645 if (octal) { |
| 641 return InternalStringToIntDouble<3>(unicode_cache, | 646 return InternalStringToIntDouble<3>(unicode_cache, |
| 642 buffer, | 647 buffer, |
| 643 buffer + buffer_pos, | 648 buffer + buffer_pos, |
| 644 negative, | 649 negative, |
| 645 allow_trailing_junk); | 650 allow_trailing_junk); |
| 646 } | 651 } |
| 647 | 652 |
| 648 if (nonzero_digit_dropped) { | 653 if (nonzero_digit_dropped) { |
| 649 buffer[buffer_pos++] = '1'; | 654 buffer[buffer_pos++] = '1'; |
| 650 exponent--; | 655 exponent--; |
| 651 } | 656 } |
| 652 | 657 |
| 653 ASSERT(buffer_pos < kBufferSize); | 658 ASSERT(buffer_pos < kBufferSize); |
| 654 buffer[buffer_pos] = '\0'; | 659 buffer[buffer_pos] = '\0'; |
| 655 | 660 |
| 656 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 661 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
| 657 return negative ? -converted : converted; | 662 return negative ? -converted : converted; |
| 658 } | 663 } |
| 659 | 664 |
| 660 } } // namespace v8::internal | 665 } } // namespace v8::internal |
| 661 | 666 |
| 662 #endif // V8_CONVERSIONS_INL_H_ | 667 #endif // V8_CONVERSIONS_INL_H_ |
| OLD | NEW |