js/src/vm/TypedArrayObject.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 #ifndef vm_TypedArrayObject_h
     8 #define vm_TypedArrayObject_h
    10 #include "jsobj.h"
    12 #include "builtin/TypedObject.h"
    13 #include "gc/Barrier.h"
    14 #include "js/Class.h"
    15 #include "vm/ArrayBufferObject.h"
    17 typedef struct JSProperty JSProperty;
    19 namespace js {
    21 /*
    22  * TypedArrayObject
    23  *
    24  * The non-templated base class for the specific typed implementations.
    25  * This class holds all the member variables that are used by
    26  * the subclasses.
    27  */
    29 class TypedArrayObject : public ArrayBufferViewObject
    30 {
    31   protected:
    32     // Typed array properties stored in slots, beyond those shared by all
    33     // ArrayBufferViews.
    34     static const size_t LENGTH_SLOT    = JS_TYPEDOBJ_SLOT_LENGTH;
    35     static const size_t TYPE_SLOT      = JS_TYPEDOBJ_SLOT_TYPE_DESCR;
    36     static const size_t RESERVED_SLOTS = JS_TYPEDOBJ_SLOTS;
    37     static const size_t DATA_SLOT      = JS_TYPEDOBJ_SLOT_DATA;
    39     static_assert(js::detail::TypedArrayLengthSlot == LENGTH_SLOT,
    40                   "bad inlined constant in jsfriendapi.h");
    42   public:
    43     static const Class classes[ScalarTypeDescr::TYPE_MAX];
    44     static const Class protoClasses[ScalarTypeDescr::TYPE_MAX];
    46     static const size_t FIXED_DATA_START = DATA_SLOT + 1;
    48     // For typed arrays which can store their data inline, the array buffer
    49     // object is created lazily.
    50     static const uint32_t INLINE_BUFFER_LIMIT =
    51         (JSObject::MAX_FIXED_SLOTS - FIXED_DATA_START) * sizeof(Value);
    53     static gc::AllocKind
    54     AllocKindForLazyBuffer(size_t nbytes)
    55     {
    56         JS_ASSERT(nbytes <= INLINE_BUFFER_LIMIT);
    57         /* For GGC we need at least one slot in which to store a forwarding pointer. */
    58         size_t dataSlots = Max(size_t(1), AlignBytes(nbytes, sizeof(Value)) / sizeof(Value));
    59         JS_ASSERT(nbytes <= dataSlots * sizeof(Value));
    60         return gc::GetGCObjectKind(FIXED_DATA_START + dataSlots);
    61     }
    63     static Value bufferValue(TypedArrayObject *tarr) {
    64         return tarr->getFixedSlot(BUFFER_SLOT);
    65     }
    66     static Value byteOffsetValue(TypedArrayObject *tarr) {
    67         return tarr->getFixedSlot(BYTEOFFSET_SLOT);
    68     }
    69     static Value byteLengthValue(TypedArrayObject *tarr) {
    70         return tarr->getFixedSlot(BYTELENGTH_SLOT);
    71     }
    72     static Value lengthValue(TypedArrayObject *tarr) {
    73         return tarr->getFixedSlot(LENGTH_SLOT);
    74     }
    76     static bool
    77     ensureHasBuffer(JSContext *cx, Handle<TypedArrayObject *> tarray);
    79     ArrayBufferObject *sharedBuffer() const;
    80     ArrayBufferObject *buffer() const {
    81         JSObject *obj = bufferValue(const_cast<TypedArrayObject*>(this)).toObjectOrNull();
    82         if (!obj)
    83             return nullptr;
    84         if (obj->is<ArrayBufferObject>())
    85             return &obj->as<ArrayBufferObject>();
    86         return sharedBuffer();
    87     }
    88     uint32_t byteOffset() const {
    89         return byteOffsetValue(const_cast<TypedArrayObject*>(this)).toInt32();
    90     }
    91     uint32_t byteLength() const {
    92         return byteLengthValue(const_cast<TypedArrayObject*>(this)).toInt32();
    93     }
    94     uint32_t length() const {
    95         return lengthValue(const_cast<TypedArrayObject*>(this)).toInt32();
    96     }
    98     uint32_t type() const {
    99         return getFixedSlot(TYPE_SLOT).toInt32();
   100     }
   101     void *viewData() const {
   102         // Keep synced with js::Get<Type>ArrayLengthAndData in jsfriendapi.h!
   103         return static_cast<void*>(getPrivate(DATA_SLOT));
   104     }
   106     Value getElement(uint32_t index);
   107     static void setElement(TypedArrayObject &obj, uint32_t index, double d);
   109     void neuter(void *newData);
   111     static uint32_t slotWidth(int atype) {
   112         switch (atype) {
   113           case ScalarTypeDescr::TYPE_INT8:
   114           case ScalarTypeDescr::TYPE_UINT8:
   115           case ScalarTypeDescr::TYPE_UINT8_CLAMPED:
   116             return 1;
   117           case ScalarTypeDescr::TYPE_INT16:
   118           case ScalarTypeDescr::TYPE_UINT16:
   119             return 2;
   120           case ScalarTypeDescr::TYPE_INT32:
   121           case ScalarTypeDescr::TYPE_UINT32:
   122           case ScalarTypeDescr::TYPE_FLOAT32:
   123             return 4;
   124           case ScalarTypeDescr::TYPE_FLOAT64:
   125             return 8;
   126           default:
   127             MOZ_ASSUME_UNREACHABLE("invalid typed array type");
   128         }
   129     }
   131     int slotWidth() {
   132         return slotWidth(type());
   133     }
   135     /*
   136      * Byte length above which created typed arrays and data views will have
   137      * singleton types regardless of the context in which they are created.
   138      */
   139     static const uint32_t SINGLETON_TYPE_BYTE_LENGTH = 1024 * 1024 * 10;
   141     static int lengthOffset();
   142     static int dataOffset();
   143 };
   145 inline bool
   146 IsTypedArrayClass(const Class *clasp)
   147 {
   148     return &TypedArrayObject::classes[0] <= clasp &&
   149            clasp < &TypedArrayObject::classes[ScalarTypeDescr::TYPE_MAX];
   150 }
   152 inline bool
   153 IsTypedArrayProtoClass(const Class *clasp)
   154 {
   155     return &TypedArrayObject::protoClasses[0] <= clasp &&
   156            clasp < &TypedArrayObject::protoClasses[ScalarTypeDescr::TYPE_MAX];
   157 }
   159 bool
   160 IsTypedArrayConstructor(HandleValue v, uint32_t type);
   162 bool
   163 IsTypedArrayBuffer(HandleValue v);
   165 ArrayBufferObject &
   166 AsTypedArrayBuffer(HandleValue v);
   168 // Return value is whether the string is some integer. If the string is an
   169 // integer which is not representable as a uint64_t, the return value is true
   170 // and the resulting index is UINT64_MAX.
   171 bool
   172 StringIsTypedArrayIndex(JSLinearString *str, uint64_t *indexp);
   174 inline bool
   175 IsTypedArrayIndex(jsid id, uint64_t *indexp)
   176 {
   177     if (JSID_IS_INT(id)) {
   178         int32_t i = JSID_TO_INT(id);
   179         JS_ASSERT(i >= 0);
   180         *indexp = (double)i;
   181         return true;
   182     }
   184     if (MOZ_UNLIKELY(!JSID_IS_STRING(id)))
   185         return false;
   187     JSAtom *atom = JSID_TO_ATOM(id);
   189     jschar c = atom->chars()[0];
   190     if (!JS7_ISDEC(c) && c != '-')
   191         return false;
   193     return StringIsTypedArrayIndex(atom, indexp);
   194 }
   196 static inline unsigned
   197 TypedArrayShift(ArrayBufferView::ViewType viewType)
   198 {
   199     switch (viewType) {
   200       case ArrayBufferView::TYPE_INT8:
   201       case ArrayBufferView::TYPE_UINT8:
   202       case ArrayBufferView::TYPE_UINT8_CLAMPED:
   203         return 0;
   204       case ArrayBufferView::TYPE_INT16:
   205       case ArrayBufferView::TYPE_UINT16:
   206         return 1;
   207       case ArrayBufferView::TYPE_INT32:
   208       case ArrayBufferView::TYPE_UINT32:
   209       case ArrayBufferView::TYPE_FLOAT32:
   210         return 2;
   211       case ArrayBufferView::TYPE_FLOAT64:
   212         return 3;
   213       default:;
   214     }
   215     MOZ_ASSUME_UNREACHABLE("Unexpected array type");
   216 }
   218 class DataViewObject : public ArrayBufferViewObject
   219 {
   220     static const size_t RESERVED_SLOTS = JS_DATAVIEW_SLOTS;
   221     static const size_t DATA_SLOT      = JS_TYPEDOBJ_SLOT_DATA;
   223   private:
   224     static const Class protoClass;
   226     static bool is(HandleValue v) {
   227         return v.isObject() && v.toObject().hasClass(&class_);
   228     }
   230     template <typename NativeType>
   231     static uint8_t *
   232     getDataPointer(JSContext *cx, Handle<DataViewObject*> obj, uint32_t offset);
   234     template<Value ValueGetter(DataViewObject *view)>
   235     static bool
   236     getterImpl(JSContext *cx, CallArgs args);
   238     template<Value ValueGetter(DataViewObject *view)>
   239     static bool
   240     getter(JSContext *cx, unsigned argc, Value *vp);
   242     template<Value ValueGetter(DataViewObject *view)>
   243     static bool
   244     defineGetter(JSContext *cx, PropertyName *name, HandleObject proto);
   246   public:
   247     static const Class class_;
   249     static Value byteOffsetValue(DataViewObject *view) {
   250         Value v = view->getReservedSlot(BYTEOFFSET_SLOT);
   251         JS_ASSERT(v.toInt32() >= 0);
   252         return v;
   253     }
   255     static Value byteLengthValue(DataViewObject *view) {
   256         Value v = view->getReservedSlot(BYTELENGTH_SLOT);
   257         JS_ASSERT(v.toInt32() >= 0);
   258         return v;
   259     }
   261     static Value bufferValue(DataViewObject *view) {
   262         return view->getReservedSlot(BUFFER_SLOT);
   263     }
   265     uint32_t byteOffset() const {
   266         return byteOffsetValue(const_cast<DataViewObject*>(this)).toInt32();
   267     }
   269     uint32_t byteLength() const {
   270         return byteLengthValue(const_cast<DataViewObject*>(this)).toInt32();
   271     }
   273     ArrayBufferObject &arrayBuffer() const {
   274         return bufferValue(const_cast<DataViewObject*>(this)).toObject().as<ArrayBufferObject>();
   275     }
   277     void *dataPointer() const {
   278         return getPrivate();
   279     }
   281     static bool class_constructor(JSContext *cx, unsigned argc, Value *vp);
   282     static bool constructWithProto(JSContext *cx, unsigned argc, Value *vp);
   283     static bool construct(JSContext *cx, JSObject *bufobj, const CallArgs &args,
   284                           HandleObject proto);
   286     static inline DataViewObject *
   287     create(JSContext *cx, uint32_t byteOffset, uint32_t byteLength,
   288            Handle<ArrayBufferObject*> arrayBuffer, JSObject *proto);
   290     static bool getInt8Impl(JSContext *cx, CallArgs args);
   291     static bool fun_getInt8(JSContext *cx, unsigned argc, Value *vp);
   293     static bool getUint8Impl(JSContext *cx, CallArgs args);
   294     static bool fun_getUint8(JSContext *cx, unsigned argc, Value *vp);
   296     static bool getInt16Impl(JSContext *cx, CallArgs args);
   297     static bool fun_getInt16(JSContext *cx, unsigned argc, Value *vp);
   299     static bool getUint16Impl(JSContext *cx, CallArgs args);
   300     static bool fun_getUint16(JSContext *cx, unsigned argc, Value *vp);
   302     static bool getInt32Impl(JSContext *cx, CallArgs args);
   303     static bool fun_getInt32(JSContext *cx, unsigned argc, Value *vp);
   305     static bool getUint32Impl(JSContext *cx, CallArgs args);
   306     static bool fun_getUint32(JSContext *cx, unsigned argc, Value *vp);
   308     static bool getFloat32Impl(JSContext *cx, CallArgs args);
   309     static bool fun_getFloat32(JSContext *cx, unsigned argc, Value *vp);
   311     static bool getFloat64Impl(JSContext *cx, CallArgs args);
   312     static bool fun_getFloat64(JSContext *cx, unsigned argc, Value *vp);
   314     static bool setInt8Impl(JSContext *cx, CallArgs args);
   315     static bool fun_setInt8(JSContext *cx, unsigned argc, Value *vp);
   317     static bool setUint8Impl(JSContext *cx, CallArgs args);
   318     static bool fun_setUint8(JSContext *cx, unsigned argc, Value *vp);
   320     static bool setInt16Impl(JSContext *cx, CallArgs args);
   321     static bool fun_setInt16(JSContext *cx, unsigned argc, Value *vp);
   323     static bool setUint16Impl(JSContext *cx, CallArgs args);
   324     static bool fun_setUint16(JSContext *cx, unsigned argc, Value *vp);
   326     static bool setInt32Impl(JSContext *cx, CallArgs args);
   327     static bool fun_setInt32(JSContext *cx, unsigned argc, Value *vp);
   329     static bool setUint32Impl(JSContext *cx, CallArgs args);
   330     static bool fun_setUint32(JSContext *cx, unsigned argc, Value *vp);
   332     static bool setFloat32Impl(JSContext *cx, CallArgs args);
   333     static bool fun_setFloat32(JSContext *cx, unsigned argc, Value *vp);
   335     static bool setFloat64Impl(JSContext *cx, CallArgs args);
   336     static bool fun_setFloat64(JSContext *cx, unsigned argc, Value *vp);
   338     static bool initClass(JSContext *cx);
   339     static void neuter(JSObject *view);
   340     template<typename NativeType>
   341     static bool read(JSContext *cx, Handle<DataViewObject*> obj,
   342                      CallArgs &args, NativeType *val, const char *method);
   343     template<typename NativeType>
   344     static bool write(JSContext *cx, Handle<DataViewObject*> obj,
   345                       CallArgs &args, const char *method);
   347     void neuter(void *newData);
   349   private:
   350     static const JSFunctionSpec jsfuncs[];
   351 };
   353 static inline int32_t
   354 ClampIntForUint8Array(int32_t x)
   355 {
   356     if (x < 0)
   357         return 0;
   358     if (x > 255)
   359         return 255;
   360     return x;
   361 }
   363 } // namespace js
   365 template <>
   366 inline bool
   367 JSObject::is<js::TypedArrayObject>() const
   368 {
   369     return js::IsTypedArrayClass(getClass());
   370 }
   372 template <>
   373 inline bool
   374 JSObject::is<js::ArrayBufferViewObject>() const
   375 {
   376     return is<js::DataViewObject>() || is<js::TypedArrayObject>() ||
   377            IsTypedObjectClass(getClass());
   378 }
   380 #endif /* vm_TypedArrayObject_h */

mercurial