Home | History | Annotate | Download | only in src
      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 V8_FINAL : public StringAllocator {
     28  public:
     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);
     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:
     55   FmtElm(int value) : type_(INT) {  // NOLINT
     56     data_.u_int_ = value;
     57   }
     58   explicit FmtElm(double value) : type_(DOUBLE) {
     59     data_.u_double_ = value;
     60   }
     61   FmtElm(const char* value) : type_(C_STR) {  // NOLINT
     62     data_.u_c_str_ = value;
     63   }
     64   FmtElm(const Vector<const uc16>& value) : type_(LC_STR) {  // NOLINT
     65     data_.u_lc_str_ = &value;
     66   }
     67   FmtElm(Object* value) : type_(OBJ) {  // NOLINT
     68     data_.u_obj_ = value;
     69   }
     70   FmtElm(Handle<Object> value) : type_(HANDLE) {  // NOLINT
     71     data_.u_handle_ = value.location();
     72   }
     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:
     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);
    126   void OutputToStdOut() { OutputToFile(stdout); }
    127   void Log(Isolate* isolate);
    128   Handle<String> ToString(Isolate* isolate);
    129   SmartArrayPointer<const char> ToCString() const;
    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.
    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 
    165   bool full() const { return (capacity_ - length_) == 1; }
    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 
    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