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 |