1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
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/CheckedInt.h"
11 
12 #include "gc/Barrier.h"
13 #include "js/Class.h"
14 #include "vm/ArrayBufferObject.h"
15 #include "vm/ArrayBufferViewObject.h"
16 #include "vm/JSObject.h"
17 #include "vm/SharedArrayObject.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 ArrayBufferViewObject {
27  private:
28   static const ClassSpec classSpec_;
29 
is(HandleValue v)30   static bool is(HandleValue v) {
31     return v.isObject() && v.toObject().hasClass(&class_);
32   }
33 
34   template <typename NativeType>
35   SharedMem<uint8_t*> getDataPointer(uint64_t offset, bool* isSharedMemory);
36 
37   static bool bufferGetterImpl(JSContext* cx, const CallArgs& args);
38   static bool bufferGetter(JSContext* cx, unsigned argc, Value* vp);
39 
40   static bool byteLengthGetterImpl(JSContext* cx, const CallArgs& args);
41   static bool byteLengthGetter(JSContext* cx, unsigned argc, Value* vp);
42 
43   static bool byteOffsetGetterImpl(JSContext* cx, const CallArgs& args);
44   static bool byteOffsetGetter(JSContext* cx, unsigned argc, Value* vp);
45 
46   static bool getAndCheckConstructorArgs(JSContext* cx, HandleObject bufobj,
47                                          const CallArgs& args,
48                                          size_t* byteOffset,
49                                          size_t* byteLength);
50   static bool constructSameCompartment(JSContext* cx, HandleObject bufobj,
51                                        const CallArgs& args);
52   static bool constructWrapped(JSContext* cx, HandleObject bufobj,
53                                const CallArgs& args);
54 
55   static DataViewObject* create(
56       JSContext* cx, size_t byteOffset, size_t byteLength,
57       Handle<ArrayBufferObjectMaybeShared*> arrayBuffer, HandleObject proto);
58 
59  public:
60   static const JSClass class_;
61   static const JSClass protoClass_;
62 
byteLength()63   size_t byteLength() const {
64     return size_t(getFixedSlot(LENGTH_SLOT).toPrivate());
65   }
66 
byteLengthValue()67   Value byteLengthValue() const {
68     size_t len = byteLength();
69     return NumberValue(len);
70   }
71 
72   template <typename NativeType>
offsetIsInBounds(uint64_t offset)73   bool offsetIsInBounds(uint64_t offset) const {
74     return offsetIsInBounds(sizeof(NativeType), offset);
75   }
offsetIsInBounds(uint32_t byteSize,uint64_t offset)76   bool offsetIsInBounds(uint32_t byteSize, uint64_t offset) const {
77     MOZ_ASSERT(byteSize <= 8);
78     mozilla::CheckedInt<uint64_t> endOffset(offset);
79     endOffset += byteSize;
80     return endOffset.isValid() && endOffset.value() <= byteLength();
81   }
82 
isOriginalByteOffsetGetter(Native native)83   static bool isOriginalByteOffsetGetter(Native native) {
84     return native == byteOffsetGetter;
85   }
86 
isOriginalByteLengthGetter(Native native)87   static bool isOriginalByteLengthGetter(Native native) {
88     return native == byteLengthGetter;
89   }
90 
91   static bool construct(JSContext* cx, unsigned argc, Value* vp);
92 
93   static bool getInt8Impl(JSContext* cx, const CallArgs& args);
94   static bool fun_getInt8(JSContext* cx, unsigned argc, Value* vp);
95 
96   static bool getUint8Impl(JSContext* cx, const CallArgs& args);
97   static bool fun_getUint8(JSContext* cx, unsigned argc, Value* vp);
98 
99   static bool getInt16Impl(JSContext* cx, const CallArgs& args);
100   static bool fun_getInt16(JSContext* cx, unsigned argc, Value* vp);
101 
102   static bool getUint16Impl(JSContext* cx, const CallArgs& args);
103   static bool fun_getUint16(JSContext* cx, unsigned argc, Value* vp);
104 
105   static bool getInt32Impl(JSContext* cx, const CallArgs& args);
106   static bool fun_getInt32(JSContext* cx, unsigned argc, Value* vp);
107 
108   static bool getUint32Impl(JSContext* cx, const CallArgs& args);
109   static bool fun_getUint32(JSContext* cx, unsigned argc, Value* vp);
110 
111   static bool getBigInt64Impl(JSContext* cx, const CallArgs& args);
112   static bool fun_getBigInt64(JSContext* cx, unsigned argc, Value* vp);
113 
114   static bool getBigUint64Impl(JSContext* cx, const CallArgs& args);
115   static bool fun_getBigUint64(JSContext* cx, unsigned argc, Value* vp);
116 
117   static bool getFloat32Impl(JSContext* cx, const CallArgs& args);
118   static bool fun_getFloat32(JSContext* cx, unsigned argc, Value* vp);
119 
120   static bool getFloat64Impl(JSContext* cx, const CallArgs& args);
121   static bool fun_getFloat64(JSContext* cx, unsigned argc, Value* vp);
122 
123   static bool setInt8Impl(JSContext* cx, const CallArgs& args);
124   static bool fun_setInt8(JSContext* cx, unsigned argc, Value* vp);
125 
126   static bool setUint8Impl(JSContext* cx, const CallArgs& args);
127   static bool fun_setUint8(JSContext* cx, unsigned argc, Value* vp);
128 
129   static bool setInt16Impl(JSContext* cx, const CallArgs& args);
130   static bool fun_setInt16(JSContext* cx, unsigned argc, Value* vp);
131 
132   static bool setUint16Impl(JSContext* cx, const CallArgs& args);
133   static bool fun_setUint16(JSContext* cx, unsigned argc, Value* vp);
134 
135   static bool setInt32Impl(JSContext* cx, const CallArgs& args);
136   static bool fun_setInt32(JSContext* cx, unsigned argc, Value* vp);
137 
138   static bool setUint32Impl(JSContext* cx, const CallArgs& args);
139   static bool fun_setUint32(JSContext* cx, unsigned argc, Value* vp);
140 
141   static bool setBigInt64Impl(JSContext* cx, const CallArgs& args);
142   static bool fun_setBigInt64(JSContext* cx, unsigned argc, Value* vp);
143 
144   static bool setBigUint64Impl(JSContext* cx, const CallArgs& args);
145   static bool fun_setBigUint64(JSContext* cx, unsigned argc, Value* vp);
146 
147   static bool setFloat32Impl(JSContext* cx, const CallArgs& args);
148   static bool fun_setFloat32(JSContext* cx, unsigned argc, Value* vp);
149 
150   static bool setFloat64Impl(JSContext* cx, const CallArgs& args);
151   static bool fun_setFloat64(JSContext* cx, unsigned argc, Value* vp);
152 
153   template <typename NativeType>
154   NativeType read(uint64_t offset, bool isLittleEndian);
155 
156   template <typename NativeType>
157   static bool read(JSContext* cx, Handle<DataViewObject*> obj,
158                    const CallArgs& args, NativeType* val);
159   template <typename NativeType>
160   static bool write(JSContext* cx, Handle<DataViewObject*> obj,
161                     const CallArgs& args);
162 
163  private:
164   static const JSFunctionSpec methods[];
165   static const JSPropertySpec properties[];
166 };
167 
168 }  // namespace js
169 
170 #endif /* vm_DataViewObject_h */
171