Line data Source code
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/allocation.h"
9 : #include "src/handles.h"
10 : #include "src/vector.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : // Forward declarations.
16 : class ByteArray;
17 :
18 918 : class StringAllocator {
19 : public:
20 17 : virtual ~StringAllocator() { }
21 : // Allocate a number of bytes.
22 : virtual char* allocate(unsigned bytes) = 0;
23 : // Allocate a larger number of bytes and copy the old buffer to the new one.
24 : // bytes is an input and output parameter passing the old size of the buffer
25 : // and returning the new size. If allocation fails then we return the old
26 : // buffer and do not increase the size.
27 : virtual char* grow(unsigned* bytes) = 0;
28 : };
29 :
30 :
31 : // Normal allocator uses new[] and delete[].
32 918 : class HeapStringAllocator final : public StringAllocator {
33 : public:
34 918 : ~HeapStringAllocator() { DeleteArray(space_); }
35 : char* allocate(unsigned bytes) override;
36 : char* grow(unsigned* bytes) override;
37 :
38 : private:
39 : char* space_;
40 : };
41 :
42 :
43 : class FixedStringAllocator final : public StringAllocator {
44 : public:
45 : FixedStringAllocator(char* buffer, unsigned length)
46 0 : : buffer_(buffer), length_(length) {}
47 0 : ~FixedStringAllocator() override{};
48 : char* allocate(unsigned bytes) override;
49 : char* grow(unsigned* bytes) override;
50 :
51 : private:
52 : char* buffer_;
53 : unsigned length_;
54 : DISALLOW_COPY_AND_ASSIGN(FixedStringAllocator);
55 : };
56 :
57 : class StringStream final {
58 : class FmtElm final {
59 : public:
60 : FmtElm(int value) : FmtElm(INT) { // NOLINT
61 497 : data_.u_int_ = value;
62 : }
63 : explicit FmtElm(double value) : FmtElm(DOUBLE) { // NOLINT
64 0 : data_.u_double_ = value;
65 : }
66 : FmtElm(const char* value) : FmtElm(C_STR) { // NOLINT
67 536 : data_.u_c_str_ = value;
68 : }
69 : FmtElm(const Vector<const uc16>& value) : FmtElm(LC_STR) { // NOLINT
70 : data_.u_lc_str_ = &value;
71 : }
72 : FmtElm(Object* value) : FmtElm(OBJ) { // NOLINT
73 733 : data_.u_obj_ = value;
74 : }
75 : FmtElm(Handle<Object> value) : FmtElm(HANDLE) { // NOLINT
76 : data_.u_handle_ = value.location();
77 : }
78 : FmtElm(void* value) : FmtElm(POINTER) { // NOLINT
79 85 : data_.u_pointer_ = value;
80 : }
81 :
82 : private:
83 : friend class StringStream;
84 : enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER };
85 :
86 : #ifdef DEBUG
87 : Type type_;
88 : explicit FmtElm(Type type) : type_(type) {}
89 : #else
90 : explicit FmtElm(Type) {}
91 : #endif
92 :
93 : union {
94 : int u_int_;
95 : double u_double_;
96 : const char* u_c_str_;
97 : const Vector<const uc16>* u_lc_str_;
98 : Object* u_obj_;
99 : Object** u_handle_;
100 : void* u_pointer_;
101 : } data_;
102 : };
103 :
104 : public:
105 : enum ObjectPrintMode { kPrintObjectConcise, kPrintObjectVerbose };
106 : StringStream(StringAllocator* allocator,
107 : ObjectPrintMode object_print_mode = kPrintObjectVerbose)
108 : : allocator_(allocator),
109 : object_print_mode_(object_print_mode),
110 : capacity_(kInitialCapacity),
111 : length_(0),
112 918 : buffer_(allocator_->allocate(kInitialCapacity)) {
113 918 : buffer_[0] = 0;
114 : }
115 :
116 : bool Put(char c);
117 : bool Put(String* str);
118 : bool Put(String* str, int start, int end);
119 4878 : void Add(const char* format) { Add(CStrVector(format)); }
120 3433 : void Add(Vector<const char> format) { Add(format, Vector<FmtElm>()); }
121 :
122 : template <typename... Args>
123 1286 : void Add(const char* format, Args... args) {
124 : Add(CStrVector(format), args...);
125 1286 : }
126 :
127 : template <typename... Args>
128 : void Add(Vector<const char> format, Args... args) {
129 201 : FmtElm elems[]{args...};
130 1286 : Add(format, ArrayVector(elems));
131 : }
132 :
133 : // Getting the message out.
134 : void OutputToFile(FILE* out);
135 0 : void OutputToStdOut() { OutputToFile(stdout); }
136 : void Log(Isolate* isolate);
137 : Handle<String> ToString(Isolate* isolate);
138 : std::unique_ptr<char[]> ToCString() const;
139 0 : int length() const { return length_; }
140 :
141 : // Object printing support.
142 : void PrintName(Object* o);
143 : void PrintFixedArray(FixedArray* array, unsigned int limit);
144 : void PrintByteArray(ByteArray* ba);
145 : void PrintUsingMap(JSObject* js_object);
146 : void PrintPrototype(JSFunction* fun, Object* receiver);
147 : void PrintSecurityTokenIfChanged(Object* function);
148 : // NOTE: Returns the code in the output parameter.
149 : void PrintFunction(Object* function, Object* receiver, Code** code);
150 :
151 : // Reset the stream.
152 : void Reset() {
153 0 : length_ = 0;
154 0 : buffer_[0] = 0;
155 : }
156 :
157 : // Mentioned object cache support.
158 : void PrintMentionedObjectCache(Isolate* isolate);
159 : static void ClearMentionedObjectCache(Isolate* isolate);
160 : #ifdef DEBUG
161 : bool IsMentionedObjectCacheClear(Isolate* isolate);
162 : #endif
163 :
164 : static const int kInitialCapacity = 16;
165 :
166 : private:
167 : void Add(Vector<const char> format, Vector<FmtElm> elms);
168 : void PrintObject(Object* obj);
169 :
170 : StringAllocator* allocator_;
171 : ObjectPrintMode object_print_mode_;
172 : unsigned capacity_;
173 : unsigned length_; // does not include terminating 0-character
174 : char* buffer_;
175 :
176 43191 : bool full() const { return (capacity_ - length_) == 1; }
177 : int space() const { return capacity_ - length_; }
178 :
179 : DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
180 : };
181 :
182 : } // namespace internal
183 : } // namespace v8
184 :
185 : #endif // V8_STRING_STREAM_H_
|