The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / conversions-inl.h @ f230a1cf

History | View | Annotate | Download (21.9 KB)

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
#ifndef V8_CONVERSIONS_INL_H_
29
#define V8_CONVERSIONS_INL_H_
30

    
31
#include <limits.h>        // Required for INT_MAX etc.
32
#include <float.h>         // Required for DBL_MAX and on Win32 for finite()
33
#include <stdarg.h>
34
#include <cmath>
35
#include "globals.h"       // Required for V8_INFINITY
36

    
37
// ----------------------------------------------------------------------------
38
// Extra POSIX/ANSI functions for Win32/MSVC.
39

    
40
#include "conversions.h"
41
#include "double.h"
42
#include "platform.h"
43
#include "scanner.h"
44
#include "strtod.h"
45

    
46
namespace v8 {
47
namespace internal {
48

    
49
inline double JunkStringValue() {
50
  return BitCast<double, uint64_t>(kQuietNaNMask);
51
}
52

    
53

    
54
inline double SignedZero(bool negative) {
55
  return negative ? uint64_to_double(Double::kSignMask) : 0.0;
56
}
57

    
58

    
59
// The fast double-to-unsigned-int conversion routine does not guarantee
60
// rounding towards zero, or any reasonable value if the argument is larger
61
// than what fits in an unsigned 32-bit integer.
62
inline unsigned int FastD2UI(double x) {
63
  // There is no unsigned version of lrint, so there is no fast path
64
  // in this function as there is in FastD2I. Using lrint doesn't work
65
  // for values of 2^31 and above.
66

    
67
  // Convert "small enough" doubles to uint32_t by fixing the 32
68
  // least significant non-fractional bits in the low 32 bits of the
69
  // double, and reading them from there.
70
  const double k2Pow52 = 4503599627370496.0;
71
  bool negative = x < 0;
72
  if (negative) {
73
    x = -x;
74
  }
75
  if (x < k2Pow52) {
76
    x += k2Pow52;
77
    uint32_t result;
78
    Address mantissa_ptr = reinterpret_cast<Address>(&x);
79
    // Copy least significant 32 bits of mantissa.
80
    OS::MemCopy(&result, mantissa_ptr, sizeof(result));
81
    return negative ? ~result + 1 : result;
82
  }
83
  // Large number (outside uint32 range), Infinity or NaN.
84
  return 0x80000000u;  // Return integer indefinite.
85
}
86

    
87

    
88
inline double DoubleToInteger(double x) {
89
  if (std::isnan(x)) return 0;
90
  if (!std::isfinite(x) || x == 0) return x;
91
  return (x >= 0) ? floor(x) : ceil(x);
92
}
93

    
94

    
95
int32_t DoubleToInt32(double x) {
96
  int32_t i = FastD2I(x);
97
  if (FastI2D(i) == x) return i;
98
  Double d(x);
99
  int exponent = d.Exponent();
100
  if (exponent < 0) {
101
    if (exponent <= -Double::kSignificandSize) return 0;
102
    return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent);
103
  } else {
104
    if (exponent > 31) return 0;
105
    return d.Sign() * static_cast<int32_t>(d.Significand() << exponent);
106
  }
107
}
108

    
109

    
110
template <class Iterator, class EndMark>
111
bool SubStringEquals(Iterator* current,
112
                     EndMark end,
113
                     const char* substring) {
114
  ASSERT(**current == *substring);
115
  for (substring++; *substring != '\0'; substring++) {
116
    ++*current;
117
    if (*current == end || **current != *substring) return false;
118
  }
119
  ++*current;
120
  return true;
121
}
122

    
123

    
124
// Returns true if a nonspace character has been found and false if the
125
// end was been reached before finding a nonspace character.
126
template <class Iterator, class EndMark>
127
inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
128
                              Iterator* current,
129
                              EndMark end) {
130
  while (*current != end) {
131
    if (!unicode_cache->IsWhiteSpace(**current)) return true;
132
    ++*current;
133
  }
134
  return false;
135
}
136

    
137

    
138
// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
139
template <int radix_log_2, class Iterator, class EndMark>
140
double InternalStringToIntDouble(UnicodeCache* unicode_cache,
141
                                 Iterator current,
142
                                 EndMark end,
143
                                 bool negative,
144
                                 bool allow_trailing_junk) {
145
  ASSERT(current != end);
146

    
147
  // Skip leading 0s.
148
  while (*current == '0') {
149
    ++current;
150
    if (current == end) return SignedZero(negative);
151
  }
152

    
153
  int64_t number = 0;
154
  int exponent = 0;
155
  const int radix = (1 << radix_log_2);
156

    
157
  do {
158
    int digit;
159
    if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
160
      digit = static_cast<char>(*current) - '0';
161
    } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
162
      digit = static_cast<char>(*current) - 'a' + 10;
163
    } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
