Home | History | Annotate | Download | only in src
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_V8UTILS_H_
     29 #define V8_V8UTILS_H_
     30 
     31 #include "utils.h"
     32 #include "platform.h"  // For va_list on Solaris.
     33 
     34 namespace v8 {
     35 namespace internal {
     36 
     37 // ----------------------------------------------------------------------------
     38 // I/O support.
     39 
     40 #if __GNUC__ >= 4
     41 // On gcc we can ask the compiler to check the types of %d-style format
     42 // specifiers and their associated arguments.  TODO(erikcorry) fix this
     43 // so it works on MacOSX.
     44 #if defined(__MACH__) && defined(__APPLE__)
     45 #define PRINTF_CHECKING
     46 #define FPRINTF_CHECKING
     47 #else  // MacOsX.
     48 #define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
     49 #define FPRINTF_CHECKING __attribute__ ((format (printf, 2, 3)))
     50 #endif
     51 #else
     52 #define PRINTF_CHECKING
     53 #define FPRINTF_CHECKING
     54 #endif
     55 
     56 // Our version of printf().
     57 void PRINTF_CHECKING PrintF(const char* format, ...);
     58 void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
     59 
     60 // Our version of fflush.
     61 void Flush(FILE* out);
     62 
     63 inline void Flush() {
     64   Flush(stdout);
     65 }
     66 
     67 
     68 // Read a line of characters after printing the prompt to stdout. The resulting
     69 // char* needs to be disposed off with DeleteArray by the caller.
     70 char* ReadLine(const char* prompt);
     71 
     72 
     73 // Read and return the raw bytes in a file. the size of the buffer is returned
     74 // in size.
     75 // The returned buffer must be freed by the caller.
     76 byte* ReadBytes(const char* filename, int* size, bool verbose = true);
     77 
     78 
     79 // Append size chars from str to the file given by filename.
     80 // The file is overwritten. Returns the number of chars written.
     81 int AppendChars(const char* filename,
     82                 const char* str,
     83                 int size,
     84                 bool verbose = true);
     85 
     86 
     87 // Write size chars from str to the file given by filename.
     88 // The file is overwritten. Returns the number of chars written.
     89 int WriteChars(const char* filename,
     90                const char* str,
     91                int size,
     92                bool verbose = true);
     93 
     94 
     95 // Write size bytes to the file given by filename.
     96 // The file is overwritten. Returns the number of bytes written.
     97 int WriteBytes(const char* filename,
     98                const byte* bytes,
     99                int size,
    100                bool verbose = true);
    101 
    102 
    103 // Write the C code
    104 // const char* <varname> = "<str>";
    105 // const int <varname>_len = <len>;
    106 // to the file given by filename. Only the first len chars are written.
    107 int WriteAsCFile(const char* filename, const char* varname,
    108                  const char* str, int size, bool verbose = true);
    109 
    110 
    111 // Data structures
    112 
    113 template <typename T>
    114 inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
    115                                              int length) {
    116   return Vector< Handle<Object> >(
    117       reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
    118 }
    119 
    120 // Memory
    121 
    122 // Copies data from |src| to |dst|.  The data spans MUST not overlap.
    123 template <typename T>
    124 inline void CopyWords(T* dst, T* src, int num_words) {
    125   STATIC_ASSERT(sizeof(T) == kPointerSize);
    126   ASSERT(Min(dst, src) + num_words <= Max(dst, src));
    127   ASSERT(num_words > 0);
    128 
    129   // Use block copying memcpy if the segment we're copying is
    130   // enough to justify the extra call/setup overhead.
    131   static const int kBlockCopyLimit = 16;
    132 
    133   if (num_words >= kBlockCopyLimit) {
    134     memcpy(dst, src, num_words * kPointerSize);
    135   } else {
    136     int remaining = num_words;
    137     do {
    138       remaining--;
    139       *dst++ = *src++;
    140     } while (remaining > 0);
    141   }
    142 }
    143 
    144 
    145 template <typename T, typename U>
    146 inline void MemsetPointer(T** dest, U* value, int counter) {
    147 #ifdef DEBUG
    148   T* a = NULL;
    149   U* b = NULL;
    150   a = b;  // Fake assignment to check assignability.
    151   USE(a);
    152 #endif  // DEBUG
    153 #if defined(V8_HOST_ARCH_IA32)
    154 #define STOS "stosl"
    155 #elif defined(V8_HOST_ARCH_X64)
    156 #define STOS "stosq"
    157 #endif
    158 
    159 #if defined(__GNUC__) && defined(STOS)
    160   asm volatile(
    161       "cld;"
    162       "rep ; " STOS
    163       : "+&c" (counter), "+&D" (dest)
    164       : "a" (value)
    165       : "memory", "cc");
    166 #else
    167   for (int i = 0; i < counter; i++) {
    168     dest[i] = value;
    169   }
    170 #endif
    171 
    172 #undef STOS
    173 }
    174 
    175 
    176 // Simple wrapper that allows an ExternalString to refer to a
    177 // Vector<const char>. Doesn't assume ownership of the data.
    178 class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
    179  public:
    180   explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
    181 
    182   virtual const char* data() const { return data_.start(); }
    183 
    184   virtual size_t length() const { return data_.length(); }
    185 
    186  private:
    187   Vector<const char> data_;
    188 };
    189 
    190 
    191 // Simple support to read a file into a 0-terminated C-string.
    192 // The returned buffer must be freed by the caller.
    193 // On return, *exits tells whether the file existed.
    194 Vector<const char> ReadFile(const char* filename,
    195                             bool* exists,
    196                             bool verbose = true);
    197 Vector<const char> ReadFile(FILE* file,
    198                             bool* exists,
    199                             bool verbose = true);
    200 
    201 
    202 
    203 // Copy from ASCII/16bit chars to ASCII/16bit chars.
    204 template <typename sourcechar, typename sinkchar>
    205 inline void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
    206   sinkchar* limit = dest + chars;
    207 #ifdef V8_HOST_CAN_READ_UNALIGNED
    208   if (sizeof(*dest) == sizeof(*src)) {
    209     if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) {
    210       OS::MemCopy(dest, src, chars * sizeof(*dest));
    211       return;
    212     }
    213     // Number of characters in a uintptr_t.
    214     static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest);  // NOLINT
    215     while (dest <= limit - kStepSize) {
    216       *reinterpret_cast<uintptr_t*>(dest) =
    217           *reinterpret_cast<const uintptr_t*>(src);
    218       dest += kStepSize;
    219       src += kStepSize;
    220     }
    221   }
    222 #endif
    223   while (dest < limit) {
    224     *dest++ = static_cast<sinkchar>(*src++);
    225   }
    226 }
    227 
    228 
    229 // A resource for using mmapped files to back external strings that are read
    230 // from files.
    231 class MemoryMappedExternalResource: public
    232     v8::String::ExternalAsciiStringResource {
    233  public:
    234   explicit MemoryMappedExternalResource(const char* filename);
    235   MemoryMappedExternalResource(const char* filename,
    236                                bool remove_file_on_cleanup);
    237   virtual ~MemoryMappedExternalResource();
    238 
    239   virtual const char* data() const { return data_; }
    240   virtual size_t length() const { return length_; }
    241 
    242   bool exists() const { return file_ != NULL; }
    243   bool is_empty() const { return length_ == 0; }
    244 
    245   bool EnsureIsAscii(bool abort_if_failed) const;
    246   bool EnsureIsAscii() const { return EnsureIsAscii(true); }
    247   bool IsAscii() const { return EnsureIsAscii(false); }
    248 
    249  private:
    250   void Init(const char* filename);
    251 
    252   char* filename_;
    253   OS::MemoryMappedFile* file_;
    254 
    255   const char* data_;
    256   size_t length_;
    257   bool remove_file_on_cleanup_;
    258 };
    259 
    260 class StringBuilder : public SimpleStringBuilder {
    261  public:
    262   explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
    263   StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
    264 
    265   // Add formatted contents to the builder just like printf().
    266   void AddFormatted(const char* format, ...);
    267 
    268   // Add formatted contents like printf based on a va_list.
    269   void AddFormattedList(const char* format, va_list list);
    270  private:
    271   DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
    272 };
    273 
    274 } }  // namespace v8::internal
    275 
    276 #endif  // V8_V8UTILS_H_
    277