1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_STRING_STREAM_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_STRING_STREAM_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StringAllocator {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~StringAllocator() {}
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocate a number of bytes.
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual char* allocate(unsigned bytes) = 0;
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocate a larger number of bytes and copy the old buffer to the new one.
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bytes is an input and output parameter passing the old size of the buffer
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and returning the new size.  If allocation fails then we return the old
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // buffer and do not increase the size.
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual char* grow(unsigned* bytes) = 0;
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Normal allocator uses new[] and delete[].
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass HeapStringAllocator: public StringAllocator {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ~HeapStringAllocator() { DeleteArray(space_); }
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* allocate(unsigned bytes);
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* grow(unsigned* bytes);
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* space_;
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Allocator for use when no new c++ heap allocation is allowed.
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Given a preallocated buffer up front and does no allocation while
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// building message.
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass NoAllocationStringAllocator: public StringAllocator {
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  NoAllocationStringAllocator(char* memory, unsigned size);
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* allocate(unsigned bytes) { return space_; }
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* grow(unsigned* bytes);
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  unsigned size_;
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* space_;
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass FmtElm {
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FmtElm(int value) : type_(INT) {  // NOLINT
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    data_.u_int_ = value;
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit FmtElm(double value) : type_(DOUBLE) {
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    data_.u_double_ = value;
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FmtElm(const char* value) : type_(C_STR) {  // NOLINT
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    data_.u_c_str_ = value;
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FmtElm(const Vector<const uc16>& value) : type_(LC_STR) {  // NOLINT
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    data_.u_lc_str_ = &value;
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FmtElm(Object* value) : type_(OBJ) {  // NOLINT
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    data_.u_obj_ = value;
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FmtElm(Handle<Object> value) : type_(HANDLE) {  // NOLINT
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    data_.u_handle_ = value.location();
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FmtElm(void* value) : type_(POINTER) {  // NOLINT
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    data_.u_pointer_ = value;
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
96589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class StringStream;
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER };
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Type type_;
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  union {
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int u_int_;
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    double u_double_;
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const char* u_c_str_;
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const Vector<const uc16>* u_lc_str_;
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* u_obj_;
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object** u_handle_;
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void* u_pointer_;
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } data_;
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StringStream {
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit StringStream(StringAllocator* allocator):
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    allocator_(allocator),
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    capacity_(kInitialCapacity),
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    length_(0),
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    buffer_(allocator_->allocate(kInitialCapacity)) {
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    buffer_[0] = 0;
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ~StringStream() {
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool Put(char c);
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool Put(String* str);
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool Put(String* str, int start, int end);
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Add(Vector<const char> format, Vector<FmtElm> elms);
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Add(const char* format);
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Add(Vector<const char> format);
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Add(const char* format, FmtElm arg0);
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Add(const char* format, FmtElm arg0, FmtElm arg1);
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Add(const char* format, FmtElm arg0, FmtElm arg1, FmtElm arg2);
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Add(const char* format,
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           FmtElm arg0,
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           FmtElm arg1,
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           FmtElm arg2,
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           FmtElm arg3);
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Getting the message out.
142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void OutputToFile(FILE* out);
143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void OutputToStdOut() { OutputToFile(stdout); }
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Log();
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> ToString();
146589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  SmartArrayPointer<const char> ToCString() const;
147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int length() const { return length_; }
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Object printing support.
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintName(Object* o);
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintFixedArray(FixedArray* array, unsigned int limit);
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintByteArray(ByteArray* ba);
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintUsingMap(JSObject* js_object);
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintPrototype(JSFunction* fun, Object* receiver);
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintSecurityTokenIfChanged(Object* function);
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NOTE: Returns the code in the output parameter.
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintFunction(Object* function, Object* receiver, Code** code);
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Reset the stream.
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Reset() {
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    length_ = 0;
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    buffer_[0] = 0;
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Mentioned object cache support.
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintMentionedObjectCache();
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void ClearMentionedObjectCache();
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool IsMentionedObjectCacheClear();
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInitialCapacity = 16;
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintObject(Object* obj);
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StringAllocator* allocator_;
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  unsigned capacity_;
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  unsigned length_;  // does not include terminating 0-character
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* buffer_;
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool full() const { return (capacity_ - length_) == 1; }
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int space() const { return capacity_ - length_; }
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_STRING_STREAM_H_
193