164
      digit = static_cast<char>(*current) - 'A' + 10;
165
    } else {
166
      if (allow_trailing_junk ||
167
          !AdvanceToNonspace(unicode_cache, &current, end)) {
168
        break;
169
      } else {
170
        return JunkStringValue();
171
      }
172
    }
173

    
174
    number = number * radix + digit;
175
    int overflow = static_cast<int>(number >> 53);
176
    if (overflow != 0) {
177
      // Overflow occurred. Need to determine which direction to round the
178
      // result.
179
      int overflow_bits_count = 1;
180
      while (overflow > 1) {
181
        overflow_bits_count++;
182
        overflow >>= 1;
183
      }
184

    
185
      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
186
      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
187
      number >>= overflow_bits_count;
188
      exponent = overflow_bits_count;
189

    
190
      bool zero_tail = true;
191
      while (true) {
192
        ++current;
193
        if (current == end || !isDigit(*current, radix)) break;
194
        zero_tail = zero_tail && *current == '0';
195
        exponent += radix_log_2;
196
      }
197

    
198
      if (!allow_trailing_junk &&
199
          AdvanceToNonspace(unicode_cache, &current, end)) {
200
        return JunkStringValue();
201
      }
202

    
203
      int middle_value = (1 << (overflow_bits_count - 1));
204
      if (dropped_bits > middle_value) {
205
        number++;  // Rounding up.
206
      } else if (dropped_bits == middle_value) {
207
        // Rounding to even to consistency with decimals: half-way case rounds
208
        // up if significant part is odd and down otherwise.
209
        if ((number & 1) != 0 || !zero_tail) {
210
          number++;  // Rounding up.
211
        }
212
      }
213

    
214
      // Rounding up may cause overflow.
215
      if ((number & (static_cast<int64_t>(1) << 53)) != 0) {
216
        exponent++;
217
        number >>= 1;
218
      }
219
      break;
220
    }
221
    ++current;
222
  } while (current != end);
223

    
224
  ASSERT(number < ((int64_t)1 << 53));
225
  ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
226

    
227
  if (exponent == 0) {
228
    if (negative) {
229
      if (number == 0) return -0.0;
230
      number = -number;
231
    }
232
    return static_cast<double>(number);
233
  }
234

    
235
  ASSERT(number != 0);
236
  return ldexp(static_cast<double>(negative ? -number : number), exponent);
237
}
238

    
239

    
240
template <class Iterator, class EndMark>
241
double InternalStringToInt(UnicodeCache* unicode_cache,
242
                           Iterator current,
243
                           EndMark end,
244
                           int radix) {
245
  const bool allow_trailing_junk = true;
246
  const double empty_string_val = JunkStringValue();
247

    
248
  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
249
    return empty_string_val;
250
  }
251

    
252
  bool negative = false;
253
  bool leading_zero = false;
254

    
255
  if (*current == '+') {
256
    // Ignore leading sign; skip following spaces.
257
    ++current;
258
    if (current == end) {
259
      return JunkStringValue();
260
    }
261
  } else if (*current == '-') {
262
    ++current;
263
    if (current == end) {
264
      return JunkStringValue();
265
    }
266
    negative = true;
267
  }
268

    
269
  if (radix == 0) {
270
    // Radix detection.
271
    radix = 10;
272
    if (*current == '0') {
273
      ++current;
274
      if (current == end) return SignedZero(negative);
275
      if (*current == 'x' || *current == 'X') {
276
        radix = 16;
277
        ++current;
278
        if (current == end) return JunkStringValue();
279
      } else {
280
        leading_zero = true;
281
      }
282
    }
283
  } else if (radix == 16) {
284
    if (*current == '0') {
285
      // Allow "0x" prefix.
286
      ++current;
287
      if (current == end) return SignedZero(negative);
288
      if (*current == 'x' || *current == 'X') {
289
        ++current;
290
        if (current == end) return JunkStringValue();
291
      } else {
292
        leading_zero = true;
293
      }
294
    }
295
  }
296

    
297
  if (radix < 2 || radix > 36) return JunkStringValue();
298

    
299
  // Skip leading zeros.
300
  while (*current == '0') {
301
    leading_zero = true;
302
    ++current;
303
    if (current == end) return SignedZero(negative);
304
  }
