Chromium Code Reviews| Index: src/api.cc |
| diff --git a/src/api.cc b/src/api.cc |
| index b2dc2e1e943abbd81efadccc18fb6ed5c5f1c299..07f34f78ccea044eeefd5a7ee1aaf1d2cfbdda85 100644 |
| --- a/src/api.cc |
| +++ b/src/api.cc |
| @@ -4304,6 +4304,84 @@ bool String::IsOneByte() const { |
| } |
| +class DefinitelyContainsOnlyOneByteHelper { |
| + public: |
| + DefinitelyContainsOnlyOneByteHelper() : is_one_byte_(true) {} |
| + bool Check(i::String* string) { |
| + i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); |
| + if (cons_string == NULL) return is_one_byte_; |
| + return CheckCons(cons_string); |
| + } |
| + void VisitOneByteString(const uint8_t* chars, int length) { |
| + // Nothing to do. |
| + } |
| + void VisitTwoByteString(const uint16_t* chars, int length) { |
| + for (int i = 0; i < length; i++) { |
| + if (chars[i] >> 8) { |
| + is_one_byte_ = false; |
| + return; |
| + } |
| + } |
| + } |
| + |
| + private: |
| + bool CheckCons(i::ConsString* cons_string) { |
| + while (true) { |
| + // Check left side if flat. |
| + i::String* left = cons_string->first(); |
| + i::ConsString* left_as_cons = |
| + i::String::VisitFlat(this, left, 0); |
| + if (!is_one_byte_) return false; |
| + // Check right side if flat. |
| + i::String* right = cons_string->second(); |
| + i::ConsString* right_as_cons = |
| + i::String::VisitFlat(this, right, 0); |
| + if (!is_one_byte_) return false; |
| + // Standard recurse/iterate trick. |
| + // Falls through to the cases below for the iteration. |
| + if (left_as_cons != NULL && right_as_cons != NULL) { |
| + if (left->length() < right->length()) { |
| + CheckCons(right_as_cons); |
| + right_as_cons = NULL; |
|
Yang
2013/06/06 09:12:59
I think it's a bit easier to read if you just set
dcarney
2013/06/06 09:17:26
okay
|
| + } else { |
| + CheckCons(left_as_cons); |
| + left_as_cons = NULL; |
| + } |
| + // Check fast return. |
| + if (!is_one_byte_) return false; |
| + } |
| + // Descend left in place. |
| + if (left_as_cons != NULL) { |
| + cons_string = left_as_cons; |
| + continue; |
| + } |
| + // Descend right in place. |
| + if (right_as_cons != NULL) { |
| + cons_string = right_as_cons; |
| + continue; |
| + } |
| + // Terminate. |
| + break; |
| + } |
| + return is_one_byte_; |
| + } |
| + bool is_one_byte_; |
| + DISALLOW_COPY_AND_ASSIGN(DefinitelyContainsOnlyOneByteHelper); |
| +}; |
| + |
| + |
| +bool String::DefinitelyContainsOnlyOneByte() const { |
| + i::Handle<i::String> str = Utils::OpenHandle(this); |
| + if (IsDeadCheck(str->GetIsolate(), |
| + "v8::String::DefinitelyContainsOnlyOneByte()")) { |
| + return false; |
| + } |
| + if (str->HasOnlyOneByteChars()) return true; |
| + DefinitelyContainsOnlyOneByteHelper helper; |
| + return helper.Check(*str); |
|
Yang
2013/06/06 09:12:59
If we find that the string only contains one byte
dcarney
2013/06/06 09:17:26
will do
|
| +} |
| + |
| + |
| class Utf8LengthHelper : public i::AllStatic { |
| public: |
| enum State { |