| 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 30 matching lines...) Expand all Loading... |
| 41 int HexValue(uc32 c) { | 41 int HexValue(uc32 c) { |
| 42 if ('0' <= c && c <= '9') | 42 if ('0' <= c && c <= '9') |
| 43 return c - '0'; | 43 return c - '0'; |
| 44 if ('a' <= c && c <= 'f') | 44 if ('a' <= c && c <= 'f') |
| 45 return c - 'a' + 10; | 45 return c - 'a' + 10; |
| 46 if ('A' <= c && c <= 'F') | 46 if ('A' <= c && c <= 'F') |
| 47 return c - 'A' + 10; | 47 return c - 'A' + 10; |
| 48 return -1; | 48 return -1; |
| 49 } | 49 } |
| 50 | 50 |
| 51 |
| 52 // Provide a common interface to getting a character at a certain |
| 53 // index from a char* or a String object. |
| 54 static inline int GetChar(const char* str, int index) { |
| 55 ASSERT(index >= 0 && index < StrLength(str)); |
| 56 return str[index]; |
| 57 } |
| 58 |
| 59 |
| 60 static inline int GetChar(String* str, int index) { |
| 61 return str->Get(index); |
| 62 } |
| 63 |
| 64 |
| 65 static inline int GetLength(const char* str) { |
| 66 return StrLength(str); |
| 67 } |
| 68 |
| 69 |
| 70 static inline int GetLength(String* str) { |
| 71 return str->length(); |
| 72 } |
| 73 |
| 74 |
| 75 static inline const char* GetCString(const char* str, int index) { |
| 76 return str + index; |
| 77 } |
| 78 |
| 79 |
| 80 static inline const char* GetCString(String* str, int index) { |
| 81 int length = str->length(); |
| 82 char* result = NewArray<char>(length + 1); |
| 83 for (int i = index; i < length; i++) { |
| 84 uc16 c = str->Get(i); |
| 85 if (c <= 127) { |
| 86 result[i - index] = static_cast<char>(c); |
| 87 } else { |
| 88 result[i - index] = 127; // Force number parsing to fail. |
| 89 } |
| 90 } |
| 91 result[length - index] = '\0'; |
| 92 return result; |
| 93 } |
| 94 |
| 95 |
| 51 namespace { | 96 namespace { |
| 52 | 97 |
| 53 // C++-style iterator adaptor for StringInputBuffer | 98 // C++-style iterator adaptor for StringInputBuffer |
| 54 // (unlike C++ iterators the end-marker has different type). | 99 // (unlike C++ iterators the end-marker has different type). |
| 55 class StringInputBufferIterator { | 100 class StringInputBufferIterator { |
| 56 public: | 101 public: |
| 57 class EndMarker {}; | 102 class EndMarker {}; |
| 58 | 103 |
| 59 explicit StringInputBufferIterator(StringInputBuffer* buffer); | 104 explicit StringInputBufferIterator(StringInputBuffer* buffer); |
| 60 | 105 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 82 | 127 |
| 83 void StringInputBufferIterator::operator++() { | 128 void StringInputBufferIterator::operator++() { |
| 84 end_ = !buffer_->has_more(); | 129 end_ = !buffer_->has_more(); |
| 85 if (!end_) { | 130 if (!end_) { |
| 86 current_ = buffer_->GetNext(); | 131 current_ = buffer_->GetNext(); |
| 87 } | 132 } |
| 88 } | 133 } |
| 89 } | 134 } |
| 90 | 135 |
| 91 | 136 |
| 137 static inline void ReleaseCString(const char* original, const char* str) { |
| 138 } |
| 139 |
| 140 |
| 141 static inline void ReleaseCString(String* original, const char* str) { |
| 142 DeleteArray(const_cast<char *>(str)); |
| 143 } |
| 144 |
| 145 |
| 92 template <class Iterator, class EndMark> | 146 template <class Iterator, class EndMark> |
| 93 static bool SubStringEquals(Iterator* current, | 147 static bool SubStringEquals(Iterator* current, |
| 94 EndMark end, | 148 EndMark end, |
| 95 const char* substring) { | 149 const char* substring) { |
| 96 ASSERT(**current == *substring); | 150 ASSERT(**current == *substring); |
| 97 for (substring++; *substring != '\0'; substring++) { | 151 for (substring++; *substring != '\0'; substring++) { |
| 98 ++*current; | 152 ++*current; |
| 99 if (*current == end || **current != *substring) return false; | 153 if (*current == end || **current != *substring) return false; |
| 100 } | 154 } |
| 101 ++*current; | 155 ++*current; |
| 102 return true; | 156 return true; |
| 103 } | 157 } |
| 104 | 158 |
| 105 | 159 |
| 106 extern "C" double gay_strtod(const char* s00, const char** se); | 160 extern "C" double gay_strtod(const char* s00, const char** se); |
| 107 | 161 |
| 108 // Maximum number of significant digits in decimal representation. | 162 // Maximum number of significant digits in decimal representation. |
| 109 // The longest possible double in decimal representation is | 163 // The longest possible double in decimal representation is |
| 110 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 | 164 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 |
| 111 // (768 digits). If we parse a number whose first digits are equal to a | 165 // (768 digits). If we parse a number whose first digits are equal to a |
| 112 // mean of 2 adjacent doubles (that could have up to 769 digits) the result | 166 // mean of 2 adjacent doubles (that could have up to 769 digits) the result |
| 113 // must be rounded to the bigger one unless the tail consists of zeros, so | 167 // must be rounded to the bigger one unless the tail consists of zeros, so |
| 114 // we don't need to preserve all the digits. | 168 // we don't need to preserve all the digits. |
| 115 const int kMaxSignificantDigits = 772; | 169 const int kMaxSignificantDigits = 772; |
| 116 | 170 |
| 171 // Parse an int from a string starting a given index and in a given |
| 172 // radix. The string can be either a char* or a String*. |
| 173 template <class S> |
| 174 static int InternalStringToInt(S* s, int i, int radix, double* value) { |
| 175 int len = GetLength(s); |
| 176 |
| 177 // Setup limits for computing the value. |
| 178 ASSERT(2 <= radix && radix <= 36); |
| 179 int lim_0 = '0' + (radix < 10 ? radix : 10); |
| 180 int lim_a = 'a' + (radix - 10); |
| 181 int lim_A = 'A' + (radix - 10); |
| 182 |
| 183 // NOTE: The code for computing the value may seem a bit complex at |
| 184 // first glance. It is structured to use 32-bit multiply-and-add |
| 185 // loops as long as possible to avoid loosing precision. |
| 186 |
| 187 double v = 0.0; |
| 188 int j; |
| 189 for (j = i; j < len;) { |
| 190 // Parse the longest part of the string starting at index j |
| 191 // possible while keeping the multiplier, and thus the part |
| 192 // itself, within 32 bits. |
| 193 uint32_t part = 0, multiplier = 1; |
| 194 int k; |
| 195 for (k = j; k < len; k++) { |
| 196 int c = GetChar(s, k); |
| 197 if (c >= '0' && c < lim_0) { |
| 198 c = c - '0'; |
| 199 } else if (c >= 'a' && c < lim_a) { |
| 200 c = c - 'a' + 10; |
| 201 } else if (c >= 'A' && c < lim_A) { |
| 202 c = c - 'A' + 10; |
| 203 } else { |
| 204 break; |
| 205 } |
| 206 |
| 207 // Update the value of the part as long as the multiplier fits |
| 208 // in 32 bits. When we can't guarantee that the next iteration |
| 209 // will not overflow the multiplier, we stop parsing the part |
| 210 // by leaving the loop. |
| 211 static const uint32_t kMaximumMultiplier = 0xffffffffU / 36; |
| 212 uint32_t m = multiplier * radix; |
| 213 if (m > kMaximumMultiplier) break; |
| 214 part = part * radix + c; |
| 215 multiplier = m; |
| 216 ASSERT(multiplier > part); |
| 217 } |
| 218 |
| 219 // Compute the number of part digits. If no digits were parsed; |
| 220 // we're done parsing the entire string. |
| 221 int digits = k - j; |
| 222 if (digits == 0) break; |
| 223 |
| 224 // Update the value and skip the part in the string. |
| 225 ASSERT(multiplier == |
| 226 pow(static_cast<double>(radix), static_cast<double>(digits))); |
| 227 v = v * multiplier + part; |
| 228 j = k; |
| 229 } |
| 230 |
| 231 // If the resulting value is larger than 2^53 the value does not fit |
| 232 // in the mantissa of the double and there is a loss of precision. |
| 233 // When the value is larger than 2^53 the rounding depends on the |
| 234 // code generation. If the code generator spills the double value |
| 235 // it uses 64 bits and if it does not it uses 80 bits. |
| 236 // |
| 237 // If there is a potential for overflow we resort to strtod for |
| 238 // radix 10 numbers to get higher precision. For numbers in another |
| 239 // radix we live with the loss of precision. |
| 240 static const double kPreciseConversionLimit = 9007199254740992.0; |
| 241 if (radix == 10 && v > kPreciseConversionLimit) { |
| 242 const char* cstr = GetCString(s, i); |
| 243 const char* end; |
| 244 v = gay_strtod(cstr, &end); |
| 245 ReleaseCString(s, cstr); |
| 246 } |
| 247 |
| 248 *value = v; |
| 249 return j; |
| 250 } |
| 251 |
| 252 |
| 253 int StringToInt(String* str, int index, int radix, double* value) { |
| 254 return InternalStringToInt(str, index, radix, value); |
| 255 } |
| 256 |
| 257 |
| 258 int StringToInt(const char* str, int index, int radix, double* value) { |
| 259 return InternalStringToInt(const_cast<char*>(str), index, radix, value); |
| 260 } |
| 261 |
| 117 | 262 |
| 118 static const double JUNK_STRING_VALUE = OS::nan_value(); | 263 static const double JUNK_STRING_VALUE = OS::nan_value(); |
| 119 | 264 |
| 120 | 265 |
| 121 // Returns true if a nonspace found and false if the end has reached. | 266 // Returns true if a nonspace found and false if the end has reached. |
| 122 template <class Iterator, class EndMark> | 267 template <class Iterator, class EndMark> |
| 123 static inline bool AdvanceToNonspace(Iterator* current, EndMark end) { | 268 static inline bool AdvanceToNonspace(Iterator* current, EndMark end) { |
| 124 while (*current != end) { | 269 while (*current != end) { |
| 125 if (!Scanner::kIsWhiteSpace.get(**current)) return true; | 270 if (!Scanner::kIsWhiteSpace.get(**current)) return true; |
| 126 ++*current; | 271 ++*current; |
| 127 } | 272 } |
| 128 return false; | 273 return false; |
| 129 } | 274 } |
| 130 | 275 |
| 131 | 276 |
| 132 static bool isDigit(int x, int radix) { | 277 static bool isDigit(int x, int radix) { |
| 133 return (x >= '0' && x <= '9' && x < '0' + radix) | 278 return (x >= '0' && x <= '9' && x < '0' + radix) |
| 134 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) | 279 || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) |
| 135 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); | 280 || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); |
| 136 } | 281 } |
| 137 | 282 |
| 138 | 283 |
| 139 static double SignedZero(bool sign) { | |
| 140 return sign ? -0.0 : 0.0; | |
| 141 } | |
| 142 | |
| 143 | |
| 144 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. | 284 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. |
| 145 template <int radix_log_2, class Iterator, class EndMark> | 285 template <int radix_log_2, class Iterator, class EndMark> |
| 146 static double InternalStringToIntDouble(Iterator current, | 286 static double InternalStringToIntDouble(Iterator current, |
| 147 EndMark end, | 287 EndMark end, |
| 148 bool sign, | 288 bool sign, |
| 149 bool allow_trailing_junk) { | 289 bool allow_trailing_junk) { |
| 150 ASSERT(current != end); | 290 ASSERT(current != end); |
| 151 | 291 |
| 152 // Skip leading 0s. | 292 // Skip leading 0s. |
| 153 while (*current == '0') { | 293 while (*current == '0') { |
| 154 ++current; | 294 ++current; |
| 155 if (current == end) return SignedZero(sign); | 295 if (current == end) return sign ? -0.0 : 0.0; |
| 156 } | 296 } |
| 157 | 297 |
| 158 int64_t number = 0; | 298 int64_t number = 0; |
| 159 int exponent = 0; | 299 int exponent = 0; |
| 160 const int radix = (1 << radix_log_2); | 300 const int radix = (1 << radix_log_2); |
| 161 | 301 |
| 162 do { | 302 do { |
| 163 int digit; | 303 int digit; |
| 164 if (*current >= '0' && *current <= '9' && *current < '0' + radix) { | 304 if (*current >= '0' && *current <= '9' && *current < '0' + radix) { |
| 165 digit = static_cast<char>(*current) - '0'; | 305 digit = static_cast<char>(*current) - '0'; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 return static_cast<double>(number); | 375 return static_cast<double>(number); |
| 236 } | 376 } |
| 237 | 377 |
| 238 ASSERT(number != 0); | 378 ASSERT(number != 0); |
| 239 // The double could be constructed faster from number (mantissa), exponent | 379 // The double could be constructed faster from number (mantissa), exponent |
| 240 // and sign. Assuming it's a rare case more simple code is used. | 380 // and sign. Assuming it's a rare case more simple code is used. |
| 241 return static_cast<double>(sign ? -number : number) * pow(2.0, exponent); | 381 return static_cast<double>(sign ? -number : number) * pow(2.0, exponent); |
| 242 } | 382 } |
| 243 | 383 |
| 244 | 384 |
| 245 template <class Iterator, class EndMark> | |
| 246 static double InternalStringToInt(Iterator current, EndMark end, int radix) { | |
| 247 const bool allow_trailing_junk = true; | |
| 248 const double empty_string_val = JUNK_STRING_VALUE; | |
| 249 | |
| 250 if (!AdvanceToNonspace(¤t, end)) return empty_string_val; | |
| 251 | |
| 252 bool sign = false; | |
| 253 bool leading_zero = false; | |
| 254 | |
| 255 if (*current == '+') { | |
| 256 // Ignore leading sign; skip following spaces. | |
| 257 ++current; | |
| 258 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; | |
| 259 } else if (*current == '-') { | |
| 260 ++current; | |
| 261 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; | |
| 262 sign = true; | |
| 263 } | |
| 264 | |
| 265 if (radix == 0) { | |
| 266 // Radix detection. | |
| 267 if (*current == '0') { | |
| 268 ++current; | |
| 269 if (current == end) return SignedZero(sign); | |
| 270 if (*current == 'x' || *current == 'X') { | |
| 271 radix = 16; | |
| 272 ++current; | |
| 273 if (current == end) return JUNK_STRING_VALUE; | |
| 274 } else { | |
| 275 radix = 8; | |
| 276 leading_zero = true; | |
| 277 } | |
| 278 } else { | |
| 279 radix = 10; | |
| 280 } | |
| 281 } else if (radix == 16) { | |
| 282 if (*current == '0') { | |
| 283 // Allow "0x" prefix. | |
| 284 ++current; | |
| 285 if (current == end) return SignedZero(sign); | |
| 286 if (*current == 'x' || *current == 'X') { | |
| 287 ++current; | |
| 288 if (current == end) return JUNK_STRING_VALUE; | |
| 289 } else { | |
| 290 leading_zero = true; | |
| 291 } | |
| 292 } | |
| 293 } | |
| 294 | |
| 295 if (radix < 2 || radix > 36) return JUNK_STRING_VALUE; | |
| 296 | |
| 297 // Skip leading zeros. | |
| 298 while (*current == '0') { | |
| 299 leading_zero = true; | |
| 300 ++current; | |
| 301 if (current == end) return SignedZero(sign); | |
| 302 } | |
| 303 | |
| 304 if (!leading_zero && !isDigit(*current, radix)) { | |
| 305 return JUNK_STRING_VALUE; | |
| 306 } | |
| 307 | |
| 308 if (IsPowerOf2(radix)) { | |
| 309 switch (radix) { | |
| 310 case 2: | |
| 311 return InternalStringToIntDouble<1>( | |
| 312 current, end, sign, allow_trailing_junk); | |
| 313 case 4: | |
| 314 return InternalStringToIntDouble<2>( | |
| 315 current, end, sign, allow_trailing_junk); | |
| 316 case 8: | |
| 317 return InternalStringToIntDouble<3>( | |
| 318 current, end, sign, allow_trailing_junk); | |
| 319 | |
| 320 case 16: | |
| 321 return InternalStringToIntDouble<4>( | |
| 322 current, end, sign, allow_trailing_junk); | |
| 323 | |
| 324 case 32: | |
| 325 return InternalStringToIntDouble<5>( | |
| 326 current, end, sign, allow_trailing_junk); | |
| 327 default: | |
| 328 UNREACHABLE(); | |
| 329 } | |
| 330 } | |
| 331 | |
| 332 if (radix == 10) { | |
| 333 // Parsing with strtod. | |
| 334 const int kMaxSignificantDigits = 308; // Doubles are less than 1.8e308. | |
| 335 // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero | |
| 336 // end. | |
| 337 const int kBufferSize = kMaxSignificantDigits + 2; | |
| 338 char buffer[kBufferSize]; | |
| 339 int buffer_pos = 0; | |
| 340 while (*current >= '0' && *current <= '9') { | |
| 341 if (buffer_pos <= kMaxSignificantDigits) { | |
| 342 // If the number has more than kMaxSignificantDigits it will be parsed | |
| 343 // as infinity. | |
| 344 ASSERT(buffer_pos < kBufferSize); | |
| 345 buffer[buffer_pos++] = static_cast<char>(*current); | |
| 346 } | |
| 347 ++current; | |
| 348 if (current == end) break; | |
| 349 } | |
| 350 | |
| 351 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | |
| 352 return JUNK_STRING_VALUE; | |
| 353 } | |
| 354 | |
| 355 ASSERT(buffer_pos < kBufferSize); | |
| 356 buffer[buffer_pos++] = '\0'; | |
| 357 return sign ? -gay_strtod(buffer, NULL) : gay_strtod(buffer, NULL); | |
| 358 } | |
| 359 | |
| 360 // TODO(serya): The following legacy code causes accumulating rounding | |
| 361 // error for number greater than ~2^56. It should be rewritten using long | |
| 362 // arithmetic. | |
| 363 | |
| 364 int lim_0 = '0' + (radix < 10 ? radix : 10); | |
| 365 int lim_a = 'a' + (radix - 10); | |
| 366 int lim_A = 'A' + (radix - 10); | |
| 367 | |
| 368 // NOTE: The code for computing the value may seem a bit complex at | |
| 369 // first glance. It is structured to use 32-bit multiply-and-add | |
| 370 // loops as long as possible to avoid loosing precision. | |
| 371 | |
| 372 double v = 0.0; | |
| 373 bool done = false; | |
| 374 do { | |
| 375 // Parse the longest part of the string starting at index j | |
| 376 // possible while keeping the multiplier, and thus the part | |
| 377 // itself, within 32 bits. | |
| 378 unsigned int part = 0, multiplier = 1; | |
| 379 while (true) { | |
| 380 int d; | |
| 381 if (*current >= '0' && *current < lim_0) { | |
| 382 d = *current - '0'; | |
| 383 } else if (*current >= 'a' && *current < lim_a) { | |
| 384 d = *current - 'a' + 10; | |
| 385 } else if (*current >= 'A' && *current < lim_A) { | |
| 386 d = *current - 'A' + 10; | |
| 387 } else { | |
| 388 done = true; | |
| 389 break; | |
| 390 } | |
| 391 | |
| 392 // Update the value of the part as long as the multiplier fits | |
| 393 // in 32 bits. When we can't guarantee that the next iteration | |
| 394 // will not overflow the multiplier, we stop parsing the part | |
| 395 // by leaving the loop. | |
| 396 const unsigned int kMaximumMultiplier = 0xffffffffU / 36; | |
| 397 uint32_t m = multiplier * radix; | |
| 398 if (m > kMaximumMultiplier) break; | |
| 399 part = part * radix + d; | |
| 400 multiplier = m; | |
| 401 ASSERT(multiplier > part); | |
| 402 | |
| 403 ++current; | |
| 404 if (current == end) { | |
| 405 done = true; | |
| 406 break; | |
| 407 } | |
| 408 } | |
| 409 | |
| 410 // Update the value and skip the part in the string. | |
| 411 v = v * multiplier + part; | |
| 412 } while (!done); | |
| 413 | |
| 414 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | |
| 415 return JUNK_STRING_VALUE; | |
| 416 } | |
| 417 | |
| 418 return sign ? -v : v; | |
| 419 } | |
| 420 | |
| 421 | |
| 422 // Converts a string to a double value. Assumes the Iterator supports | 385 // Converts a string to a double value. Assumes the Iterator supports |
| 423 // the following operations: | 386 // the following operations: |
| 424 // 1. current == end (other ops are not allowed), current != end. | 387 // 1. current == end (other ops are not allowed), current != end. |
| 425 // 2. *current - gets the current character in the sequence. | 388 // 2. *current - gets the current character in the sequence. |
| 426 // 3. ++current (advances the position). | 389 // 3. ++current (advances the position). |
| 427 template <class Iterator, class EndMark> | 390 template <class Iterator, class EndMark> |
| 428 static double InternalStringToDouble(Iterator current, | 391 static double InternalStringToDouble(Iterator current, |
| 429 EndMark end, | 392 EndMark end, |
| 430 int flags, | 393 int flags, |
| 431 double empty_string_val) { | 394 double empty_string_val) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 447 int buffer_pos = 0; | 410 int buffer_pos = 0; |
| 448 | 411 |
| 449 // Exponent will be adjusted if insignificant digits of the integer part | 412 // Exponent will be adjusted if insignificant digits of the integer part |
| 450 // or insignificant leading zeros of the fractional part are dropped. | 413 // or insignificant leading zeros of the fractional part are dropped. |
| 451 int exponent = 0; | 414 int exponent = 0; |
| 452 int significant_digits = 0; | 415 int significant_digits = 0; |
| 453 int insignificant_digits = 0; | 416 int insignificant_digits = 0; |
| 454 bool nonzero_digit_dropped = false; | 417 bool nonzero_digit_dropped = false; |
| 455 bool fractional_part = false; | 418 bool fractional_part = false; |
| 456 | 419 |
| 457 bool sign = false; | 420 double signed_zero = 0.0; |
| 458 | 421 |
| 459 if (*current == '+') { | 422 if (*current == '+') { |
| 460 // Ignore leading sign; skip following spaces. | 423 // Ignore leading sign; skip following spaces. |
| 461 ++current; | 424 ++current; |
| 462 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; | 425 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; |
| 463 } else if (*current == '-') { | 426 } else if (*current == '-') { |
| 464 buffer[buffer_pos++] = '-'; | 427 buffer[buffer_pos++] = '-'; |
| 465 ++current; | 428 ++current; |
| 466 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; | 429 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; |
| 467 sign = true; | 430 signed_zero = -0.0; |
| 468 } | 431 } |
| 469 | 432 |
| 470 static const char kInfinitySymbol[] = "Infinity"; | 433 static const char kInfinitySymbol[] = "Infinity"; |
| 471 if (*current == kInfinitySymbol[0]) { | 434 if (*current == kInfinitySymbol[0]) { |
| 472 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { | 435 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { |
| 473 return JUNK_STRING_VALUE; | 436 return JUNK_STRING_VALUE; |
| 474 } | 437 } |
| 475 | 438 |
| 476 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 439 if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
| 477 return JUNK_STRING_VALUE; | 440 return JUNK_STRING_VALUE; |
| 478 } | 441 } |
| 479 | 442 |
| 480 ASSERT(buffer_pos == 0 || buffer[0] == '-'); | 443 ASSERT(buffer_pos == 0 || buffer[0] == '-'); |
| 481 return buffer_pos > 0 ? -V8_INFINITY : V8_INFINITY; | 444 return buffer_pos > 0 ? -V8_INFINITY : V8_INFINITY; |
| 482 } | 445 } |
| 483 | 446 |
| 484 bool leading_zero = false; | 447 bool leading_zero = false; |
| 485 if (*current == '0') { | 448 if (*current == '0') { |
| 486 ++current; | 449 ++current; |
| 487 if (current == end) return SignedZero(sign); | 450 if (current == end) return signed_zero; |
| 488 | 451 |
| 489 leading_zero = true; | 452 leading_zero = true; |
| 490 | 453 |
| 491 // It could be hexadecimal value. | 454 // It could be hexadecimal value. |
| 492 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 455 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { |
| 493 ++current; | 456 ++current; |
| 494 if (current == end) return JUNK_STRING_VALUE; // "0x". | 457 if (current == end) return JUNK_STRING_VALUE; // "0x". |
| 495 | 458 |
| 496 bool sign = (buffer_pos > 0 && buffer[0] == '-'); | 459 bool sign = (buffer_pos > 0 && buffer[0] == '-'); |
| 497 return InternalStringToIntDouble<4>(current, | 460 return InternalStringToIntDouble<4>(current, |
| 498 end, | 461 end, |
| 499 sign, | 462 sign, |
| 500 allow_trailing_junk); | 463 allow_trailing_junk); |
| 501 } | 464 } |
| 502 | 465 |
| 503 // Ignore leading zeros in the integer part. | 466 // Ignore leading zeros in the integer part. |
| 504 while (*current == '0') { | 467 while (*current == '0') { |
| 505 ++current; | 468 ++current; |
| 506 if (current == end) return SignedZero(sign); | 469 if (current == end) return signed_zero; |
| 507 } | 470 } |
| 508 } | 471 } |
| 509 | 472 |
| 510 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; | 473 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; |
| 511 | 474 |
| 512 // Copy significant digits of the integer part (if any) to the buffer. | 475 // Copy significant digits of the integer part (if any) to the buffer. |
| 513 while (*current >= '0' && *current <= '9') { | 476 while (*current >= '0' && *current <= '9') { |
| 514 if (significant_digits < kMaxSignificantDigits) { | 477 if (significant_digits < kMaxSignificantDigits) { |
| 515 ASSERT(buffer_pos < kBufferSize); | 478 ASSERT(buffer_pos < kBufferSize); |
| 516 buffer[buffer_pos++] = static_cast<char>(*current); | 479 buffer[buffer_pos++] = static_cast<char>(*current); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 538 goto parsing_done; | 501 goto parsing_done; |
| 539 } | 502 } |
| 540 } | 503 } |
| 541 | 504 |
| 542 if (significant_digits == 0) { | 505 if (significant_digits == 0) { |
| 543 // octal = false; | 506 // octal = false; |
| 544 // Integer part consists of 0 or is absent. Significant digits start after | 507 // Integer part consists of 0 or is absent. Significant digits start after |
| 545 // leading zeros (if any). | 508 // leading zeros (if any). |
| 546 while (*current == '0') { | 509 while (*current == '0') { |
| 547 ++current; | 510 ++current; |
| 548 if (current == end) return SignedZero(sign); | 511 if (current == end) return signed_zero; |
| 549 exponent--; // Move this 0 into the exponent. | 512 exponent--; // Move this 0 into the exponent. |
| 550 } | 513 } |
| 551 } | 514 } |
| 552 | 515 |
| 553 ASSERT(buffer_pos < kBufferSize); | 516 ASSERT(buffer_pos < kBufferSize); |
| 554 buffer[buffer_pos++] = '.'; | 517 buffer[buffer_pos++] = '.'; |
| 555 fractional_part = true; | 518 fractional_part = true; |
| 556 | 519 |
| 557 // There is the fractional part. | 520 // There is the fractional part. |
| 558 while (*current >= '0' && *current <= '9') { | 521 while (*current >= '0' && *current <= '9') { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 if (exponent > 999) exponent = 999; // Result will be Infinity or 0 or -0. | 628 if (exponent > 999) exponent = 999; // Result will be Infinity or 0 or -0. |
| 666 | 629 |
| 667 const int exp_digits = 3; | 630 const int exp_digits = 3; |
| 668 for (int i = 0; i < exp_digits; i++) { | 631 for (int i = 0; i < exp_digits; i++) { |
| 669 buffer[buffer_pos + exp_digits - 1 - i] = '0' + exponent % 10; | 632 buffer[buffer_pos + exp_digits - 1 - i] = '0' + exponent % 10; |
| 670 exponent /= 10; | 633 exponent /= 10; |
| 671 } | 634 } |
| 672 ASSERT(exponent == 0); | 635 ASSERT(exponent == 0); |
| 673 buffer_pos += exp_digits; | 636 buffer_pos += exp_digits; |
| 674 } else if (!fractional_part && significant_digits <= kMaxDigitsInInt) { | 637 } else if (!fractional_part && significant_digits <= kMaxDigitsInInt) { |
| 675 if (significant_digits == 0) return SignedZero(sign); | 638 if (significant_digits == 0) return signed_zero; |
| 676 ASSERT(buffer_pos > 0); | 639 ASSERT(buffer_pos > 0); |
| 677 int num = 0; | 640 int num = 0; |
| 678 int start_pos = (buffer[0] == '-' ? 1 : 0); | 641 int start_pos = (buffer[0] == '-' ? 1 : 0); |
| 679 for (int i = start_pos; i < buffer_pos; i++) { | 642 for (int i = start_pos; i < buffer_pos; i++) { |
| 680 ASSERT(buffer[i] >= '0' && buffer[i] <= '9'); | 643 ASSERT(buffer[i] >= '0' && buffer[i] <= '9'); |
| 681 num = 10 * num + (buffer[i] - '0'); | 644 num = 10 * num + (buffer[i] - '0'); |
| 682 } | 645 } |
| 683 return static_cast<double>(start_pos == 0 ? num : -num); | 646 return static_cast<double>(start_pos == 0 ? num : -num); |
| 684 } | 647 } |
| 685 | 648 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 702 } else { | 665 } else { |
| 703 StringInputBuffer buffer(str); | 666 StringInputBuffer buffer(str); |
| 704 return InternalStringToDouble(StringInputBufferIterator(&buffer), | 667 return InternalStringToDouble(StringInputBufferIterator(&buffer), |
| 705 StringInputBufferIterator::EndMarker(), | 668 StringInputBufferIterator::EndMarker(), |
| 706 flags, | 669 flags, |
| 707 empty_string_val); | 670 empty_string_val); |
| 708 } | 671 } |
| 709 } | 672 } |
| 710 | 673 |
| 711 | 674 |
| 712 double StringToInt(String* str, int radix) { | |
| 713 StringShape shape(str); | |
| 714 if (shape.IsSequentialAscii()) { | |
| 715 const char* begin = SeqAsciiString::cast(str)->GetChars(); | |
| 716 const char* end = begin + str->length(); | |
| 717 return InternalStringToInt(begin, end, radix); | |
| 718 } else if (shape.IsSequentialTwoByte()) { | |
| 719 const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); | |
| 720 const uc16* end = begin + str->length(); | |
| 721 return InternalStringToInt(begin, end, radix); | |
| 722 } else { | |
| 723 StringInputBuffer buffer(str); | |
| 724 return InternalStringToInt(StringInputBufferIterator(&buffer), | |
| 725 StringInputBufferIterator::EndMarker(), | |
| 726 radix); | |
| 727 } | |
| 728 } | |
| 729 | |
| 730 | |
| 731 double StringToDouble(const char* str, int flags, double empty_string_val) { | 675 double StringToDouble(const char* str, int flags, double empty_string_val) { |
| 732 const char* end = str + StrLength(str); | 676 const char* end = str + StrLength(str); |
| 733 | 677 |
| 734 return InternalStringToDouble(str, end, flags, empty_string_val); | 678 return InternalStringToDouble(str, end, flags, empty_string_val); |
| 735 } | 679 } |
| 736 | 680 |
| 737 | 681 |
| 738 extern "C" char* dtoa(double d, int mode, int ndigits, | 682 extern "C" char* dtoa(double d, int mode, int ndigits, |
| 739 int* decpt, int* sign, char** rve); | 683 int* decpt, int* sign, char** rve); |
| 740 | 684 |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 // Allocate result and fill in the parts. | 1035 // Allocate result and fill in the parts. |
| 1092 StringBuilder builder(result_size + 1); | 1036 StringBuilder builder(result_size + 1); |
| 1093 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); | 1037 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); |
| 1094 if (decimal_pos > 0) builder.AddCharacter('.'); | 1038 if (decimal_pos > 0) builder.AddCharacter('.'); |
| 1095 builder.AddSubstring(decimal_buffer, decimal_pos); | 1039 builder.AddSubstring(decimal_buffer, decimal_pos); |
| 1096 return builder.Finalize(); | 1040 return builder.Finalize(); |
| 1097 } | 1041 } |
| 1098 | 1042 |
| 1099 | 1043 |
| 1100 } } // namespace v8::internal | 1044 } } // namespace v8::internal |
| OLD | NEW |