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