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