js/src/jsutil.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /*
     8  * PR assertion checker.
     9  */
    11 #ifndef jsutil_h
    12 #define jsutil_h
    14 #include "mozilla/Assertions.h"
    15 #include "mozilla/Compiler.h"
    16 #include "mozilla/GuardObjects.h"
    18 #include <limits.h>
    20 #include "js/Utility.h"
    22 #define JS_ALWAYS_TRUE(expr)      MOZ_ALWAYS_TRUE(expr)
    23 #define JS_ALWAYS_FALSE(expr)     MOZ_ALWAYS_FALSE(expr)
    25 #if defined(JS_DEBUG)
    26 # define JS_DIAGNOSTICS_ASSERT(expr) MOZ_ASSERT(expr)
    27 #elif defined(JS_CRASH_DIAGNOSTICS)
    28 # define JS_DIAGNOSTICS_ASSERT(expr) do { if (MOZ_UNLIKELY(!(expr))) MOZ_CRASH(); } while(0)
    29 #else
    30 # define JS_DIAGNOSTICS_ASSERT(expr) ((void) 0)
    31 #endif
    33 static MOZ_ALWAYS_INLINE void *
    34 js_memcpy(void *dst_, const void *src_, size_t len)
    35 {
    36     char *dst = (char *) dst_;
    37     const char *src = (const char *) src_;
    38     JS_ASSERT_IF(dst >= src, (size_t) (dst - src) >= len);
    39     JS_ASSERT_IF(src >= dst, (size_t) (src - dst) >= len);
    41     return memcpy(dst, src, len);
    42 }
    44 namespace js {
    46 template <class T>
    47 struct AlignmentTestStruct
    48 {
    49     char c;
    50     T t;
    51 };
    53 /* This macro determines the alignment requirements of a type. */
    54 #define JS_ALIGNMENT_OF(t_) \
    55   (sizeof(js::AlignmentTestStruct<t_>) - sizeof(t_))
    57 template <class T>
    58 class AlignedPtrAndFlag
    59 {
    60     uintptr_t bits;
    62   public:
    63     AlignedPtrAndFlag(T *t, bool aFlag) {
    64         JS_ASSERT((uintptr_t(t) & 1) == 0);
    65         bits = uintptr_t(t) | uintptr_t(aFlag);
    66     }
    68     T *ptr() const {
    69         return (T *)(bits & ~uintptr_t(1));
    70     }
    72     bool flag() const {
    73         return (bits & 1) != 0;
    74     }
    76     void setPtr(T *t) {
    77         JS_ASSERT((uintptr_t(t) & 1) == 0);
    78         bits = uintptr_t(t) | uintptr_t(flag());
    79     }
    81     void setFlag() {
    82         bits |= 1;
    83     }
    85     void unsetFlag() {
    86         bits &= ~uintptr_t(1);
    87     }
    89     void set(T *t, bool aFlag) {
    90         JS_ASSERT((uintptr_t(t) & 1) == 0);
    91         bits = uintptr_t(t) | aFlag;
    92     }
    93 };
    95 template <class T>
    96 static inline void
    97 Reverse(T *beg, T *end)
    98 {
    99     while (beg != end) {
   100         if (--end == beg)
   101             return;
   102         T tmp = *beg;
   103         *beg = *end;
   104         *end = tmp;
   105         ++beg;
   106     }
   107 }
   109 template <class T>
   110 static inline T *
   111 Find(T *beg, T *end, const T &v)
   112 {
   113     for (T *p = beg; p != end; ++p) {
   114         if (*p == v)
   115             return p;
   116     }
   117     return end;
   118 }
   120 template <class Container>
   121 static inline typename Container::ElementType *
   122 Find(Container &c, const typename Container::ElementType &v)
   123 {
   124     return Find(c.begin(), c.end(), v);
   125 }
   127 template <typename InputIterT, typename CallableT>
   128 void
   129 ForEach(InputIterT begin, InputIterT end, CallableT f)
   130 {
   131     for (; begin != end; ++begin)
   132         f(*begin);
   133 }
   135 template <class T>
   136 static inline T
   137 Min(T t1, T t2)
   138 {
   139     return t1 < t2 ? t1 : t2;
   140 }
   142 template <class T>
   143 static inline T
   144 Max(T t1, T t2)
   145 {
   146     return t1 > t2 ? t1 : t2;
   147 }
   149 /* Allows a const variable to be initialized after its declaration. */
   150 template <class T>
   151 static T&
   152 InitConst(const T &t)
   153 {
   154     return const_cast<T &>(t);
   155 }
   157 template <class T, class U>
   158 MOZ_ALWAYS_INLINE T &
   159 ImplicitCast(U &u)
   160 {
   161     T &t = u;
   162     return t;
   163 }
   165 template<typename T>
   166 class AutoScopedAssign
   167 {
   168   public:
   169     AutoScopedAssign(T *addr, const T &value
   170                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   171         : addr_(addr), old(*addr_)
   172     {
   173         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   174         *addr_ = value;
   175     }
   177     ~AutoScopedAssign() { *addr_ = old; }
   179   private:
   180     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   181     T *addr_;
   182     T old;
   183 };
   185 template <typename T>
   186 static inline bool
   187 IsPowerOfTwo(T t)
   188 {
   189     return t && !(t & (t - 1));
   190 }
   192 template <typename T, typename U>
   193 static inline U
   194 ComputeByteAlignment(T bytes, U alignment)
   195 {
   196     JS_ASSERT(IsPowerOfTwo(alignment));
   197     return (alignment - (bytes % alignment)) % alignment;
   198 }
   200 template <typename T, typename U>
   201 static inline T
   202 AlignBytes(T bytes, U alignment)
   203 {
   204     return bytes + ComputeByteAlignment(bytes, alignment);
   205 }
   207 static MOZ_ALWAYS_INLINE size_t
   208 UnsignedPtrDiff(const void *bigger, const void *smaller)
   209 {
   210     return size_t(bigger) - size_t(smaller);
   211 }
   213 /*****************************************************************************/
   215 /* A bit array is an array of bits represented by an array of words (size_t). */
   217 static const size_t BitArrayElementBits = sizeof(size_t) * CHAR_BIT;
   219 static inline unsigned
   220 NumWordsForBitArrayOfLength(size_t length)
   221 {
   222     return (length + (BitArrayElementBits - 1)) / BitArrayElementBits;
   223 }
   225 static inline unsigned
   226 BitArrayIndexToWordIndex(size_t length, size_t bitIndex)
   227 {
   228     unsigned wordIndex = bitIndex / BitArrayElementBits;
   229     JS_ASSERT(wordIndex < length);
   230     return wordIndex;
   231 }
   233 static inline size_t
   234 BitArrayIndexToWordMask(size_t i)
   235 {
   236     return size_t(1) << (i % BitArrayElementBits);
   237 }
   239 static inline bool
   240 IsBitArrayElementSet(size_t *array, size_t length, size_t i)
   241 {
   242     return array[BitArrayIndexToWordIndex(length, i)] & BitArrayIndexToWordMask(i);
   243 }
   245 static inline bool
   246 IsAnyBitArrayElementSet(size_t *array, size_t length)
   247 {
   248     unsigned numWords = NumWordsForBitArrayOfLength(length);
   249     for (unsigned i = 0; i < numWords; ++i) {
   250         if (array[i])
   251             return true;
   252     }
   253     return false;
   254 }
   256 static inline void
   257 SetBitArrayElement(size_t *array, size_t length, size_t i)
   258 {
   259     array[BitArrayIndexToWordIndex(length, i)] |= BitArrayIndexToWordMask(i);
   260 }
   262 static inline void
   263 ClearBitArrayElement(size_t *array, size_t length, size_t i)
   264 {
   265     array[BitArrayIndexToWordIndex(length, i)] &= ~BitArrayIndexToWordMask(i);
   266 }
   268 static inline void
   269 ClearAllBitArrayElements(size_t *array, size_t length)
   270 {
   271     for (unsigned i = 0; i < length; ++i)
   272         array[i] = 0;
   273 }
   275 }  /* namespace js */
   277 /* Crash diagnostics */
   278 #ifdef DEBUG
   279 # define JS_CRASH_DIAGNOSTICS 1
   280 #endif
   281 #if defined(JS_CRASH_DIAGNOSTICS) || defined(JS_GC_ZEAL)
   282 # define JS_POISON(p, val, size) memset((p), (val), (size))
   283 #else
   284 # define JS_POISON(p, val, size) ((void) 0)
   285 #endif
   287 /* Bug 984101: Disable labeled poisoning until we have poison checking. */
   288 #define JS_EXTRA_POISON(p, val, size) ((void) 0)
   290 /* Basic stats */
   291 #ifdef DEBUG
   292 # define JS_BASIC_STATS 1
   293 #endif
   294 #ifdef JS_BASIC_STATS
   295 # include <stdio.h>
   296 typedef struct JSBasicStats {
   297     uint32_t    num;
   298     uint32_t    max;
   299     double      sum;
   300     double      sqsum;
   301     uint32_t    logscale;           /* logarithmic scale: 0 (linear), 2, 10 */
   302     uint32_t    hist[11];
   303 } JSBasicStats;
   304 # define JS_INIT_STATIC_BASIC_STATS  {0,0,0,0,0,{0,0,0,0,0,0,0,0,0,0,0}}
   305 # define JS_BASIC_STATS_INIT(bs)     memset((bs), 0, sizeof(JSBasicStats))
   306 # define JS_BASIC_STATS_ACCUM(bs,val)                                         \
   307     JS_BasicStatsAccum(bs, val)
   308 # define JS_MeanAndStdDevBS(bs,sigma)                                         \
   309     JS_MeanAndStdDev((bs)->num, (bs)->sum, (bs)->sqsum, sigma)
   310 extern void
   311 JS_BasicStatsAccum(JSBasicStats *bs, uint32_t val);
   312 extern double
   313 JS_MeanAndStdDev(uint32_t num, double sum, double sqsum, double *sigma);
   314 extern void
   315 JS_DumpBasicStats(JSBasicStats *bs, const char *title, FILE *fp);
   316 extern void
   317 JS_DumpHistogram(JSBasicStats *bs, FILE *fp);
   318 #else
   319 # define JS_BASIC_STATS_ACCUM(bs,val)
   320 #endif
   322 /* A jsbitmap_t is a long integer that can be used for bitmaps. */
   323 typedef size_t jsbitmap;
   324 #define JS_BITMAP_NBITS (sizeof(jsbitmap) * CHAR_BIT)
   325 #define JS_TEST_BIT(_map,_bit)  ((_map)[(_bit)/JS_BITMAP_NBITS] &             \
   326                                  (jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
   327 #define JS_SET_BIT(_map,_bit)   ((_map)[(_bit)/JS_BITMAP_NBITS] |=            \
   328                                  (jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
   329 #define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)/JS_BITMAP_NBITS] &=            \
   330                                  ~(jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
   332 /* Wrapper for various macros to stop warnings coming from their expansions. */
   333 #if defined(__clang__)
   334 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
   335     JS_BEGIN_MACRO                                                            \
   336         _Pragma("clang diagnostic push")                                      \
   337         /* If these _Pragmas cause warnings for you, try disabling ccache. */ \
   338         _Pragma("clang diagnostic ignored \"-Wunused-value\"")                \
   339         { expr; }                                                             \
   340         _Pragma("clang diagnostic pop")                                       \
   341     JS_END_MACRO
   342 #elif MOZ_IS_GCC
   344 #if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0)
   345 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
   346     JS_BEGIN_MACRO                                                            \
   347         _Pragma("GCC diagnostic push")                                        \
   348         _Pragma("GCC diagnostic ignored \"-Wunused-but-set-variable\"")       \
   349         expr;                                                                 \
   350         _Pragma("GCC diagnostic pop")                                         \
   351     JS_END_MACRO
   352 #endif
   353 #endif
   355 #if !defined(JS_SILENCE_UNUSED_VALUE_IN_EXPR)
   356 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
   357     JS_BEGIN_MACRO                                                            \
   358         expr;                                                                 \
   359     JS_END_MACRO
   360 #endif
   362 #endif /* jsutil_h */

mercurial