• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~StringAllocator()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 V8_FINAL : public StringAllocator {
28  public:
~HeapStringAllocator()29   ~HeapStringAllocator() { DeleteArray(space_); }
30   virtual char* allocate(unsigned bytes) V8_OVERRIDE;
31   virtual char* grow(unsigned* bytes) V8_OVERRIDE;
32 
33  private:
34   char* space_;
35 };
36 
37 
38 // Allocator for use when no new c++ heap allocation is allowed.
39 // Given a preallocated buffer up front and does no allocation while
40 // building message.
41 class NoAllocationStringAllocator V8_FINAL : public StringAllocator {
42  public:
43   NoAllocationStringAllocator(char* memory, unsigned size);
allocate(unsigned bytes)44   virtual char* allocate(unsigned bytes) V8_OVERRIDE { return space_; }
45   virtual char* grow(unsigned* bytes) V8_OVERRIDE;
46 
47  private:
48   unsigned size_;
49   char* space_;
50 };
51 
52 
53 class FmtElm V8_FINAL {
54  public:
FmtElm(int value)55   FmtElm(int value) : type_(INT) {  // NOLINT
56     data_.u_int_ = value;
57   }
FmtElm(double value)58   explicit FmtElm(double value) : type_(DOUBLE) {
59     data_.u_double_ = value;
60   }
FmtElm(const char * value)61   FmtElm(const char* value) : type_(C_STR) {  // NOLINT
62     data_.u_c_str_ = value;
63   }
FmtElm(const Vector<const uc16> & value)64   FmtElm(const Vector<const uc16>& value) : type_(LC_STR) {  // NOLINT
65     data_.u_lc_str_ = &value;
66   }
FmtElm(Object * value)67   FmtElm(Object* value) : type_(OBJ) {  // NOLINT
68     data_.u_obj_ = value;
69   }
FmtElm(Handle<Object> value)70   FmtElm(Handle<Object> value) : type_(HANDLE) {  // NOLINT
71     data_.u_handle_ = value.location();
72   }
FmtElm(void * value)73   FmtElm(void* value) : type_(POINTER) {  // NOLINT
74     data_.u_pointer_ = value;
75   }
76 
77  private:
78   friend class StringStream;
79   enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER };
80   Type type_;
81   union {
82     int u_int_;
83     double u_double_;
84     const char* u_c_str_;
85     const Vector<const uc16>* u_lc_str_;
86     Object* u_obj_;
87     Object** u_handle_;
88     void* u_pointer_;
89   } data_;
90 };
91 
92 
93 class StringStream V8_FINAL {
94  public:
StringStream(StringAllocator * allocator)95   explicit StringStream(StringAllocator* allocator):
96     allocator_(allocator),
97     capacity_(kInitialCapacity),
98     length_(0),
99     buffer_(allocator_->allocate(kInitialCapacity)) {
100     buffer_[0] = 0;
101   }
102 
103   bool Put(char c);
104   bool Put(String* str);
105   bool Put(String* str, int start, int end);
106   void Add(Vector<const char> format, Vector<FmtElm> elms);
107   void Add(const char* format);
108   void Add(Vector<const char> format);
109   void Add(const char* format, FmtElm arg0);
110   void Add(const char* format, FmtElm arg0, FmtElm arg1);
111   void Add(const char* format, FmtElm arg0, FmtElm arg1, FmtElm arg2);
112   void Add(const char* format,
113            FmtElm arg0,
114            FmtElm arg1,
115            FmtElm arg2,
116            FmtElm arg3);
117   void Add(const char* format,
118            FmtElm arg0,
119            FmtElm arg1,
120            FmtElm arg2,
121            FmtElm arg3,
122            FmtElm arg4);
123 
124   // Getting the message out.
125   void OutputToFile(FILE* out);
OutputToStdOut()126   void OutputToStdOut() { OutputToFile(stdout); }
127   void Log(Isolate* isolate);
128   Handle<String> ToString(Isolate* isolate);
129   SmartArrayPointer<const char> ToCString() const;
length()130   int length() const { return length_; }
131 
132   // Object printing support.
133   void PrintName(Object* o);
134   void PrintFixedArray(FixedArray* array, unsigned int limit);
135   void PrintByteArray(ByteArray* ba);
136   void PrintUsingMap(JSObject* js_object);
137   void PrintPrototype(JSFunction* fun, Object* receiver);
138   void PrintSecurityTokenIfChanged(Object* function);
139   // NOTE: Returns the code in the output parameter.
140   void PrintFunction(Object* function, Object* receiver, Code** code);
141 
142   // Reset the stream.
Reset()143   void Reset() {
144     length_ = 0;
145     buffer_[0] = 0;
146   }
147 
148   // Mentioned object cache support.
149   void PrintMentionedObjectCache(Isolate* isolate);
150   static void ClearMentionedObjectCache(Isolate* isolate);
151 #ifdef DEBUG
152   static bool IsMentionedObjectCacheClear(Isolate* isolate);
153 #endif
154 
155   static const int kInitialCapacity = 16;
156 
157  private:
158   void PrintObject(Object* obj);
159 
160   StringAllocator* allocator_;
161   unsigned capacity_;
162   unsigned length_;  // does not include terminating 0-character
163   char* buffer_;
164 
full()165   bool full() const { return (capacity_ - length_) == 1; }
space()166   int space() const { return capacity_ - length_; }
167 
168   DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
169 };
170 
171 
172 // Utility class to print a list of items to a stream, divided by a separator.
173 class SimpleListPrinter V8_FINAL {
174  public:
175   explicit SimpleListPrinter(StringStream* stream, char separator = ',') {
176     separator_ = separator;
177     stream_ = stream;
178     first_ = true;
179   }
180 
Add(const char * str)181   void Add(const char* str) {
182     if (first_) {
183       first_ = false;
184     } else {
185       stream_->Put(separator_);
186     }
187     stream_->Add(str);
188   }
189 
190  private:
191   bool first_;
192   char separator_;
193   StringStream* stream_;
194 };
195 
196 } }  // namespace v8::internal
197 
198 #endif  // V8_STRING_STREAM_H_
199