dom/bindings/TypedArray.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: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
     2 /* vim: set ts=2 sw=2 et tw=79: */
     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 file,
     5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef mozilla_dom_TypedArray_h
     8 #define mozilla_dom_TypedArray_h
    10 #include "jsapi.h"
    11 #include "jsfriendapi.h"
    12 #include "js/RootingAPI.h"
    13 #include "js/TracingAPI.h"
    14 #include "mozilla/Attributes.h"
    15 #include "mozilla/Move.h"
    16 #include "mozilla/dom/BindingDeclarations.h"
    17 #include "nsWrapperCache.h"
    19 namespace mozilla {
    20 namespace dom {
    22 /*
    23  * Class that just handles the JSObject storage and tracing for typed arrays
    24  */
    25 struct TypedArrayObjectStorage : AllTypedArraysBase {
    26 protected:
    27   JSObject* mObj;
    29   TypedArrayObjectStorage(JSObject *obj) : mObj(obj)
    30   {
    31   }
    33   explicit TypedArrayObjectStorage(TypedArrayObjectStorage&& aOther)
    34     : mObj(aOther.mObj)
    35   {
    36     aOther.mObj = nullptr;
    37   }
    39 public:
    40   inline void TraceSelf(JSTracer* trc)
    41   {
    42     if (mObj) {
    43       JS_CallObjectTracer(trc, &mObj, "TypedArray.mObj");
    44     }
    45   }
    47 private:
    48   TypedArrayObjectStorage(const TypedArrayObjectStorage&) MOZ_DELETE;
    49 };
    51 /*
    52  * Various typed array classes for argument conversion.  We have a base class
    53  * that has a way of initializing a TypedArray from an existing typed array, and
    54  * a subclass of the base class that supports creation of a relevant typed array
    55  * or array buffer object.
    56  */
    57 template<typename T,
    58          JSObject* UnwrapArray(JSObject*),
    59          void GetLengthAndData(JSObject*, uint32_t*, T**)>
    60 struct TypedArray_base : public TypedArrayObjectStorage {
    61   typedef T element_type;
    63   TypedArray_base(JSObject* obj)
    64     : TypedArrayObjectStorage(obj),
    65       mData(nullptr),
    66       mLength(0),
    67       mComputed(false)
    68   {
    69     MOZ_ASSERT(obj != nullptr);
    70   }
    72   TypedArray_base()
    73     : TypedArrayObjectStorage(nullptr),
    74       mData(nullptr),
    75       mLength(0),
    76       mComputed(false)
    77   {
    78   }
    80   explicit TypedArray_base(TypedArray_base&& aOther)
    81     : TypedArrayObjectStorage(Move(aOther)),
    82       mData(aOther.mData),
    83       mLength(aOther.mLength)
    84   {
    85     aOther.mData = nullptr;
    86     aOther.mLength = 0;
    87   }
    89 private:
    90   mutable T* mData;
    91   mutable uint32_t mLength;
    92   mutable bool mComputed;
    94 public:
    95   inline bool Init(JSObject* obj)
    96   {
    97     MOZ_ASSERT(!inited());
    98     DoInit(obj);
    99     return inited();
   100   }
   102   inline bool inited() const {
   103     return !!mObj;
   104   }
   106   inline T *Data() const {
   107     MOZ_ASSERT(mComputed);
   108     return mData;
   109   }
   111   inline uint32_t Length() const {
   112     MOZ_ASSERT(mComputed);
   113     return mLength;
   114   }
   116   inline JSObject *Obj() const {
   117     MOZ_ASSERT(inited());
   118     return mObj;
   119   }
   121   inline bool WrapIntoNewCompartment(JSContext* cx)
   122   {
   123     return JS_WrapObject(cx,
   124       JS::MutableHandle<JSObject*>::fromMarkedLocation(&mObj));
   125   }
   127   inline void ComputeLengthAndData() const
   128   {
   129     MOZ_ASSERT(inited());
   130     MOZ_ASSERT(!mComputed);
   131     GetLengthAndData(mObj, &mLength, &mData);
   132     mComputed = true;
   133   }
   135 protected:
   136   inline void DoInit(JSObject* obj)
   137   {
   138     mObj = UnwrapArray(obj);
   139   }
   141   inline void ComputeData() const {
   142     MOZ_ASSERT(inited());
   143     if (!mComputed) {
   144       GetLengthAndData(mObj, &mLength, &mData);
   145       mComputed = true;
   146     }
   147   }
   149 private:
   150   TypedArray_base(const TypedArray_base&) MOZ_DELETE;
   151 };
   154 template<typename T,
   155          JSObject* UnwrapArray(JSObject*),
   156          T* GetData(JSObject*),
   157          void GetLengthAndData(JSObject*, uint32_t*, T**),
   158          JSObject* CreateNew(JSContext*, uint32_t)>
   159 struct TypedArray : public TypedArray_base<T, UnwrapArray, GetLengthAndData> {
   160   TypedArray(JSObject* obj) :
   161     TypedArray_base<T, UnwrapArray, GetLengthAndData>(obj)
   162   {}
   164   TypedArray() :
   165     TypedArray_base<T, UnwrapArray, GetLengthAndData>()
   166   {}
   168   explicit TypedArray(TypedArray&& aOther)
   169     : TypedArray_base<T, UnwrapArray, GetLengthAndData>(Move(aOther))
   170   {
   171   }
   173   static inline JSObject*
   174   Create(JSContext* cx, nsWrapperCache* creator, uint32_t length,
   175          const T* data = nullptr) {
   176     JS::Rooted<JSObject*> creatorWrapper(cx);
   177     Maybe<JSAutoCompartment> ac;
   178     if (creator && (creatorWrapper = creator->GetWrapperPreserveColor())) {
   179       ac.construct(cx, creatorWrapper);
   180     }
   182     return CreateCommon(cx, length, data);
   183   }
   185   static inline JSObject*
   186   Create(JSContext* cx, uint32_t length, const T* data = nullptr) {
   187     return CreateCommon(cx, length, data);
   188   }
   190 private:
   191   static inline JSObject*
   192   CreateCommon(JSContext* cx, uint32_t length, const T* data) {
   193     JSObject* obj = CreateNew(cx, length);
   194     if (!obj) {
   195       return nullptr;
   196     }
   197     if (data) {
   198       T* buf = static_cast<T*>(GetData(obj));
   199       memcpy(buf, data, length*sizeof(T));
   200     }
   201     return obj;
   202   }
   204   TypedArray(const TypedArray&) MOZ_DELETE;
   205 };
   207 typedef TypedArray<int8_t, js::UnwrapInt8Array, JS_GetInt8ArrayData,
   208                    js::GetInt8ArrayLengthAndData, JS_NewInt8Array>
   209         Int8Array;
   210 typedef TypedArray<uint8_t, js::UnwrapUint8Array, JS_GetUint8ArrayData,
   211                    js::GetUint8ArrayLengthAndData, JS_NewUint8Array>
   212         Uint8Array;
   213 typedef TypedArray<uint8_t, js::UnwrapUint8ClampedArray, JS_GetUint8ClampedArrayData,
   214                    js::GetUint8ClampedArrayLengthAndData, JS_NewUint8ClampedArray>
   215         Uint8ClampedArray;
   216 typedef TypedArray<int16_t, js::UnwrapInt16Array, JS_GetInt16ArrayData,
   217                    js::GetInt16ArrayLengthAndData, JS_NewInt16Array>
   218         Int16Array;
   219 typedef TypedArray<uint16_t, js::UnwrapUint16Array, JS_GetUint16ArrayData,
   220                    js::GetUint16ArrayLengthAndData, JS_NewUint16Array>
   221         Uint16Array;
   222 typedef TypedArray<int32_t, js::UnwrapInt32Array, JS_GetInt32ArrayData,
   223                    js::GetInt32ArrayLengthAndData, JS_NewInt32Array>
   224         Int32Array;
   225 typedef TypedArray<uint32_t, js::UnwrapUint32Array, JS_GetUint32ArrayData,
   226                    js::GetUint32ArrayLengthAndData, JS_NewUint32Array>
   227         Uint32Array;
   228 typedef TypedArray<float, js::UnwrapFloat32Array, JS_GetFloat32ArrayData,
   229                    js::GetFloat32ArrayLengthAndData, JS_NewFloat32Array>
   230         Float32Array;
   231 typedef TypedArray<double, js::UnwrapFloat64Array, JS_GetFloat64ArrayData,
   232                    js::GetFloat64ArrayLengthAndData, JS_NewFloat64Array>
   233         Float64Array;
   234 typedef TypedArray_base<uint8_t, js::UnwrapArrayBufferView, js::GetArrayBufferViewLengthAndData>
   235         ArrayBufferView;
   236 typedef TypedArray<uint8_t, js::UnwrapArrayBuffer, JS_GetArrayBufferData,
   237                    js::GetArrayBufferLengthAndData, JS_NewArrayBuffer>
   238         ArrayBuffer;
   240 // A class for converting an nsTArray to a TypedArray
   241 // Note: A TypedArrayCreator must not outlive the nsTArray it was created from.
   242 //       So this is best used to pass from things that understand nsTArray to
   243 //       things that understand TypedArray, as with Promise::ArgumentToJSValue.
   244 template<typename TypedArrayType>
   245 class TypedArrayCreator
   246 {
   247   typedef nsTArray<typename TypedArrayType::element_type> ArrayType;
   249   public:
   250     TypedArrayCreator(const ArrayType& aArray)
   251       : mArray(aArray)
   252     {}
   254     JSObject* Create(JSContext* aCx) const
   255     {
   256       return TypedArrayType::Create(aCx, mArray.Length(), mArray.Elements());
   257     }
   259   private:
   260     const ArrayType& mArray;
   261 };
   263 // A class for rooting an existing TypedArray struct
   264 template<typename ArrayType>
   265 class MOZ_STACK_CLASS TypedArrayRooter : private JS::CustomAutoRooter
   266 {
   267 public:
   268   TypedArrayRooter(JSContext* cx,
   269                    ArrayType* aArray MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
   270     JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
   271     mArray(aArray)
   272   {
   273   }
   275   virtual void trace(JSTracer* trc) MOZ_OVERRIDE
   276   {
   277     mArray->TraceSelf(trc);
   278   }
   280 private:
   281   TypedArrayObjectStorage* const mArray;
   282 };
   284 // And a specialization for dealing with nullable typed arrays
   285 template<typename Inner> struct Nullable;
   286 template<typename ArrayType>
   287 class MOZ_STACK_CLASS TypedArrayRooter<Nullable<ArrayType> > :
   288     private JS::CustomAutoRooter
   289 {
   290 public:
   291   TypedArrayRooter(JSContext* cx,
   292                    Nullable<ArrayType>* aArray MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
   293     JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
   294     mArray(aArray)
   295   {
   296   }
   298   virtual void trace(JSTracer* trc) MOZ_OVERRIDE
   299   {
   300     if (!mArray->IsNull()) {
   301       mArray->Value().TraceSelf(trc);
   302     }
   303   }
   305 private:
   306   Nullable<ArrayType>* const mArray;
   307 };
   309 // Class for easily setting up a rooted typed array object on the stack
   310 template<typename ArrayType>
   311 class MOZ_STACK_CLASS RootedTypedArray : public ArrayType,
   312                                          private TypedArrayRooter<ArrayType>
   313 {
   314 public:
   315   RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
   316     ArrayType(),
   317     TypedArrayRooter<ArrayType>(cx,
   318                                 MOZ_THIS_IN_INITIALIZER_LIST()
   319                                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
   320   {
   321   }
   323   RootedTypedArray(JSContext* cx, JSObject* obj MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
   324     ArrayType(obj),
   325     TypedArrayRooter<ArrayType>(cx,
   326                                 MOZ_THIS_IN_INITIALIZER_LIST()
   327                                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
   328   {
   329   }
   330 };
   332 } // namespace dom
   333 } // namespace mozilla
   335 #endif /* mozilla_dom_TypedArray_h */

mercurial