| 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 digit = static_cast<char>(*current) - '0'; | 144 digit = static_cast<char>(*current) - '0'; |
| 145 } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { | 145 } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { |
| 146 digit = static_cast<char>(*current) - 'a' + 10; | 146 digit = static_cast<char>(*current) - 'a' + 10; |
| 147 } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { | 147 } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { |
| 148 digit = static_cast<char>(*current) - 'A' + 10; | 148 digit = static_cast<char>(*current) - 'A' + 10; |
| 149 } else { | 149 } else { |
| 150 if (allow_trailing_junk || | 150 if (allow_trailing_junk || |
| 151 !AdvanceToNonspace(unicode_cache, ¤t, end)) { | 151 !AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 152 break; | 152 break; |
| 153 } else { | 153 } else { |
| 154 return JUNK_STRING_VALUE; | 154 return JunkStringValue(); |
| 155 } | 155 } |
| 156 } | 156 } |
| 157 | 157 |
| 158 number = number * radix + digit; | 158 number = number * radix + digit; |
| 159 int overflow = static_cast<int>(number >> 53); | 159 int overflow = static_cast<int>(number >> 53); |
| 160 if (overflow != 0) { | 160 if (overflow != 0) { |
| 161 // Overflow occurred. Need to determine which direction to round the | 161 // Overflow occurred. Need to determine which direction to round the |
| 162 // result. | 162 // result. |
| 163 int overflow_bits_count = 1; | 163 int overflow_bits_count = 1; |
| 164 while (overflow > 1) { | 164 while (overflow > 1) { |
| 165 overflow_bits_count++; | 165 overflow_bits_count++; |
| 166 overflow >>= 1; | 166 overflow >>= 1; |
| 167 } | 167 } |
| 168 | 168 |
| 169 int dropped_bits_mask = ((1 << overflow_bits_count) - 1); | 169 int dropped_bits_mask = ((1 << overflow_bits_count) - 1); |
| 170 int dropped_bits = static_cast<int>(number) & dropped_bits_mask; | 170 int dropped_bits = static_cast<int>(number) & dropped_bits_mask; |
| 171 number >>= overflow_bits_count; | 171 number >>= overflow_bits_count; |
| 172 exponent = overflow_bits_count; | 172 exponent = overflow_bits_count; |
| 173 | 173 |
| 174 bool zero_tail = true; | 174 bool zero_tail = true; |
| 175 while (true) { | 175 while (true) { |
| 176 ++current; | 176 ++current; |
| 177 if (current == end || !isDigit(*current, radix)) break; | 177 if (current == end || !isDigit(*current, radix)) break; |
| 178 zero_tail = zero_tail && *current == '0'; | 178 zero_tail = zero_tail && *current == '0'; |
| 179 exponent += radix_log_2; | 179 exponent += radix_log_2; |
| 180 } | 180 } |
| 181 | 181 |
| 182 if (!allow_trailing_junk && | 182 if (!allow_trailing_junk && |
| 183 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 183 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 184 return JUNK_STRING_VALUE; | 184 return JunkStringValue(); |
| 185 } | 185 } |
| 186 | 186 |
| 187 int middle_value = (1 << (overflow_bits_count - 1)); | 187 int middle_value = (1 << (overflow_bits_count - 1)); |
| 188 if (dropped_bits > middle_value) { | 188 if (dropped_bits > middle_value) { |
| 189 number++; // Rounding up. | 189 number++; // Rounding up. |
| 190 } else if (dropped_bits == middle_value) { | 190 } else if (dropped_bits == middle_value) { |
| 191 // Rounding to even to consistency with decimals: half-way case rounds | 191 // Rounding to even to consistency with decimals: half-way case rounds |
| 192 // up if significant part is odd and down otherwise. | 192 // up if significant part is odd and down otherwise. |
| 193 if ((number & 1) != 0 || !zero_tail) { | 193 if ((number & 1) != 0 || !zero_tail) { |
| 194 number++; // Rounding up. | 194 number++; // Rounding up. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 222 return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); | 222 return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); |
| 223 } | 223 } |
| 224 | 224 |
| 225 | 225 |
| 226 template <class Iterator, class EndMark> | 226 template <class Iterator, class EndMark> |
| 227 static double InternalStringToInt(UnicodeCache* unicode_cache, | 227 static double InternalStringToInt(UnicodeCache* unicode_cache, |
| 228 Iterator current, | 228 Iterator current, |
| 229 EndMark end, | 229 EndMark end, |
| 230 int radix) { | 230 int radix) { |
| 231 const bool allow_trailing_junk = true; | 231 const bool allow_trailing_junk = true; |
| 232 const double empty_string_val = JUNK_STRING_VALUE; | 232 const double empty_string_val = JunkStringValue(); |
| 233 | 233 |
| 234 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { | 234 if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 235 return empty_string_val; | 235 return empty_string_val; |
| 236 } | 236 } |
| 237 | 237 |
| 238 bool negative = false; | 238 bool negative = false; |
| 239 bool leading_zero = false; | 239 bool leading_zero = false; |
| 240 | 240 |
| 241 if (*current == '+') { | 241 if (*current == '+') { |
| 242 // Ignore leading sign; skip following spaces. | 242 // Ignore leading sign; skip following spaces. |
| 243 ++current; | 243 ++current; |
| 244 if (current == end) { | 244 if (current == end) { |
| 245 return JUNK_STRING_VALUE; | 245 return JunkStringValue(); |
| 246 } | 246 } |
| 247 } else if (*current == '-') { | 247 } else if (*current == '-') { |
| 248 ++current; | 248 ++current; |
| 249 if (current == end) { | 249 if (current == end) { |
| 250 return JUNK_STRING_VALUE; | 250 return JunkStringValue(); |
| 251 } | 251 } |
| 252 negative = true; | 252 negative = true; |
| 253 } | 253 } |
| 254 | 254 |
| 255 if (radix == 0) { | 255 if (radix == 0) { |
| 256 // Radix detection. | 256 // Radix detection. |
| 257 if (*current == '0') { | 257 if (*current == '0') { |
| 258 ++current; | 258 ++current; |
| 259 if (current == end) return SignedZero(negative); | 259 if (current == end) return SignedZero(negative); |
| 260 if (*current == 'x' || *current == 'X') { | 260 if (*current == 'x' || *current == 'X') { |
| 261 radix = 16; | 261 radix = 16; |
| 262 ++current; | 262 ++current; |
| 263 if (current == end) return JUNK_STRING_VALUE; | 263 if (current == end) return JunkStringValue(); |
| 264 } else { | 264 } else { |
| 265 radix = 8; | 265 radix = 8; |
| 266 leading_zero = true; | 266 leading_zero = true; |
| 267 } | 267 } |
| 268 } else { | 268 } else { |
| 269 radix = 10; | 269 radix = 10; |
| 270 } | 270 } |
| 271 } else if (radix == 16) { | 271 } else if (radix == 16) { |
| 272 if (*current == '0') { | 272 if (*current == '0') { |
| 273 // Allow "0x" prefix. | 273 // Allow "0x" prefix. |
| 274 ++current; | 274 ++current; |
| 275 if (current == end) return SignedZero(negative); | 275 if (current == end) return SignedZero(negative); |
| 276 if (*current == 'x' || *current == 'X') { | 276 if (*current == 'x' || *current == 'X') { |
| 277 ++current; | 277 ++current; |
| 278 if (current == end) return JUNK_STRING_VALUE; | 278 if (current == end) return JunkStringValue(); |
| 279 } else { | 279 } else { |
| 280 leading_zero = true; | 280 leading_zero = true; |
| 281 } | 281 } |
| 282 } | 282 } |
| 283 } | 283 } |
| 284 | 284 |
| 285 if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; | 285 if (radix < 2 || radix > 36) return JunkStringValue(); |
| 286 | 286 |
| 287 // Skip leading zeros. | 287 // Skip leading zeros. |
| 288 while (*current == '0') { | 288 while (*current == '0') { |
| 289 leading_zero = true; | 289 leading_zero = true; |
| 290 ++current; | 290 ++current; |
| 291 if (current == end) return SignedZero(negative); | 291 if (current == end) return SignedZero(negative); |
| 292 } | 292 } |
| 293 | 293 |
| 294 if (!leading_zero && !isDigit(*current, radix)) { | 294 if (!leading_zero && !isDigit(*current, radix)) { |
| 295 return JUNK_STRING_VALUE; | 295 return JunkStringValue(); |
| 296 } | 296 } |
| 297 | 297 |
| 298 if (IsPowerOf2(radix)) { | 298 if (IsPowerOf2(radix)) { |
| 299 switch (radix) { | 299 switch (radix) { |
| 300 case 2: | 300 case 2: |
| 301 return InternalStringToIntDouble<1>( | 301 return InternalStringToIntDouble<1>( |
| 302 unicode_cache, current, end, negative, allow_trailing_junk); | 302 unicode_cache, current, end, negative, allow_trailing_junk); |
| 303 case 4: | 303 case 4: |
| 304 return InternalStringToIntDouble<2>( | 304 return InternalStringToIntDouble<2>( |
| 305 unicode_cache, current, end, negative, allow_trailing_junk); | 305 unicode_cache, current, end, negative, allow_trailing_junk); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 333 // as infinity. | 333 // as infinity. |
| 334 ASSERT(buffer_pos < kBufferSize); | 334 ASSERT(buffer_pos < kBufferSize); |
| 335 buffer[buffer_pos++] = static_cast<char>(*current); | 335 buffer[buffer_pos++] = static_cast<char>(*current); |
| 336 } | 336 } |
| 337 ++current; | 337 ++current; |
| 338 if (current == end) break; | 338 if (current == end) break; |
| 339 } | 339 } |
| 340 | 340 |
| 341 if (!allow_trailing_junk && | 341 if (!allow_trailing_junk && |
| 342 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 342 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 343 return JUNK_STRING_VALUE; | 343 return JunkStringValue(); |
| 344 } | 344 } |
| 345 | 345 |
| 346 ASSERT(buffer_pos < kBufferSize); | 346 ASSERT(buffer_pos < kBufferSize); |
| 347 buffer[buffer_pos] = '\0'; | 347 buffer[buffer_pos] = '\0'; |
| 348 Vector<const char> buffer_vector(buffer, buffer_pos); | 348 Vector<const char> buffer_vector(buffer, buffer_pos); |
| 349 return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); | 349 return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); |
| 350 } | 350 } |
| 351 | 351 |
| 352 // The following code causes accumulating rounding error for numbers greater | 352 // 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, | 353 // 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; | 399 break; |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 | 402 |
| 403 // Update the value and skip the part in the string. | 403 // Update the value and skip the part in the string. |
| 404 v = v * multiplier + part; | 404 v = v * multiplier + part; |
| 405 } while (!done); | 405 } while (!done); |
| 406 | 406 |
| 407 if (!allow_trailing_junk && | 407 if (!allow_trailing_junk && |
| 408 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 408 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 409 return JUNK_STRING_VALUE; | 409 return JunkStringValue(); |
| 410 } | 410 } |
| 411 | 411 |
| 412 return negative ? -v : v; | 412 return negative ? -v : v; |
| 413 } | 413 } |
| 414 | 414 |
| 415 | 415 |
| 416 // Converts a string to a double value. Assumes the Iterator supports | 416 // Converts a string to a double value. Assumes the Iterator supports |
| 417 // the following operations: | 417 // the following operations: |
| 418 // 1. current == end (other ops are not allowed), current != end. | 418 // 1. current == end (other ops are not allowed), current != end. |
| 419 // 2. *current - gets the current character in the sequence. | 419 // 2. *current - gets the current character in the sequence. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 449 int significant_digits = 0; | 449 int significant_digits = 0; |
| 450 int insignificant_digits = 0; | 450 int insignificant_digits = 0; |
| 451 bool nonzero_digit_dropped = false; | 451 bool nonzero_digit_dropped = false; |
| 452 bool fractional_part = false; | 452 bool fractional_part = false; |
| 453 | 453 |
| 454 bool negative = false; | 454 bool negative = false; |
| 455 | 455 |
| 456 if (*current == '+') { | 456 if (*current == '+') { |
| 457 // Ignore leading sign. | 457 // Ignore leading sign. |
| 458 ++current; | 458 ++current; |
| 459 if (current == end) return JUNK_STRING_VALUE; | 459 if (current == end) return JunkStringValue(); |
| 460 } else if (*current == '-') { | 460 } else if (*current == '-') { |
| 461 ++current; | 461 ++current; |
| 462 if (current == end) return JUNK_STRING_VALUE; | 462 if (current == end) return JunkStringValue(); |
| 463 negative = true; | 463 negative = true; |
| 464 } | 464 } |
| 465 | 465 |
| 466 static const char kInfinitySymbol[] = "Infinity"; | 466 static const char kInfinitySymbol[] = "Infinity"; |
| 467 if (*current == kInfinitySymbol[0]) { | 467 if (*current == kInfinitySymbol[0]) { |
| 468 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { | 468 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { |
| 469 return JUNK_STRING_VALUE; | 469 return JunkStringValue(); |
| 470 } | 470 } |
| 471 | 471 |
| 472 if (!allow_trailing_junk && | 472 if (!allow_trailing_junk && |
| 473 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 473 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 474 return JUNK_STRING_VALUE; | 474 return JunkStringValue(); |
| 475 } | 475 } |
| 476 | 476 |
| 477 ASSERT(buffer_pos == 0); | 477 ASSERT(buffer_pos == 0); |
| 478 return negative ? -V8_INFINITY : V8_INFINITY; | 478 return negative ? -V8_INFINITY : V8_INFINITY; |
| 479 } | 479 } |
| 480 | 480 |
| 481 bool leading_zero = false; | 481 bool leading_zero = false; |
| 482 if (*current == '0') { | 482 if (*current == '0') { |
| 483 ++current; | 483 ++current; |
| 484 if (current == end) return SignedZero(negative); | 484 if (current == end) return SignedZero(negative); |
| 485 | 485 |
| 486 leading_zero = true; | 486 leading_zero = true; |
| 487 | 487 |
| 488 // It could be hexadecimal value. | 488 // It could be hexadecimal value. |
| 489 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 489 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { |
| 490 ++current; | 490 ++current; |
| 491 if (current == end || !isDigit(*current, 16)) { | 491 if (current == end || !isDigit(*current, 16)) { |
| 492 return JUNK_STRING_VALUE; // "0x". | 492 return JunkStringValue(); // "0x". |
| 493 } | 493 } |
| 494 | 494 |
| 495 return InternalStringToIntDouble<4>(unicode_cache, | 495 return InternalStringToIntDouble<4>(unicode_cache, |
| 496 current, | 496 current, |
| 497 end, | 497 end, |
| 498 negative, | 498 negative, |
| 499 allow_trailing_junk); | 499 allow_trailing_junk); |
| 500 } | 500 } |
| 501 | 501 |
| 502 // Ignore leading zeros in the integer part. | 502 // Ignore leading zeros in the integer part. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 522 octal = octal && *current < '8'; | 522 octal = octal && *current < '8'; |
| 523 ++current; | 523 ++current; |
| 524 if (current == end) goto parsing_done; | 524 if (current == end) goto parsing_done; |
| 525 } | 525 } |
| 526 | 526 |
| 527 if (significant_digits == 0) { | 527 if (significant_digits == 0) { |
| 528 octal = false; | 528 octal = false; |
| 529 } | 529 } |
| 530 | 530 |
| 531 if (*current == '.') { | 531 if (*current == '.') { |
| 532 if (octal && !allow_trailing_junk) return JUNK_STRING_VALUE; | 532 if (octal && !allow_trailing_junk) return JunkStringValue(); |
| 533 if (octal) goto parsing_done; | 533 if (octal) goto parsing_done; |
| 534 | 534 |
| 535 ++current; | 535 ++current; |
| 536 if (current == end) { | 536 if (current == end) { |
| 537 if (significant_digits == 0 && !leading_zero) { | 537 if (significant_digits == 0 && !leading_zero) { |
| 538 return JUNK_STRING_VALUE; | 538 return JunkStringValue(); |
| 539 } else { | 539 } else { |
| 540 goto parsing_done; | 540 goto parsing_done; |
| 541 } | 541 } |
| 542 } | 542 } |
| 543 | 543 |
| 544 if (significant_digits == 0) { | 544 if (significant_digits == 0) { |
| 545 // octal = false; | 545 // octal = false; |
| 546 // Integer part consists of 0 or is absent. Significant digits start after | 546 // Integer part consists of 0 or is absent. Significant digits start after |
| 547 // leading zeros (if any). | 547 // leading zeros (if any). |
| 548 while (*current == '0') { | 548 while (*current == '0') { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 569 ++current; | 569 ++current; |
| 570 if (current == end) goto parsing_done; | 570 if (current == end) goto parsing_done; |
| 571 } | 571 } |
| 572 } | 572 } |
| 573 | 573 |
| 574 if (!leading_zero && exponent == 0 && significant_digits == 0) { | 574 if (!leading_zero && exponent == 0 && significant_digits == 0) { |
| 575 // If leading_zeros is true then the string contains zeros. | 575 // If leading_zeros is true then the string contains zeros. |
| 576 // If exponent < 0 then string was [+-]\.0*... | 576 // If exponent < 0 then string was [+-]\.0*... |
| 577 // If significant_digits != 0 the string is not equal to 0. | 577 // If significant_digits != 0 the string is not equal to 0. |
| 578 // Otherwise there are no digits in the string. | 578 // Otherwise there are no digits in the string. |
| 579 return JUNK_STRING_VALUE; | 579 return JunkStringValue(); |
| 580 } | 580 } |
| 581 | 581 |
| 582 // Parse exponential part. | 582 // Parse exponential part. |
| 583 if (*current == 'e' || *current == 'E') { | 583 if (*current == 'e' || *current == 'E') { |
| 584 if (octal) return JUNK_STRING_VALUE; | 584 if (octal) return JunkStringValue(); |
| 585 ++current; | 585 ++current; |
| 586 if (current == end) { | 586 if (current == end) { |
| 587 if (allow_trailing_junk) { | 587 if (allow_trailing_junk) { |
| 588 goto parsing_done; | 588 goto parsing_done; |
| 589 } else { | 589 } else { |
| 590 return JUNK_STRING_VALUE; | 590 return JunkStringValue(); |
| 591 } | 591 } |
| 592 } | 592 } |
| 593 char sign = '+'; | 593 char sign = '+'; |
| 594 if (*current == '+' || *current == '-') { | 594 if (*current == '+' || *current == '-') { |
| 595 sign = static_cast<char>(*current); | 595 sign = static_cast<char>(*current); |
| 596 ++current; | 596 ++current; |
| 597 if (current == end) { | 597 if (current == end) { |
| 598 if (allow_trailing_junk) { | 598 if (allow_trailing_junk) { |
| 599 goto parsing_done; | 599 goto parsing_done; |
| 600 } else { | 600 } else { |
| 601 return JUNK_STRING_VALUE; | 601 return JunkStringValue(); |
| 602 } | 602 } |
| 603 } | 603 } |
| 604 } | 604 } |
| 605 | 605 |
| 606 if (current == end || *current < '0' || *current > '9') { | 606 if (current == end || *current < '0' || *current > '9') { |
| 607 if (allow_trailing_junk) { | 607 if (allow_trailing_junk) { |
| 608 goto parsing_done; | 608 goto parsing_done; |
| 609 } else { | 609 } else { |
| 610 return JUNK_STRING_VALUE; | 610 return JunkStringValue(); |
| 611 } | 611 } |
| 612 } | 612 } |
| 613 | 613 |
| 614 const int max_exponent = INT_MAX / 2; | 614 const int max_exponent = INT_MAX / 2; |
| 615 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); | 615 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); |
| 616 int num = 0; | 616 int num = 0; |
| 617 do { | 617 do { |
| 618 // Check overflow. | 618 // Check overflow. |
| 619 int digit = *current - '0'; | 619 int digit = *current - '0'; |
| 620 if (num >= max_exponent / 10 | 620 if (num >= max_exponent / 10 |
| 621 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { | 621 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { |
| 622 num = max_exponent; | 622 num = max_exponent; |
| 623 } else { | 623 } else { |
| 624 num = num * 10 + digit; | 624 num = num * 10 + digit; |
| 625 } | 625 } |
| 626 ++current; | 626 ++current; |
| 627 } while (current != end && *current >= '0' && *current <= '9'); | 627 } while (current != end && *current >= '0' && *current <= '9'); |
| 628 | 628 |
| 629 exponent += (sign == '-' ? -num : num); | 629 exponent += (sign == '-' ? -num : num); |
| 630 } | 630 } |
| 631 | 631 |
| 632 if (!allow_trailing_junk && | 632 if (!allow_trailing_junk && |
| 633 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 633 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
| 634 return JUNK_STRING_VALUE; | 634 return JunkStringValue(); |
| 635 } | 635 } |
| 636 | 636 |
| 637 parsing_done: | 637 parsing_done: |
| 638 exponent += insignificant_digits; | 638 exponent += insignificant_digits; |
| 639 | 639 |
| 640 if (octal) { | 640 if (octal) { |
| 641 return InternalStringToIntDouble<3>(unicode_cache, | 641 return InternalStringToIntDouble<3>(unicode_cache, |
| 642 buffer, | 642 buffer, |
| 643 buffer + buffer_pos, | 643 buffer + buffer_pos, |
| 644 negative, | 644 negative, |
| 645 allow_trailing_junk); | 645 allow_trailing_junk); |
| 646 } | 646 } |
| 647 | 647 |
| 648 if (nonzero_digit_dropped) { | 648 if (nonzero_digit_dropped) { |
| 649 buffer[buffer_pos++] = '1'; | 649 buffer[buffer_pos++] = '1'; |
| 650 exponent--; | 650 exponent--; |
| 651 } | 651 } |
| 652 | 652 |
| 653 ASSERT(buffer_pos < kBufferSize); | 653 ASSERT(buffer_pos < kBufferSize); |
| 654 buffer[buffer_pos] = '\0'; | 654 buffer[buffer_pos] = '\0'; |
| 655 | 655 |
| 656 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 656 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
| 657 return negative ? -converted : converted; | 657 return negative ? -converted : converted; |
| 658 } | 658 } |
| 659 | 659 |
| 660 } } // namespace v8::internal | 660 } } // namespace v8::internal |
| 661 | 661 |
| 662 #endif // V8_CONVERSIONS_INL_H_ | 662 #endif // V8_CONVERSIONS_INL_H_ |
| OLD | NEW |