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

Annotation of /trunk/js/jstl.h

Parent Directory Parent Directory | Revision Log Revision Log


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

1 siliconforks 507 /* -*- 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