diff options
Diffstat (limited to 'js/src/builtin/DataViewObject.h')
-rw-r--r-- | js/src/builtin/DataViewObject.h | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/js/src/builtin/DataViewObject.h b/js/src/builtin/DataViewObject.h new file mode 100644 index 0000000000..a17b3e1174 --- /dev/null +++ b/js/src/builtin/DataViewObject.h @@ -0,0 +1,224 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef vm_DataViewObject_h +#define vm_DataViewObject_h + +#include "mozilla/CheckedInt.h" +#include "mozilla/Maybe.h" + +#include "js/Class.h" +#include "vm/ArrayBufferViewObject.h" +#include "vm/JSObject.h" + +namespace js { + +class ArrayBufferObjectMaybeShared; + +// In the DataViewObject, the private slot contains a raw pointer into +// the buffer. The buffer may be shared memory and the raw pointer +// should not be exposed without sharedness information accompanying +// it. +// +// DataViewObject is an abstract base class and has exactly two concrete +// subclasses, FixedLengthDataViewObject and ResizableDataViewObject. + +class DataViewObject : public ArrayBufferViewObject { + protected: + static const ClassSpec classSpec_; + + private: + template <typename NativeType> + SharedMem<uint8_t*> getDataPointer(uint64_t offset, size_t length, + bool* isSharedMemory); + + static bool bufferGetterImpl(JSContext* cx, const CallArgs& args); + static bool bufferGetter(JSContext* cx, unsigned argc, Value* vp); + + static bool byteLengthGetterImpl(JSContext* cx, const CallArgs& args); + static bool byteLengthGetter(JSContext* cx, unsigned argc, Value* vp); + + static bool byteOffsetGetterImpl(JSContext* cx, const CallArgs& args); + static bool byteOffsetGetter(JSContext* cx, unsigned argc, Value* vp); + + static bool getAndCheckConstructorArgs(JSContext* cx, HandleObject bufobj, + const CallArgs& args, + size_t* byteOffsetPtr, + size_t* byteLengthPtr, + bool* autoLengthPtr); + static bool constructSameCompartment(JSContext* cx, HandleObject bufobj, + const CallArgs& args); + static bool constructWrapped(JSContext* cx, HandleObject bufobj, + const CallArgs& args); + + static DataViewObject* create( + JSContext* cx, size_t byteOffset, size_t byteLength, + Handle<ArrayBufferObjectMaybeShared*> arrayBuffer, HandleObject proto); + + protected: + size_t rawByteLength() const { + return size_t(getFixedSlot(LENGTH_SLOT).toPrivate()); + } + + public: + static const JSClass protoClass_; + + mozilla::Maybe<size_t> byteLength(); + mozilla::Maybe<size_t> byteOffset(); + + template <typename NativeType> + static bool offsetIsInBounds(uint64_t offset, size_t byteLength) { + return offsetIsInBounds(sizeof(NativeType), offset, byteLength); + } + static bool offsetIsInBounds(uint32_t byteSize, uint64_t offset, + size_t byteLength) { + MOZ_ASSERT(byteSize <= 8); + mozilla::CheckedInt<uint64_t> endOffset(offset); + endOffset += byteSize; + return endOffset.isValid() && endOffset.value() <= byteLength; + } + + static bool isOriginalByteOffsetGetter(Native native) { + return native == byteOffsetGetter; + } + + static bool isOriginalByteLengthGetter(Native native) { + return native == byteLengthGetter; + } + + static bool construct(JSContext* cx, unsigned argc, Value* vp); + + static bool getInt8Impl(JSContext* cx, const CallArgs& args); + static bool fun_getInt8(JSContext* cx, unsigned argc, Value* vp); + + static bool getUint8Impl(JSContext* cx, const CallArgs& args); + static bool fun_getUint8(JSContext* cx, unsigned argc, Value* vp); + + static bool getInt16Impl(JSContext* cx, const CallArgs& args); + static bool fun_getInt16(JSContext* cx, unsigned argc, Value* vp); + + static bool getUint16Impl(JSContext* cx, const CallArgs& args); + static bool fun_getUint16(JSContext* cx, unsigned argc, Value* vp); + + static bool getInt32Impl(JSContext* cx, const CallArgs& args); + static bool fun_getInt32(JSContext* cx, unsigned argc, Value* vp); + + static bool getUint32Impl(JSContext* cx, const CallArgs& args); + static bool fun_getUint32(JSContext* cx, unsigned argc, Value* vp); + + static bool getBigInt64Impl(JSContext* cx, const CallArgs& args); + static bool fun_getBigInt64(JSContext* cx, unsigned argc, Value* vp); + + static bool getBigUint64Impl(JSContext* cx, const CallArgs& args); + static bool fun_getBigUint64(JSContext* cx, unsigned argc, Value* vp); + + static bool getFloat32Impl(JSContext* cx, const CallArgs& args); + static bool fun_getFloat32(JSContext* cx, unsigned argc, Value* vp); + + static bool getFloat64Impl(JSContext* cx, const CallArgs& args); + static bool fun_getFloat64(JSContext* cx, unsigned argc, Value* vp); + + static bool setInt8Impl(JSContext* cx, const CallArgs& args); + static bool fun_setInt8(JSContext* cx, unsigned argc, Value* vp); + + static bool setUint8Impl(JSContext* cx, const CallArgs& args); + static bool fun_setUint8(JSContext* cx, unsigned argc, Value* vp); + + static bool setInt16Impl(JSContext* cx, const CallArgs& args); + static bool fun_setInt16(JSContext* cx, unsigned argc, Value* vp); + + static bool setUint16Impl(JSContext* cx, const CallArgs& args); + static bool fun_setUint16(JSContext* cx, unsigned argc, Value* vp); + + static bool setInt32Impl(JSContext* cx, const CallArgs& args); + static bool fun_setInt32(JSContext* cx, unsigned argc, Value* vp); + + static bool setUint32Impl(JSContext* cx, const CallArgs& args); + static bool fun_setUint32(JSContext* cx, unsigned argc, Value* vp); + + static bool setBigInt64Impl(JSContext* cx, const CallArgs& args); + static bool fun_setBigInt64(JSContext* cx, unsigned argc, Value* vp); + + static bool setBigUint64Impl(JSContext* cx, const CallArgs& args); + static bool fun_setBigUint64(JSContext* cx, unsigned argc, Value* vp); + + static bool setFloat32Impl(JSContext* cx, const CallArgs& args); + static bool fun_setFloat32(JSContext* cx, unsigned argc, Value* vp); + + static bool setFloat64Impl(JSContext* cx, const CallArgs& args); + static bool fun_setFloat64(JSContext* cx, unsigned argc, Value* vp); + + template <typename NativeType> + NativeType read(uint64_t offset, size_t length, bool isLittleEndian); + + template <typename NativeType> + static bool read(JSContext* cx, Handle<DataViewObject*> obj, + const CallArgs& args, NativeType* val); + template <typename NativeType> + static bool write(JSContext* cx, Handle<DataViewObject*> obj, + const CallArgs& args); + + private: + static const JSFunctionSpec methods[]; + static const JSPropertySpec properties[]; +}; + +/** + * DataView whose buffer is a fixed-length (Shared)ArrayBuffer object. + */ +class FixedLengthDataViewObject : public DataViewObject { + public: + static const JSClass class_; + + size_t byteOffset() const { return ArrayBufferViewObject::byteOffset(); } + + size_t byteLength() const { return rawByteLength(); } + + bool offsetIsInBounds(uint32_t byteSize, uint64_t offset) const { + return DataViewObject::offsetIsInBounds(byteSize, offset, byteLength()); + } + + template <typename NativeType> + NativeType read(uint64_t offset, bool isLittleEndian) { + return DataViewObject::read<NativeType>(offset, byteLength(), + isLittleEndian); + } +}; + +/** + * DataView whose buffer is a resizable (Shared)ArrayBuffer object. + */ +class ResizableDataViewObject : public DataViewObject { + friend class DataViewObject; + + static ResizableDataViewObject* create( + JSContext* cx, size_t byteOffset, size_t byteLength, bool autoLength, + Handle<ArrayBufferObjectMaybeShared*> arrayBuffer, HandleObject proto); + + public: + static const uint8_t AUTO_LENGTH_SLOT = DataViewObject::RESERVED_SLOTS; + + static const uint8_t RESERVED_SLOTS = DataViewObject::RESERVED_SLOTS + 1; + + static const JSClass class_; + + bool isAutoLength() const { + return getFixedSlot(AUTO_LENGTH_SLOT).toBoolean(); + } +}; + +// For structured cloning. +JSObject* NewDataView(JSContext* cx, HandleObject buffer, size_t byteOffset); + +} // namespace js + +template <> +inline bool JSObject::is<js::DataViewObject>() const { + return is<js::FixedLengthDataViewObject>() || + is<js::ResizableDataViewObject>(); +} + +#endif /* vm_DataViewObject_h */ |