305

    
306
  if (!leading_zero && !isDigit(*current, radix)) {
307
    return JunkStringValue();
308
  }
309

    
310
  if (IsPowerOf2(radix)) {
311
    switch (radix) {
312
      case 2:
313
        return InternalStringToIntDouble<1>(
314
            unicode_cache, current, end, negative, allow_trailing_junk);
315
      case 4:
316
        return InternalStringToIntDouble<2>(
317
            unicode_cache, current, end, negative, allow_trailing_junk);
318
      case 8:
319
        return InternalStringToIntDouble<3>(
320
            unicode_cache, current, end, negative, allow_trailing_junk);
321

    
322
      case 16:
323
        return InternalStringToIntDouble<4>(
324
            unicode_cache, current, end, negative, allow_trailing_junk);
325

    
326
      case 32:
327
        return InternalStringToIntDouble<5>(
328
            unicode_cache, current, end, negative, allow_trailing_junk);
329
      default:
330
        UNREACHABLE();
331
    }
332
  }
333

    
334
  if (radix == 10) {
335
    // Parsing with strtod.
336
    const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308.
337
    // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
338
    // end.
339
    const int kBufferSize = kMaxSignificantDigits + 2;
340
    char buffer[kBufferSize];
341
    int buffer_pos = 0;
342
    while (*current >= '0' && *current <= '9') {
343
      if (buffer_pos <= kMaxSignificantDigits) {
344
        // If the number has more than kMaxSignificantDigits it will be parsed
345
        // as infinity.
346
        ASSERT(buffer_pos < kBufferSize);
347
        buffer[buffer_pos++] = static_cast<char>(*current);
348
      }
349
      ++current;
350
      if (current == end) break;
351
    }
352

    
353
    if (!allow_trailing_junk &&
354
        AdvanceToNonspace(unicode_cache, &current, end)) {
355
      return JunkStringValue();
356
    }
357

    
358
    SLOW_ASSERT(buffer_pos < kBufferSize);
359
    buffer[buffer_pos] = '\0';
360
    Vector<const char> buffer_vector(buffer, buffer_pos);
361
    return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
362
  }
363

    
364
  // The following code causes accumulating rounding error for numbers greater
365
  // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
366
  // 16, or 32, then mathInt may be an implementation-dependent approximation to
367
  // the mathematical integer value" (15.1.2.2).
368

    
369
  int lim_0 = '0' + (radix < 10 ? radix : 10);
370
  int lim_a = 'a' + (radix - 10);
371
  int lim_A = 'A' + (radix - 10);
372

    
373
  // NOTE: The code for computing the value may seem a bit complex at
374
  // first glance. It is structured to use 32-bit multiply-and-add
375
  // loops as long as possible to avoid loosing precision.
376

    
377
  double v = 0.0;
378
  bool done = false;
379
  do {
380
    // Parse the longest part of the string starting at index j
381
    // possible while keeping the multiplier, and thus the part
382
    // itself, within 32 bits.
383
    unsigned int part = 0, multiplier = 1;
384
    while (true) {
385
      int d;
386
      if (*current >= '0' && *current < lim_0) {
387
        d = *current - '0';
388
      } else if (*current >= 'a' && *current < lim_a) {
389
        d = *current - 'a' + 10;
390
      } else if (*current >= 'A' && *current < lim_A) {
391
        d = *current - 'A' + 10;
392
      } else {
393
        done = true;
394
        break;
395
      }
396

    
397
      // Update the value of the part as long as the multiplier fits
398
      // in 32 bits. When we can't guarantee that the next iteration
399
      // will not overflow the multiplier, we stop parsing the part
400
      // by leaving the loop.
401
      const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
402
      uint32_t m = multiplier * radix;
403
      if (m > kMaximumMultiplier) break;
404
      part = part * radix + d;
405
      multiplier = m;
406
      ASSERT(multiplier > part);
407

    
408
      ++current;
409
      if (current == end) {
410
        done = true;
411
        break;
412
      }
413
    }
414

    
415
    // Update the value and skip the part in the string.
416
    v = v * multiplier + part;
417
  } while (!done);
418

    
419
  if (!allow_trailing_junk &&
420
      AdvanceToNonspace(unicode_cache, &current, end)) {
421
    return JunkStringValue();
422
  }
423

    
424
  return negative ? -v : v;
