Initial export.
git-svn-id: http://v8.googlecode.com/svn/trunk@2 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..8e51d14
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,358 @@
+// Copyright 2006-2008 Google Inc. All Rights Reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_UTILS_H_
+#define V8_UTILS_H_
+
+namespace v8 { namespace internal {
+
+// ----------------------------------------------------------------------------
+// General helper functions
+
+// Returns true iff x is a power of 2. Does not work for zero.
+template <typename T>
+static inline bool IsPowerOf2(T x) {
+ return (x & (x - 1)) == 0;
+}
+
+
+// Returns smallest power of 2 greater or equal to x (from Hacker's Delight).
+int32_t NextPowerOf2(uint32_t x);
+
+
+// The C++ standard leaves the semantics of '>>'
+// undefined for negative signed operands. Most
+// implementations do the right thing, though.
+static inline int ArithmeticShiftRight(int x, int s) {
+ return x >> s;
+}
+
+
+// Compute the 0-relative offset of some absolute value x of type T.
+// This allows conversion of Addresses and integral types into 0-relative
+// int offsets.
+template <typename T>
+static inline int OffsetFrom(T x) {
+ return x - static_cast<T>(0);
+}
+
+
+// Compute the absolute value of type T for some 0-relative offset x.
+// This allows conversion of 0-relative int offsets into Addresses
+// and integral types.
+template <typename T>
+static inline T AddressFrom(int x) {
+ return static_cast<T>(0) + x;
+}
+
+
+// Return the largest multiple of m which is <= x.
+template <typename T>
+static inline T RoundDown(T x, int m) {
+ ASSERT(IsPowerOf2(m));
+ return AddressFrom<T>(OffsetFrom(x) & -m);
+}
+
+
+// Return the smallest multiple of m which is >= x.
+template <typename T>
+static inline T RoundUp(T x, int m) {
+ return RoundDown(x + m - 1, m);
+}
+
+
+template <typename T>
+static inline bool IsAligned(T value, T alignment) {
+ ASSERT(IsPowerOf2(alignment));
+ return (value & (alignment - 1)) == 0;
+}
+
+
+// Returns true if (addr + offset) is aligned.
+static inline bool IsAddressAligned(Address addr, int alignment, int offset) {
+ int offs = OffsetFrom(addr + offset);
+ return IsAligned(offs, alignment);
+}
+
+
+// Returns the maximum of the two parameters.
+template <typename T>
+static T Max(T a, T b) {
+ return a < b ? b : a;
+}
+
+
+// Returns the minimum of the two parameters.
+template <typename T>
+static T Min(T a, T b) {
+ return a < b ? a : b;
+}
+
+
+// ----------------------------------------------------------------------------
+// BitField is a help template for encoding and decode bitfield with unsigned
+// content.
+template<class T, int shift, int size>
+class BitField {
+ public:
+ // Tells whether the provided value fits into the bit field.
+ static bool is_valid(T value) {
+ return (static_cast<uint32_t>(value) & ~((1U << (size)) - 1)) == 0;
+ }
+
+ // Returns a uint32_t mask of bit field.
+ static uint32_t mask() {
+ return (1U << (size + shift)) - (1U << shift);
+ }
+
+ // Returns a uint32_t with the bit field value encoded.
+ static uint32_t encode(T value) {
+ ASSERT(is_valid(value));
+ return static_cast<uint32_t>(value) << shift;
+ }
+
+ // Extracts the bit field from the value.
+ static T decode(uint32_t value) {
+ return static_cast<T>((value >> shift) & ((1U << (size)) - 1));
+ }
+};
+
+
+// ----------------------------------------------------------------------------
+// Support for compressed, machine-independent encoding
+// and decoding of integer values of arbitrary size.
+
+// Encoding and decoding from/to a buffer at position p;
+// the result is the position after the encoded integer.
+// Small signed integers in the range -64 <= x && x < 64
+// are encoded in 1 byte; larger values are encoded in 2
+// or more bytes. At most sizeof(int) + 1 bytes are used
+// in the worst case.
+byte* EncodeInt(byte* p, int x);
+byte* DecodeInt(byte* p, int* x);
+
+
+// Encoding and decoding from/to a buffer at position p - 1
+// moving backward; the result is the position of the last
+// byte written. These routines are useful to read/write
+// into a buffer starting at the end of the buffer.
+byte* EncodeUnsignedIntBackward(byte* p, unsigned int x);
+
+// The decoding function is inlined since its performance is
+// important to mark-sweep garbage collection.
+inline byte* DecodeUnsignedIntBackward(byte* p, unsigned int* x) {
+ byte b = *--p;
+ if (b >= 128) {
+ *x = static_cast<unsigned int>(b) - 128;
+ return p;
+ }
+ unsigned int r = static_cast<unsigned int>(b);
+ unsigned int s = 7;
+ b = *--p;
+ while (b < 128) {
+ r |= static_cast<unsigned int>(b) << s;
+ s += 7;
+ b = *--p;
+ }
+ // b >= 128
+ *x = r | ((static_cast<unsigned int>(b) - 128) << s);
+ return p;
+}
+
+
+// ----------------------------------------------------------------------------
+// I/O support.
+
+// Our version of printf(). Avoids compilation errors that we get
+// with standard printf when attempting to print pointers, etc.
+// (the errors are due to the extra compilation flags, which we
+// want elsewhere).
+void PrintF(const char* format, ...);
+
+// Our version of fflush.
+void Flush();
+
+
+// Read a line of characters after printing the prompt to stdout. The resulting
+// char* needs to be disposed off with DeleteArray by the caller.
+char* ReadLine(const char* prompt);
+
+
+// Read and return the raw chars in a file. the size of the buffer is returned
+// in size.
+// The returned buffer is not 0-terminated. It must be freed by the caller.
+char* ReadChars(const char* filename, int* size, bool verbose = true);
+
+
+// Write size chars from str to the file given by filename.
+// The file is overwritten. Returns the number of chars written.
+int WriteChars(const char* filename,
+ const char* str,
+ int size,
+ bool verbose = true);
+
+
+// Write the C code
+// const char* <varname> = "<str>";
+// const int <varname>_len = <len>;
+// to the file given by filename. Only the first len chars are written.
+int WriteAsCFile(const char* filename, const char* varname,
+ const char* str, int size, bool verbose = true);
+
+
+// ----------------------------------------------------------------------------
+// Miscellaneous
+
+// A static resource holds a static instance that can be reserved in
+// a local scope using an instance of Access. Attempts to re-reserve
+// the instance will cause an error.
+template <typename T>
+class StaticResource {
+ public:
+ StaticResource() : is_reserved_(false) {}
+
+ private:
+ template <typename S> friend class Access;
+ T instance_;
+ bool is_reserved_;
+};
+
+
+// Locally scoped access to a static resource.
+template <typename T>
+class Access {
+ public:
+ explicit Access(StaticResource<T>* resource)
+ : resource_(resource)
+ , instance_(&resource->instance_) {
+ ASSERT(!resource->is_reserved_);
+ resource->is_reserved_ = true;
+ }
+
+ ~Access() {
+ resource_->is_reserved_ = false;
+ resource_ = NULL;
+ instance_ = NULL;
+ }
+
+ T* value() { return instance_; }
+ T* operator -> () { return instance_; }
+
+ private:
+ StaticResource<T>* resource_;
+ T* instance_;
+};
+
+
+template <typename T>
+class Vector {
+ public:
+ Vector(T* data, int length) : start_(data), length_(length) {
+ ASSERT(length == 0 || (length > 0 && data != NULL));
+ }
+
+ // Returns the length of the vector.
+ int length() const { return length_; }
+
+ // Returns whether or not the vector is empty.
+ bool is_empty() const { return length_ == 0; }
+
+ // Returns the pointer to the start of the data in the vector.
+ T* start() const { return start_; }
+
+ // Access individual vector elements - checks bounds in debug mode.
+ T& operator[](int index) const {
+ ASSERT(0 <= index && index < length_);
+ return start_[index];
+ }
+
+ // Returns a clone of this vector with a new backing store.
+ Vector<T> Clone() const {
+ T* result = NewArray<T>(length_);
+ for (int i = 0; i < length_; i++) result[i] = start_[i];
+ return Vector<T>(result, length_);
+ }
+
+ // Releases the array underlying this vector. Once disposed the
+ // vector is empty.
+ void Dispose() {
+ DeleteArray(start_);
+ start_ = NULL;
+ length_ = 0;
+ }
+
+ // Factory method for creating empty vectors.
+ static Vector<T> empty() { return Vector<T>(NULL, 0); }
+
+ private:
+ T* start_;
+ int length_;
+};
+
+
+inline Vector<const char> CStrVector(const char* data) {
+ return Vector<const char>(data, strlen(data));
+}
+
+inline Vector<char> MutableCStrVector(char* data) {
+ return Vector<char>(data, strlen(data));
+}
+
+template <typename T>
+inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
+ int length) {
+ return Vector< Handle<Object> >(
+ reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
+}
+
+
+// Simple support to read a file into a 0-terminated C-string.
+// The returned buffer must be freed by the caller.
+// On return, *exits tells whether the file exisited.
+Vector<const char> ReadFile(const char* filename,
+ bool* exists,
+ bool verbose = true);
+
+
+// Simple wrapper that allows an ExternalString to refer to a
+// Vector<const char>. Doesn't assume ownership of the data.
+class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
+ public:
+ explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
+
+ virtual const char* data() const { return data_.start(); }
+
+ virtual size_t length() const { return data_.length(); }
+
+ private:
+ Vector<const char> data_;
+};
+
+
+} } // namespace v8::internal
+
+#endif // V8_UTILS_H_