| 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 } | 120 } |
| 121 | 121 |
| 122 | 122 |
| 123 static bool isDigit(int x, int radix) { | 123 static bool isDigit(int x, int radix) { |
| 124 return (x >= '0' && x <= '9' && x < '0' + radix) | 124 return (x >= '0' && x <= '9' && x < '0' + radix) |
| 125 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) | 125 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) |
| 126 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); | 126 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); |
| 127 } | 127 } |
| 128 | 128 |
| 129 | 129 |
| 130 static double SignedZero(bool sign) { | 130 static double SignedZero(bool negative) { |
| 131 return sign ? -0.0 : 0.0; | 131 return negative ? -0.0 : 0.0; |
| 132 } | 132 } |
| 133 | 133 |
| 134 | 134 |
| 135 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. | 135 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. |
| 136 template <int radix_log_2, class Iterator, class EndMark> | 136 template <int radix_log_2, class Iterator, class EndMark> |
| 137 static double InternalStringToIntDouble( | 137 static double InternalStringToIntDouble(ScannerConstants* scanner_constants, |
| 138 ScannerConstants* scanner_constants, | 138 Iterator current, |
| 139 Iterator current, | 139 EndMark end, |
| 140 EndMark end, | 140 bool negative, |
| 141 bool sign, | 141 bool allow_trailing_junk) { |
| 142 bool allow_trailing_junk) { | |
| 143 ASSERT(current != end); | 142 ASSERT(current != end); |
| 144 | 143 |
| 145 // Skip leading 0s. | 144 // Skip leading 0s. |
| 146 while (*current == '0') { | 145 while (*current == '0') { |
| 147 ++current; | 146 ++current; |
| 148 if (current == end) return SignedZero(sign); | 147 if (current == end) return SignedZero(negative); |
| 149 } | 148 } |
| 150 | 149 |
| 151 int64_t number = 0; | 150 int64_t number = 0; |
| 152 int exponent = 0; | 151 int exponent = 0; |
| 153 const int radix = (1 << radix_log_2); | 152 const int radix = (1 << radix_log_2); |
| 154 | 153 |
| 155 do { | 154 do { |
| 156 int digit; | 155 int digit; |
| 157 if (*current >= '0' && *current <= '9' && *current < '0' + radix) { | 156 if (*current >= '0' && *current <= '9' && *current < '0' + radix) { |
| 158 digit = static_cast<char>(*current) - '0'; | 157 digit = static_cast<char>(*current) - '0'; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 } | 215 } |
| 217 break; | 216 break; |
| 218 } | 217 } |
| 219 ++current; | 218 ++current; |
| 220 } while (current != end); | 219 } while (current != end); |
| 221 | 220 |
| 222 ASSERT(number < ((int64_t)1 << 53)); | 221 ASSERT(number < ((int64_t)1 << 53)); |
| 223 ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); | 222 ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); |
| 224 | 223 |
| 225 if (exponent == 0) { | 224 if (exponent == 0) { |
| 226 if (sign) { | 225 if (negative) { |
| 227 if (number == 0) return -0.0; | 226 if (number == 0) return -0.0; |
| 228 number = -number; | 227 number = -number; |
| 229 } | 228 } |
| 230 return static_cast<double>(number); | 229 return static_cast<double>(number); |
| 231 } | 230 } |
| 232 | 231 |
| 233 ASSERT(number != 0); | 232 ASSERT(number != 0); |
| 234 // The double could be constructed faster from number (mantissa), exponent | 233 // The double could be constructed faster from number (mantissa), exponent |
| 235 // and sign. Assuming it's a rare case more simple code is used. | 234 // and sign. Assuming it's a rare case more simple code is used. |
| 236 return static_cast<double>(sign ? -number : number) * pow(2.0, exponent); | 235 return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); |
| 237 } | 236 } |
| 238 | 237 |
| 239 | 238 |
| 240 template <class Iterator, class EndMark> | 239 template <class Iterator, class EndMark> |
| 241 static double InternalStringToInt(ScannerConstants* scanner_constants, | 240 static double InternalStringToInt(ScannerConstants* scanner_constants, |
| 242 Iterator current, | 241 Iterator current, |
| 243 EndMark end, | 242 EndMark end, |
| 244 int radix) { | 243 int radix) { |
| 245 const bool allow_trailing_junk = true; | 244 const bool allow_trailing_junk = true; |
| 246 const double empty_string_val = JUNK_STRING_VALUE; | 245 const double empty_string_val = JUNK_STRING_VALUE; |
| 247 | 246 |
| 248 if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { | 247 if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { |
| 249 return empty_string_val; | 248 return empty_string_val; |
| 250 } | 249 } |
| 251 | 250 |
| 252 bool sign = false; | 251 bool negative = false; |
| 253 bool leading_zero = false; | 252 bool leading_zero = false; |
| 254 | 253 |
| 255 if (*current == '+') { | 254 if (*current == '+') { |
| 256 // Ignore leading sign; skip following spaces. | 255 // Ignore leading sign; skip following spaces. |
| 257 ++current; | 256 ++current; |
| 258 if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { | 257 if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { |
| 259 return JUNK_STRING_VALUE; | 258 return JUNK_STRING_VALUE; |
| 260 } | 259 } |
| 261 } else if (*current == '-') { | 260 } else if (*current == '-') { |
| 262 ++current; | 261 ++current; |
| 263 if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { | 262 if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { |
| 264 return JUNK_STRING_VALUE; | 263 return JUNK_STRING_VALUE; |
| 265 } | 264 } |
| 266 sign = true; | 265 negative = true; |
| 267 } | 266 } |
| 268 | 267 |
| 269 if (radix == 0) { | 268 if (radix == 0) { |
| 270 // Radix detection. | 269 // Radix detection. |
| 271 if (*current == '0') { | 270 if (*current == '0') { |
| 272 ++current; | 271 ++current; |
| 273 if (current == end) return SignedZero(sign); | 272 if (current == end) return SignedZero(negative); |
| 274 if (*current == 'x' || *current == 'X') { | 273 if (*current == 'x' || *current == 'X') { |
| 275 radix = 16; | 274 radix = 16; |
| 276 ++current; | 275 ++current; |
| 277 if (current == end) return JUNK_STRING_VALUE; | 276 if (current == end) return JUNK_STRING_VALUE; |
| 278 } else { | 277 } else { |
| 279 radix = 8; | 278 radix = 8; |
| 280 leading_zero = true; | 279 leading_zero = true; |
| 281 } | 280 } |
| 282 } else { | 281 } else { |
| 283 radix = 10; | 282 radix = 10; |
| 284 } | 283 } |
| 285 } else if (radix == 16) { | 284 } else if (radix == 16) { |
| 286 if (*current == '0') { | 285 if (*current == '0') { |
| 287 // Allow "0x" prefix. | 286 // Allow "0x" prefix. |
| 288 ++current; | 287 ++current; |
| 289 if (current == end) return SignedZero(sign); | 288 if (current == end) return SignedZero(negative); |
| 290 if (*current == 'x' || *current == 'X') { | 289 if (*current == 'x' || *current == 'X') { |
| 291 ++current; | 290 ++current; |
| 292 if (current == end) return JUNK_STRING_VALUE; | 291 if (current == end) return JUNK_STRING_VALUE; |
| 293 } else { | 292 } else { |
| 294 leading_zero = true; | 293 leading_zero = true; |
| 295 } | 294 } |
| 296 } | 295 } |
| 297 } | 296 } |
| 298 | 297 |
| 299 if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; | 298 if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; |
| 300 | 299 |
| 301 // Skip leading zeros. | 300 // Skip leading zeros. |
| 302 while (*current == '0') { | 301 while (*current == '0') { |
| 303 leading_zero = true; | 302 leading_zero = true; |
| 304 ++current; | 303 ++current; |
| 305 if (current == end) return SignedZero(sign); | 304 if (current == end) return SignedZero(negative); |
| 306 } | 305 } |
| 307 | 306 |
| 308 if (!leading_zero && !isDigit(*current, radix)) { | 307 if (!leading_zero && !isDigit(*current, radix)) { |
| 309 return JUNK_STRING_VALUE; | 308 return JUNK_STRING_VALUE; |
| 310 } | 309 } |
| 311 | 310 |
| 312 if (IsPowerOf2(radix)) { | 311 if (IsPowerOf2(radix)) { |
| 313 switch (radix) { | 312 switch (radix) { |
| 314 case 2: | 313 case 2: |
| 315 return InternalStringToIntDouble<1>( | 314 return InternalStringToIntDouble<1>( |
| 316 scanner_constants, current, end, sign, allow_trailing_junk); | 315 scanner_constants, current, end, negative, allow_trailing_junk); |
| 317 case 4: | 316 case 4: |
| 318 return InternalStringToIntDouble<2>( | 317 return InternalStringToIntDouble<2>( |
| 319 scanner_constants, current, end, sign, allow_trailing_junk); | 318 scanner_constants, current, end, negative, allow_trailing_junk); |
| 320 case 8: | 319 case 8: |
| 321 return InternalStringToIntDouble<3>( | 320 return InternalStringToIntDouble<3>( |
| 322 scanner_constants, current, end, sign, allow_trailing_junk); | 321 scanner_constants, current, end, negative, allow_trailing_junk); |
| 323 | 322 |
| 324 case 16: | 323 case 16: |
| 325 return InternalStringToIntDouble<4>( | 324 return InternalStringToIntDouble<4>( |
| 326 scanner_constants, current, end, sign, allow_trailing_junk); | 325 scanner_constants, current, end, negative, allow_trailing_junk); |
| 327 | 326 |
| 328 case 32: | 327 case 32: |
| 329 return InternalStringToIntDouble<5>( | 328 return InternalStringToIntDouble<5>( |
| 330 scanner_constants, current, end, sign, allow_trailing_junk); | 329 scanner_constants, current, end, negative, allow_trailing_junk); |
| 331 default: | 330 default: |
| 332 UNREACHABLE(); | 331 UNREACHABLE(); |
| 333 } | 332 } |
| 334 } | 333 } |
| 335 | 334 |
| 336 if (radix == 10) { | 335 if (radix == 10) { |
| 337 // Parsing with strtod. | 336 // Parsing with strtod. |
| 338 const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308. | 337 const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308. |
| 339 // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero | 338 // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero |
| 340 // end. | 339 // end. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 353 } | 352 } |
| 354 | 353 |
| 355 if (!allow_trailing_junk && | 354 if (!allow_trailing_junk && |
| 356 AdvanceToNonspace(scanner_constants, ¤t, end)) { | 355 AdvanceToNonspace(scanner_constants, ¤t, end)) { |
| 357 return JUNK_STRING_VALUE; | 356 return JUNK_STRING_VALUE; |
| 358 } | 357 } |
| 359 | 358 |
| 360 ASSERT(buffer_pos < kBufferSize); | 359 ASSERT(buffer_pos < kBufferSize); |
| 361 buffer[buffer_pos] = '\0'; | 360 buffer[buffer_pos] = '\0'; |
| 362 Vector<const char> buffer_vector(buffer, buffer_pos); | 361 Vector<const char> buffer_vector(buffer, buffer_pos); |
| 363 return sign ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); | 362 return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); |
| 364 } | 363 } |
| 365 | 364 |
| 366 // The following code causes accumulating rounding error for numbers greater | 365 // The following code causes accumulating rounding error for numbers greater |
| 367 // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, | 366 // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, |
| 368 // 16, or 32, then mathInt may be an implementation-dependent approximation to | 367 // 16, or 32, then mathInt may be an implementation-dependent approximation to |
| 369 // the mathematical integer value" (15.1.2.2). | 368 // the mathematical integer value" (15.1.2.2). |
| 370 | 369 |
| 371 int lim_0 = '0' + (radix < 10 ? radix : 10); | 370 int lim_0 = '0' + (radix < 10 ? radix : 10); |
| 372 int lim_a = 'a' + (radix - 10); | 371 int lim_a = 'a' + (radix - 10); |
| 373 int lim_A = 'A' + (radix - 10); | 372 int lim_A = 'A' + (radix - 10); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 | 415 |
| 417 // Update the value and skip the part in the string. | 416 // Update the value and skip the part in the string. |
| 418 v = v * multiplier + part; | 417 v = v * multiplier + part; |
| 419 } while (!done); | 418 } while (!done); |
| 420 | 419 |
| 421 if (!allow_trailing_junk && | 420 if (!allow_trailing_junk && |
| 422 AdvanceToNonspace(scanner_constants, ¤t, end)) { | 421 AdvanceToNonspace(scanner_constants, ¤t, end)) { |
| 423 return JUNK_STRING_VALUE; | 422 return JUNK_STRING_VALUE; |
| 424 } | 423 } |
| 425 | 424 |
| 426 return sign ? -v : v; | 425 return negative ? -v : v; |
| 427 } | 426 } |
| 428 | 427 |
| 429 | 428 |
| 430 // Converts a string to a double value. Assumes the Iterator supports | 429 // Converts a string to a double value. Assumes the Iterator supports |
| 431 // the following operations: | 430 // the following operations: |
| 432 // 1. current == end (other ops are not allowed), current != end. | 431 // 1. current == end (other ops are not allowed), current != end. |
| 433 // 2. *current - gets the current character in the sequence. | 432 // 2. *current - gets the current character in the sequence. |
| 434 // 3. ++current (advances the position). | 433 // 3. ++current (advances the position). |
| 435 template <class Iterator, class EndMark> | 434 template <class Iterator, class EndMark> |
| 436 static double InternalStringToDouble(ScannerConstants* scanner_constants, | 435 static double InternalStringToDouble(ScannerConstants* scanner_constants, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 458 int buffer_pos = 0; | 457 int buffer_pos = 0; |
| 459 | 458 |
| 460 // Exponent will be adjusted if insignificant digits of the integer part | 459 // Exponent will be adjusted if insignificant digits of the integer part |
| 461 // or insignificant leading zeros of the fractional part are dropped. | 460 // or insignificant leading zeros of the fractional part are dropped. |
| 462 int exponent = 0; | 461 int exponent = 0; |
| 463 int significant_digits = 0; | 462 int significant_digits = 0; |
| 464 int insignificant_digits = 0; | 463 int insignificant_digits = 0; |
| 465 bool nonzero_digit_dropped = false; | 464 bool nonzero_digit_dropped = false; |
| 466 bool fractional_part = false; | 465 bool fractional_part = false; |
| 467 | 466 |
| 468 bool sign = false; | 467 bool negative = false; |
| 469 | 468 |
| 470 if (*current == '+') { | 469 if (*current == '+') { |
| 471 // Ignore leading sign. | 470 // Ignore leading sign. |
| 472 ++current; | 471 ++current; |
| 473 if (current == end) return JUNK_STRING_VALUE; | 472 if (current == end) return JUNK_STRING_VALUE; |
| 474 } else if (*current == '-') { | 473 } else if (*current == '-') { |
| 475 ++current; | 474 ++current; |
| 476 if (current == end) return JUNK_STRING_VALUE; | 475 if (current == end) return JUNK_STRING_VALUE; |
| 477 sign = true; | 476 negative = true; |
| 478 } | 477 } |
| 479 | 478 |
| 480 static const char kInfinitySymbol[] = "Infinity"; | 479 static const char kInfinitySymbol[] = "Infinity"; |
| 481 if (*current == kInfinitySymbol[0]) { | 480 if (*current == kInfinitySymbol[0]) { |
| 482 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { | 481 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { |
| 483 return JUNK_STRING_VALUE; | 482 return JUNK_STRING_VALUE; |
| 484 } | 483 } |
| 485 | 484 |
| 486 if (!allow_trailing_junk && | 485 if (!allow_trailing_junk && |
| 487 AdvanceToNonspace(scanner_constants, ¤t, end)) { | 486 AdvanceToNonspace(scanner_constants, ¤t, end)) { |
| 488 return JUNK_STRING_VALUE; | 487 return JUNK_STRING_VALUE; |
| 489 } | 488 } |
| 490 | 489 |
| 491 ASSERT(buffer_pos == 0); | 490 ASSERT(buffer_pos == 0); |
| 492 return sign ? -V8_INFINITY : V8_INFINITY; | 491 return negative ? -V8_INFINITY : V8_INFINITY; |
| 493 } | 492 } |
| 494 | 493 |
| 495 bool leading_zero = false; | 494 bool leading_zero = false; |
| 496 if (*current == '0') { | 495 if (*current == '0') { |
| 497 ++current; | 496 ++current; |
| 498 if (current == end) return SignedZero(sign); | 497 if (current == end) return SignedZero(negative); |
| 499 | 498 |
| 500 leading_zero = true; | 499 leading_zero = true; |
| 501 | 500 |
| 502 // It could be hexadecimal value. | 501 // It could be hexadecimal value. |
| 503 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 502 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { |
| 504 ++current; | 503 ++current; |
| 505 if (current == end || !isDigit(*current, 16)) { | 504 if (current == end || !isDigit(*current, 16)) { |
| 506 return JUNK_STRING_VALUE; // "0x". | 505 return JUNK_STRING_VALUE; // "0x". |
| 507 } | 506 } |
| 508 | 507 |
| 509 return InternalStringToIntDouble<4>(scanner_constants, | 508 return InternalStringToIntDouble<4>(scanner_constants, |
| 510 current, | 509 current, |
| 511 end, | 510 end, |
| 512 sign, | 511 negative, |
| 513 allow_trailing_junk); | 512 allow_trailing_junk); |
| 514 } | 513 } |
| 515 | 514 |
| 516 // Ignore leading zeros in the integer part. | 515 // Ignore leading zeros in the integer part. |
| 517 while (*current == '0') { | 516 while (*current == '0') { |
| 518 ++current; | 517 ++current; |
| 519 if (current == end) return SignedZero(sign); | 518 if (current == end) return SignedZero(negative); |
| 520 } | 519 } |
| 521 } | 520 } |
| 522 | 521 |
| 523 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; | 522 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; |
| 524 | 523 |
| 525 // Copy significant digits of the integer part (if any) to the buffer. | 524 // Copy significant digits of the integer part (if any) to the buffer. |
| 526 while (*current >= '0' && *current <= '9') { | 525 while (*current >= '0' && *current <= '9') { |
| 527 if (significant_digits < kMaxSignificantDigits) { | 526 if (significant_digits < kMaxSignificantDigits) { |
| 528 ASSERT(buffer_pos < kBufferSize); | 527 ASSERT(buffer_pos < kBufferSize); |
| 529 buffer[buffer_pos++] = static_cast<char>(*current); | 528 buffer[buffer_pos++] = static_cast<char>(*current); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 554 goto parsing_done; | 553 goto parsing_done; |
| 555 } | 554 } |
| 556 } | 555 } |
| 557 | 556 |
| 558 if (significant_digits == 0) { | 557 if (significant_digits == 0) { |
| 559 // octal = false; | 558 // octal = false; |
| 560 // Integer part consists of 0 or is absent. Significant digits start after | 559 // Integer part consists of 0 or is absent. Significant digits start after |
| 561 // leading zeros (if any). | 560 // leading zeros (if any). |
| 562 while (*current == '0') { | 561 while (*current == '0') { |
| 563 ++current; | 562 ++current; |
| 564 if (current == end) return SignedZero(sign); | 563 if (current == end) return SignedZero(negative); |
| 565 exponent--; // Move this 0 into the exponent. | 564 exponent--; // Move this 0 into the exponent. |
| 566 } | 565 } |
| 567 } | 566 } |
| 568 | 567 |
| 569 // We don't emit a '.', but adjust the exponent instead. | 568 // We don't emit a '.', but adjust the exponent instead. |
| 570 fractional_part = true; | 569 fractional_part = true; |
| 571 | 570 |
| 572 // There is a fractional part. | 571 // There is a fractional part. |
| 573 while (*current >= '0' && *current <= '9') { | 572 while (*current >= '0' && *current <= '9') { |
| 574 if (significant_digits < kMaxSignificantDigits) { | 573 if (significant_digits < kMaxSignificantDigits) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 return JUNK_STRING_VALUE; | 647 return JUNK_STRING_VALUE; |
| 649 } | 648 } |
| 650 | 649 |
| 651 parsing_done: | 650 parsing_done: |
| 652 exponent += insignificant_digits; | 651 exponent += insignificant_digits; |
| 653 | 652 |
| 654 if (octal) { | 653 if (octal) { |
| 655 return InternalStringToIntDouble<3>(scanner_constants, | 654 return InternalStringToIntDouble<3>(scanner_constants, |
| 656 buffer, | 655 buffer, |
| 657 buffer + buffer_pos, | 656 buffer + buffer_pos, |
| 658 sign, | 657 negative, |
| 659 allow_trailing_junk); | 658 allow_trailing_junk); |
| 660 } | 659 } |
| 661 | 660 |
| 662 if (nonzero_digit_dropped) { | 661 if (nonzero_digit_dropped) { |
| 663 buffer[buffer_pos++] = '1'; | 662 buffer[buffer_pos++] = '1'; |
| 664 exponent--; | 663 exponent--; |
| 665 } | 664 } |
| 666 | 665 |
| 667 ASSERT(buffer_pos < kBufferSize); | 666 ASSERT(buffer_pos < kBufferSize); |
| 668 buffer[buffer_pos] = '\0'; | 667 buffer[buffer_pos] = '\0'; |
| 669 | 668 |
| 670 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 669 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
| 671 return sign ? -converted : converted; | 670 return negative ? -converted : converted; |
| 672 } | 671 } |
| 673 | 672 |
| 674 | 673 |
| 675 double StringToDouble(String* str, int flags, double empty_string_val) { | 674 double StringToDouble(String* str, int flags, double empty_string_val) { |
| 676 ScannerConstants* scanner_constants = | 675 ScannerConstants* scanner_constants = |
| 677 Isolate::Current()->scanner_constants(); | 676 Isolate::Current()->scanner_constants(); |
| 678 StringShape shape(str); | 677 StringShape shape(str); |
| 679 if (shape.IsSequentialAscii()) { | 678 if (shape.IsSequentialAscii()) { |
| 680 const char* begin = SeqAsciiString::cast(str)->GetChars(); | 679 const char* begin = SeqAsciiString::cast(str)->GetChars(); |
| 681 const char* end = begin + str->length(); | 680 const char* end = begin + str->length(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 double empty_string_val) { | 732 double empty_string_val) { |
| 734 ScannerConstants* scanner_constants = | 733 ScannerConstants* scanner_constants = |
| 735 Isolate::Current()->scanner_constants(); | 734 Isolate::Current()->scanner_constants(); |
| 736 const char* end = str.start() + str.length(); | 735 const char* end = str.start() + str.length(); |
| 737 return InternalStringToDouble(scanner_constants, str.start(), end, flags, | 736 return InternalStringToDouble(scanner_constants, str.start(), end, flags, |
| 738 empty_string_val); | 737 empty_string_val); |
| 739 } | 738 } |
| 740 | 739 |
| 741 | 740 |
| 742 const char* DoubleToCString(double v, Vector<char> buffer) { | 741 const char* DoubleToCString(double v, Vector<char> buffer) { |
| 743 StringBuilder builder(buffer.start(), buffer.length()); | |
| 744 | |
| 745 switch (fpclassify(v)) { | 742 switch (fpclassify(v)) { |
| 746 case FP_NAN: | 743 case FP_NAN: return "NaN"; |
| 747 builder.AddString("NaN"); | 744 case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity"); |
| 748 break; | 745 case FP_ZERO: return "0"; |
| 749 | |
| 750 case FP_INFINITE: | |
| 751 if (v < 0.0) { | |
| 752 builder.AddString("-Infinity"); | |
| 753 } else { | |
| 754 builder.AddString("Infinity"); | |
| 755 } | |
| 756 break; | |
| 757 | |
| 758 case FP_ZERO: | |
| 759 builder.AddCharacter('0'); | |
| 760 break; | |
| 761 | |
| 762 default: { | 746 default: { |
| 747 StringBuilder builder(buffer.start(), buffer.length()); |
| 763 int decimal_point; | 748 int decimal_point; |
| 764 int sign; | 749 int sign; |
| 765 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; | 750 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; |
| 766 char decimal_rep[kV8DtoaBufferCapacity]; | 751 char decimal_rep[kV8DtoaBufferCapacity]; |
| 767 int length; | 752 int length; |
| 768 | 753 |
| 769 DoubleToAscii(v, DTOA_SHORTEST, 0, | 754 DoubleToAscii(v, DTOA_SHORTEST, 0, |
| 770 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), | 755 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
| 771 &sign, &length, &decimal_point); | 756 &sign, &length, &decimal_point); |
| 772 | 757 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 795 if (length != 1) { | 780 if (length != 1) { |
| 796 builder.AddCharacter('.'); | 781 builder.AddCharacter('.'); |
| 797 builder.AddString(decimal_rep + 1); | 782 builder.AddString(decimal_rep + 1); |
| 798 } | 783 } |
| 799 builder.AddCharacter('e'); | 784 builder.AddCharacter('e'); |
| 800 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); | 785 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); |
| 801 int exponent = decimal_point - 1; | 786 int exponent = decimal_point - 1; |
| 802 if (exponent < 0) exponent = -exponent; | 787 if (exponent < 0) exponent = -exponent; |
| 803 builder.AddFormatted("%d", exponent); | 788 builder.AddFormatted("%d", exponent); |
| 804 } | 789 } |
| 790 return builder.Finalize(); |
| 805 } | 791 } |
| 806 } | 792 } |
| 807 return builder.Finalize(); | |
| 808 } | 793 } |
| 809 | 794 |
| 810 | 795 |
| 811 const char* IntToCString(int n, Vector<char> buffer) { | 796 const char* IntToCString(int n, Vector<char> buffer) { |
| 812 bool negative = false; | 797 bool negative = false; |
| 813 if (n < 0) { | 798 if (n < 0) { |
| 814 // We must not negate the most negative int. | 799 // We must not negate the most negative int. |
| 815 if (n == kMinInt) return DoubleToCString(n, buffer); | 800 if (n == kMinInt) return DoubleToCString(n, buffer); |
| 816 negative = true; | 801 negative = true; |
| 817 n = -n; | 802 n = -n; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock(); | 1116 (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock(); |
| 1132 } | 1117 } |
| 1133 | 1118 |
| 1134 | 1119 |
| 1135 void FREE_DTOA_LOCK(int n) { | 1120 void FREE_DTOA_LOCK(int n) { |
| 1136 ASSERT(n == 0 || n == 1); | 1121 ASSERT(n == 0 || n == 1); |
| 1137 (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)-> | 1122 (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)-> |
| 1138 Unlock(); | 1123 Unlock(); |
| 1139 } | 1124 } |
| 1140 } | 1125 } |
| OLD | NEW |