1 // Copyright 2012 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
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.
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.
32 #include "platform.h" // For va_list on Solaris.
37 // ----------------------------------------------------------------------------
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
48 #define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
49 #define FPRINTF_CHECKING __attribute__ ((format (printf, 2, 3)))
52 #define PRINTF_CHECKING
53 #define FPRINTF_CHECKING
56 // Our version of printf().
57 void PRINTF_CHECKING PrintF(const char* format, ...);
58 void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
60 // Prepends the current process ID to the output.
61 void PRINTF_CHECKING PrintPID(const char* format, ...);
63 // Our version of fflush.
64 void Flush(FILE* out);
71 // Read a line of characters after printing the prompt to stdout. The resulting
72 // char* needs to be disposed off with DeleteArray by the caller.
73 char* ReadLine(const char* prompt);
76 // Read and return the raw bytes in a file. the size of the buffer is returned
78 // The returned buffer must be freed by the caller.
79 byte* ReadBytes(const char* filename, int* size, bool verbose = true);
82 // Append size chars from str to the file given by filename.
83 // The file is overwritten. Returns the number of chars written.
84 int AppendChars(const char* filename,
90 // Write size chars from str to the file given by filename.
91 // The file is overwritten. Returns the number of chars written.
92 int WriteChars(const char* filename,
98 // Write size bytes to the file given by filename.
99 // The file is overwritten. Returns the number of bytes written.
100 int WriteBytes(const char* filename,
103 bool verbose = true);
107 // const char* <varname> = "<str>";
108 // const int <varname>_len = <len>;
109 // to the file given by filename. Only the first len chars are written.
110 int WriteAsCFile(const char* filename, const char* varname,
111 const char* str, int size, bool verbose = true);
114 // ----------------------------------------------------------------------------
117 template <typename T>
118 inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
120 return Vector< Handle<Object> >(
121 reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
125 // ----------------------------------------------------------------------------
128 // Copies words from |src| to |dst|. The data spans must not overlap.
129 template <typename T>
130 inline void CopyWords(T* dst, const T* src, size_t num_words) {
131 STATIC_ASSERT(sizeof(T) == kPointerSize);
132 ASSERT(Min(dst, const_cast<T*>(src)) + num_words <=
133 Max(dst, const_cast<T*>(src)));
134 ASSERT(num_words > 0);
136 // Use block copying OS::MemCopy if the segment we're copying is
137 // enough to justify the extra call/setup overhead.
138 static const size_t kBlockCopyLimit = 16;
140 if (num_words < kBlockCopyLimit) {
144 } while (num_words > 0);
146 OS::MemCopy(dst, src, num_words * kPointerSize);
151 // Copies words from |src| to |dst|. No restrictions.
152 template <typename T>
153 inline void MoveWords(T* dst, const T* src, size_t num_words) {
154 STATIC_ASSERT(sizeof(T) == kPointerSize);
155 ASSERT(num_words > 0);
157 // Use block copying OS::MemCopy if the segment we're copying is
158 // enough to justify the extra call/setup overhead.
159 static const size_t kBlockCopyLimit = 16;
161 if (num_words < kBlockCopyLimit &&
162 ((dst < src) || (dst >= (src + num_words * kPointerSize)))) {
163 T* end = dst + num_words;
167 } while (num_words > 0);
169 OS::MemMove(dst, src, num_words * kPointerSize);
174 // Copies data from |src| to |dst|. The data spans must not overlap.
175 template <typename T>
176 inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
177 STATIC_ASSERT(sizeof(T) == 1);
178 ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <=
179 Max(dst, const_cast<T*>(src)));
180 if (num_bytes == 0) return;
182 // Use block copying OS::MemCopy if the segment we're copying is
183 // enough to justify the extra call/setup overhead.
184 static const int kBlockCopyLimit = OS::kMinComplexMemCopy;
186 if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
190 } while (num_bytes > 0);
192 OS::MemCopy(dst, src, num_bytes);
197 template <typename T, typename U>
198 inline void MemsetPointer(T** dest, U* value, int counter) {
202 a = b; // Fake assignment to check assignability.
205 #if V8_HOST_ARCH_IA32
207 #elif V8_HOST_ARCH_X64
210 #if defined(__native_client__)
211 // This STOS sequence does not validate for x86_64 Native Client.
212 // Here we #undef STOS to force use of the slower C version.
213 // TODO(bradchen): Profile V8 and implement a faster REP STOS
214 // here if the profile indicates it matters.
218 #if defined(__GNUC__) && defined(STOS)
222 : "+&c" (counter), "+&D" (dest)
226 for (int i = 0; i < counter; i++) {
235 // Simple wrapper that allows an ExternalString to refer to a
236 // Vector<const char>. Doesn't assume ownership of the data.
237 class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
239 explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
241 virtual const char* data() const { return data_.start(); }
243 virtual size_t length() const { return data_.length(); }
246 Vector<const char> data_;
250 // Simple support to read a file into a 0-terminated C-string.
251 // The returned buffer must be freed by the caller.
252 // On return, *exits tells whether the file existed.
253 Vector<const char> ReadFile(const char* filename,
255 bool verbose = true);
256 Vector<const char> ReadFile(FILE* file,
258 bool verbose = true);
261 template <typename sourcechar, typename sinkchar>
262 INLINE(static void CopyCharsUnsigned(sinkchar* dest,
263 const sourcechar* src,
265 #if defined(V8_HOST_ARCH_ARM)
266 INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
267 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars));
268 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
269 #elif defined(V8_HOST_ARCH_MIPS)
270 INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
271 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
274 // Copy from ASCII/16bit chars to ASCII/16bit chars.
275 template <typename sourcechar, typename sinkchar>
276 INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
278 template<typename sourcechar, typename sinkchar>
279 void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
280 ASSERT(sizeof(sourcechar) <= 2);
281 ASSERT(sizeof(sinkchar) <= 2);
282 if (sizeof(sinkchar) == 1) {
283 if (sizeof(sourcechar) == 1) {
284 CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
285 reinterpret_cast<const uint8_t*>(src),
288 CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
289 reinterpret_cast<const uint16_t*>(src),
293 if (sizeof(sourcechar) == 1) {
294 CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
295 reinterpret_cast<const uint8_t*>(src),
298 CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
299 reinterpret_cast<const uint16_t*>(src),
305 template <typename sourcechar, typename sinkchar>
306 void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
307 sinkchar* limit = dest + chars;
308 #ifdef V8_HOST_CAN_READ_UNALIGNED
309 if (sizeof(*dest) == sizeof(*src)) {
310 if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) {
311 OS::MemCopy(dest, src, chars * sizeof(*dest));
314 // Number of characters in a uintptr_t.
315 static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT
316 ASSERT(dest + kStepSize > dest); // Check for overflow.
317 while (dest + kStepSize <= limit) {
318 *reinterpret_cast<uintptr_t*>(dest) =
319 *reinterpret_cast<const uintptr_t*>(src);
325 while (dest < limit) {
326 *dest++ = static_cast<sinkchar>(*src++);
331 #if defined(V8_HOST_ARCH_ARM)
332 void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
333 switch (static_cast<unsigned>(chars)) {
340 memcpy(dest, src, 2);
343 memcpy(dest, src, 3);
346 memcpy(dest, src, 4);
349 memcpy(dest, src, 5);
352 memcpy(dest, src, 6);
355 memcpy(dest, src, 7);
358 memcpy(dest, src, 8);
361 memcpy(dest, src, 9);
364 memcpy(dest, src, 10);
367 memcpy(dest, src, 11);
370 memcpy(dest, src, 12);
373 memcpy(dest, src, 13);
376 memcpy(dest, src, 14);
379 memcpy(dest, src, 15);
382 OS::MemCopy(dest, src, chars);
388 void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) {
389 if (chars >= OS::kMinComplexConvertMemCopy) {
390 OS::MemCopyUint16Uint8(dest, src, chars);
392 OS::MemCopyUint16Uint8Wrapper(dest, src, chars);
397 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
398 switch (static_cast<unsigned>(chars)) {
405 memcpy(dest, src, 4);
408 memcpy(dest, src, 6);
411 memcpy(dest, src, 8);
414 memcpy(dest, src, 10);
417 memcpy(dest, src, 12);
420 memcpy(dest, src, 14);
423 OS::MemCopy(dest, src, chars * sizeof(*dest));
429 #elif defined(V8_HOST_ARCH_MIPS)
430 void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
431 if (chars < OS::kMinComplexMemCopy) {
432 memcpy(dest, src, chars);
434 OS::MemCopy(dest, src, chars);
438 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
439 if (chars < OS::kMinComplexMemCopy) {
440 memcpy(dest, src, chars * sizeof(*dest));
442 OS::MemCopy(dest, src, chars * sizeof(*dest));
448 class StringBuilder : public SimpleStringBuilder {
450 explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
451 StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
453 // Add formatted contents to the builder just like printf().
454 void AddFormatted(const char* format, ...);
456 // Add formatted contents like printf based on a va_list.
457 void AddFormattedList(const char* format, va_list list);
459 DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
462 } } // namespace v8::internal
464 #endif // V8_V8UTILS_H_