00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef V8_UTILS_H_
00029 #define V8_UTILS_H_
00030
00031 namespace v8 { namespace internal {
00032
00033
00034
00035
00036
00037 template <typename T>
00038 static inline bool IsPowerOf2(T x) {
00039 return (x & (x - 1)) == 0;
00040 }
00041
00042
00043
00044
00045
00046
00047
00048 static inline int ArithmeticShiftRight(int x, int s) {
00049 return x >> s;
00050 }
00051
00052
00053
00054
00055
00056 template <typename T>
00057 static inline int OffsetFrom(T x) {
00058 return x - static_cast<T>(0);
00059 }
00060
00061
00062
00063
00064
00065 template <typename T>
00066 static inline T AddressFrom(int x) {
00067 return static_cast<T>(0) + x;
00068 }
00069
00070
00071
00072 template <typename T>
00073 static inline T RoundDown(T x, int m) {
00074 ASSERT(IsPowerOf2(m));
00075 return AddressFrom<T>(OffsetFrom(x) & -m);
00076 }
00077
00078
00079
00080 template <typename T>
00081 static inline T RoundUp(T x, int m) {
00082 return RoundDown(x + m - 1, m);
00083 }
00084
00085
00086
00087
00088 uint32_t RoundUpToPowerOf2(uint32_t x);
00089
00090
00091 template <typename T>
00092 static inline bool IsAligned(T value, T alignment) {
00093 ASSERT(IsPowerOf2(alignment));
00094 return (value & (alignment - 1)) == 0;
00095 }
00096
00097
00098
00099 static inline bool IsAddressAligned(Address addr, int alignment, int offset) {
00100 int offs = OffsetFrom(addr + offset);
00101 return IsAligned(offs, alignment);
00102 }
00103
00104
00105
00106 template <typename T>
00107 static T Max(T a, T b) {
00108 return a < b ? b : a;
00109 }
00110
00111
00112
00113 template <typename T>
00114 static T Min(T a, T b) {
00115 return a < b ? a : b;
00116 }
00117
00118
00119
00120
00121
00122 template<class T, int shift, int size>
00123 class BitField {
00124 public:
00125
00126 static bool is_valid(T value) {
00127 return (static_cast<uint32_t>(value) & ~((1U << (size)) - 1)) == 0;
00128 }
00129
00130
00131 static uint32_t mask() {
00132 return (1U << (size + shift)) - (1U << shift);
00133 }
00134
00135
00136 static uint32_t encode(T value) {
00137 ASSERT(is_valid(value));
00138 return static_cast<uint32_t>(value) << shift;
00139 }
00140
00141
00142 static T decode(uint32_t value) {
00143 return static_cast<T>((value >> shift) & ((1U << (size)) - 1));
00144 }
00145 };
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 byte* EncodeInt(byte* p, int x);
00159 byte* DecodeInt(byte* p, int* x);
00160
00161
00162
00163
00164
00165
00166 byte* EncodeUnsignedIntBackward(byte* p, unsigned int x);
00167
00168
00169
00170 inline byte* DecodeUnsignedIntBackward(byte* p, unsigned int* x) {
00171 byte b = *--p;
00172 if (b >= 128) {
00173 *x = static_cast<unsigned int>(b) - 128;
00174 return p;
00175 }
00176 unsigned int r = static_cast<unsigned int>(b);
00177 unsigned int s = 7;
00178 b = *--p;
00179 while (b < 128) {
00180 r |= static_cast<unsigned int>(b) << s;
00181 s += 7;
00182 b = *--p;
00183 }
00184
00185 *x = r | ((static_cast<unsigned int>(b) - 128) << s);
00186 return p;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 void PrintF(const char* format, ...);
00198
00199
00200 void Flush();
00201
00202
00203
00204
00205 char* ReadLine(const char* prompt);
00206
00207
00208
00209
00210
00211 char* ReadChars(const char* filename, int* size, bool verbose = true);
00212
00213
00214
00215
00216 int WriteChars(const char* filename,
00217 const char* str,
00218 int size,
00219 bool verbose = true);
00220
00221
00222
00223
00224
00225
00226 int WriteAsCFile(const char* filename, const char* varname,
00227 const char* str, int size, bool verbose = true);
00228
00229
00230
00231
00232
00233
00234
00235
00236 template <typename T>
00237 class StaticResource {
00238 public:
00239 StaticResource() : is_reserved_(false) {}
00240
00241 private:
00242 template <typename S> friend class Access;
00243 T instance_;
00244 bool is_reserved_;
00245 };
00246
00247
00248
00249 template <typename T>
00250 class Access {
00251 public:
00252 explicit Access(StaticResource<T>* resource)
00253 : resource_(resource)
00254 , instance_(&resource->instance_) {
00255 ASSERT(!resource->is_reserved_);
00256 resource->is_reserved_ = true;
00257 }
00258
00259 ~Access() {
00260 resource_->is_reserved_ = false;
00261 resource_ = NULL;
00262 instance_ = NULL;
00263 }
00264
00265 T* value() { return instance_; }
00266 T* operator -> () { return instance_; }
00267
00268 private:
00269 StaticResource<T>* resource_;
00270 T* instance_;
00271 };
00272
00273
00274 template <typename T>
00275 class Vector {
00276 public:
00277 Vector() : start_(NULL), length_(0) {}
00278 Vector(T* data, int length) : start_(data), length_(length) {
00279 ASSERT(length == 0 || (length > 0 && data != NULL));
00280 }
00281
00282 static Vector<T> New(int length) {
00283 return Vector<T>(NewArray<T>(length), length);
00284 }
00285
00286
00287 int length() const { return length_; }
00288
00289
00290 bool is_empty() const { return length_ == 0; }
00291
00292
00293 T* start() const { return start_; }
00294
00295
00296 T& operator[](int index) const {
00297 ASSERT(0 <= index && index < length_);
00298 return start_[index];
00299 }
00300
00301
00302 Vector<T> Clone() const {
00303 T* result = NewArray<T>(length_);
00304 for (int i = 0; i < length_; i++) result[i] = start_[i];
00305 return Vector<T>(result, length_);
00306 }
00307
00308
00309
00310 void Dispose() {
00311 if (is_empty()) return;
00312 DeleteArray(start_);
00313 start_ = NULL;
00314 length_ = 0;
00315 }
00316
00317 inline Vector<T> operator+(int offset) {
00318 ASSERT(offset < length_);
00319 return Vector<T>(start_ + offset, length_ - offset);
00320 }
00321
00322
00323 static Vector<T> empty() { return Vector<T>(NULL, 0); }
00324
00325 private:
00326 T* start_;
00327 int length_;
00328 };
00329
00330
00331 template <typename T, int kSize>
00332 class EmbeddedVector : public Vector<T> {
00333 public:
00334 EmbeddedVector() : Vector<T>(buffer_, kSize) { }
00335 private:
00336 T buffer_[kSize];
00337 };
00338
00339
00340 inline Vector<const char> CStrVector(const char* data) {
00341 return Vector<const char>(data, strlen(data));
00342 }
00343
00344 inline Vector<char> MutableCStrVector(char* data) {
00345 return Vector<char>(data, strlen(data));
00346 }
00347
00348 inline Vector<char> MutableCStrVector(char* data, int max) {
00349 int length = strlen(data);
00350 return Vector<char>(data, (length < max) ? length : max);
00351 }
00352
00353 template <typename T>
00354 inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
00355 int length) {
00356 return Vector< Handle<Object> >(
00357 reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
00358 }
00359
00360
00361
00362
00363
00364 Vector<const char> ReadFile(const char* filename,
00365 bool* exists,
00366 bool verbose = true);
00367
00368
00369
00370
00371 class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
00372 public:
00373 explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
00374
00375 virtual const char* data() const { return data_.start(); }
00376
00377 virtual size_t length() const { return data_.length(); }
00378
00379 private:
00380 Vector<const char> data_;
00381 };
00382
00383
00384
00385
00386
00387 class StringBuilder {
00388 public:
00389
00390
00391
00392 explicit StringBuilder(int size);
00393
00394 StringBuilder(char* buffer, int size)
00395 : buffer_(buffer, size), position_(0) { }
00396
00397 ~StringBuilder() { if (!is_finalized()) Finalize(); }
00398
00399 int size() const { return buffer_.length(); }
00400
00401
00402 int position() const {
00403 ASSERT(!is_finalized());
00404 return position_;
00405 }
00406
00407
00408 void Reset() { position_ = 0; }
00409
00410
00411
00412
00413 void AddCharacter(char c) {
00414 ASSERT(c != '\0');
00415 ASSERT(!is_finalized() && position_ < buffer_.length());
00416 buffer_[position_++] = c;
00417 }
00418
00419
00420
00421 void AddString(const char* s);
00422
00423
00424
00425 void AddSubstring(const char* s, int n);
00426
00427
00428 void AddFormatted(const char* format, ...);
00429
00430
00431
00432 void AddPadding(char c, int count);
00433
00434
00435 char* Finalize();
00436
00437 private:
00438 Vector<char> buffer_;
00439 int position_;
00440
00441 bool is_finalized() const { return position_ < 0; }
00442
00443 DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
00444 };
00445
00446
00447
00448 template <typename sourcechar, typename sinkchar>
00449 static inline void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
00450 sinkchar* limit = dest + chars;
00451 #ifdef CAN_READ_UNALIGNED
00452 if (sizeof(*dest) == sizeof(*src)) {
00453
00454 static const int kStepSize = sizeof(uint32_t) / sizeof(*dest);
00455 while (dest <= limit - kStepSize) {
00456 *reinterpret_cast<uint32_t*>(dest) =
00457 *reinterpret_cast<const uint32_t*>(src);
00458 dest += kStepSize;
00459 src += kStepSize;
00460 }
00461 }
00462 #endif
00463 while (dest < limit) {
00464 *dest++ = static_cast<sinkchar>(*src++);
00465 }
00466 }
00467
00468 } }
00469
00470 #endif // V8_UTILS_H_