Index: src/objects.h |
diff --git a/src/objects.h b/src/objects.h |
index a3f1130e93e1eda28c3af24bc6cd8771a2632e2e..5404f8ab76a57efe41a0fcac086ff43e5d89b1ea 100644 |
--- a/src/objects.h |
+++ b/src/objects.h |
@@ -7505,6 +7505,14 @@ class String: public HeapObject { |
return NonAsciiStart(chars, length) >= length; |
} |
+ template<class Visitor, class ConsOp> |
+ static inline void Visit(String* string, |
+ unsigned offset, |
+ Visitor& visitor, |
+ ConsOp& consOp, |
+ int32_t type, |
+ unsigned length); |
+ |
protected: |
class ReadBlockBuffer { |
public: |
@@ -7954,6 +7962,78 @@ class StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> { |
}; |
+// This maintains an off-stack representation of the stack frames required |
+// to traverse a ConsString, allowing an entirely iterative and restartable |
+// traversal of the entire string |
+// Note: this class is not GC-safe. |
+class ConsStringIteratorOp { |
+ public: |
+ struct ContinueResponse { |
+ String* string_; |
+ unsigned offset_; |
+ unsigned length_; |
+ int32_t type_; |
+ }; |
+ inline ConsStringIteratorOp() {} |
+ String* Operate(ConsString* consString, unsigned* outerOffset, |
+ int32_t* typeOut, unsigned* lengthOut); |
+ inline bool ContinueOperation(ContinueResponse* response); |
+ inline void Reset(); |
+ inline bool HasMore(); |
+ |
+ private: |
+ // TODO(dcarney): Templatize this out for different stack sizes. |
+ static const unsigned kStackSize = 32; |
+ // Use a mask instead of doing modulo operations for stack wrapping. |
+ static const unsigned kDepthMask = kStackSize-1; |
+ STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize)); |
+ static inline unsigned OffsetForDepth(unsigned depth); |
+ static inline uint32_t MaskForDepth(unsigned depth); |
+ |
+ inline void ClearRightDescent(); |
+ inline void SetRightDescent(); |
+ inline void PushLeft(ConsString* string); |
+ inline void PushRight(ConsString* string, int32_t type); |
+ inline void AdjustMaximumDepth(); |
+ inline void Pop(); |
+ inline void ResetStack(); |
+ String* NextLeaf(bool* blewStack, int32_t* typeOut); |
+ |
+ unsigned depth_; |
+ unsigned maximum_depth_; |
+ uint32_t trace_; |
+ ConsString* frames_[kStackSize]; |
+ unsigned consumed_; |
+ ConsString* root_; |
+ int32_t root_type_; |
+ unsigned root_length_; |
+ DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp); |
+}; |
+ |
+ |
+// Note: this class is not GC-safe. |
+class StringCharacterStream { |
+ public: |
+ inline StringCharacterStream( |
+ String* string, unsigned offset, ConsStringIteratorOp* op); |
+ inline uint16_t GetNext(); |
+ inline bool HasMore(); |
+ inline void Reset(String* string, unsigned offset, ConsStringIteratorOp* op); |
+ inline void VisitOneByteString(const uint8_t* chars, unsigned length); |
+ inline void VisitTwoByteString(const uint16_t* chars, unsigned length); |
+ |
+ private: |
+ bool is_one_byte_; |
+ union { |
+ const uint8_t* buffer8_; |
+ const uint16_t* buffer16_; |
+ }; |
+ const uint8_t* end_; |
+ ConsStringIteratorOp* op_; |
+ DISALLOW_COPY_AND_ASSIGN(StringCharacterStream); |
+}; |
+ |
+ |
template <typename T> |
class VectorIterator { |
public: |