| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits.h> | 5 #include <limits.h> |
| 6 #include <stdarg.h> | 6 #include <stdarg.h> |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 } while (n); | 190 } while (n); |
| 191 if (negative) buffer[--i] = '-'; | 191 if (negative) buffer[--i] = '-'; |
| 192 return buffer.start() + i; | 192 return buffer.start() + i; |
| 193 } | 193 } |
| 194 | 194 |
| 195 | 195 |
| 196 char* DoubleToFixedCString(double value, int f) { | 196 char* DoubleToFixedCString(double value, int f) { |
| 197 const int kMaxDigitsBeforePoint = 21; | 197 const int kMaxDigitsBeforePoint = 21; |
| 198 const double kFirstNonFixed = 1e21; | 198 const double kFirstNonFixed = 1e21; |
| 199 const int kMaxDigitsAfterPoint = 20; | 199 const int kMaxDigitsAfterPoint = 20; |
| 200 ASSERT(f >= 0); | 200 DCHECK(f >= 0); |
| 201 ASSERT(f <= kMaxDigitsAfterPoint); | 201 DCHECK(f <= kMaxDigitsAfterPoint); |
| 202 | 202 |
| 203 bool negative = false; | 203 bool negative = false; |
| 204 double abs_value = value; | 204 double abs_value = value; |
| 205 if (value < 0) { | 205 if (value < 0) { |
| 206 abs_value = -value; | 206 abs_value = -value; |
| 207 negative = true; | 207 negative = true; |
| 208 } | 208 } |
| 209 | 209 |
| 210 // If abs_value has more than kMaxDigitsBeforePoint digits before the point | 210 // If abs_value has more than kMaxDigitsBeforePoint digits before the point |
| 211 // use the non-fixed conversion routine. | 211 // use the non-fixed conversion routine. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 builder.AddCharacter('e'); | 292 builder.AddCharacter('e'); |
| 293 builder.AddCharacter(negative_exponent ? '-' : '+'); | 293 builder.AddCharacter(negative_exponent ? '-' : '+'); |
| 294 builder.AddDecimalInteger(exponent); | 294 builder.AddDecimalInteger(exponent); |
| 295 return builder.Finalize(); | 295 return builder.Finalize(); |
| 296 } | 296 } |
| 297 | 297 |
| 298 | 298 |
| 299 char* DoubleToExponentialCString(double value, int f) { | 299 char* DoubleToExponentialCString(double value, int f) { |
| 300 const int kMaxDigitsAfterPoint = 20; | 300 const int kMaxDigitsAfterPoint = 20; |
| 301 // f might be -1 to signal that f was undefined in JavaScript. | 301 // f might be -1 to signal that f was undefined in JavaScript. |
| 302 ASSERT(f >= -1 && f <= kMaxDigitsAfterPoint); | 302 DCHECK(f >= -1 && f <= kMaxDigitsAfterPoint); |
| 303 | 303 |
| 304 bool negative = false; | 304 bool negative = false; |
| 305 if (value < 0) { | 305 if (value < 0) { |
| 306 value = -value; | 306 value = -value; |
| 307 negative = true; | 307 negative = true; |
| 308 } | 308 } |
| 309 | 309 |
| 310 // Find a sufficiently precise decimal representation of n. | 310 // Find a sufficiently precise decimal representation of n. |
| 311 int decimal_point; | 311 int decimal_point; |
| 312 int sign; | 312 int sign; |
| 313 // f corresponds to the digits after the point. There is always one digit | 313 // f corresponds to the digits after the point. There is always one digit |
| 314 // before the point. The number of requested_digits equals hence f + 1. | 314 // before the point. The number of requested_digits equals hence f + 1. |
| 315 // And we have to add one character for the null-terminator. | 315 // And we have to add one character for the null-terminator. |
| 316 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; | 316 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; |
| 317 // Make sure that the buffer is big enough, even if we fall back to the | 317 // Make sure that the buffer is big enough, even if we fall back to the |
| 318 // shortest representation (which happens when f equals -1). | 318 // shortest representation (which happens when f equals -1). |
| 319 ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); | 319 DCHECK(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); |
| 320 char decimal_rep[kV8DtoaBufferCapacity]; | 320 char decimal_rep[kV8DtoaBufferCapacity]; |
| 321 int decimal_rep_length; | 321 int decimal_rep_length; |
| 322 | 322 |
| 323 if (f == -1) { | 323 if (f == -1) { |
| 324 DoubleToAscii(value, DTOA_SHORTEST, 0, | 324 DoubleToAscii(value, DTOA_SHORTEST, 0, |
| 325 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), | 325 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
| 326 &sign, &decimal_rep_length, &decimal_point); | 326 &sign, &decimal_rep_length, &decimal_point); |
| 327 f = decimal_rep_length - 1; | 327 f = decimal_rep_length - 1; |
| 328 } else { | 328 } else { |
| 329 DoubleToAscii(value, DTOA_PRECISION, f + 1, | 329 DoubleToAscii(value, DTOA_PRECISION, f + 1, |
| 330 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), | 330 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
| 331 &sign, &decimal_rep_length, &decimal_point); | 331 &sign, &decimal_rep_length, &decimal_point); |
| 332 } | 332 } |
| 333 ASSERT(decimal_rep_length > 0); | 333 DCHECK(decimal_rep_length > 0); |
| 334 ASSERT(decimal_rep_length <= f + 1); | 334 DCHECK(decimal_rep_length <= f + 1); |
| 335 | 335 |
| 336 int exponent = decimal_point - 1; | 336 int exponent = decimal_point - 1; |
| 337 char* result = | 337 char* result = |
| 338 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); | 338 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); |
| 339 | 339 |
| 340 return result; | 340 return result; |
| 341 } | 341 } |
| 342 | 342 |
| 343 | 343 |
| 344 char* DoubleToPrecisionCString(double value, int p) { | 344 char* DoubleToPrecisionCString(double value, int p) { |
| 345 const int kMinimalDigits = 1; | 345 const int kMinimalDigits = 1; |
| 346 const int kMaximalDigits = 21; | 346 const int kMaximalDigits = 21; |
| 347 ASSERT(p >= kMinimalDigits && p <= kMaximalDigits); | 347 DCHECK(p >= kMinimalDigits && p <= kMaximalDigits); |
| 348 USE(kMinimalDigits); | 348 USE(kMinimalDigits); |
| 349 | 349 |
| 350 bool negative = false; | 350 bool negative = false; |
| 351 if (value < 0) { | 351 if (value < 0) { |
| 352 value = -value; | 352 value = -value; |
| 353 negative = true; | 353 negative = true; |
| 354 } | 354 } |
| 355 | 355 |
| 356 // Find a sufficiently precise decimal representation of n. | 356 // Find a sufficiently precise decimal representation of n. |
| 357 int decimal_point; | 357 int decimal_point; |
| 358 int sign; | 358 int sign; |
| 359 // Add one for the terminating null character. | 359 // Add one for the terminating null character. |
| 360 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; | 360 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; |
| 361 char decimal_rep[kV8DtoaBufferCapacity]; | 361 char decimal_rep[kV8DtoaBufferCapacity]; |
| 362 int decimal_rep_length; | 362 int decimal_rep_length; |
| 363 | 363 |
| 364 DoubleToAscii(value, DTOA_PRECISION, p, | 364 DoubleToAscii(value, DTOA_PRECISION, p, |
| 365 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), | 365 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
| 366 &sign, &decimal_rep_length, &decimal_point); | 366 &sign, &decimal_rep_length, &decimal_point); |
| 367 ASSERT(decimal_rep_length <= p); | 367 DCHECK(decimal_rep_length <= p); |
| 368 | 368 |
| 369 int exponent = decimal_point - 1; | 369 int exponent = decimal_point - 1; |
| 370 | 370 |
| 371 char* result = NULL; | 371 char* result = NULL; |
| 372 | 372 |
| 373 if (exponent < -6 || exponent >= p) { | 373 if (exponent < -6 || exponent >= p) { |
| 374 result = | 374 result = |
| 375 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); | 375 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); |
| 376 } else { | 376 } else { |
| 377 // Use fixed notation. | 377 // Use fixed notation. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 405 } | 405 } |
| 406 } | 406 } |
| 407 result = builder.Finalize(); | 407 result = builder.Finalize(); |
| 408 } | 408 } |
| 409 | 409 |
| 410 return result; | 410 return result; |
| 411 } | 411 } |
| 412 | 412 |
| 413 | 413 |
| 414 char* DoubleToRadixCString(double value, int radix) { | 414 char* DoubleToRadixCString(double value, int radix) { |
| 415 ASSERT(radix >= 2 && radix <= 36); | 415 DCHECK(radix >= 2 && radix <= 36); |
| 416 | 416 |
| 417 // Character array used for conversion. | 417 // Character array used for conversion. |
| 418 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; | 418 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
| 419 | 419 |
| 420 // Buffer for the integer part of the result. 1024 chars is enough | 420 // Buffer for the integer part of the result. 1024 chars is enough |
| 421 // for max integer value in radix 2. We need room for a sign too. | 421 // for max integer value in radix 2. We need room for a sign too. |
| 422 static const int kBufferSize = 1100; | 422 static const int kBufferSize = 1100; |
| 423 char integer_buffer[kBufferSize]; | 423 char integer_buffer[kBufferSize]; |
| 424 integer_buffer[kBufferSize - 1] = '\0'; | 424 integer_buffer[kBufferSize - 1] = '\0'; |
| 425 | 425 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 439 // Convert the integer part starting from the back. Always generate | 439 // Convert the integer part starting from the back. Always generate |
| 440 // at least one digit. | 440 // at least one digit. |
| 441 int integer_pos = kBufferSize - 2; | 441 int integer_pos = kBufferSize - 2; |
| 442 do { | 442 do { |
| 443 double remainder = std::fmod(integer_part, radix); | 443 double remainder = std::fmod(integer_part, radix); |
| 444 integer_buffer[integer_pos--] = chars[static_cast<int>(remainder)]; | 444 integer_buffer[integer_pos--] = chars[static_cast<int>(remainder)]; |
| 445 integer_part -= remainder; | 445 integer_part -= remainder; |
| 446 integer_part /= radix; | 446 integer_part /= radix; |
| 447 } while (integer_part >= 1.0); | 447 } while (integer_part >= 1.0); |
| 448 // Sanity check. | 448 // Sanity check. |
| 449 ASSERT(integer_pos > 0); | 449 DCHECK(integer_pos > 0); |
| 450 // Add sign if needed. | 450 // Add sign if needed. |
| 451 if (is_negative) integer_buffer[integer_pos--] = '-'; | 451 if (is_negative) integer_buffer[integer_pos--] = '-'; |
| 452 | 452 |
| 453 // Convert the decimal part. Repeatedly multiply by the radix to | 453 // Convert the decimal part. Repeatedly multiply by the radix to |
| 454 // generate the next char. Never generate more than kBufferSize - 1 | 454 // generate the next char. Never generate more than kBufferSize - 1 |
| 455 // chars. | 455 // chars. |
| 456 // | 456 // |
| 457 // TODO(1093998): We will often generate a full decimal_buffer of | 457 // TODO(1093998): We will often generate a full decimal_buffer of |
| 458 // chars because hitting zero will often not happen. The right | 458 // chars because hitting zero will often not happen. The right |
| 459 // solution would be to continue until the string representation can | 459 // solution would be to continue until the string representation can |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 return StringToDouble( | 494 return StringToDouble( |
| 495 unicode_cache, flat.ToOneByteVector(), flags, empty_string_val); | 495 unicode_cache, flat.ToOneByteVector(), flags, empty_string_val); |
| 496 } else { | 496 } else { |
| 497 return StringToDouble( | 497 return StringToDouble( |
| 498 unicode_cache, flat.ToUC16Vector(), flags, empty_string_val); | 498 unicode_cache, flat.ToUC16Vector(), flags, empty_string_val); |
| 499 } | 499 } |
| 500 } | 500 } |
| 501 | 501 |
| 502 | 502 |
| 503 } } // namespace v8::internal | 503 } } // namespace v8::internal |
| OLD | NEW |