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 34namespace v8 { 35namespace 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(). 57void PRINTF_CHECKING PrintF(const char* format, ...); 58void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...); 59 60// Our version of fflush. 61void Flush(FILE* out); 62 63inline 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. 70char* 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. 76byte* 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. 81int 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. 89int 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. 97int 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. 107int WriteAsCFile(const char* filename, const char* varname, 108 const char* str, int size, bool verbose = true); 109 110 111// Data structures 112 113template <typename T> 114inline 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. 123template <typename T> 124inline 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 145template <typename T, typename U> 146inline 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. 178class 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. 194Vector<const char> ReadFile(const char* filename, 195 bool* exists, 196 bool verbose = true); 197Vector<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. 204template <typename sourcechar, typename sinkchar> 205inline 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. 231class 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 260class 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