Index: src/conversions.cc |
diff --git a/src/conversions.cc b/src/conversions.cc |
index 663f4e8dec254c4126142dc2b5e628e5a8aad97c..6ec97504fcc1765ef3ea9eab7f1a416e2e0284cb 100644 |
--- a/src/conversions.cc |
+++ b/src/conversions.cc |
@@ -9,6 +9,7 @@ |
#include "src/v8.h" |
#include "src/assert-scope.h" |
+#include "src/char-predicates-inl.h" |
#include "src/conversions-inl.h" |
#include "src/conversions.h" |
#include "src/dtoa.h" |
@@ -502,4 +503,47 @@ double StringToDouble(UnicodeCache* unicode_cache, Handle<String> string, |
} |
+bool IsNonArrayIndexInteger(String* string) { |
+ const int kBufferSize = 64; |
+ const int kUint32MaxChars = 11; |
+ uint16_t buffer[kBufferSize]; |
+ int offset = 0; |
+ const int length = string->length(); |
+ DCHECK_NE(0, length); |
+ // First iteration, check for minus, 0 followed by anything else, etc. |
+ { |
+ int to = std::min(offset + kUint32MaxChars, length); |
+ String::WriteToFlat(string, buffer, offset, to); |
+ bool negative = false; |
+ if (buffer[offset] == '-') { |
+ negative = true; |
+ ++offset; |
+ if (offset == to) return false; // Just '-' is bad. |
+ } |
+ if (buffer[offset] == '0') { |
+ ++offset; |
+ return offset == 2 && offset == to; // Match just '-0'. |
Toon Verwaest
2015/03/10 14:26:09
Quite some boilerplate pretending to be in a loop
|
+ } |
+ uint64_t acc = 0; |
Toon Verwaest
2015/03/10 14:26:10
Wrap the entire "fast-path" into
if (!negative) {.
|
+ for (; offset < to; ++offset) { |
+ uint64_t digit = buffer[offset] - '0'; |
+ if (digit > 9) return false; |
+ acc = 10 * acc + digit; |
+ } |
+ // String is consumed. Evaluate what we have. |
+ if (offset == length) { |
+ if (negative) return true; |
+ return acc > static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()); |
+ } |
+ } |
+ // Consume rest of string. If we get here, we're way out of uint32_t bounds. |
+ while (offset != length) { |
+ int to = std::min(offset + kBufferSize, length); |
+ String::WriteToFlat(string, buffer, offset, to); |
+ for (; offset < to; ++offset) { |
+ if (!IsDecimalDigit(buffer[offset])) return false; |
+ } |
+ } |
+ return true; |
+} |
} } // namespace v8::internal |