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