1 : // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 : // Redistribution and use in source and binary forms, with or without
3 : // modification, are permitted provided that the following conditions are
4 : // met:
5 : //
6 : // * Redistributions of source code must retain the above copyright
7 : // notice, this list of conditions and the following disclaimer.
8 : // * Redistributions in binary form must reproduce the above
9 : // copyright notice, this list of conditions and the following
10 : // disclaimer in the documentation and/or other materials provided
11 : // with the distribution.
12 : // * Neither the name of Google Inc. nor the names of its
13 : // contributors may be used to endorse or promote products derived
14 : // from this software without specific prior written permission.
15 : //
16 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 :
28 : #ifndef V8_UTILS_H_
29 : #define V8_UTILS_H_
30 :
31 : #include <stdlib.h>
32 : #include <string.h>
33 :
34 : namespace v8 {
35 : namespace internal {
36 :
37 : // ----------------------------------------------------------------------------
38 : // General helper functions
39 :
40 353510 : inline int StrLength(const char* string) {
41 353510 : size_t length = strlen(string);
42 353510 : ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
43 353510 : return static_cast<int>(length);
44 : }
45 :
46 : // ----------------------------------------------------------------------------
47 : // Miscellaneous
48 :
49 : template <typename T>
50 : class Vector {
51 : public:
52 : Vector() : start_(NULL), length_(0) {}
53 536846 : Vector(T* data, int length) : start_(data), length_(length) {
54 536846 : ASSERT(length == 0 || (length > 0 && data != NULL));
55 536846 : }
56 :
57 : // Returns the length of the vector.
58 1106238 : int length() const { return length_; }
59 :
60 : // Returns the pointer to the start of the data in the vector.
61 559022 : T* start() const { return start_; }
62 :
63 : // Access individual vector elements - checks bounds in debug mode.
64 4530967 : T& operator[](int index) const {
65 4530967 : ASSERT(0 <= index && index < length_);
66 4530967 : return start_[index];
67 : }
68 :
69 : inline Vector<T> operator+(int offset) {
70 : ASSERT(offset < length_);
71 : return Vector<T>(start_ + offset, length_ - offset);
72 : }
73 :
74 : private:
75 : T* start_;
76 : int length_;
77 : };
78 :
79 :
80 : // Helper class for building result strings in a character buffer. The
81 : // purpose of the class is to use safe operations that checks the
82 : // buffer bounds on all operations in debug mode.
83 : class StringBuilder {
84 : public:
85 :
86 279511 : StringBuilder(char* buffer, int size)
87 279511 : : buffer_(buffer, size), position_(0) { }
88 :
89 279511 : ~StringBuilder() { if (!is_finalized()) Finalize(); }
90 :
91 : // Add a single character to the builder. It is not allowed to add
92 : // 0-characters; use the Finalize() method to terminate the string
93 : // instead.
94 375803 : void AddCharacter(char c) {
95 375803 : ASSERT(c != '\0');
96 375803 : ASSERT(!is_finalized() && position_ < buffer_.length());
97 375803 : buffer_[position_++] = c;
98 375803 : }
99 :
100 : // Add an entire string to the builder. Uses strlen() internally to
101 : // compute the length of the input string.
102 : void AddString(const char* s);
103 :
104 : // Add the first 'n' characters of the given string 's' to the
105 : // builder. The input string must have enough characters.
106 : void AddSubstring(const char* s, int n);
107 :
108 : // Add an integer to the builder.
109 : void AddInteger(int n);
110 :
111 : // Add character padding to the builder. If count is non-positive,
112 : // nothing is added to the builder.
113 : void AddPadding(char c, int count);
114 :
115 : // Finalize the string by 0-terminating it and returning the buffer.
116 : char* Finalize();
117 :
118 : private:
119 : Vector<char> buffer_;
120 : int position_;
121 :
122 1665260 : bool is_finalized() const { return position_ < 0; }
123 :
124 : DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
125 : };
126 :
127 :
128 : // The type-based aliasing rule allows the compiler to assume that pointers of
129 : // different types (for some definition of different) never alias each other.
130 : // Thus the following code does not work:
131 : //
132 : // float f = foo();
133 : // int fbits = *(int*)(&f);
134 : //
135 : // The compiler 'knows' that the int pointer can't refer to f since the types
136 : // don't match, so the compiler may cache f in a register, leaving random data
137 : // in fbits. Using C++ style casts makes no difference, however a pointer to
138 : // char data is assumed to alias any other pointer. This is the 'memcpy
139 : // exception'.
140 : //
141 : // Bit_cast uses the memcpy exception to move the bits from a variable of one
142 : // type of a variable of another type. Of course the end result is likely to
143 : // be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
144 : // will completely optimize BitCast away.
145 : //
146 : // There is an additional use for BitCast.
147 : // Recent gccs will warn when they see casts that may result in breakage due to
148 : // the type-based aliasing rule. If you have checked that there is no breakage
149 : // you can use BitCast to cast one pointer type to another. This confuses gcc
150 : // enough that it can no longer see that you have cast one pointer type to
151 : // another thus avoiding the warning.
152 : template <class Dest, class Source>
153 1286675 : inline Dest BitCast(const Source& source) {
154 : // Compile time assertion: sizeof(Dest) == sizeof(Source)
155 : // A compile error here means your Dest and Source have different sizes.
156 : typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
157 :
158 : Dest dest;
159 1286675 : memcpy(&dest, &source, sizeof(dest));
160 1286675 : return dest;
161 : }
162 :
163 : } } // namespace v8::internal
164 :
165 : #endif // V8_UTILS_H_
|