/[jscoverage]/trunk/js/jstl.h
ViewVC logotype

Contents of /trunk/js/jstl.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 507 - (show annotations)
Sun Jan 10 07:23:34 2010 UTC (9 years, 10 months ago) by siliconforks
File MIME type: text/plain
File size: 9123 byte(s)
Update SpiderMonkey from Firefox 3.6rc1.

1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sw=4 et tw=99 ft=cpp:
3 *
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
18 * July 16, 2009.
19 *
20 * The Initial Developer of the Original Code is
21 * the Mozilla Corporation.
22 *
23 * Contributor(s):
24 * Luke Wagner <lw@mozilla.com>
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40 #ifndef jstl_h_
41 #define jstl_h_
42
43 #include "jsbit.h"
44
45 namespace js {
46
47 /* JavaScript Template Library. */
48 namespace tl {
49
50 /* Compute min/max/clamp. */
51 template <size_t i, size_t j> struct Min {
52 static const size_t result = i < j ? i : j;
53 };
54 template <size_t i, size_t j> struct Max {
55 static const size_t result = i > j ? i : j;
56 };
57 template <size_t i, size_t min, size_t max> struct Clamp {
58 static const size_t result = i < min ? min : (i > max ? max : i);
59 };
60
61 /* Compute x^y. */
62 template <size_t x, size_t y> struct Pow {
63 static const size_t result = x * Pow<x, y - 1>::result;
64 };
65 template <size_t x> struct Pow<x,0> {
66 static const size_t result = 1;
67 };
68
69 /* Compute floor(log2(i)). */
70 template <size_t i> struct FloorLog2 {
71 static const size_t result = 1 + FloorLog2<i / 2>::result;
72 };
73 template <> struct FloorLog2<0> { /* Error */ };
74 template <> struct FloorLog2<1> { static const size_t result = 0; };
75
76 /* Compute ceiling(log2(i)). */
77 template <size_t i> struct CeilingLog2 {
78 static const size_t result = FloorLog2<2 * i - 1>::result;
79 };
80
81 /* Round up to the nearest power of 2. */
82 template <size_t i> struct RoundUpPow2 {
83 static const size_t result = 1u << CeilingLog2<i>::result;
84 };
85 template <> struct RoundUpPow2<0> {
86 static const size_t result = 1;
87 };
88
89 /* Compute the number of bits in the given unsigned type. */
90 template <class T> struct BitSize {
91 static const size_t result = sizeof(T) * JS_BITS_PER_BYTE;
92 };
93
94 /* Allow Assertions by only including the 'result' typedef if 'true'. */
95 template <bool> struct StaticAssert {};
96 template <> struct StaticAssert<true> { typedef int result; };
97
98 /* Boolean test for whether two types are the same. */
99 template <class T, class U> struct IsSameType {
100 static const bool result = false;
101 };
102 template <class T> struct IsSameType<T,T> {
103 static const bool result = true;
104 };
105
106 /*
107 * Produce an N-bit mask, where N <= BitSize<size_t>::result. Handle the
108 * language-undefined edge case when N = BitSize<size_t>::result.
109 */
110 template <size_t N> struct NBitMask {
111 typedef typename StaticAssert<N < BitSize<size_t>::result>::result _;
112 static const size_t result = ~((size_t(1) << N) - 1);
113 };
114 template <> struct NBitMask<BitSize<size_t>::result> {
115 static const size_t result = size_t(-1);
116 };
117
118 /*
119 * For the unsigned integral type size_t, compute a mask M for N such that
120 * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t)
121 */
122 template <size_t N> struct MulOverflowMask {
123 static const size_t result =
124 NBitMask<BitSize<size_t>::result - CeilingLog2<N>::result>::result;
125 };
126 template <> struct MulOverflowMask<0> { /* Error */ };
127 template <> struct MulOverflowMask<1> { static const size_t result = 0; };
128
129 /*
130 * Generate a mask for T such that if (X & sUnsafeRangeSizeMask), an X-sized
131 * array of T's is big enough to cause a ptrdiff_t overflow when subtracting
132 * a pointer to the end of the array from the beginning.
133 */
134 template <class T> struct UnsafeRangeSizeMask {
135 /*
136 * The '2' factor means the top bit is clear, sizeof(T) converts from
137 * units of elements to bytes.
138 */
139 static const size_t result = MulOverflowMask<2 * sizeof(T)>::result;
140 };
141
142 /*
143 * Traits class for identifying POD types. Until C++0x, there is no automatic
144 * way to detect PODs, so for the moment it is done manually.
145 */
146 template <class T> struct IsPodType { static const bool result = false; };
147 template <> struct IsPodType<char> { static const bool result = true; };
148 template <> struct IsPodType<signed char> { static const bool result = true; };
149 template <> struct IsPodType<unsigned char> { static const bool result = true; };
150 template <> struct IsPodType<short> { static const bool result = true; };
151 template <> struct IsPodType<unsigned short> { static const bool result = true; };
152 template <> struct IsPodType<int> { static const bool result = true; };
153 template <> struct IsPodType<unsigned int> { static const bool result = true; };
154 template <> struct IsPodType<long> { static const bool result = true; };
155 template <> struct IsPodType<unsigned long> { static const bool result = true; };
156 template <> struct IsPodType<float> { static const bool result = true; };
157 template <> struct IsPodType<double> { static const bool result = true; };
158
159 /* Return the size/end of an array without using macros. */
160 template <class T, size_t N> inline T *ArraySize(T (&)[N]) { return N; }
161 template <class T, size_t N> inline T *ArrayEnd(T (&arr)[N]) { return arr + N; }
162
163 } /* namespace tl */
164
165 /* Useful for implementing containers that assert non-reentrancy */
166 class ReentrancyGuard
167 {
168 #ifdef DEBUG
169 bool &entered;
170 #endif
171 public:
172 template <class T>
173 ReentrancyGuard(T &obj)
174 #ifdef DEBUG
175 : entered(obj.mEntered)
176 #endif
177 {
178 #ifdef DEBUG
179 JS_ASSERT(!entered);
180 entered = true;
181 #endif
182 }
183 ~ReentrancyGuard()
184 {
185 #ifdef DEBUG
186 entered = false;
187 #endif
188 }
189 };
190
191 /*
192 * Round x up to the nearest power of 2. This function assumes that the most
193 * significant bit of x is not set, which would lead to overflow.
194 */
195 static JS_ALWAYS_INLINE size_t
196 RoundUpPow2(size_t x)
197 {
198 typedef tl::StaticAssert<tl::IsSameType<size_t,JSUword>::result>::result _;
199 size_t log2 = JS_CEILING_LOG2W(x);
200 JS_ASSERT(log2 < tl::BitSize<size_t>::result);
201 size_t result = size_t(1) << log2;
202 return result;
203 }
204
205 /*
206 * Safely subtract two pointers when it is known that end > begin. This avoids
207 * the common compiler bug that if (size_t(end) - size_t(begin)) has the MSB
208 * set, the unsigned subtraction followed by right shift will produce -1, or
209 * size_t(-1), instead of the real difference.
210 */
211 template <class T>
212 static JS_ALWAYS_INLINE size_t
213 PointerRangeSize(T *begin, T *end)
214 {
215 return (size_t(end) - size_t(begin)) / sizeof(T);
216 }
217
218 /*
219 * Allocation policies. These model the concept:
220 * - public copy constructor, assignment, destructor
221 * - void *malloc(size_t)
222 * Responsible for OOM reporting on NULL return value.
223 * - void *realloc(size_t)
224 * Responsible for OOM reporting on NULL return value.
225 * - void free(void *)
226 * - reportAllocOverflow()
227 * Called on overflow before the container returns NULL.
228 */
229
230 /*
231 * Policy that calls JSContext:: memory functions and reports errors to the
232 * context. Since the JSContext* given on construction is stored for the
233 * lifetime of the container, this policy may only be used for containers whose
234 * lifetime is a shorter than the given JSContext.
235 */
236 class ContextAllocPolicy
237 {
238 JSContext *mCx;
239
240 public:
241 ContextAllocPolicy(JSContext *cx) : mCx(cx) {}
242 JSContext *context() const { return mCx; }
243
244 void *malloc(size_t bytes) { return mCx->malloc(bytes); }
245 void free(void *p) { mCx->free(p); }
246 void *realloc(void *p, size_t bytes) { return mCx->realloc(p, bytes); }
247 void reportAllocOverflow() const { js_ReportAllocationOverflow(mCx); }
248 };
249
250 /* Policy for using system memory functions and doing no error reporting. */
251 class SystemAllocPolicy
252 {
253 public:
254 void *malloc(size_t bytes) { return ::malloc(bytes); }
255 void *realloc(void *p, size_t bytes) { return ::realloc(p, bytes); }
256 void free(void *p) { ::free(p); }
257 void reportAllocOverflow() const {}
258 };
259
260 } /* namespace js */
261
262 #endif /* jstl_h_ */

  ViewVC Help
Powered by ViewVC 1.1.24