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/. */
6 
7 #ifndef vm_DataViewObject_h
8 #define vm_DataViewObject_h
9 
10 #include "mozilla/Attributes.h"
11 
12 #include "gc/Barrier.h"
13 #include "js/Class.h"
14 #include "vm/ArrayBufferObject.h"
15 #include "vm/JSObject.h"
16 #include "vm/SharedArrayObject.h"
17 #include "vm/TypedArrayObject.h"
18 
19 namespace js {
20 
21 // In the DataViewObject, the private slot contains a raw pointer into
22 // the buffer.  The buffer may be shared memory and the raw pointer
23 // should not be exposed without sharedness information accompanying
24 // it.
25 
26 class DataViewObject : public NativeObject {
27  private:
28   static const Class protoClass_;
29   static const ClassSpec classSpec_;
30 
31   static JSObject* CreatePrototype(JSContext* cx, JSProtoKey key);
32 
is(HandleValue v)33   static bool is(HandleValue v) {
34     return v.isObject() && v.toObject().hasClass(&class_);
35   }
36 
37   template <typename NativeType>
38   static SharedMem<uint8_t*> getDataPointer(JSContext* cx,
39                                             Handle<DataViewObject*> obj,
40                                             uint64_t offset,
41                                             bool* isSharedMemory);
42 
43   static bool bufferGetterImpl(JSContext* cx, const CallArgs& args);
44   static bool bufferGetter(JSContext* cx, unsigned argc, Value* vp);
45 
46   static bool byteLengthGetterImpl(JSContext* cx, const CallArgs& args);
47   static bool byteLengthGetter(JSContext* cx, unsigned argc, Value* vp);
48 
49   static bool byteOffsetGetterImpl(JSContext* cx, const CallArgs& args);
50   static bool byteOffsetGetter(JSContext* cx, unsigned argc, Value* vp);
51 
52   static bool getAndCheckConstructorArgs(JSContext* cx, HandleObject bufobj,
53                                          const CallArgs& args,
54                                          uint32_t* byteOffset,
55                                          uint32_t* byteLength);
56   static bool constructSameCompartment(JSContext* cx, HandleObject bufobj,
57                                        const CallArgs& args);
58   static bool constructWrapped(JSContext* cx, HandleObject bufobj,
59                                const CallArgs& args);
60 
61   static DataViewObject* create(
62       JSContext* cx, uint32_t byteOffset, uint32_t byteLength,
63       Handle<ArrayBufferObjectMaybeShared*> arrayBuffer, HandleObject proto);
64 
65  public:
66   static const Class class_;
67 
byteOffsetValue(DataViewObject * view)68   static Value byteOffsetValue(DataViewObject* view) {
69     Value v = view->getFixedSlot(TypedArrayObject::BYTEOFFSET_SLOT);
70     MOZ_ASSERT(v.toInt32() >= 0);
71     return v;
72   }
73 
byteLengthValue(DataViewObject * view)74   static Value byteLengthValue(DataViewObject* view) {
75     Value v = view->getFixedSlot(TypedArrayObject::LENGTH_SLOT);
76     MOZ_ASSERT(v.toInt32() >= 0);
77     return v;
78   }
79 
bufferValue(DataViewObject * view)80   static Value bufferValue(DataViewObject* view) {
81     return view->getFixedSlot(TypedArrayObject::BUFFER_SLOT);
82   }
83 
byteOffset()84   uint32_t byteOffset() const {
85     return byteOffsetValue(const_cast<DataViewObject*>(this)).toInt32();
86   }
87 
byteLength()88   uint32_t byteLength() const {
89     return byteLengthValue(const_cast<DataViewObject*>(this)).toInt32();
90   }
91 
arrayBufferEither()92   ArrayBufferObjectMaybeShared& arrayBufferEither() const {
93     return bufferValue(const_cast<DataViewObject*>(this))
94         .toObject()
95         .as<ArrayBufferObjectMaybeShared>();
96   }
97 
dataPointerEither()98   SharedMem<void*> dataPointerEither() const {
99     void* p = getPrivate();
100     if (isSharedMemory()) return SharedMem<void*>::shared(p);
101     return SharedMem<void*>::unshared(p);
102   }
103 
dataPointerUnshared()104   void* dataPointerUnshared() const {
105     MOZ_ASSERT(!isSharedMemory());
106     return getPrivate();
107   }
108 
dataPointerShared()109   void* dataPointerShared() const {
110     MOZ_ASSERT(isSharedMemory());
111     return getPrivate();
112   }
113 
114   static bool construct(JSContext* cx, unsigned argc, Value* vp);
115 
116   static bool getInt8Impl(JSContext* cx, const CallArgs& args);
117   static bool fun_getInt8(JSContext* cx, unsigned argc, Value* vp);
118 
119   static bool getUint8Impl(JSContext* cx, const CallArgs& args);
120   static bool fun_getUint8(JSContext* cx, unsigned argc, Value* vp);
121 
122   static bool getInt16Impl(JSContext* cx, const CallArgs& args);
123   static bool fun_getInt16(JSContext* cx, unsigned argc, Value* vp);
124 
125   static bool getUint16Impl(JSContext* cx, const CallArgs& args);
126   static bool fun_getUint16(JSContext* cx, unsigned argc, Value* vp);
127 
128   static bool getInt32Impl(JSContext* cx, const CallArgs& args);
129   static bool fun_getInt32(JSContext* cx, unsigned argc, Value* vp);
130 
131   static bool getUint32Impl(JSContext* cx, const CallArgs& args);
132   static bool fun_getUint32(JSContext* cx, unsigned argc, Value* vp);
133 
134   static bool getFloat32Impl(JSContext* cx, const CallArgs& args);
135   static bool fun_getFloat32(JSContext* cx, unsigned argc, Value* vp);
136 
137   static bool getFloat64Impl(JSContext* cx, const CallArgs& args);
138   static bool fun_getFloat64(JSContext* cx, unsigned argc, Value* vp);
139 
140   static bool setInt8Impl(JSContext* cx, const CallArgs& args);
141   static bool fun_setInt8(JSContext* cx, unsigned argc, Value* vp);
142 
143   static bool setUint8Impl(JSContext* cx, const CallArgs& args);
144   static bool fun_setUint8(JSContext* cx, unsigned argc, Value* vp);
145 
146   static bool setInt16Impl(JSContext* cx, const CallArgs& args);
147   static bool fun_setInt16(JSContext* cx, unsigned argc, Value* vp);
148 
149   static bool setUint16Impl(JSContext* cx, const CallArgs& args);
150   static bool fun_setUint16(JSContext* cx, unsigned argc, Value* vp);
151 
152   static bool setInt32Impl(JSContext* cx, const CallArgs& args);
153   static bool fun_setInt32(JSContext* cx, unsigned argc, Value* vp);
154 
155   static bool setUint32Impl(JSContext* cx, const CallArgs& args);
156   static bool fun_setUint32(JSContext* cx, unsigned argc, Value* vp);
157 
158   static bool setFloat32Impl(JSContext* cx, const CallArgs& args);
159   static bool fun_setFloat32(JSContext* cx, unsigned argc, Value* vp);
160 
161   static bool setFloat64Impl(JSContext* cx, const CallArgs& args);
162   static bool fun_setFloat64(JSContext* cx, unsigned argc, Value* vp);
163 
164   static bool initClass(JSContext* cx);
165   template <typename NativeType>
166   static bool read(JSContext* cx, Handle<DataViewObject*> obj,
167                    const CallArgs& args, NativeType* val);
168   template <typename NativeType>
169   static bool write(JSContext* cx, Handle<DataViewObject*> obj,
170                     const CallArgs& args);
171 
172   void notifyBufferDetached(void* newData);
173 
174  private:
175   static const JSFunctionSpec methods[];
176   static const JSPropertySpec properties[];
177 };
178 
179 }  // namespace js
180 
181 #endif /* vm_DataViewObject_h */
182