Sat, 03 Jan 2015 20:18:00 +0100
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 */