| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #ifndef PLATFORM_UTILS_H_ | |
| #define PLATFORM_UTILS_H_ | |
| #include "platform/assert.h" | |
| #include "platform/globals.h" | |
| namespace dart { | |
| class Utils { | |
| public: | |
| template<typename T> | |
| static inline T Minimum(T x, T y) { | |
| return x < y ? x : y; | |
| } | |
| template<typename T> | |
| static inline T Maximum(T x, T y) { | |
| return x > y ? x : y; | |
| } | |
| template<typename T> | |
| static inline T Abs(T x) { | |
| if (x < 0) return -x; | |
| return x; | |
| } | |
| template<typename T> | |
| static inline bool IsPowerOfTwo(T x) { | |
| return (x & (x - 1)) == 0; | |
| } | |
| template<typename T> | |
| static inline int ShiftForPowerOfTwo(T x) { | |
| ASSERT(IsPowerOfTwo(x)); | |
| int num_shifts = 0; | |
| while (x > 1) { | |
| num_shifts++; | |
| x = x >> 1; | |
| } | |
| return num_shifts; | |
| } | |
| template<typename T> | |
| static inline bool IsAligned(T x, int n) { | |
| ASSERT(IsPowerOfTwo(n)); | |
| return (x & (n - 1)) == 0; | |
| } | |
| template<typename T> | |
| static inline bool IsAligned(T* x, int n) { | |
| return IsAligned(reinterpret_cast<uword>(x), n); | |
| } | |
| template<typename T> | |
| static inline T RoundDown(T x, int n) { | |
| ASSERT(IsPowerOfTwo(n)); | |
| return (x & -n); | |
| } | |
| template<typename T> | |
| static inline T* RoundDown(T* x, int n) { | |
| return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uword>(x), n)); | |
| } | |
| template<typename T> | |
| static inline T RoundUp(T x, int n) { | |
| return RoundDown(x + n - 1, n); | |
| } | |
| template<typename T> | |
| static inline T* RoundUp(T* x, int n) { | |
| return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uword>(x), n)); | |
| } | |
| static uint32_t RoundUpToPowerOfTwo(uint32_t x); | |
| static int CountOneBits(uint32_t x); | |
| static int HighestBit(int64_t v); | |
| static int CountTrailingZeros(uword x); | |
| // Computes a hash value for the given string. | |
| static uint32_t StringHash(const char* data, int length); | |
| // Computes a hash value for the given word. | |
| static uint32_t WordHash(word key); | |
| // Check whether an N-bit two's-complement representation can hold value. | |
| template<typename T> | |
| static inline bool IsInt(int N, T value) { | |
| ASSERT((0 < N) && | |
| (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); | |
| T limit = static_cast<T>(1) << (N - 1); | |
| return (-limit <= value) && (value < limit); | |
| } | |
| template<typename T> | |
| static inline bool IsUint(int N, T value) { | |
| ASSERT((0 < N) && | |
| (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); | |
| T limit = static_cast<T>(1) << N; | |
| return (0 <= value) && (value < limit); | |
| } | |
| // Check whether the magnitude of value fits in N bits, i.e., whether an | |
| // (N+1)-bit sign-magnitude representation can hold value. | |
| template<typename T> | |
| static inline bool IsAbsoluteUint(int N, T value) { | |
| ASSERT((0 < N) && | |
| (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); | |
| if (value < 0) value = -value; | |
| return IsUint(N, value); | |
| } | |
| static inline int32_t Low16Bits(int32_t value) { | |
| return static_cast<int32_t>(value & 0xffff); | |
| } | |
| static inline int32_t High16Bits(int32_t value) { | |
| return static_cast<int32_t>(value >> 16); | |
| } | |
| static inline int32_t Low32Bits(int64_t value) { | |
| return static_cast<int32_t>(value); | |
| } | |
| static inline int32_t High32Bits(int64_t value) { | |
| return static_cast<int32_t>(value >> 32); | |
| } | |
| static inline int64_t LowHighTo64Bits(uint32_t low, int32_t high) { | |
| return (static_cast<int64_t>(high) << 32) | (low & 0x0ffffffffLL); | |
| } | |
| static bool IsDecimalDigit(char c) { | |
| return ('0' <= c) && (c <= '9'); | |
| } | |
| static bool IsHexDigit(char c) { | |
| return IsDecimalDigit(c) | |
| || (('A' <= c) && (c <= 'F')) | |
| || (('a' <= c) && (c <= 'f')); | |
| } | |
| static int HexDigitToInt(char c) { | |
| ASSERT(IsHexDigit(c)); | |
| if (IsDecimalDigit(c)) return c - '0'; | |
| if (('A' <= c) && (c <= 'F')) return 10 + (c - 'A'); | |
| return 10 + (c - 'a'); | |
| } | |
| static char IntToHexDigit(int i) { | |
| ASSERT(0 <= i && i < 16); | |
| if (i < 10) return static_cast<char>('0' + i); | |
| return static_cast<char>('A' + (i - 10)); | |
| } | |
| // Perform a range check, checking if | |
| // offset + count <= length | |
| // without the risk of integer overflow. | |
| static inline bool RangeCheck(intptr_t offset, | |
| intptr_t count, | |
| intptr_t length) { | |
| return offset >= 0 && | |
| count >= 0 && | |
| length >= 0 && | |
| count <= (length - offset); | |
| } | |
| }; | |
| } // namespace dart | |
| #if defined(TARGET_OS_ANDROID) | |
| #include "platform/utils_android.h" | |
| #elif defined(TARGET_OS_LINUX) | |
| #include "platform/utils_linux.h" | |
| #elif defined(TARGET_OS_MACOS) | |
| #include "platform/utils_macos.h" | |
| #elif defined(TARGET_OS_WINDOWS) | |
| #include "platform/utils_win.h" | |
| #else | |
| #error Unknown target os. | |
| #endif | |
| #endif // PLATFORM_UTILS_H_ |