OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 118 } |
119 | 119 |
120 | 120 |
121 static bool isDigit(int x, int radix) { | 121 static bool isDigit(int x, int radix) { |
122 return (x >= '0' && x <= '9' && x < '0' + radix) | 122 return (x >= '0' && x <= '9' && x < '0' + radix) |
123 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) | 123 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) |
124 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); | 124 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); |
125 } | 125 } |
126 | 126 |
127 | 127 |
128 static double SignedZero(bool sign) { | 128 static double SignedZero(bool negative) { |
129 return sign ? -0.0 : 0.0; | 129 return negative ? -0.0 : 0.0; |
130 } | 130 } |
131 | 131 |
132 | 132 |
133 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. | 133 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. |
134 template <int radix_log_2, class Iterator, class EndMark> | 134 template <int radix_log_2, class Iterator, class EndMark> |
135 static double InternalStringToIntDouble(Iterator current, | 135 static double InternalStringToIntDouble(Iterator current, |
136 EndMark end, | 136 EndMark end, |
137 bool sign, | 137 bool negative, |
138 bool allow_trailing_junk) { | 138 bool allow_trailing_junk) { |
139 ASSERT(current != end); | 139 ASSERT(current != end); |
140 | 140 |
141 // Skip leading 0s. | 141 // Skip leading 0s. |
142 while (*current == '0') { | 142 while (*current == '0') { |
143 ++current; | 143 ++current; |
144 if (current == end) return SignedZero(sign); | 144 if (current == end) return SignedZero(negative); |
145 } | 145 } |
146 | 146 |
147 int64_t number = 0; | 147 int64_t number = 0; |
148 int exponent = 0; | 148 int exponent = 0; |
149 const int radix = (1 << radix_log_2); | 149 const int radix = (1 << radix_log_2); |
150 | 150 |
151 do { | 151 do { |
152 int digit; | 152 int digit; |
153 if (*current >= '0' && *current <= '9' && *current < '0' + radix) { | 153 if (*current >= '0' && *current <= '9' && *current < '0' + radix) { |
154 digit = static_cast<char>(*current) - '0'; | 154 digit = static_cast<char>(*current) - '0'; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 } | 210 } |
211 break; | 211 break; |
212 } | 212 } |
213 ++current; | 213 ++current; |
214 } while (current != end); | 214 } while (current != end); |
215 | 215 |
216 ASSERT(number < ((int64_t)1 << 53)); | 216 ASSERT(number < ((int64_t)1 << 53)); |
217 ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); | 217 ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); |
218 | 218 |
219 if (exponent == 0) { | 219 if (exponent == 0) { |
220 if (sign) { | 220 if (negative) { |
221 if (number == 0) return -0.0; | 221 if (number == 0) return -0.0; |
222 number = -number; | 222 number = -number; |
223 } | 223 } |
224 return static_cast<double>(number); | 224 return static_cast<double>(number); |
225 } | 225 } |
226 | 226 |
227 ASSERT(number != 0); | 227 ASSERT(number != 0); |
228 // The double could be constructed faster from number (mantissa), exponent | 228 // The double could be constructed faster from number (mantissa), exponent |
229 // and sign. Assuming it's a rare case more simple code is used. | 229 // and sign. Assuming it's a rare case more simple code is used. |
230 return static_cast<double>(sign ? -number : number) * pow(2.0, exponent); | 230 return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); |
231 } | 231 } |
232 | 232 |
233 | 233 |
234 template <class Iterator, class EndMark> | 234 template <class Iterator, class EndMark> |
235 static double InternalStringToInt(Iterator current, EndMark end, int radix) { | 235 static double InternalStringToInt(Iterator current, EndMark end, int radix) { |
236 const bool allow_trailing_junk = true; | 236 const bool allow_trailing_junk = true; |
237 const double empty_string_val = JUNK_STRING_VALUE; | 237 const double empty_string_val = JUNK_STRING_VALUE; |
238 | 238 |
239 if (!AdvanceToNonspace(¤t, end)) return empty_string_val; | 239 if (!AdvanceToNonspace(¤t, end)) return empty_string_val; |
240 | 240 |
241 bool sign = false; | 241 bool negative = false; |
242 bool leading_zero = false; | 242 bool leading_zero = false; |
243 | 243 |
244 if (*current == '+') { | 244 if (*current == '+') { |
245 // Ignore leading sign; skip following spaces. | 245 // Ignore leading sign; skip following spaces. |
246 ++current; | 246 ++current; |
247 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; | 247 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; |
248 } else if (*current == '-') { | 248 } else if (*current == '-') { |
249 ++current; | 249 ++current; |
250 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; | 250 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; |
251 sign = true; | 251 negative = true; |
252 } | 252 } |
253 | 253 |
254 if (radix == 0) { | 254 if (radix == 0) { |
255 // Radix detection. | 255 // Radix detection. |
256 if (*current == '0') { | 256 if (*current == '0') { |
257 ++current; | 257 ++current; |
258 if (current == end) return SignedZero(sign); | 258 if (current == end) return SignedZero(negative); |
259 if (*current == 'x' || *current == 'X') { | 259 if (*current == 'x' || *current == 'X') { |
260 radix = 16; | 260 radix = 16; |
261 ++current; | 261 ++current; |
262 if (current == end) return JUNK_STRING_VALUE; | 262 if (current == end) return JUNK_STRING_VALUE; |
263 } else { | 263 } else { |
264 radix = 8; | 264 radix = 8; |
265 leading_zero = true; | 265 leading_zero = true; |
266 } | 266 } |
267 } else { | 267 } else { |
268 radix = 10; | 268 radix = 10; |
269 } | 269 } |
270 } else if (radix == 16) { | 270 } else if (radix == 16) { |
271 if (*current == '0') { | 271 if (*current == '0') { |
272 // Allow "0x" prefix. | 272 // Allow "0x" prefix. |
273 ++current; | 273 ++current; |
274 if (current == end) return SignedZero(sign); | 274 if (current == end) return SignedZero(negative); |
275 if (*current == 'x' || *current == 'X') { | 275 if (*current == 'x' || *current == 'X') { |
276 ++current; | 276 ++current; |
277 if (current == end) return JUNK_STRING_VALUE; | 277 if (current == end) return JUNK_STRING_VALUE; |
278 } else { | 278 } else { |
279 leading_zero = true; | 279 leading_zero = true; |
280 } | 280 } |
281 } | 281 } |
282 } | 282 } |
283 | 283 |
284 if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; | 284 if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; |
285 | 285 |
286 // Skip leading zeros. | 286 // Skip leading zeros. |
287 while (*current == '0') { | 287 while (*current == '0') { |
288 leading_zero = true; | 288 leading_zero = true; |
289 ++current; | 289 ++current; |
290 if (current == end) return SignedZero(sign); | 290 if (current == end) return SignedZero(negative); |
291 } | 291 } |
292 | 292 |
293 if (!leading_zero && !isDigit(*current, radix)) { | 293 if (!leading_zero && !isDigit(*current, radix)) { |
294 return JUNK_STRING_VALUE; | 294 return JUNK_STRING_VALUE; |
295 } | 295 } |
296 | 296 |
297 if (IsPowerOf2(radix)) { | 297 if (IsPowerOf2(radix)) { |
298 switch (radix) { | 298 switch (radix) { |
299 case 2: | 299 case 2: |
300 return InternalStringToIntDouble<1>( | 300 return InternalStringToIntDouble<1>( |
301 current, end, sign, allow_trailing_junk); | 301 current, end, negative, allow_trailing_junk); |
302 case 4: | 302 case 4: |
303 return InternalStringToIntDouble<2>( | 303 return InternalStringToIntDouble<2>( |
304 current, end, sign, allow_trailing_junk); | 304 current, end, negative, allow_trailing_junk); |
305 case 8: | 305 case 8: |
306 return InternalStringToIntDouble<3>( | 306 return InternalStringToIntDouble<3>( |
307 current, end, sign, allow_trailing_junk); | 307 current, end, negative, allow_trailing_junk); |
308 | 308 |
309 case 16: | 309 case 16: |
310 return InternalStringToIntDouble<4>( | 310 return InternalStringToIntDouble<4>( |
311 current, end, sign, allow_trailing_junk); | 311 current, end, negative, allow_trailing_junk); |
312 | 312 |
313 case 32: | 313 case 32: |
314 return InternalStringToIntDouble<5>( | 314 return InternalStringToIntDouble<5>( |
315 current, end, sign, allow_trailing_junk); | 315 current, end, negative, allow_trailing_junk); |
316 default: | 316 default: |
317 UNREACHABLE(); | 317 UNREACHABLE(); |
318 } | 318 } |
319 } | 319 } |
320 | 320 |
321 if (radix == 10) { | 321 if (radix == 10) { |
322 // Parsing with strtod. | 322 // Parsing with strtod. |
323 const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308. | 323 const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308. |
324 // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero | 324 // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero |
325 // end. | 325 // end. |
(...skipping 11 matching lines...) Expand all Loading... |
337 if (current == end) break; | 337 if (current == end) break; |
338 } | 338 } |
339 | 339 |
340 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 340 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
341 return JUNK_STRING_VALUE; | 341 return JUNK_STRING_VALUE; |
342 } | 342 } |
343 | 343 |
344 ASSERT(buffer_pos < kBufferSize); | 344 ASSERT(buffer_pos < kBufferSize); |
345 buffer[buffer_pos] = '\0'; | 345 buffer[buffer_pos] = '\0'; |
346 Vector<const char> buffer_vector(buffer, buffer_pos); | 346 Vector<const char> buffer_vector(buffer, buffer_pos); |
347 return sign ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); | 347 return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); |
348 } | 348 } |
349 | 349 |
350 // The following code causes accumulating rounding error for numbers greater | 350 // The following code causes accumulating rounding error for numbers greater |
351 // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, | 351 // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, |
352 // 16, or 32, then mathInt may be an implementation-dependent approximation to | 352 // 16, or 32, then mathInt may be an implementation-dependent approximation to |
353 // the mathematical integer value" (15.1.2.2). | 353 // the mathematical integer value" (15.1.2.2). |
354 | 354 |
355 int lim_0 = '0' + (radix < 10 ? radix : 10); | 355 int lim_0 = '0' + (radix < 10 ? radix : 10); |
356 int lim_a = 'a' + (radix - 10); | 356 int lim_a = 'a' + (radix - 10); |
357 int lim_A = 'A' + (radix - 10); | 357 int lim_A = 'A' + (radix - 10); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 } | 399 } |
400 | 400 |
401 // Update the value and skip the part in the string. | 401 // Update the value and skip the part in the string. |
402 v = v * multiplier + part; | 402 v = v * multiplier + part; |
403 } while (!done); | 403 } while (!done); |
404 | 404 |
405 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 405 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
406 return JUNK_STRING_VALUE; | 406 return JUNK_STRING_VALUE; |
407 } | 407 } |
408 | 408 |
409 return sign ? -v : v; | 409 return negative ? -v : v; |
410 } | 410 } |
411 | 411 |
412 | 412 |
413 // Converts a string to a double value. Assumes the Iterator supports | 413 // Converts a string to a double value. Assumes the Iterator supports |
414 // the following operations: | 414 // the following operations: |
415 // 1. current == end (other ops are not allowed), current != end. | 415 // 1. current == end (other ops are not allowed), current != end. |
416 // 2. *current - gets the current character in the sequence. | 416 // 2. *current - gets the current character in the sequence. |
417 // 3. ++current (advances the position). | 417 // 3. ++current (advances the position). |
418 template <class Iterator, class EndMark> | 418 template <class Iterator, class EndMark> |
419 static double InternalStringToDouble(Iterator current, | 419 static double InternalStringToDouble(Iterator current, |
(...skipping 18 matching lines...) Expand all Loading... |
438 int buffer_pos = 0; | 438 int buffer_pos = 0; |
439 | 439 |
440 // Exponent will be adjusted if insignificant digits of the integer part | 440 // Exponent will be adjusted if insignificant digits of the integer part |
441 // or insignificant leading zeros of the fractional part are dropped. | 441 // or insignificant leading zeros of the fractional part are dropped. |
442 int exponent = 0; | 442 int exponent = 0; |
443 int significant_digits = 0; | 443 int significant_digits = 0; |
444 int insignificant_digits = 0; | 444 int insignificant_digits = 0; |
445 bool nonzero_digit_dropped = false; | 445 bool nonzero_digit_dropped = false; |
446 bool fractional_part = false; | 446 bool fractional_part = false; |
447 | 447 |
448 bool sign = false; | 448 bool negative = false; |
449 | 449 |
450 if (*current == '+') { | 450 if (*current == '+') { |
451 // Ignore leading sign. | 451 // Ignore leading sign. |
452 ++current; | 452 ++current; |
453 if (current == end) return JUNK_STRING_VALUE; | 453 if (current == end) return JUNK_STRING_VALUE; |
454 } else if (*current == '-') { | 454 } else if (*current == '-') { |
455 ++current; | 455 ++current; |
456 if (current == end) return JUNK_STRING_VALUE; | 456 if (current == end) return JUNK_STRING_VALUE; |
457 sign = true; | 457 negative = true; |
458 } | 458 } |
459 | 459 |
460 static const char kInfinitySymbol[] = "Infinity"; | 460 static const char kInfinitySymbol[] = "Infinity"; |
461 if (*current == kInfinitySymbol[0]) { | 461 if (*current == kInfinitySymbol[0]) { |
462 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { | 462 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { |
463 return JUNK_STRING_VALUE; | 463 return JUNK_STRING_VALUE; |
464 } | 464 } |
465 | 465 |
466 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 466 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
467 return JUNK_STRING_VALUE; | 467 return JUNK_STRING_VALUE; |
468 } | 468 } |
469 | 469 |
470 ASSERT(buffer_pos == 0); | 470 ASSERT(buffer_pos == 0); |
471 return sign ? -V8_INFINITY : V8_INFINITY; | 471 return negative ? -V8_INFINITY : V8_INFINITY; |
472 } | 472 } |
473 | 473 |
474 bool leading_zero = false; | 474 bool leading_zero = false; |
475 if (*current == '0') { | 475 if (*current == '0') { |
476 ++current; | 476 ++current; |
477 if (current == end) return SignedZero(sign); | 477 if (current == end) return SignedZero(negative); |
478 | 478 |
479 leading_zero = true; | 479 leading_zero = true; |
480 | 480 |
481 // It could be hexadecimal value. | 481 // It could be hexadecimal value. |
482 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 482 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { |
483 ++current; | 483 ++current; |
484 if (current == end || !isDigit(*current, 16)) { | 484 if (current == end || !isDigit(*current, 16)) { |
485 return JUNK_STRING_VALUE; // "0x". | 485 return JUNK_STRING_VALUE; // "0x". |
486 } | 486 } |
487 | 487 |
488 return InternalStringToIntDouble<4>(current, | 488 return InternalStringToIntDouble<4>(current, |
489 end, | 489 end, |
490 sign, | 490 negative, |
491 allow_trailing_junk); | 491 allow_trailing_junk); |
492 } | 492 } |
493 | 493 |
494 // Ignore leading zeros in the integer part. | 494 // Ignore leading zeros in the integer part. |
495 while (*current == '0') { | 495 while (*current == '0') { |
496 ++current; | 496 ++current; |
497 if (current == end) return SignedZero(sign); | 497 if (current == end) return SignedZero(negative); |
498 } | 498 } |
499 } | 499 } |
500 | 500 |
501 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; | 501 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; |
502 | 502 |
503 // Copy significant digits of the integer part (if any) to the buffer. | 503 // Copy significant digits of the integer part (if any) to the buffer. |
504 while (*current >= '0' && *current <= '9') { | 504 while (*current >= '0' && *current <= '9') { |
505 if (significant_digits < kMaxSignificantDigits) { | 505 if (significant_digits < kMaxSignificantDigits) { |
506 ASSERT(buffer_pos < kBufferSize); | 506 ASSERT(buffer_pos < kBufferSize); |
507 buffer[buffer_pos++] = static_cast<char>(*current); | 507 buffer[buffer_pos++] = static_cast<char>(*current); |
(...skipping 24 matching lines...) Expand all Loading... |
532 goto parsing_done; | 532 goto parsing_done; |
533 } | 533 } |
534 } | 534 } |
535 | 535 |
536 if (significant_digits == 0) { | 536 if (significant_digits == 0) { |
537 // octal = false; | 537 // octal = false; |
538 // Integer part consists of 0 or is absent. Significant digits start after | 538 // Integer part consists of 0 or is absent. Significant digits start after |
539 // leading zeros (if any). | 539 // leading zeros (if any). |
540 while (*current == '0') { | 540 while (*current == '0') { |
541 ++current; | 541 ++current; |
542 if (current == end) return SignedZero(sign); | 542 if (current == end) return SignedZero(negative); |
543 exponent--; // Move this 0 into the exponent. | 543 exponent--; // Move this 0 into the exponent. |
544 } | 544 } |
545 } | 545 } |
546 | 546 |
547 // We don't emit a '.', but adjust the exponent instead. | 547 // We don't emit a '.', but adjust the exponent instead. |
548 fractional_part = true; | 548 fractional_part = true; |
549 | 549 |
550 // There is a fractional part. | 550 // There is a fractional part. |
551 while (*current >= '0' && *current <= '9') { | 551 while (*current >= '0' && *current <= '9') { |
552 if (significant_digits < kMaxSignificantDigits) { | 552 if (significant_digits < kMaxSignificantDigits) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 624 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
625 return JUNK_STRING_VALUE; | 625 return JUNK_STRING_VALUE; |
626 } | 626 } |
627 | 627 |
628 parsing_done: | 628 parsing_done: |
629 exponent += insignificant_digits; | 629 exponent += insignificant_digits; |
630 | 630 |
631 if (octal) { | 631 if (octal) { |
632 return InternalStringToIntDouble<3>(buffer, | 632 return InternalStringToIntDouble<3>(buffer, |
633 buffer + buffer_pos, | 633 buffer + buffer_pos, |
634 sign, | 634 negative, |
635 allow_trailing_junk); | 635 allow_trailing_junk); |
636 } | 636 } |
637 | 637 |
638 if (nonzero_digit_dropped) { | 638 if (nonzero_digit_dropped) { |
639 buffer[buffer_pos++] = '1'; | 639 buffer[buffer_pos++] = '1'; |
640 exponent--; | 640 exponent--; |
641 } | 641 } |
642 | 642 |
643 ASSERT(buffer_pos < kBufferSize); | 643 ASSERT(buffer_pos < kBufferSize); |
644 buffer[buffer_pos] = '\0'; | 644 buffer[buffer_pos] = '\0'; |
645 | 645 |
646 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 646 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
647 return sign ? -converted : converted; | 647 return negative ? -converted : converted; |
648 } | 648 } |
649 | 649 |
650 | 650 |
651 double StringToDouble(String* str, int flags, double empty_string_val) { | 651 double StringToDouble(String* str, int flags, double empty_string_val) { |
652 StringShape shape(str); | 652 StringShape shape(str); |
653 if (shape.IsSequentialAscii()) { | 653 if (shape.IsSequentialAscii()) { |
654 const char* begin = SeqAsciiString::cast(str)->GetChars(); | 654 const char* begin = SeqAsciiString::cast(str)->GetChars(); |
655 const char* end = begin + str->length(); | 655 const char* end = begin + str->length(); |
656 return InternalStringToDouble(begin, end, flags, empty_string_val); | 656 return InternalStringToDouble(begin, end, flags, empty_string_val); |
657 } else if (shape.IsSequentialTwoByte()) { | 657 } else if (shape.IsSequentialTwoByte()) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 | 695 |
696 double StringToDouble(Vector<const char> str, | 696 double StringToDouble(Vector<const char> str, |
697 int flags, | 697 int flags, |
698 double empty_string_val) { | 698 double empty_string_val) { |
699 const char* end = str.start() + str.length(); | 699 const char* end = str.start() + str.length(); |
700 return InternalStringToDouble(str.start(), end, flags, empty_string_val); | 700 return InternalStringToDouble(str.start(), end, flags, empty_string_val); |
701 } | 701 } |
702 | 702 |
703 | 703 |
704 const char* DoubleToCString(double v, Vector<char> buffer) { | 704 const char* DoubleToCString(double v, Vector<char> buffer) { |
705 StringBuilder builder(buffer.start(), buffer.length()); | |
706 | |
707 switch (fpclassify(v)) { | 705 switch (fpclassify(v)) { |
708 case FP_NAN: | 706 case FP_NAN: return "NaN"; |
709 builder.AddString("NaN"); | 707 case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity"); |
710 break; | 708 case FP_ZERO: return "0"; |
711 | |
712 case FP_INFINITE: | |
713 if (v < 0.0) { | |
714 builder.AddString("-Infinity"); | |
715 } else { | |
716 builder.AddString("Infinity"); | |
717 } | |
718 break; | |
719 | |
720 case FP_ZERO: | |
721 builder.AddCharacter('0'); | |
722 break; | |
723 | |
724 default: { | 709 default: { |
| 710 StringBuilder builder(buffer.start(), buffer.length()); |
725 int decimal_point; | 711 int decimal_point; |
726 int sign; | 712 int sign; |
727 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; | 713 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; |
728 char decimal_rep[kV8DtoaBufferCapacity]; | 714 char decimal_rep[kV8DtoaBufferCapacity]; |
729 int length; | 715 int length; |
730 | 716 |
731 DoubleToAscii(v, DTOA_SHORTEST, 0, | 717 DoubleToAscii(v, DTOA_SHORTEST, 0, |
732 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), | 718 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
733 &sign, &length, &decimal_point); | 719 &sign, &length, &decimal_point); |
734 | 720 |
(...skipping 22 matching lines...) Expand all Loading... |
757 if (length != 1) { | 743 if (length != 1) { |
758 builder.AddCharacter('.'); | 744 builder.AddCharacter('.'); |
759 builder.AddString(decimal_rep + 1); | 745 builder.AddString(decimal_rep + 1); |
760 } | 746 } |
761 builder.AddCharacter('e'); | 747 builder.AddCharacter('e'); |
762 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); | 748 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); |
763 int exponent = decimal_point - 1; | 749 int exponent = decimal_point - 1; |
764 if (exponent < 0) exponent = -exponent; | 750 if (exponent < 0) exponent = -exponent; |
765 builder.AddFormatted("%d", exponent); | 751 builder.AddFormatted("%d", exponent); |
766 } | 752 } |
| 753 return builder.Finalize(); |
767 } | 754 } |
768 } | 755 } |
769 return builder.Finalize(); | |
770 } | 756 } |
771 | 757 |
772 | 758 |
773 const char* IntToCString(int n, Vector<char> buffer) { | 759 const char* IntToCString(int n, Vector<char> buffer) { |
774 bool negative = false; | 760 bool negative = false; |
775 if (n < 0) { | 761 if (n < 0) { |
776 // We must not negate the most negative int. | 762 // We must not negate the most negative int. |
777 if (n == kMinInt) return DoubleToCString(n, buffer); | 763 if (n == kMinInt) return DoubleToCString(n, buffer); |
778 negative = true; | 764 negative = true; |
779 n = -n; | 765 n = -n; |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 // Allocate result and fill in the parts. | 1060 // Allocate result and fill in the parts. |
1075 StringBuilder builder(result_size + 1); | 1061 StringBuilder builder(result_size + 1); |
1076 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); | 1062 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); |
1077 if (decimal_pos > 0) builder.AddCharacter('.'); | 1063 if (decimal_pos > 0) builder.AddCharacter('.'); |
1078 builder.AddSubstring(decimal_buffer, decimal_pos); | 1064 builder.AddSubstring(decimal_buffer, decimal_pos); |
1079 return builder.Finalize(); | 1065 return builder.Finalize(); |
1080 } | 1066 } |
1081 | 1067 |
1082 | 1068 |
1083 } } // namespace v8::internal | 1069 } } // namespace v8::internal |
OLD | NEW |