Index: src/objects-inl.h |
diff --git a/src/objects-inl.h b/src/objects-inl.h |
index 5aea3b5106bc741386914a21207499ff6471d5c3..6ae80124c9d3a2839bdc7b50096ddd7d9649c9f0 100644 |
--- a/src/objects-inl.h |
+++ b/src/objects-inl.h |
@@ -3130,96 +3130,60 @@ String* String::GetUnderlying() { |
} |
-template<class Visitor, class ConsOp> |
-void String::Visit( |
- String* string, |
- unsigned offset, |
- Visitor& visitor, |
- ConsOp& cons_op, |
- int32_t type, |
- unsigned length) { |
- ASSERT(length == static_cast<unsigned>(string->length())); |
+template<class Visitor> |
+ConsString* String::VisitFlat(Visitor* visitor, |
+ String* string, |
+ const int offset) { |
+ int slice_offset = offset; |
+ const int length = string->length(); |
ASSERT(offset <= length); |
- unsigned slice_offset = offset; |
while (true) { |
- ASSERT(type == string->map()->instance_type()); |
- |
+ int32_t type = string->map()->instance_type(); |
switch (type & (kStringRepresentationMask | kStringEncodingMask)) { |
case kSeqStringTag | kOneByteStringTag: |
- visitor.VisitOneByteString( |
+ visitor->VisitOneByteString( |
SeqOneByteString::cast(string)->GetChars() + slice_offset, |
length - offset); |
- return; |
+ return NULL; |
case kSeqStringTag | kTwoByteStringTag: |
- visitor.VisitTwoByteString( |
+ visitor->VisitTwoByteString( |
SeqTwoByteString::cast(string)->GetChars() + slice_offset, |
length - offset); |
- return; |
+ return NULL; |
case kExternalStringTag | kOneByteStringTag: |
- visitor.VisitOneByteString( |
+ visitor->VisitOneByteString( |
ExternalAsciiString::cast(string)->GetChars() + slice_offset, |
length - offset); |
- return; |
+ return NULL; |
case kExternalStringTag | kTwoByteStringTag: |
- visitor.VisitTwoByteString( |
+ visitor->VisitTwoByteString( |
ExternalTwoByteString::cast(string)->GetChars() + slice_offset, |
length - offset); |
- return; |
+ return NULL; |
case kSlicedStringTag | kOneByteStringTag: |
case kSlicedStringTag | kTwoByteStringTag: { |
SlicedString* slicedString = SlicedString::cast(string); |
slice_offset += slicedString->offset(); |
string = slicedString->parent(); |
- type = string->map()->instance_type(); |
continue; |
} |
case kConsStringTag | kOneByteStringTag: |
case kConsStringTag | kTwoByteStringTag: |
- string = cons_op.Operate(string, &offset, &type, &length); |
- if (string == NULL) return; |
- slice_offset = offset; |
- ASSERT(length == static_cast<unsigned>(string->length())); |
- continue; |
+ return ConsString::cast(string); |
default: |
UNREACHABLE(); |
- return; |
+ return NULL; |
} |
} |
} |
-// TODO(dcarney): Remove this class after conversion to VisitFlat. |
-class ConsStringCaptureOp { |
- public: |
- inline ConsStringCaptureOp() : cons_string_(NULL) {} |
- inline String* Operate(String* string, unsigned*, int32_t*, unsigned*) { |
- cons_string_ = ConsString::cast(string); |
- return NULL; |
- } |
- ConsString* cons_string_; |
-}; |
- |
- |
-template<class Visitor> |
-ConsString* String::VisitFlat(Visitor* visitor, |
- String* string, |
- int offset, |
- int length, |
- int32_t type) { |
- ASSERT(length >= 0 && length == string->length()); |
- ASSERT(offset >= 0 && offset <= length); |
- ConsStringCaptureOp op; |
- Visit(string, offset, *visitor, op, type, static_cast<unsigned>(length)); |
- return op.cons_string_; |
-} |
- |
- |
uint16_t SeqOneByteString::SeqOneByteStringGet(int index) { |
ASSERT(index >= 0 && index < length()); |
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); |
@@ -3399,12 +3363,7 @@ const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData( |
} |
-String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) { |
- return NULL; |
-} |
- |
- |
-unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) { |
+int ConsStringIteratorOp::OffsetForDepth(int depth) { |
return depth & kDepthMask; |
} |
@@ -3432,45 +3391,9 @@ void ConsStringIteratorOp::Pop() { |
} |
-bool ConsStringIteratorOp::HasMore() { |
- return depth_ != 0; |
-} |
- |
- |
-void ConsStringIteratorOp::Reset() { |
- depth_ = 0; |
-} |
- |
- |
-String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out, |
- unsigned* length_out) { |
- bool blew_stack = false; |
- String* string = NextLeaf(&blew_stack, type_out, length_out); |
- // String found. |
- if (string != NULL) { |
- // Verify output. |
- ASSERT(*length_out == static_cast<unsigned>(string->length())); |
- ASSERT(*type_out == string->map()->instance_type()); |
- return string; |
- } |
- // Traversal complete. |
- if (!blew_stack) return NULL; |
- // Restart search from root. |
- unsigned offset_out; |
- string = Search(&offset_out, type_out, length_out); |
- // Verify output. |
- ASSERT(string == NULL || offset_out == 0); |
- ASSERT(string == NULL || |
- *length_out == static_cast<unsigned>(string->length())); |
- ASSERT(string == NULL || *type_out == string->map()->instance_type()); |
- return string; |
-} |
- |
- |
uint16_t StringCharacterStream::GetNext() { |
ASSERT(buffer8_ != NULL && end_ != NULL); |
// Advance cursor if needed. |
- // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this. |
if (buffer8_ == end_) HasMore(); |
ASSERT(buffer8_ < end_); |
return is_one_byte_ ? *buffer8_++ : *buffer16_++; |
@@ -3479,41 +3402,39 @@ uint16_t StringCharacterStream::GetNext() { |
StringCharacterStream::StringCharacterStream(String* string, |
ConsStringIteratorOp* op, |
- unsigned offset) |
+ int offset) |
: is_one_byte_(false), |
op_(op) { |
Reset(string, offset); |
} |
-void StringCharacterStream::Reset(String* string, unsigned offset) { |
- op_->Reset(); |
+void StringCharacterStream::Reset(String* string, int offset) { |
buffer8_ = NULL; |
end_ = NULL; |
- int32_t type = string->map()->instance_type(); |
- unsigned length = string->length(); |
- String::Visit(string, offset, *this, *op_, type, length); |
+ ConsString* cons_string = String::VisitFlat(this, string, offset); |
+ op_->Reset(cons_string, offset); |
+ if (cons_string != NULL) { |
+ string = op_->Next(&offset); |
+ if (string != NULL) String::VisitFlat(this, string, offset); |
+ } |
} |
bool StringCharacterStream::HasMore() { |
if (buffer8_ != end_) return true; |
- if (!op_->HasMore()) return false; |
- unsigned length; |
- int32_t type; |
- String* string = op_->ContinueOperation(&type, &length); |
+ int offset; |
+ String* string = op_->Next(&offset); |
+ ASSERT_EQ(offset, 0); |
if (string == NULL) return false; |
- ASSERT(!string->IsConsString()); |
- ASSERT(string->length() != 0); |
- ConsStringNullOp null_op; |
- String::Visit(string, 0, *this, null_op, type, length); |
+ String::VisitFlat(this, string); |
ASSERT(buffer8_ != end_); |
return true; |
} |
void StringCharacterStream::VisitOneByteString( |
- const uint8_t* chars, unsigned length) { |
+ const uint8_t* chars, int length) { |
is_one_byte_ = true; |
buffer8_ = chars; |
end_ = chars + length; |
@@ -3521,7 +3442,7 @@ void StringCharacterStream::VisitOneByteString( |
void StringCharacterStream::VisitTwoByteString( |
- const uint16_t* chars, unsigned length) { |
+ const uint16_t* chars, int length) { |
is_one_byte_ = false; |
buffer16_ = chars; |
end_ = reinterpret_cast<const uint8_t*>(chars + length); |