425
}
426

    
427

    
428
// Converts a string to a double value. Assumes the Iterator supports
429
// the following operations:
430
// 1. current == end (other ops are not allowed), current != end.
431
// 2. *current - gets the current character in the sequence.
432
// 3. ++current (advances the position).
433
template <class Iterator, class EndMark>
434
double InternalStringToDouble(UnicodeCache* unicode_cache,
435
                              Iterator current,
436
                              EndMark end,
437
                              int flags,
438
                              double empty_string_val) {
439
  // To make sure that iterator dereferencing is valid the following
440
  // convention is used:
441
  // 1. Each '++current' statement is followed by check for equality to 'end'.
442
  // 2. If AdvanceToNonspace returned false then current == end.
443
  // 3. If 'current' becomes be equal to 'end' the function returns or goes to
444
  // 'parsing_done'.
445
  // 4. 'current' is not dereferenced after the 'parsing_done' label.
446
  // 5. Code before 'parsing_done' may rely on 'current != end'.
447
  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
448
    return empty_string_val;
449
  }
450

    
451
  const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
452

    
453
  // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
454
  const int kBufferSize = kMaxSignificantDigits + 10;
455
  char buffer[kBufferSize];  // NOLINT: size is known at compile time.
456
  int buffer_pos = 0;
457

    
458
  // Exponent will be adjusted if insignificant digits of the integer part
459
  // or insignificant leading zeros of the fractional part are dropped.
460
  int exponent = 0;
461
  int significant_digits = 0;
462
  int insignificant_digits = 0;
463
  bool nonzero_digit_dropped = false;
464

    
465
  enum Sign {
466
    NONE,
467
    NEGATIVE,
468
    POSITIVE
469
  };
470

    
471
  Sign sign = NONE;
472

    
473
  if (*current == '+') {
474
    // Ignore leading sign.
475
    ++current;
476
    if (current == end) return JunkStringValue();
477
    sign = POSITIVE;
478
  } else if (*current == '-') {
479
    ++current;
480
    if (current == end) return JunkStringValue();
481
    sign = NEGATIVE;
482
  }
483

    
484
  static const char kInfinityString[] = "Infinity";
485
  if (*current == kInfinityString[0]) {
486
    if (!SubStringEquals(&current, end, kInfinityString)) {
487
      return JunkStringValue();
488
    }
489

    
490
    if (!allow_trailing_junk &&
491
        AdvanceToNonspace(unicode_cache, &current, end)) {
492
      return JunkStringValue();
493
    }
494

    
495
    ASSERT(buffer_pos == 0);
496
    return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
497
  }
498

    
499
  bool leading_zero = false;
500
  if (*current == '0') {
501
    ++current;
502
    if (current == end) return SignedZero(sign == NEGATIVE);
503

    
504
    leading_zero = true;
505

    
506
    // It could be hexadecimal value.
507
    if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
508
      ++current;
509
      if (current == end || !isDigit(*current, 16) || sign != NONE) {
510
        return JunkStringValue();  // "0x".
511
      }
512

    
513
      return InternalStringToIntDouble<4>(unicode_cache,
514
                                          current,
515
                                          end,
516
                                          false,
517
                                          allow_trailing_junk);
518

    
519
    // It could be an explicit octal value.
520
    } else if ((flags & ALLOW_OCTAL) && (*current == 'o' || *current == 'O')) {
521
      ++current;
522
      if (current == end || !isDigit(*current, 8) || sign != NONE) {
523
        return JunkStringValue();  // "0o".
524
      }
525

    
526
      return InternalStringToIntDouble<3>(unicode_cache,
527
                                          current,
528
                                          end,
529
                                          false,
530
                                          allow_trailing_junk);
531

    
532
    // It could be a binary value.
533
    } else if ((flags & ALLOW_BINARY) && (*current == 'b' || *current == 'B')) {
534
      ++current;
535
      if (current == end || !isBinaryDigit(*current) || sign != NONE) {
536
        return JunkStringValue();  // "0b".
537
      }
538

    
539
      return InternalStringToIntDouble<1>(unicode_cache,
540
                                          current,
541
                                          end,
542
                                          false,
543
                                          allow_trailing_junk);
544
    }
545

    
546
    // Ignore leading zeros in the integer part.
547
    while (*current == '0') {
548
      ++current;
549
      if (current == end) return SignedZero(sign == NEGATIVE);
550
    }
551
  }
552

    
553
  bool octal = leading_zero && (flags & ALLOW_IMPLICIT_OCTAL) != 0;
554

    
555
  // Copy significant digits of the integer part (if any) to the buffer.
