1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_STRING_STREAM_H_ 6 #define V8_STRING_STREAM_H_ 7 8 #include "src/handles.h" 9 10 namespace v8 { 11 namespace internal { 12 13 class StringAllocator { 14 public: 15 virtual ~StringAllocator() { } 16 // Allocate a number of bytes. 17 virtual char* allocate(unsigned bytes) = 0; 18 // Allocate a larger number of bytes and copy the old buffer to the new one. 19 // bytes is an input and output parameter passing the old size of the buffer 20 // and returning the new size. If allocation fails then we return the old 21 // buffer and do not increase the size. 22 virtual char* grow(unsigned* bytes) = 0; 23 }; 24 25 26 // Normal allocator uses new[] and delete[]. 27 class HeapStringAllocator FINAL : public StringAllocator { 28 public: 29 ~HeapStringAllocator() { DeleteArray(space_); } 30 virtual char* allocate(unsigned bytes) OVERRIDE; 31 virtual char* grow(unsigned* bytes) OVERRIDE; 32 33 private: 34 char* space_; 35 }; 36 37 38 class FmtElm FINAL { 39 public: 40 FmtElm(int value) : type_(INT) { // NOLINT 41 data_.u_int_ = value; 42 } 43 explicit FmtElm(double value) : type_(DOUBLE) { 44 data_.u_double_ = value; 45 } 46 FmtElm(const char* value) : type_(C_STR) { // NOLINT 47 data_.u_c_str_ = value; 48 } 49 FmtElm(const Vector<const uc16>& value) : type_(LC_STR) { // NOLINT 50 data_.u_lc_str_ = &value; 51 } 52 FmtElm(Object* value) : type_(OBJ) { // NOLINT 53 data_.u_obj_ = value; 54 } 55 FmtElm(Handle<Object> value) : type_(HANDLE) { // NOLINT 56 data_.u_handle_ = value.location(); 57 } 58 FmtElm(void* value) : type_(POINTER) { // NOLINT 59 data_.u_pointer_ = value; 60 } 61 62 private: 63 friend class StringStream; 64 enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER }; 65 Type type_; 66 union { 67 int u_int_; 68 double u_double_; 69 const char* u_c_str_; 70 const Vector<const uc16>* u_lc_str_; 71 Object* u_obj_; 72 Object** u_handle_; 73 void* u_pointer_; 74 } data_; 75 }; 76 77 78 class StringStream FINAL { 79 public: 80 explicit StringStream(StringAllocator* allocator): 81 allocator_(allocator), 82 capacity_(kInitialCapacity), 83 length_(0), 84 buffer_(allocator_->allocate(kInitialCapacity)) { 85 buffer_[0] = 0; 86 } 87 88 bool Put(char c); 89 bool Put(String* str); 90 bool Put(String* str, int start, int end); 91 void Add(Vector<const char> format, Vector<FmtElm> elms); 92 void Add(const char* format); 93 void Add(Vector<const char> format); 94 void Add(const char* format, FmtElm arg0); 95 void Add(const char* format, FmtElm arg0, FmtElm arg1); 96 void Add(const char* format, FmtElm arg0, FmtElm arg1, FmtElm arg2); 97 void Add(const char* format, 98 FmtElm arg0, 99 FmtElm arg1, 100 FmtElm arg2, 101 FmtElm arg3); 102 void Add(const char* format, 103 FmtElm arg0, 104 FmtElm arg1, 105 FmtElm arg2, 106 FmtElm arg3, 107 FmtElm arg4); 108 109 // Getting the message out. 110 void OutputToFile(FILE* out); 111 void OutputToStdOut() { OutputToFile(stdout); } 112 void Log(Isolate* isolate); 113 Handle<String> ToString(Isolate* isolate); 114 SmartArrayPointer<const char> ToCString() const; 115 int length() const { return length_; } 116 117 // Object printing support. 118 void PrintName(Object* o); 119 void PrintFixedArray(FixedArray* array, unsigned int limit); 120 void PrintByteArray(ByteArray* ba); 121 void PrintUsingMap(JSObject* js_object); 122 void PrintPrototype(JSFunction* fun, Object* receiver); 123 void PrintSecurityTokenIfChanged(Object* function); 124 // NOTE: Returns the code in the output parameter. 125 void PrintFunction(Object* function, Object* receiver, Code** code); 126 127 // Reset the stream. 128 void Reset() { 129 length_ = 0; 130 buffer_[0] = 0; 131 } 132 133 // Mentioned object cache support. 134 void PrintMentionedObjectCache(Isolate* isolate); 135 static void ClearMentionedObjectCache(Isolate* isolate); 136 #ifdef DEBUG 137 static bool IsMentionedObjectCacheClear(Isolate* isolate); 138 #endif 139 140 static const int kInitialCapacity = 16; 141 142 private: 143 void PrintObject(Object* obj); 144 145 StringAllocator* allocator_; 146 unsigned capacity_; 147 unsigned length_; // does not include terminating 0-character 148 char* buffer_; 149 150 bool full() const { return (capacity_ - length_) == 1; } 151 int space() const { return capacity_ - length_; } 152 153 DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream); 154 }; 155 156 } } // namespace v8::internal 157 158 #endif // V8_STRING_STREAM_H_ 159