1// Copyright 2012 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_UTILS_H_
6#define V8_UTILS_H_
7
8#include <limits.h>
9#include <stdlib.h>
10#include <string.h>
11#include <cmath>
12
13#include "include/v8.h"
14#include "src/allocation.h"
15#include "src/base/bits.h"
16#include "src/base/compiler-specific.h"
17#include "src/base/logging.h"
18#include "src/base/macros.h"
19#include "src/base/platform/platform.h"
20#include "src/globals.h"
21#include "src/list.h"
22#include "src/vector.h"
23
24namespace v8 {
25namespace internal {
26
27// ----------------------------------------------------------------------------
28// General helper functions
29
30// Returns the value (0 .. 15) of a hexadecimal character c.
31// If c is not a legal hexadecimal character, returns a value < 0.
32inline int HexValue(uc32 c) {
33  c -= '0';
34  if (static_cast<unsigned>(c) <= 9) return c;
35  c = (c | 0x20) - ('a' - '0');  // detect 0x11..0x16 and 0x31..0x36.
36  if (static_cast<unsigned>(c) <= 5) return c + 10;
37  return -1;
38}
39
40inline char HexCharOfValue(int value) {
41  DCHECK(0 <= value && value <= 16);
42  if (value < 10) return value + '0';
43  return value - 10 + 'A';
44}
45
46inline int BoolToInt(bool b) { return b ? 1 : 0; }
47
48
49// Same as strcmp, but can handle NULL arguments.
50inline bool CStringEquals(const char* s1, const char* s2) {
51  return (s1 == s2) || (s1 != NULL && s2 != NULL && strcmp(s1, s2) == 0);
52}
53
54
55// X must be a power of 2.  Returns the number of trailing zeros.
56inline int WhichPowerOf2(uint32_t x) {
57  DCHECK(base::bits::IsPowerOfTwo32(x));
58  int bits = 0;
59#ifdef DEBUG
60  uint32_t original_x = x;
61#endif
62  if (x >= 0x10000) {
63    bits += 16;
64    x >>= 16;
65  }
66  if (x >= 0x100) {
67    bits += 8;
68    x >>= 8;
69  }
70  if (x >= 0x10) {
71    bits += 4;
72    x >>= 4;
73  }
74  switch (x) {
75    default: UNREACHABLE();
76    case 8: bits++;  // Fall through.
77    case 4: bits++;  // Fall through.
78    case 2: bits++;  // Fall through.
79    case 1: break;
80  }
81  DCHECK_EQ(static_cast<uint32_t>(1) << bits, original_x);
82  return bits;
83}
84
85
86// X must be a power of 2.  Returns the number of trailing zeros.
87inline int WhichPowerOf2_64(uint64_t x) {
88  DCHECK(base::bits::IsPowerOfTwo64(x));
89  int bits = 0;
90#ifdef DEBUG
91  uint64_t original_x = x;
92#endif
93  if (x >= 0x100000000L) {
94    bits += 32;
95    x >>= 32;
96  }
97  if (x >= 0x10000) {
98    bits += 16;
99    x >>= 16;
100  }
101  if (x >= 0x100) {
102    bits += 8;
103    x >>= 8;
104  }
105  if (x >= 0x10) {
106    bits += 4;
107    x >>= 4;
108  }
109  switch (x) {
110    default: UNREACHABLE();
111    case 8: bits++;  // Fall through.
112    case 4: bits++;  // Fall through.
113    case 2: bits++;  // Fall through.
114    case 1: break;
115  }
116  DCHECK_EQ(static_cast<uint64_t>(1) << bits, original_x);
117  return bits;
118}
119
120
121inline int MostSignificantBit(uint32_t x) {
122  static const int msb4[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
123  int nibble = 0;
124  if (x & 0xffff0000) {
125    nibble += 16;
126    x >>= 16;
127  }
128  if (x & 0xff00) {
129    nibble += 8;
130    x >>= 8;
131  }
132  if (x & 0xf0) {
133    nibble += 4;
134    x >>= 4;
135  }
136  return nibble + msb4[x];
137}
138
139
140// The C++ standard leaves the semantics of '>>' undefined for
141// negative signed operands. Most implementations do the right thing,
142// though.
143inline int ArithmeticShiftRight(int x, int s) {
144  return x >> s;
145}
146
147
148template <typename T>
149int Compare(const T& a, const T& b) {
150  if (a == b)
151    return 0;
152  else if (a < b)
153    return -1;
154  else
155    return 1;
156}
157
158
159template <typename T>
160int PointerValueCompare(const T* a, const T* b) {
161  return Compare<T>(*a, *b);
162}
163
164
165// Compare function to compare the object pointer value of two
166// handlified objects. The handles are passed as pointers to the
167// handles.
168template<typename T> class Handle;  // Forward declaration.
169template <typename T>
170int HandleObjectPointerCompare(const Handle<T>* a, const Handle<T>* b) {
171  return Compare<T*>(*(*a), *(*b));
172}
173
174
175template <typename T, typename U>
176inline bool IsAligned(T value, U alignment) {
177  return (value & (alignment - 1)) == 0;
178}
179
180
181// Returns true if (addr + offset) is aligned.
182inline bool IsAddressAligned(Address addr,
183                             intptr_t alignment,
184                             int offset = 0) {
185  intptr_t offs = OffsetFrom(addr + offset);
186  return IsAligned(offs, alignment);
187}
188
189
190// Returns the maximum of the two parameters.
191template <typename T>
192T Max(T a, T b) {
193  return a < b ? b : a;
194}
195
196
197// Returns the minimum of the two parameters.
198template <typename T>
199T Min(T a, T b) {
200  return a < b ? a : b;
201}
202
203// Returns the maximum of the two parameters according to JavaScript semantics.
204template <typename T>
205T JSMax(T x, T y) {
206  if (std::isnan(x)) return x;
207  if (std::isnan(y)) return y;
208  if (std::signbit(x) < std::signbit(y)) return x;
209  return x > y ? x : y;
210}
211
212// Returns the maximum of the two parameters according to JavaScript semantics.
213template <typename T>
214T JSMin(T x, T y) {
215  if (std::isnan(x)) return x;
216  if (std::isnan(y)) return y;
217  if (std::signbit(x) < std::signbit(y)) return y;
218  return x > y ? y : x;
219}
220
221// Returns the absolute value of its argument.
222template <typename T>
223T Abs(T a) {
224  return a < 0 ? -a : a;
225}
226
227
228// Floor(-0.0) == 0.0
229inline double Floor(double x) {
230#if V8_CC_MSVC
231  if (x == 0) return x;  // Fix for issue 3477.
232#endif
233  return std::floor(x);
234}
235
236inline double Pow(double x, double y) {
237  if (y == 0.0) return 1.0;
238  if (std::isnan(y) || ((x == 1 || x == -1) && std::isinf(y))) {
239    return std::numeric_limits<double>::quiet_NaN();
240  }
241#if (defined(__MINGW64_VERSION_MAJOR) &&                              \
242     (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1)) || \
243    defined(V8_OS_AIX)
244  // MinGW64 and AIX have a custom implementation for pow.  This handles certain
245  // special cases that are different.
246  if ((x == 0.0 || std::isinf(x)) && y != 0.0 && std::isfinite(y)) {
247    double f;
248    double result = ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0;
249    /* retain sign if odd integer exponent */
250    return ((std::modf(y, &f) == 0.0) && (static_cast<int64_t>(y) & 1))
251               ? copysign(result, x)
252               : result;
253  }
254
255  if (x == 2.0) {
256    int y_int = static_cast<int>(y);
257    if (y == y_int) {
258      return std::ldexp(1.0, y_int);
259    }
260  }
261#endif
262  return std::pow(x, y);
263}
264
265// TODO(svenpanne) Clean up the whole power-of-2 mess.
266inline int32_t WhichPowerOf2Abs(int32_t x) {
267  return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x));
268}
269
270
271// Obtains the unsigned type corresponding to T
272// available in C++11 as std::make_unsigned
273template<typename T>
274struct make_unsigned {
275  typedef T type;
276};
277
278
279// Template specializations necessary to have make_unsigned work
280template<> struct make_unsigned<int32_t> {
281  typedef uint32_t type;
282};
283
284
285template<> struct make_unsigned<int64_t> {
286  typedef uint64_t type;
287};
288
289
290// ----------------------------------------------------------------------------
291// BitField is a help template for encoding and decode bitfield with
292// unsigned content.
293
294template<class T, int shift, int size, class U>
295class BitFieldBase {
296 public:
297  // A type U mask of bit field.  To use all bits of a type U of x bits
298  // in a bitfield without compiler warnings we have to compute 2^x
299  // without using a shift count of x in the computation.
300  static const U kOne = static_cast<U>(1U);
301  static const U kMask = ((kOne << shift) << size) - (kOne << shift);
302  static const U kShift = shift;
303  static const U kSize = size;
304  static const U kNext = kShift + kSize;
305
306  // Value for the field with all bits set.
307  static const T kMax = static_cast<T>((kOne << size) - 1);
308
309  // Tells whether the provided value fits into the bit field.
310  static bool is_valid(T value) {
311    return (static_cast<U>(value) & ~static_cast<U>(kMax)) == 0;
312  }
313
314  // Returns a type U with the bit field value encoded.
315  static U encode(T value) {
316    DCHECK(is_valid(value));
317    return static_cast<U>(value) << shift;
318  }
319
320  // Returns a type U with the bit field value updated.
321  static U update(U previous, T value) {
322    return (previous & ~kMask) | encode(value);
323  }
324
325  // Extracts the bit field from the value.
326  static T decode(U value) {
327    return static_cast<T>((value & kMask) >> shift);
328  }
329
330  STATIC_ASSERT((kNext - 1) / 8 < sizeof(U));
331};
332
333template <class T, int shift, int size>
334class BitField8 : public BitFieldBase<T, shift, size, uint8_t> {};
335
336
337template <class T, int shift, int size>
338class BitField16 : public BitFieldBase<T, shift, size, uint16_t> {};
339
340
341template<class T, int shift, int size>
342class BitField : public BitFieldBase<T, shift, size, uint32_t> { };
343
344
345template<class T, int shift, int size>
346class BitField64 : public BitFieldBase<T, shift, size, uint64_t> { };
347
348
349// ----------------------------------------------------------------------------
350// BitSetComputer is a help template for encoding and decoding information for
351// a variable number of items in an array.
352//
353// To encode boolean data in a smi array you would use:
354// typedef BitSetComputer<bool, 1, kSmiValueSize, uint32_t> BoolComputer;
355//
356template <class T, int kBitsPerItem, int kBitsPerWord, class U>
357class BitSetComputer {
358 public:
359  static const int kItemsPerWord = kBitsPerWord / kBitsPerItem;
360  static const int kMask = (1 << kBitsPerItem) - 1;
361
362  // The number of array elements required to embed T information for each item.
363  static int word_count(int items) {
364    if (items == 0) return 0;
365    return (items - 1) / kItemsPerWord + 1;
366  }
367
368  // The array index to look at for item.
369  static int index(int base_index, int item) {
370    return base_index + item / kItemsPerWord;
371  }
372
373  // Extract T data for a given item from data.
374  static T decode(U data, int item) {
375    return static_cast<T>((data >> shift(item)) & kMask);
376  }
377
378  // Return the encoding for a store of value for item in previous.
379  static U encode(U previous, int item, T value) {
380    int shift_value = shift(item);
381    int set_bits = (static_cast<int>(value) << shift_value);
382    return (previous & ~(kMask << shift_value)) | set_bits;
383  }
384
385  static int shift(int item) { return (item % kItemsPerWord) * kBitsPerItem; }
386};
387
388
389// ----------------------------------------------------------------------------
390// Hash function.
391
392static const uint32_t kZeroHashSeed = 0;
393
394// Thomas Wang, Integer Hash Functions.
395// http://www.concentric.net/~Ttwang/tech/inthash.htm
396inline uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed) {
397  uint32_t hash = key;
398  hash = hash ^ seed;
399  hash = ~hash + (hash << 15);  // hash = (hash << 15) - hash - 1;
400  hash = hash ^ (hash >> 12);
401  hash = hash + (hash << 2);
402  hash = hash ^ (hash >> 4);
403  hash = hash * 2057;  // hash = (hash + (hash << 3)) + (hash << 11);
404  hash = hash ^ (hash >> 16);
405  return hash & 0x3fffffff;
406}
407
408
409inline uint32_t ComputeLongHash(uint64_t key) {
410  uint64_t hash = key;
411  hash = ~hash + (hash << 18);  // hash = (hash << 18) - hash - 1;
412  hash = hash ^ (hash >> 31);
413  hash = hash * 21;  // hash = (hash + (hash << 2)) + (hash << 4);
414  hash = hash ^ (hash >> 11);
415  hash = hash + (hash << 6);
416  hash = hash ^ (hash >> 22);
417  return static_cast<uint32_t>(hash);
418}
419
420
421inline uint32_t ComputePointerHash(void* ptr) {
422  return ComputeIntegerHash(
423      static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)),
424      v8::internal::kZeroHashSeed);
425}
426
427
428// ----------------------------------------------------------------------------
429// Generated memcpy/memmove
430
431// Initializes the codegen support that depends on CPU features.
432void init_memcopy_functions(Isolate* isolate);
433
434#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X87)
435// Limit below which the extra overhead of the MemCopy function is likely
436// to outweigh the benefits of faster copying.
437const int kMinComplexMemCopy = 64;
438
439// Copy memory area. No restrictions.
440V8_EXPORT_PRIVATE void MemMove(void* dest, const void* src, size_t size);
441typedef void (*MemMoveFunction)(void* dest, const void* src, size_t size);
442
443// Keep the distinction of "move" vs. "copy" for the benefit of other
444// architectures.
445V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
446  MemMove(dest, src, size);
447}
448#elif defined(V8_HOST_ARCH_ARM)
449typedef void (*MemCopyUint8Function)(uint8_t* dest, const uint8_t* src,
450                                     size_t size);
451V8_EXPORT_PRIVATE extern MemCopyUint8Function memcopy_uint8_function;
452V8_INLINE void MemCopyUint8Wrapper(uint8_t* dest, const uint8_t* src,
453                                   size_t chars) {
454  memcpy(dest, src, chars);
455}
456// For values < 16, the assembler function is slower than the inlined C code.
457const int kMinComplexMemCopy = 16;
458V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
459  (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
460                            reinterpret_cast<const uint8_t*>(src), size);
461}
462V8_EXPORT_PRIVATE V8_INLINE void MemMove(void* dest, const void* src,
463                                         size_t size) {
464  memmove(dest, src, size);
465}
466
467typedef void (*MemCopyUint16Uint8Function)(uint16_t* dest, const uint8_t* src,
468                                           size_t size);
469extern MemCopyUint16Uint8Function memcopy_uint16_uint8_function;
470void MemCopyUint16Uint8Wrapper(uint16_t* dest, const uint8_t* src,
471                               size_t chars);
472// For values < 12, the assembler function is slower than the inlined C code.
473const int kMinComplexConvertMemCopy = 12;
474V8_INLINE void MemCopyUint16Uint8(uint16_t* dest, const uint8_t* src,
475                                  size_t size) {
476  (*memcopy_uint16_uint8_function)(dest, src, size);
477}
478#elif defined(V8_HOST_ARCH_MIPS)
479typedef void (*MemCopyUint8Function)(uint8_t* dest, const uint8_t* src,
480                                     size_t size);
481V8_EXPORT_PRIVATE extern MemCopyUint8Function memcopy_uint8_function;
482V8_INLINE void MemCopyUint8Wrapper(uint8_t* dest, const uint8_t* src,
483                                   size_t chars) {
484  memcpy(dest, src, chars);
485}
486// For values < 16, the assembler function is slower than the inlined C code.
487const int kMinComplexMemCopy = 16;
488V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
489  (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
490                            reinterpret_cast<const uint8_t*>(src), size);
491}
492V8_EXPORT_PRIVATE V8_INLINE void MemMove(void* dest, const void* src,
493                                         size_t size) {
494  memmove(dest, src, size);
495}
496#else
497// Copy memory area to disjoint memory area.
498V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
499  memcpy(dest, src, size);
500}
501V8_EXPORT_PRIVATE V8_INLINE void MemMove(void* dest, const void* src,
502                                         size_t size) {
503  memmove(dest, src, size);
504}
505const int kMinComplexMemCopy = 16 * kPointerSize;
506#endif  // V8_TARGET_ARCH_IA32
507
508
509// ----------------------------------------------------------------------------
510// Miscellaneous
511
512// A static resource holds a static instance that can be reserved in
513// a local scope using an instance of Access.  Attempts to re-reserve
514// the instance will cause an error.
515template <typename T>
516class StaticResource {
517 public:
518  StaticResource() : is_reserved_(false)  {}
519
520 private:
521  template <typename S> friend class Access;
522  T instance_;
523  bool is_reserved_;
524};
525
526
527// Locally scoped access to a static resource.
528template <typename T>
529class Access {
530 public:
531  explicit Access(StaticResource<T>* resource)
532    : resource_(resource)
533    , instance_(&resource->instance_) {
534    DCHECK(!resource->is_reserved_);
535    resource->is_reserved_ = true;
536  }
537
538  ~Access() {
539    resource_->is_reserved_ = false;
540    resource_ = NULL;
541    instance_ = NULL;
542  }
543
544  T* value()  { return instance_; }
545  T* operator -> ()  { return instance_; }
546
547 private:
548  StaticResource<T>* resource_;
549  T* instance_;
550};
551
552
553// A pointer that can only be set once and doesn't allow NULL values.
554template<typename T>
555class SetOncePointer {
556 public:
557  SetOncePointer() : pointer_(NULL) { }
558
559  bool is_set() const { return pointer_ != NULL; }
560
561  T* get() const {
562    DCHECK(pointer_ != NULL);
563    return pointer_;
564  }
565
566  void set(T* value) {
567    DCHECK(pointer_ == NULL && value != NULL);
568    pointer_ = value;
569  }
570
571 private:
572  T* pointer_;
573};
574
575
576template <typename T, int kSize>
577class EmbeddedVector : public Vector<T> {
578 public:
579  EmbeddedVector() : Vector<T>(buffer_, kSize) { }
580
581  explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) {
582    for (int i = 0; i < kSize; ++i) {
583      buffer_[i] = initial_value;
584    }
585  }
586
587  // When copying, make underlying Vector to reference our buffer.
588  EmbeddedVector(const EmbeddedVector& rhs)
589      : Vector<T>(rhs) {
590    MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
591    this->set_start(buffer_);
592  }
593
594  EmbeddedVector& operator=(const EmbeddedVector& rhs) {
595    if (this == &rhs) return *this;
596    Vector<T>::operator=(rhs);
597    MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
598    this->set_start(buffer_);
599    return *this;
600  }
601
602 private:
603  T buffer_[kSize];
604};
605
606// Compare 8bit/16bit chars to 8bit/16bit chars.
607template <typename lchar, typename rchar>
608inline int CompareCharsUnsigned(const lchar* lhs, const rchar* rhs,
609                                size_t chars) {
610  const lchar* limit = lhs + chars;
611  if (sizeof(*lhs) == sizeof(char) && sizeof(*rhs) == sizeof(char)) {
612    // memcmp compares byte-by-byte, yielding wrong results for two-byte
613    // strings on little-endian systems.
614    return memcmp(lhs, rhs, chars);
615  }
616  while (lhs < limit) {
617    int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
618    if (r != 0) return r;
619    ++lhs;
620    ++rhs;
621  }
622  return 0;
623}
624
625template <typename lchar, typename rchar>
626inline int CompareChars(const lchar* lhs, const rchar* rhs, size_t chars) {
627  DCHECK(sizeof(lchar) <= 2);
628  DCHECK(sizeof(rchar) <= 2);
629  if (sizeof(lchar) == 1) {
630    if (sizeof(rchar) == 1) {
631      return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs),
632                                  reinterpret_cast<const uint8_t*>(rhs),
633                                  chars);
634    } else {
635      return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs),
636                                  reinterpret_cast<const uint16_t*>(rhs),
637                                  chars);
638    }
639  } else {
640    if (sizeof(rchar) == 1) {
641      return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs),
642                                  reinterpret_cast<const uint8_t*>(rhs),
643                                  chars);
644    } else {
645      return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs),
646                                  reinterpret_cast<const uint16_t*>(rhs),
647                                  chars);
648    }
649  }
650}
651
652
653// Calculate 10^exponent.
654inline int TenToThe(int exponent) {
655  DCHECK(exponent <= 9);
656  DCHECK(exponent >= 1);
657  int answer = 10;
658  for (int i = 1; i < exponent; i++) answer *= 10;
659  return answer;
660}
661
662
663template<typename ElementType, int NumElements>
664class EmbeddedContainer {
665 public:
666  EmbeddedContainer() : elems_() { }
667
668  int length() const { return NumElements; }
669  const ElementType& operator[](int i) const {
670    DCHECK(i < length());
671    return elems_[i];
672  }
673  ElementType& operator[](int i) {
674    DCHECK(i < length());
675    return elems_[i];
676  }
677
678 private:
679  ElementType elems_[NumElements];
680};
681
682
683template<typename ElementType>
684class EmbeddedContainer<ElementType, 0> {
685 public:
686  int length() const { return 0; }
687  const ElementType& operator[](int i) const {
688    UNREACHABLE();
689    static ElementType t = 0;
690    return t;
691  }
692  ElementType& operator[](int i) {
693    UNREACHABLE();
694    static ElementType t = 0;
695    return t;
696  }
697};
698
699
700// Helper class for building result strings in a character buffer. The
701// purpose of the class is to use safe operations that checks the
702// buffer bounds on all operations in debug mode.
703// This simple base class does not allow formatted output.
704class SimpleStringBuilder {
705 public:
706  // Create a string builder with a buffer of the given size. The
707  // buffer is allocated through NewArray<char> and must be
708  // deallocated by the caller of Finalize().
709  explicit SimpleStringBuilder(int size);
710
711  SimpleStringBuilder(char* buffer, int size)
712      : buffer_(buffer, size), position_(0) { }
713
714  ~SimpleStringBuilder() { if (!is_finalized()) Finalize(); }
715
716  int size() const { return buffer_.length(); }
717
718  // Get the current position in the builder.
719  int position() const {
720    DCHECK(!is_finalized());
721    return position_;
722  }
723
724  // Reset the position.
725  void Reset() { position_ = 0; }
726
727  // Add a single character to the builder. It is not allowed to add
728  // 0-characters; use the Finalize() method to terminate the string
729  // instead.
730  void AddCharacter(char c) {
731    DCHECK(c != '\0');
732    DCHECK(!is_finalized() && position_ < buffer_.length());
733    buffer_[position_++] = c;
734  }
735
736  // Add an entire string to the builder. Uses strlen() internally to
737  // compute the length of the input string.
738  void AddString(const char* s);
739
740  // Add the first 'n' characters of the given 0-terminated string 's' to the
741  // builder. The input string must have enough characters.
742  void AddSubstring(const char* s, int n);
743
744  // Add character padding to the builder. If count is non-positive,
745  // nothing is added to the builder.
746  void AddPadding(char c, int count);
747
748  // Add the decimal representation of the value.
749  void AddDecimalInteger(int value);
750
751  // Finalize the string by 0-terminating it and returning the buffer.
752  char* Finalize();
753
754 protected:
755  Vector<char> buffer_;
756  int position_;
757
758  bool is_finalized() const { return position_ < 0; }
759
760 private:
761  DISALLOW_IMPLICIT_CONSTRUCTORS(SimpleStringBuilder);
762};
763
764
765// A poor man's version of STL's bitset: A bit set of enums E (without explicit
766// values), fitting into an integral type T.
767template <class E, class T = int>
768class EnumSet {
769 public:
770  explicit EnumSet(T bits = 0) : bits_(bits) {}
771  bool IsEmpty() const { return bits_ == 0; }
772  bool Contains(E element) const { return (bits_ & Mask(element)) != 0; }
773  bool ContainsAnyOf(const EnumSet& set) const {
774    return (bits_ & set.bits_) != 0;
775  }
776  void Add(E element) { bits_ |= Mask(element); }
777  void Add(const EnumSet& set) { bits_ |= set.bits_; }
778  void Remove(E element) { bits_ &= ~Mask(element); }
779  void Remove(const EnumSet& set) { bits_ &= ~set.bits_; }
780  void RemoveAll() { bits_ = 0; }
781  void Intersect(const EnumSet& set) { bits_ &= set.bits_; }
782  T ToIntegral() const { return bits_; }
783  bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
784  bool operator!=(const EnumSet& set) { return bits_ != set.bits_; }
785  EnumSet<E, T> operator|(const EnumSet& set) const {
786    return EnumSet<E, T>(bits_ | set.bits_);
787  }
788
789 private:
790  T Mask(E element) const {
791    // The strange typing in DCHECK is necessary to avoid stupid warnings, see:
792    // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680
793    DCHECK(static_cast<int>(element) < static_cast<int>(sizeof(T) * CHAR_BIT));
794    return static_cast<T>(1) << element;
795  }
796
797  T bits_;
798};
799
800// Bit field extraction.
801inline uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x) {
802  return (x >> lsb) & ((1 << (1 + msb - lsb)) - 1);
803}
804
805inline uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x) {
806  return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1);
807}
808
809inline int32_t signed_bitextract_32(int msb, int lsb, int32_t x) {
810  return (x << (31 - msb)) >> (lsb + 31 - msb);
811}
812
813inline int signed_bitextract_64(int msb, int lsb, int x) {
814  // TODO(jbramley): This is broken for big bitfields.
815  return (x << (63 - msb)) >> (lsb + 63 - msb);
816}
817
818// Check number width.
819inline bool is_intn(int64_t x, unsigned n) {
820  DCHECK((0 < n) && (n < 64));
821  int64_t limit = static_cast<int64_t>(1) << (n - 1);
822  return (-limit <= x) && (x < limit);
823}
824
825inline bool is_uintn(int64_t x, unsigned n) {
826  DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
827  return !(x >> n);
828}
829
830template <class T>
831inline T truncate_to_intn(T x, unsigned n) {
832  DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
833  return (x & ((static_cast<T>(1) << n) - 1));
834}
835
836#define INT_1_TO_63_LIST(V)                                                    \
837V(1)  V(2)  V(3)  V(4)  V(5)  V(6)  V(7)  V(8)                                 \
838V(9)  V(10) V(11) V(12) V(13) V(14) V(15) V(16)                                \
839V(17) V(18) V(19) V(20) V(21) V(22) V(23) V(24)                                \
840V(25) V(26) V(27) V(28) V(29) V(30) V(31) V(32)                                \
841V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40)                                \
842V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48)                                \
843V(49) V(50) V(51) V(52) V(53) V(54) V(55) V(56)                                \
844V(57) V(58) V(59) V(60) V(61) V(62) V(63)
845
846#define DECLARE_IS_INT_N(N)                                                    \
847inline bool is_int##N(int64_t x) { return is_intn(x, N); }
848#define DECLARE_IS_UINT_N(N)                                                   \
849template <class T>                                                             \
850inline bool is_uint##N(T x) { return is_uintn(x, N); }
851#define DECLARE_TRUNCATE_TO_INT_N(N)                                           \
852template <class T>                                                             \
853inline T truncate_to_int##N(T x) { return truncate_to_intn(x, N); }
854INT_1_TO_63_LIST(DECLARE_IS_INT_N)
855INT_1_TO_63_LIST(DECLARE_IS_UINT_N)
856INT_1_TO_63_LIST(DECLARE_TRUNCATE_TO_INT_N)
857#undef DECLARE_IS_INT_N
858#undef DECLARE_IS_UINT_N
859#undef DECLARE_TRUNCATE_TO_INT_N
860
861class TypeFeedbackId {
862 public:
863  explicit TypeFeedbackId(int id) : id_(id) { }
864  int ToInt() const { return id_; }
865
866  static TypeFeedbackId None() { return TypeFeedbackId(kNoneId); }
867  bool IsNone() const { return id_ == kNoneId; }
868
869 private:
870  static const int kNoneId = -1;
871
872  int id_;
873};
874
875inline bool operator<(TypeFeedbackId lhs, TypeFeedbackId rhs) {
876  return lhs.ToInt() < rhs.ToInt();
877}
878inline bool operator>(TypeFeedbackId lhs, TypeFeedbackId rhs) {
879  return lhs.ToInt() > rhs.ToInt();
880}
881
882
883class FeedbackVectorSlot {
884 public:
885  FeedbackVectorSlot() : id_(kInvalidSlot) {}
886  explicit FeedbackVectorSlot(int id) : id_(id) {}
887
888  int ToInt() const { return id_; }
889
890  static FeedbackVectorSlot Invalid() { return FeedbackVectorSlot(); }
891  bool IsInvalid() const { return id_ == kInvalidSlot; }
892
893  bool operator==(FeedbackVectorSlot that) const {
894    return this->id_ == that.id_;
895  }
896  bool operator!=(FeedbackVectorSlot that) const { return !(*this == that); }
897
898  friend size_t hash_value(FeedbackVectorSlot slot) { return slot.ToInt(); }
899  friend std::ostream& operator<<(std::ostream& os, FeedbackVectorSlot);
900
901 private:
902  static const int kInvalidSlot = -1;
903
904  int id_;
905};
906
907
908class BailoutId {
909 public:
910  explicit BailoutId(int id) : id_(id) { }
911  int ToInt() const { return id_; }
912
913  static BailoutId None() { return BailoutId(kNoneId); }
914  static BailoutId ScriptContext() { return BailoutId(kScriptContextId); }
915  static BailoutId FunctionContext() { return BailoutId(kFunctionContextId); }
916  static BailoutId FunctionEntry() { return BailoutId(kFunctionEntryId); }
917  static BailoutId Declarations() { return BailoutId(kDeclarationsId); }
918  static BailoutId FirstUsable() { return BailoutId(kFirstUsableId); }
919  static BailoutId StubEntry() { return BailoutId(kStubEntryId); }
920
921  bool IsNone() const { return id_ == kNoneId; }
922  bool operator==(const BailoutId& other) const { return id_ == other.id_; }
923  bool operator!=(const BailoutId& other) const { return id_ != other.id_; }
924  friend size_t hash_value(BailoutId);
925  V8_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream&, BailoutId);
926
927 private:
928  static const int kNoneId = -1;
929
930  // Using 0 could disguise errors.
931  static const int kScriptContextId = 1;
932  static const int kFunctionContextId = 2;
933  static const int kFunctionEntryId = 3;
934
935  // This AST id identifies the point after the declarations have been visited.
936  // We need it to capture the environment effects of declarations that emit
937  // code (function declarations).
938  static const int kDeclarationsId = 4;
939
940  // Every FunctionState starts with this id.
941  static const int kFirstUsableId = 5;
942
943  // Every compiled stub starts with this id.
944  static const int kStubEntryId = 6;
945
946  int id_;
947};
948
949class TokenDispenserForFinally {
950 public:
951  int GetBreakContinueToken() { return next_token_++; }
952  static const int kFallThroughToken = 0;
953  static const int kThrowToken = 1;
954  static const int kReturnToken = 2;
955
956  static const int kFirstBreakContinueToken = 3;
957  static const int kInvalidToken = -1;
958
959 private:
960  int next_token_ = kFirstBreakContinueToken;
961};
962
963// ----------------------------------------------------------------------------
964// I/O support.
965
966// Our version of printf().
967V8_EXPORT_PRIVATE void PRINTF_FORMAT(1, 2) PrintF(const char* format, ...);
968void PRINTF_FORMAT(2, 3) PrintF(FILE* out, const char* format, ...);
969
970// Prepends the current process ID to the output.
971void PRINTF_FORMAT(1, 2) PrintPID(const char* format, ...);
972
973// Prepends the current process ID and given isolate pointer to the output.
974void PRINTF_FORMAT(2, 3) PrintIsolate(void* isolate, const char* format, ...);
975
976// Safe formatting print. Ensures that str is always null-terminated.
977// Returns the number of chars written, or -1 if output was truncated.
978int PRINTF_FORMAT(2, 3) SNPrintF(Vector<char> str, const char* format, ...);
979int PRINTF_FORMAT(2, 0)
980    VSNPrintF(Vector<char> str, const char* format, va_list args);
981
982void StrNCpy(Vector<char> dest, const char* src, size_t n);
983
984// Our version of fflush.
985void Flush(FILE* out);
986
987inline void Flush() {
988  Flush(stdout);
989}
990
991
992// Read a line of characters after printing the prompt to stdout. The resulting
993// char* needs to be disposed off with DeleteArray by the caller.
994char* ReadLine(const char* prompt);
995
996
997// Read and return the raw bytes in a file. the size of the buffer is returned
998// in size.
999// The returned buffer must be freed by the caller.
1000byte* ReadBytes(const char* filename, int* size, bool verbose = true);
1001
1002
1003// Append size chars from str to the file given by filename.
1004// The file is overwritten. Returns the number of chars written.
1005int AppendChars(const char* filename,
1006                const char* str,
1007                int size,
1008                bool verbose = true);
1009
1010
1011// Write size chars from str to the file given by filename.
1012// The file is overwritten. Returns the number of chars written.
1013int WriteChars(const char* filename,
1014               const char* str,
1015               int size,
1016               bool verbose = true);
1017
1018
1019// Write size bytes to the file given by filename.
1020// The file is overwritten. Returns the number of bytes written.
1021int WriteBytes(const char* filename,
1022               const byte* bytes,
1023               int size,
1024               bool verbose = true);
1025
1026
1027// Write the C code
1028// const char* <varname> = "<str>";
1029// const int <varname>_len = <len>;
1030// to the file given by filename. Only the first len chars are written.
1031int WriteAsCFile(const char* filename, const char* varname,
1032                 const char* str, int size, bool verbose = true);
1033
1034
1035// ----------------------------------------------------------------------------
1036// Memory
1037
1038// Copies words from |src| to |dst|. The data spans must not overlap.
1039template <typename T>
1040inline void CopyWords(T* dst, const T* src, size_t num_words) {
1041  STATIC_ASSERT(sizeof(T) == kPointerSize);
1042  // TODO(mvstanton): disabled because mac builds are bogus failing on this
1043  // assert. They are doing a signed comparison. Investigate in
1044  // the morning.
1045  // DCHECK(Min(dst, const_cast<T*>(src)) + num_words <=
1046  //       Max(dst, const_cast<T*>(src)));
1047  DCHECK(num_words > 0);
1048
1049  // Use block copying MemCopy if the segment we're copying is
1050  // enough to justify the extra call/setup overhead.
1051  static const size_t kBlockCopyLimit = 16;
1052
1053  if (num_words < kBlockCopyLimit) {
1054    do {
1055      num_words--;
1056      *dst++ = *src++;
1057    } while (num_words > 0);
1058  } else {
1059    MemCopy(dst, src, num_words * kPointerSize);
1060  }
1061}
1062
1063
1064// Copies words from |src| to |dst|. No restrictions.
1065template <typename T>
1066inline void MoveWords(T* dst, const T* src, size_t num_words) {
1067  STATIC_ASSERT(sizeof(T) == kPointerSize);
1068  DCHECK(num_words > 0);
1069
1070  // Use block copying MemCopy if the segment we're copying is
1071  // enough to justify the extra call/setup overhead.
1072  static const size_t kBlockCopyLimit = 16;
1073
1074  if (num_words < kBlockCopyLimit &&
1075      ((dst < src) || (dst >= (src + num_words * kPointerSize)))) {
1076    T* end = dst + num_words;
1077    do {
1078      num_words--;
1079      *dst++ = *src++;
1080    } while (num_words > 0);
1081  } else {
1082    MemMove(dst, src, num_words * kPointerSize);
1083  }
1084}
1085
1086
1087// Copies data from |src| to |dst|.  The data spans must not overlap.
1088template <typename T>
1089inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
1090  STATIC_ASSERT(sizeof(T) == 1);
1091  DCHECK(Min(dst, const_cast<T*>(src)) + num_bytes <=
1092         Max(dst, const_cast<T*>(src)));
1093  if (num_bytes == 0) return;
1094
1095  // Use block copying MemCopy if the segment we're copying is
1096  // enough to justify the extra call/setup overhead.
1097  static const int kBlockCopyLimit = kMinComplexMemCopy;
1098
1099  if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
1100    do {
1101      num_bytes--;
1102      *dst++ = *src++;
1103    } while (num_bytes > 0);
1104  } else {
1105    MemCopy(dst, src, num_bytes);
1106  }
1107}
1108
1109
1110template <typename T, typename U>
1111inline void MemsetPointer(T** dest, U* value, int counter) {
1112#ifdef DEBUG
1113  T* a = NULL;
1114  U* b = NULL;
1115  a = b;  // Fake assignment to check assignability.
1116  USE(a);
1117#endif  // DEBUG
1118#if V8_HOST_ARCH_IA32
1119#define STOS "stosl"
1120#elif V8_HOST_ARCH_X64
1121#if V8_HOST_ARCH_32_BIT
1122#define STOS "addr32 stosl"
1123#else
1124#define STOS "stosq"
1125#endif
1126#endif
1127
1128#if defined(MEMORY_SANITIZER)
1129  // MemorySanitizer does not understand inline assembly.
1130#undef STOS
1131#endif
1132
1133#if defined(__GNUC__) && defined(STOS)
1134  asm volatile(
1135      "cld;"
1136      "rep ; " STOS
1137      : "+&c" (counter), "+&D" (dest)
1138      : "a" (value)
1139      : "memory", "cc");
1140#else
1141  for (int i = 0; i < counter; i++) {
1142    dest[i] = value;
1143  }
1144#endif
1145
1146#undef STOS
1147}
1148
1149
1150// Simple support to read a file into a 0-terminated C-string.
1151// The returned buffer must be freed by the caller.
1152// On return, *exits tells whether the file existed.
1153V8_EXPORT_PRIVATE Vector<const char> ReadFile(const char* filename,
1154                                              bool* exists,
1155                                              bool verbose = true);
1156Vector<const char> ReadFile(FILE* file,
1157                            bool* exists,
1158                            bool verbose = true);
1159
1160
1161template <typename sourcechar, typename sinkchar>
1162INLINE(static void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src,
1163                                     size_t chars));
1164#if defined(V8_HOST_ARCH_ARM)
1165INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars));
1166INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src,
1167                              size_t chars));
1168INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
1169                              size_t chars));
1170#elif defined(V8_HOST_ARCH_MIPS)
1171INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars));
1172INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
1173                              size_t chars));
1174#elif defined(V8_HOST_ARCH_PPC) || defined(V8_HOST_ARCH_S390)
1175INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars));
1176INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
1177                              size_t chars));
1178#endif
1179
1180// Copy from 8bit/16bit chars to 8bit/16bit chars.
1181template <typename sourcechar, typename sinkchar>
1182INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, size_t chars));
1183
1184template <typename sourcechar, typename sinkchar>
1185void CopyChars(sinkchar* dest, const sourcechar* src, size_t chars) {
1186  DCHECK(sizeof(sourcechar) <= 2);
1187  DCHECK(sizeof(sinkchar) <= 2);
1188  if (sizeof(sinkchar) == 1) {
1189    if (sizeof(sourcechar) == 1) {
1190      CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
1191                        reinterpret_cast<const uint8_t*>(src),
1192                        chars);
1193    } else {
1194      CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
1195                        reinterpret_cast<const uint16_t*>(src),
1196                        chars);
1197    }
1198  } else {
1199    if (sizeof(sourcechar) == 1) {
1200      CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
1201                        reinterpret_cast<const uint8_t*>(src),
1202                        chars);
1203    } else {
1204      CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
1205                        reinterpret_cast<const uint16_t*>(src),
1206                        chars);
1207    }
1208  }
1209}
1210
1211template <typename sourcechar, typename sinkchar>
1212void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, size_t chars) {
1213  sinkchar* limit = dest + chars;
1214  if ((sizeof(*dest) == sizeof(*src)) &&
1215      (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest)))) {
1216    MemCopy(dest, src, chars * sizeof(*dest));
1217  } else {
1218    while (dest < limit) *dest++ = static_cast<sinkchar>(*src++);
1219  }
1220}
1221
1222
1223#if defined(V8_HOST_ARCH_ARM)
1224void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
1225  switch (static_cast<unsigned>(chars)) {
1226    case 0:
1227      break;
1228    case 1:
1229      *dest = *src;
1230      break;
1231    case 2:
1232      memcpy(dest, src, 2);
1233      break;
1234    case 3:
1235      memcpy(dest, src, 3);
1236      break;
1237    case 4:
1238      memcpy(dest, src, 4);
1239      break;
1240    case 5:
1241      memcpy(dest, src, 5);
1242      break;
1243    case 6:
1244      memcpy(dest, src, 6);
1245      break;
1246    case 7:
1247      memcpy(dest, src, 7);
1248      break;
1249    case 8:
1250      memcpy(dest, src, 8);
1251      break;
1252    case 9:
1253      memcpy(dest, src, 9);
1254      break;
1255    case 10:
1256      memcpy(dest, src, 10);
1257      break;
1258    case 11:
1259      memcpy(dest, src, 11);
1260      break;
1261    case 12:
1262      memcpy(dest, src, 12);
1263      break;
1264    case 13:
1265      memcpy(dest, src, 13);
1266      break;
1267    case 14:
1268      memcpy(dest, src, 14);
1269      break;
1270    case 15:
1271      memcpy(dest, src, 15);
1272      break;
1273    default:
1274      MemCopy(dest, src, chars);
1275      break;
1276  }
1277}
1278
1279
1280void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, size_t chars) {
1281  if (chars >= static_cast<size_t>(kMinComplexConvertMemCopy)) {
1282    MemCopyUint16Uint8(dest, src, chars);
1283  } else {
1284    MemCopyUint16Uint8Wrapper(dest, src, chars);
1285  }
1286}
1287
1288
1289void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
1290  switch (static_cast<unsigned>(chars)) {
1291    case 0:
1292      break;
1293    case 1:
1294      *dest = *src;
1295      break;
1296    case 2:
1297      memcpy(dest, src, 4);
1298      break;
1299    case 3:
1300      memcpy(dest, src, 6);
1301      break;
1302    case 4:
1303      memcpy(dest, src, 8);
1304      break;
1305    case 5:
1306      memcpy(dest, src, 10);
1307      break;
1308    case 6:
1309      memcpy(dest, src, 12);
1310      break;
1311    case 7:
1312      memcpy(dest, src, 14);
1313      break;
1314    default:
1315      MemCopy(dest, src, chars * sizeof(*dest));
1316      break;
1317  }
1318}
1319
1320
1321#elif defined(V8_HOST_ARCH_MIPS)
1322void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
1323  if (chars < kMinComplexMemCopy) {
1324    memcpy(dest, src, chars);
1325  } else {
1326    MemCopy(dest, src, chars);
1327  }
1328}
1329
1330void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
1331  if (chars < kMinComplexMemCopy) {
1332    memcpy(dest, src, chars * sizeof(*dest));
1333  } else {
1334    MemCopy(dest, src, chars * sizeof(*dest));
1335  }
1336}
1337#elif defined(V8_HOST_ARCH_PPC) || defined(V8_HOST_ARCH_S390)
1338#define CASE(n)           \
1339  case n:                 \
1340    memcpy(dest, src, n); \
1341    break
1342void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
1343  switch (static_cast<unsigned>(chars)) {
1344    case 0:
1345      break;
1346    case 1:
1347      *dest = *src;
1348      break;
1349      CASE(2);
1350      CASE(3);
1351      CASE(4);
1352      CASE(5);
1353      CASE(6);
1354      CASE(7);
1355      CASE(8);
1356      CASE(9);
1357      CASE(10);
1358      CASE(11);
1359      CASE(12);
1360      CASE(13);
1361      CASE(14);
1362      CASE(15);
1363      CASE(16);
1364      CASE(17);
1365      CASE(18);
1366      CASE(19);
1367      CASE(20);
1368      CASE(21);
1369      CASE(22);
1370      CASE(23);
1371      CASE(24);
1372      CASE(25);
1373      CASE(26);
1374      CASE(27);
1375      CASE(28);
1376      CASE(29);
1377      CASE(30);
1378      CASE(31);
1379      CASE(32);
1380      CASE(33);
1381      CASE(34);
1382      CASE(35);
1383      CASE(36);
1384      CASE(37);
1385      CASE(38);
1386      CASE(39);
1387      CASE(40);
1388      CASE(41);
1389      CASE(42);
1390      CASE(43);
1391      CASE(44);
1392      CASE(45);
1393      CASE(46);
1394      CASE(47);
1395      CASE(48);
1396      CASE(49);
1397      CASE(50);
1398      CASE(51);
1399      CASE(52);
1400      CASE(53);
1401      CASE(54);
1402      CASE(55);
1403      CASE(56);
1404      CASE(57);
1405      CASE(58);
1406      CASE(59);
1407      CASE(60);
1408      CASE(61);
1409      CASE(62);
1410      CASE(63);
1411      CASE(64);
1412    default:
1413      memcpy(dest, src, chars);
1414      break;
1415  }
1416}
1417#undef CASE
1418
1419#define CASE(n)               \
1420  case n:                     \
1421    memcpy(dest, src, n * 2); \
1422    break
1423void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
1424  switch (static_cast<unsigned>(chars)) {
1425    case 0:
1426      break;
1427    case 1:
1428      *dest = *src;
1429      break;
1430      CASE(2);
1431      CASE(3);
1432      CASE(4);
1433      CASE(5);
1434      CASE(6);
1435      CASE(7);
1436      CASE(8);
1437      CASE(9);
1438      CASE(10);
1439      CASE(11);
1440      CASE(12);
1441      CASE(13);
1442      CASE(14);
1443      CASE(15);
1444      CASE(16);
1445      CASE(17);
1446      CASE(18);
1447      CASE(19);
1448      CASE(20);
1449      CASE(21);
1450      CASE(22);
1451      CASE(23);
1452      CASE(24);
1453      CASE(25);
1454      CASE(26);
1455      CASE(27);
1456      CASE(28);
1457      CASE(29);
1458      CASE(30);
1459      CASE(31);
1460      CASE(32);
1461    default:
1462      memcpy(dest, src, chars * 2);
1463      break;
1464  }
1465}
1466#undef CASE
1467#endif
1468
1469
1470class StringBuilder : public SimpleStringBuilder {
1471 public:
1472  explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
1473  StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
1474
1475  // Add formatted contents to the builder just like printf().
1476  void PRINTF_FORMAT(2, 3) AddFormatted(const char* format, ...);
1477
1478  // Add formatted contents like printf based on a va_list.
1479  void PRINTF_FORMAT(2, 0) AddFormattedList(const char* format, va_list list);
1480
1481 private:
1482  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
1483};
1484
1485
1486bool DoubleToBoolean(double d);
1487
1488template <typename Stream>
1489bool StringToArrayIndex(Stream* stream, uint32_t* index) {
1490  uint16_t ch = stream->GetNext();
1491
1492  // If the string begins with a '0' character, it must only consist
1493  // of it to be a legal array index.
1494  if (ch == '0') {
1495    *index = 0;
1496    return !stream->HasMore();
1497  }
1498
1499  // Convert string to uint32 array index; character by character.
1500  int d = ch - '0';
1501  if (d < 0 || d > 9) return false;
1502  uint32_t result = d;
1503  while (stream->HasMore()) {
1504    d = stream->GetNext() - '0';
1505    if (d < 0 || d > 9) return false;
1506    // Check that the new result is below the 32 bit limit.
1507    if (result > 429496729U - ((d + 3) >> 3)) return false;
1508    result = (result * 10) + d;
1509  }
1510
1511  *index = result;
1512  return true;
1513}
1514
1515
1516// Returns current value of top of the stack. Works correctly with ASAN.
1517DISABLE_ASAN
1518inline uintptr_t GetCurrentStackPosition() {
1519  // Takes the address of the limit variable in order to find out where
1520  // the top of stack is right now.
1521  uintptr_t limit = reinterpret_cast<uintptr_t>(&limit);
1522  return limit;
1523}
1524
1525template <typename V>
1526static inline V ReadUnalignedValue(const void* p) {
1527#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM)
1528  return *reinterpret_cast<const V*>(p);
1529#else   // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM
1530  V r;
1531  memmove(&r, p, sizeof(V));
1532  return r;
1533#endif  // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM
1534}
1535
1536template <typename V>
1537static inline void WriteUnalignedValue(void* p, V value) {
1538#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM)
1539  *(reinterpret_cast<V*>(p)) = value;
1540#else   // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM
1541  memmove(p, &value, sizeof(V));
1542#endif  // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM
1543}
1544
1545static inline double ReadFloatValue(const void* p) {
1546  return ReadUnalignedValue<float>(p);
1547}
1548
1549static inline double ReadDoubleValue(const void* p) {
1550  return ReadUnalignedValue<double>(p);
1551}
1552
1553static inline void WriteDoubleValue(void* p, double value) {
1554  WriteUnalignedValue(p, value);
1555}
1556
1557static inline uint16_t ReadUnalignedUInt16(const void* p) {
1558  return ReadUnalignedValue<uint16_t>(p);
1559}
1560
1561static inline void WriteUnalignedUInt16(void* p, uint16_t value) {
1562  WriteUnalignedValue(p, value);
1563}
1564
1565static inline uint32_t ReadUnalignedUInt32(const void* p) {
1566  return ReadUnalignedValue<uint32_t>(p);
1567}
1568
1569static inline void WriteUnalignedUInt32(void* p, uint32_t value) {
1570  WriteUnalignedValue(p, value);
1571}
1572
1573template <typename V>
1574static inline V ReadLittleEndianValue(const void* p) {
1575#if defined(V8_TARGET_LITTLE_ENDIAN)
1576  return ReadUnalignedValue<V>(p);
1577#elif defined(V8_TARGET_BIG_ENDIAN)
1578  V ret = 0;
1579  const byte* src = reinterpret_cast<const byte*>(p);
1580  byte* dst = reinterpret_cast<byte*>(&ret);
1581  for (size_t i = 0; i < sizeof(V); i++) {
1582    dst[i] = src[sizeof(V) - i - 1];
1583  }
1584  return ret;
1585#endif  // V8_TARGET_LITTLE_ENDIAN
1586}
1587
1588template <typename V>
1589static inline void WriteLittleEndianValue(void* p, V value) {
1590#if defined(V8_TARGET_LITTLE_ENDIAN)
1591  WriteUnalignedValue<V>(p, value);
1592#elif defined(V8_TARGET_BIG_ENDIAN)
1593  byte* src = reinterpret_cast<byte*>(&value);
1594  byte* dst = reinterpret_cast<byte*>(p);
1595  for (size_t i = 0; i < sizeof(V); i++) {
1596    dst[i] = src[sizeof(V) - i - 1];
1597  }
1598#endif  // V8_TARGET_LITTLE_ENDIAN
1599}
1600
1601// Represents a linked list that threads through the nodes in the linked list.
1602// Entries in the list are pointers to nodes. The nodes need to have a T**
1603// next() method that returns the location where the next value is stored.
1604template <typename T>
1605class ThreadedList final {
1606 public:
1607  ThreadedList() : head_(nullptr), tail_(&head_) {}
1608  void Add(T* v) {
1609    DCHECK_NULL(*tail_);
1610    DCHECK_NULL(*v->next());
1611    *tail_ = v;
1612    tail_ = v->next();
1613  }
1614
1615  void Clear() {
1616    head_ = nullptr;
1617    tail_ = &head_;
1618  }
1619
1620  class Iterator final {
1621   public:
1622    Iterator& operator++() {
1623      entry_ = (*entry_)->next();
1624      return *this;
1625    }
1626    bool operator!=(const Iterator& other) { return entry_ != other.entry_; }
1627    T* operator*() { return *entry_; }
1628    Iterator& operator=(T* entry) {
1629      T* next = *(*entry_)->next();
1630      *entry->next() = next;
1631      *entry_ = entry;
1632      return *this;
1633    }
1634
1635   private:
1636    explicit Iterator(T** entry) : entry_(entry) {}
1637
1638    T** entry_;
1639
1640    friend class ThreadedList;
1641  };
1642
1643  Iterator begin() { return Iterator(&head_); }
1644  Iterator end() { return Iterator(tail_); }
1645
1646  void Rewind(Iterator reset_point) {
1647    tail_ = reset_point.entry_;
1648    *tail_ = nullptr;
1649  }
1650
1651  void MoveTail(ThreadedList<T>* parent, Iterator location) {
1652    if (parent->end() != location) {
1653      DCHECK_NULL(*tail_);
1654      *tail_ = *location;
1655      tail_ = parent->tail_;
1656      parent->Rewind(location);
1657    }
1658  }
1659
1660  bool is_empty() const { return head_ == nullptr; }
1661
1662  // Slow. For testing purposes.
1663  int LengthForTest() {
1664    int result = 0;
1665    for (Iterator t = begin(); t != end(); ++t) ++result;
1666    return result;
1667  }
1668  T* AtForTest(int i) {
1669    Iterator t = begin();
1670    while (i-- > 0) ++t;
1671    return *t;
1672  }
1673
1674 private:
1675  T* head_;
1676  T** tail_;
1677  DISALLOW_COPY_AND_ASSIGN(ThreadedList);
1678};
1679
1680}  // namespace internal
1681}  // namespace v8
1682
1683#endif  // V8_UTILS_H_
1684