Line data Source code
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 697773 : 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 1694652 : bool negative = x < 0;
51 1694652 : if (negative) {
52 0 : x = -x;
53 : }
54 1694652 : if (x < k2Pow52) {
55 1694652 : 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 1694652 : 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 2469 : volatile float f = static_cast<float>(x);
75 2469 : return f;
76 : }
77 :
78 :
79 655638 : inline double DoubleToInteger(double x) {
80 655638 : if (std::isnan(x)) return 0;
81 647205 : if (!std::isfinite(x) || x == 0) return x;
82 345526 : return (x >= 0) ? std::floor(x) : std::ceil(x);
83 : }
84 :
85 :
86 23556933 : int32_t DoubleToInt32(double x) {
87 : int32_t i = FastD2I(x);
88 23556933 : if (FastI2D(i) == x) return i;
89 : Double d(x);
90 : int exponent = d.Exponent();
91 2545618 : if (exponent < 0) {
92 410688 : if (exponent <= -Double::kSignificandSize) return 0;
93 380887 : return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent);
94 : } else {
95 2134930 : if (exponent > 31) return 0;
96 3627 : return d.Sign() * static_cast<int32_t>(d.Significand() << exponent);
97 : }
98 : }
99 :
100 : bool DoubleToSmiInteger(double value, int* smi_int_value) {
101 60661073 : if (IsMinusZero(value)) return false;
102 : int i = FastD2IChecked(value);
103 60323026 : if (value != i || !Smi::IsValid(i)) return false;
104 : *smi_int_value = i;
105 : return true;
106 : }
107 :
108 : bool IsSmiDouble(double value) {
109 2837653 : return !IsMinusZero(value) && value >= Smi::kMinValue &&
110 5651053 : value <= Smi::kMaxValue && value == FastI2D(FastD2I(value));
111 : }
112 :
113 :
114 : bool IsInt32Double(double value) {
115 1355471 : return !IsMinusZero(value) && value >= kMinInt && value <= kMaxInt &&
116 : value == FastI2D(FastD2I(value));
117 : }
118 :
119 :
120 1744099 : bool IsUint32Double(double value) {
121 3438589 : return !IsMinusZero(value) && value >= 0 && value <= kMaxUInt32 &&
122 1744099 : 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 87813 : 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 87813 : if ((result >> 32) == kValidTopBits) {
149 86308 : *uint32_value = result & kBottomBitMask;
150 86308 : return FastUI2D(result & kBottomBitMask) == value;
151 : }
152 : return false;
153 : }
154 :
155 9258705 : int32_t NumberToInt32(Object* number) {
156 18502271 : if (number->IsSmi()) return Smi::cast(number)->value();
157 15139 : return DoubleToInt32(number->Number());
158 : }
159 :
160 13938039 : uint32_t NumberToUint32(Object* number) {
161 27846773 : if (number->IsSmi()) return Smi::cast(number)->value();
162 29305 : return DoubleToUint32(number->Number());
163 : }
164 :
165 10942 : uint32_t PositiveNumberToUint32(Object* number) {
166 10942 : if (number->IsSmi()) {
167 : int value = Smi::cast(number)->value();
168 9857 : if (value <= 0) return 0;
169 3006 : 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 1085 : if (!(value >= 1)) return 0;
175 : uint32_t max = std::numeric_limits<uint32_t>::max();
176 395 : if (value < max) return static_cast<uint32_t>(value);
177 : return max;
178 : }
179 :
180 : int64_t NumberToInt64(Object* number) {
181 12270 : if (number->IsSmi()) return Smi::cast(number)->value();
182 588 : return static_cast<int64_t>(number->Number());
183 : }
184 :
185 18923226 : 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 56631355 : 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 56614352 : if (value >= 0) {
193 56614352 : *result = static_cast<size_t>(value);
194 18923226 : 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 17003 : if (value >= 0 && value < maxSize) {
206 17003 : *result = static_cast<size_t>(value);
207 0 : return true;
208 : } else {
209 : return false;
210 : }
211 : }
212 : }
213 :
214 37572950 : size_t NumberToSize(Object* number) {
215 : size_t result = 0;
216 : bool is_valid = TryNumberToSize(number, &result);
217 37572950 : CHECK(is_valid);
218 37572950 : return result;
219 : }
220 :
221 :
222 : uint32_t DoubleToUint32(double x) {
223 17006275 : 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 105700 : for (substring++; *substring != '\0'; substring++) {
233 105771 : ++*current;
234 105771 : if (*current == end || **current != *substring) return false;
235 : }
236 15088 : ++*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 8324620 : inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
245 : Iterator* current,
246 : EndMark end) {
247 16656587 : while (*current != end) {
248 16596546 : if (!unicode_cache->IsWhiteSpaceOrLineTerminator(**current)) return true;
249 7347 : ++*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 547160 : 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 1152324 : while (*current == '0') {
266 65842 : ++current;
267 73680 : 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 2189912 : do {
275 : int digit;
276 2190598 : if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
277 1561496 : digit = static_cast<char>(*current) - '0';
278 629074 : } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
279 585370 : digit = static_cast<char>(*current) - 'a' + 10;
280 43704 : } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
281 43604 : digit = static_cast<char>(*current) - 'A' + 10;
282 : } else {
283 173 : if (allow_trailing_junk ||
284 45 : !AdvanceToNonspace(unicode_cache, ¤t, end)) {
285 : break;
286 : } else {
287 : return JunkStringValue();
288 : }
289 : }
290 :
291 2190470 : number = number * radix + digit;
292 2190470 : int overflow = static_cast<int>(number >> 53);
293 2190470 : if (overflow != 0) {
294 : // Overflow occurred. Need to determine which direction to round the
295 : // result.
296 : int overflow_bits_count = 1;
297 2109 : while (overflow > 1) {
298 1551 : overflow_bits_count++;
299 1551 : overflow >>= 1;
300 : }
301 :
302 558 : int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
303 558 : int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
304 558 : number >>= overflow_bits_count;
305 : exponent = overflow_bits_count;
306 :
307 : bool zero_tail = true;
308 : while (true) {
309 33273 : ++current;
310 33273 : if (current == end || !isDigit(*current, radix)) break;
311 32715 : zero_tail = zero_tail && *current == '0';
312 32715 : exponent += radix_log_2;
313 : }
314 :
315 1045 : if (!allow_trailing_junk &&
316 487 : AdvanceToNonspace(unicode_cache, ¤t, end)) {
317 : return JunkStringValue();
318 : }
319 :
320 558 : int middle_value = (1 << (overflow_bits_count - 1));
321 558 : if (dropped_bits > middle_value) {
322 46 : number++; // Rounding up.
323 512 : } 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 223 : if ((number & 1) != 0 || !zero_tail) {
327 163 : number++; // Rounding up.
328 : }
329 : }
330 :
331 : // Rounding up may cause overflow.
332 558 : if ((number & (static_cast<int64_t>(1) << 53)) != 0) {
333 16 : exponent++;
334 16 : number >>= 1;
335 : }
336 32715 : break;
337 : }
338 2189912 : ++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 539307 : if (exponent == 0) {
345 538749 : if (negative) {
346 14 : if (number == 0) return -0.0;
347 14 : number = -number;
348 : }
349 538749 : return static_cast<double>(number);
350 : }
351 :
352 : DCHECK(number != 0);
353 558 : 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 2104377 : 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 2104377 : if (!AdvanceToNonspace(unicode_cache, ¤t, end)) {
366 : return empty_string_val;
367 : }
368 :
369 : bool negative = false;
370 : bool leading_zero = false;
371 :
372 2104349 : if (*current == '+') {
373 : // Ignore leading sign; skip following spaces.
374 103 : ++current;
375 103 : if (current == end) {
376 : return JunkStringValue();
377 : }
378 2104246 : } else if (*current == '-') {
379 91098 : ++current;
380 91098 : if (current == end) {
381 : return JunkStringValue();
382 : }
383 : negative = true;
384 : }
385 :
386 2104335 : if (radix == 0) {
387 : // Radix detection.
388 : radix = 10;
389 2103755 : if (*current == '0') {
390 27669 : ++current;
391 33680 : if (current == end) return SignedZero(negative);
392 21658 : if (*current == 'x' || *current == 'X') {
393 : radix = 16;
394 21513 : ++current;
395 21513 : if (current == end) return JunkStringValue();
396 : } else {
397 : leading_zero = true;
398 : }
399 : }
400 580 : } else if (radix == 16) {
401 279 : if (*current == '0') {
402 : // Allow "0x" prefix.
403 223 : ++current;
404 223 : if (current == end) return SignedZero(negative);
405 223 : if (*current == 'x' || *current == 'X') {
406 169 : ++current;
407 169 : if (current == end) return JunkStringValue();
408 : } else {
409 : leading_zero = true;
410 : }
411 : }
412 : }
413 :
414 2098266 : if (radix < 2 || radix > 36) return JunkStringValue();
415 :
416 : // Skip leading zeros.
417 2098486 : while (*current == '0') {
418 : leading_zero = true;
419 220 : ++current;
420 220 : if (current == end) return SignedZero(negative);
421 : }
422 :
423 2098266 : if (!leading_zero && !isDigit(*current, radix)) {
424 : return JunkStringValue();
425 : }
426 :
427 263905 : if (base::bits::IsPowerOfTwo32(radix)) {
428 21833 : switch (radix) {
429 : case 2:
430 : return InternalStringToIntDouble<1>(
431 73 : unicode_cache, current, end, negative, allow_trailing_junk);
432 : case 4:
433 : return InternalStringToIntDouble<2>(
434 0 : unicode_cache, current, end, negative, allow_trailing_junk);
435 : case 8:
436 : return InternalStringToIntDouble<3>(
437 56 : unicode_cache, current, end, negative, allow_trailing_junk);
438 :
439 : case 16:
440 : return InternalStringToIntDouble<4>(
441 21704 : unicode_cache, current, end, negative, allow_trailing_junk);
442 :
443 : case 32:
444 : return InternalStringToIntDouble<5>(
445 0 : unicode_cache, current, end, negative, allow_trailing_junk);
446 : default:
447 0 : UNREACHABLE();
448 : }
449 : }
450 :
451 242072 : 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 1762347 : while (*current >= '0' && *current <= '9') {
460 1760348 : 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 1759289 : buffer[buffer_pos++] = static_cast<char>(*current);
465 : }
466 1760348 : ++current;
467 1760348 : 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 242027 : buffer[buffer_pos] = '\0';
477 : Vector<const char> buffer_vector(buffer, buffer_pos);
478 242027 : 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 45 : int lim_0 = '0' + (radix < 10 ? radix : 10);
487 45 : int lim_a = 'a' + (radix - 10);
488 45 : 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 75 : 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 510 : if (*current >= '0' && *current < lim_0) {
504 510 : d = *current - '0';
505 0 : } else if (*current >= 'a' && *current < lim_a) {
506 0 : d = *current - 'a' + 10;
507 0 : } else if (*current >= 'A' && *current < lim_A) {
508 0 : 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 510 : uint32_t m = multiplier * radix;
520 510 : if (m > kMaximumMultiplier) break;
521 480 : part = part * radix + d;
522 : multiplier = m;
523 : DCHECK(multiplier > part);
524 :
525 480 : ++current;
526 480 : if (current == end) {
527 : done = true;
528 : break;
529 : }
530 : }
531 :
532 : // Update the value and skip the part in the string.
533 75 : 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 45 : 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 6179209 : 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 6179209 : if (!AdvanceToNonspace(unicode_cache, ¤t, end)) {
565 : return empty_string_val;
566 : }
567 :
568 6178536 : 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 6178536 : if (*current == '+') {
591 : // Ignore leading sign.
592 6019 : ++current;
593 6019 : if (current == end) return JunkStringValue();
594 : sign = POSITIVE;
595 6172517 : } else if (*current == '-') {
596 15332 : ++current;
597 15332 : if (current == end) return JunkStringValue();
598 : sign = NEGATIVE;
599 : }
600 :
601 : static const char kInfinityString[] = "Infinity";
602 6178536 : if (*current == kInfinityString[0]) {
603 15159 : if (!SubStringEquals(¤t, end, kInfinityString)) {
604 : return JunkStringValue();
605 : }
606 :
607 30162 : if (!allow_trailing_junk &&
608 15074 : AdvanceToNonspace(unicode_cache, ¤t, end)) {
609 : return JunkStringValue();
610 : }
611 :
612 : DCHECK(buffer_pos == 0);
613 15073 : return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
614 : }
615 :
616 : bool leading_zero = false;
617 6163377 : if (*current == '0') {
618 2419294 : ++current;
619 3051762 : if (current == end) return SignedZero(sign == NEGATIVE);
620 :
621 : leading_zero = true;
622 :
623 : // It could be hexadecimal value.
624 1786826 : if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
625 370209 : ++current;
626 370209 : 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 370089 : allow_trailing_junk);
635 :
636 : // It could be an explicit octal value.
637 1416617 : } else if ((flags & ALLOW_OCTAL) && (*current == 'o' || *current == 'O')) {
638 211 : ++current;
639 211 : 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 211 : allow_trailing_junk);
648 :
649 : // It could be a binary value.
650 1416406 : } else if ((flags & ALLOW_BINARY) && (*current == 'b' || *current == 'B')) {
651 176 : ++current;
652 352 : 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 176 : allow_trailing_junk);
661 : }
662 :
663 : // Ignore leading zeros in the integer part.
664 1416297 : while (*current == '0') {
665 22242 : ++current;
666 44417 : if (current == end) return SignedZero(sign == NEGATIVE);
667 : }
668 : }
669 :
670 5138138 : bool octal = leading_zero && (flags & ALLOW_IMPLICIT_OCTAL) != 0;
671 :
672 : // Copy significant digits of the integer part (if any) to the buffer.
673 15574598 : while (*current >= '0' && *current <= '9') {
674 6477085 : if (significant_digits < kMaxSignificantDigits) {
675 : DCHECK(buffer_pos < kBufferSize);
676 6473244 : buffer[buffer_pos++] = static_cast<char>(*current);
677 6473244 : significant_digits++;
678 : // Will later check if it's an octal in the buffer.
679 : } else {
680 3841 : insignificant_digits++; // Move the digit into the exponential part.
681 3841 : nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
682 : }
683 6477085 : octal = octal && *current < '8';
684 6477085 : ++current;
685 6477085 : if (current == end) goto parsing_done;
686 : }
687 :
688 3959375 : if (significant_digits == 0) {
689 : octal = false;
690 : }
691 :
692 3959375 : if (*current == '.') {
693 1436423 : if (octal && !allow_trailing_junk) return JunkStringValue();
694 1436409 : if (octal) goto parsing_done;
695 :
696 1436409 : ++current;
697 1436409 : if (current == end) {
698 264 : if (significant_digits == 0 && !leading_zero) {
699 : return JunkStringValue();
700 : } else {
701 : goto parsing_done;
702 : }
703 : }
704 :
705 1436145 : 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 1267956 : while (*current == '0') {
710 54193 : ++current;
711 83474 : if (current == end) return SignedZero(sign == NEGATIVE);
712 24912 : 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 1923771 : while (*current >= '0' && *current <= '9') {
719 1915912 : if (significant_digits < kMaxSignificantDigits) {
720 : DCHECK(buffer_pos < kBufferSize);
721 1913749 : buffer[buffer_pos++] = static_cast<char>(*current);
722 1913749 : significant_digits++;
723 1913749 : exponent--;
724 : } else {
725 : // Ignore insignificant digits in the fractional part.
726 2163 : nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
727 : }
728 1915912 : ++current;
729 1915912 : if (current == end) goto parsing_done;
730 : }
731 : }
732 :
733 2530811 : 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 25727 : if (*current == 'e' || *current == 'E') {
743 15576 : if (octal) return JunkStringValue();
744 15562 : ++current;
745 15562 : if (current == end) {
746 22 : if (allow_trailing_junk) {
747 : goto parsing_done;
748 : } else {
749 : return JunkStringValue();
750 : }
751 : }
752 : char sign = '+';
753 15540 : if (*current == '+' || *current == '-') {
754 7342 : sign = static_cast<char>(*current);
755 7342 : ++current;
756 7342 : if (current == end) {
757 7 : if (allow_trailing_junk) {
758 : goto parsing_done;
759 : } else {
760 : return JunkStringValue();
761 : }
762 : }
763 : }
764 :
765 15533 : if (current == end || *current < '0' || *current > '9') {
766 15 : 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 23799 : do {
777 : // Check overflow.
778 23799 : int digit = *current - '0';
779 23799 : if (num >= max_exponent / 10
780 0 : && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
781 : num = max_exponent;
782 : } else {
783 23799 : num = num * 10 + digit;
784 : }
785 23799 : ++current;
786 : } while (current != end && *current >= '0' && *current <= '9');
787 :
788 15518 : exponent += (sign == '-' ? -num : num);
789 : }
790 :
791 51097 : if (!allow_trailing_junk &&
792 25428 : AdvanceToNonspace(unicode_cache, ¤t, end)) {
793 : return JunkStringValue();
794 : }
795 :
796 : parsing_done:
797 2595704 : exponent += insignificant_digits;
798 :
799 2595704 : if (octal) {
800 : return InternalStringToIntDouble<3>(unicode_cache,
801 : buffer,
802 : buffer + buffer_pos,
803 : sign == NEGATIVE,
804 154851 : allow_trailing_junk);
805 : }
806 :
807 2440853 : if (nonzero_digit_dropped) {
808 21 : buffer[buffer_pos++] = '1';
809 21 : exponent--;
810 : }
811 :
812 : SLOW_DCHECK(buffer_pos < kBufferSize);
813 2440853 : buffer[buffer_pos] = '\0';
814 :
815 2440853 : double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
816 2440853 : return (sign == NEGATIVE) ? -converted : converted;
817 : }
818 :
819 : } // namespace internal
820 : } // namespace v8
821 :
822 : #endif // V8_CONVERSIONS_INL_H_
|