556
  while (*current >= '0' && *current <= '9') {
557
    if (significant_digits < kMaxSignificantDigits) {
558
      ASSERT(buffer_pos < kBufferSize);
559
      buffer[buffer_pos++] = static_cast<char>(*current);
560
      significant_digits++;
561
      // Will later check if it's an octal in the buffer.
562
    } else {
563
      insignificant_digits++;  // Move the digit into the exponential part.
564
      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
565
    }
566
    octal = octal && *current < '8';
567
    ++current;
568
    if (current == end) goto parsing_done;
569
  }
570

    
571
  if (significant_digits == 0) {
572
    octal = false;
573
  }
574

    
575
  if (*current == '.') {
576
    if (octal && !allow_trailing_junk) return JunkStringValue();
577
    if (octal) goto parsing_done;
578

    
579
    ++current;
580
    if (current == end) {
581
      if (significant_digits == 0 && !leading_zero) {
582
        return JunkStringValue();
583
      } else {
584
        goto parsing_done;
585
      }
586
    }
587

    
588
    if (significant_digits == 0) {
589
      // octal = false;
590
      // Integer part consists of 0 or is absent. Significant digits start after
591
      // leading zeros (if any).
592
      while (*current == '0') {
593
        ++current;
594
        if (current == end) return SignedZero(sign == NEGATIVE);
595
        exponent--;  // Move this 0 into the exponent.
596
      }
597
    }
598

    
599
    // There is a fractional part.  We don't emit a '.', but adjust the exponent
600
    // instead.
601
    while (*current >= '0' && *current <= '9') {
602
      if (significant_digits < kMaxSignificantDigits) {
603
        ASSERT(buffer_pos < kBufferSize);
604
        buffer[buffer_pos++] = static_cast<char>(*current);
605
        significant_digits++;
606
        exponent--;
607
      } else {
608
        // Ignore insignificant digits in the fractional part.
609
        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
610
      }
611
      ++current;
612
      if (current == end) goto parsing_done;
613
    }
614
  }
615

    
616
  if (!leading_zero && exponent == 0 && significant_digits == 0) {
617
    // If leading_zeros is true then the string contains zeros.
618
    // If exponent < 0 then string was [+-]\.0*...
619
    // If significant_digits != 0 the string is not equal to 0.
620
    // Otherwise there are no digits in the string.
621
    return JunkStringValue();
622
  }
623

    
624
  // Parse exponential part.
625
  if (*current == 'e' || *current == 'E') {
626
    if (octal) return JunkStringValue();
627
    ++current;
628
    if (current == end) {
629
      if (allow_trailing_junk) {
630
        goto parsing_done;
631
      } else {
632
        return JunkStringValue();
633
      }
634
    }
635
    char sign = '+';
636
    if (*current == '+' || *current == '-') {
637
      sign = static_cast<char>(*current);
638
      ++current;
639
      if (current == end) {
640
        if (allow_trailing_junk) {
641
          goto parsing_done;
642
        } else {
643
          return JunkStringValue();
644
        }
645
      }
646
    }
647

    
648
    if (current == end || *current < '0' || *current > '9') {
649
      if (allow_trailing_junk) {
650
        goto parsing_done;
651
      } else {
652
        return JunkStringValue();
653
      }
654
    }
655

    
656
    const int max_exponent = INT_MAX / 2;
657
    ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
658
    int num = 0;
659
    do {
660
      // Check overflow.
661
      int digit = *current - '0';
662
      if (num >= max_exponent / 10
663
          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
664
        num = max_exponent;
665
      } else {
666
        num = num * 10 + digit;
667
      }
668
      ++current;
669
    } while (current != end && *current >= '0' && *current <= '9');
670

    
671
    exponent += (sign == '-' ? -num : num);
672
  }
673

    
674
  if (!allow_trailing_junk &&
675
      AdvanceToNonspace(unicode_cache, &current, end)) {
676
    return JunkStringValue();
677
  }
678

    
679
  parsing_done:
680
  exponent += insignificant_digits;
681

    
682
  if (octal) {
683
    return InternalStringToIntDouble<3>(unicode_cache,
684
                                        buffer,
685
                                        buffer + buffer_pos,
686
                                        sign == NEGATIVE,
687
                                        allow_trailing_junk);
688
  }
689

    
690
  if (nonzero_digit_dropped) {
691
    buffer[buffer_pos++] = '1';
692
    exponent--;
693
  }
694

    
695
  SLOW_ASSERT(buffer_pos < kBufferSize);
696
  buffer[buffer_pos] = '\0';
697

    
698
  double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
699
  return (sign == NEGATIVE) ? -converted : converted;
700
}
701

    
702
} }  // namespace v8::internal
703

    
704
#endif  // V8_CONVERSIONS_INL_H_