JSArrayBufferView.h [plain text]
#pragma once
#include "AuxiliaryBarrier.h"
#include "CagedBarrierPtr.h"
#include "JSCPoison.h"
#include "JSObject.h"
#include "TypedArrayType.h"
#include <wtf/MathExtras.h>
namespace JSC {
class LLIntOffsetsExtractor;
static constexpr uint32_t NumberOfTypedArrayPoisons = WTF::roundUpToPowerOfTwo(NumberOfTypedArrayTypes);
static constexpr uint32_t TypedArrayPoisonIndexMask = NumberOfTypedArrayPoisons - 1;
enum TypedArrayMode : uint32_t {
FastTypedArray,
OversizeTypedArray,
WastefulTypedArray,
DataViewMode
};
inline bool hasArrayBuffer(TypedArrayMode mode)
{
return mode >= WastefulTypedArray;
}
class JSArrayBufferView : public JSNonFinalObject {
public:
typedef JSNonFinalObject Base;
static const unsigned fastSizeLimit = 1000;
static size_t sizeOf(uint32_t length, uint32_t elementSize)
{
return (length * elementSize + sizeof(EncodedJSValue) - 1)
& ~(sizeof(EncodedJSValue) - 1);
}
static size_t allocationSize(Checked<size_t> inlineCapacity)
{
ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
return sizeof(JSArrayBufferView);
}
protected:
class ConstructionContext {
WTF_MAKE_NONCOPYABLE(ConstructionContext);
public:
enum InitializationMode { ZeroFill, DontInitialize };
JS_EXPORT_PRIVATE ConstructionContext(VM&, Structure*, uint32_t length, uint32_t elementSize, InitializationMode = ZeroFill);
ConstructionContext(Structure*, uint32_t length, void* vector);
JS_EXPORT_PRIVATE ConstructionContext(
VM&, Structure*, RefPtr<ArrayBuffer>&&,
unsigned byteOffset, unsigned length);
enum DataViewTag { DataView };
ConstructionContext(
Structure*, RefPtr<ArrayBuffer>&&,
unsigned byteOffset, unsigned length, DataViewTag);
bool operator!() const { return !m_structure; }
Structure* structure() const { return m_structure; }
void* vector() const { return m_vector.getMayBeNull(); }
uint32_t length() const { return m_length; }
TypedArrayMode mode() const { return m_mode; }
Butterfly* butterfly() const { return m_butterfly; }
private:
Structure* m_structure;
CagedPtr<Gigacage::Primitive, void> m_vector;
uint32_t m_length;
TypedArrayMode m_mode;
Butterfly* m_butterfly;
};
JS_EXPORT_PRIVATE JSArrayBufferView(VM&, ConstructionContext&);
JS_EXPORT_PRIVATE void finishCreation(VM&);
static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
static void visitChildren(JSCell*, SlotVisitor&);
public:
TypedArrayMode mode() const { return m_mode; }
bool hasArrayBuffer() const { return JSC::hasArrayBuffer(mode()); }
bool isShared();
JS_EXPORT_PRIVATE ArrayBuffer* unsharedBuffer();
ArrayBuffer* possiblySharedBuffer();
JSArrayBuffer* unsharedJSBuffer(ExecState* exec);
JSArrayBuffer* possiblySharedJSBuffer(ExecState* exec);
RefPtr<ArrayBufferView> unsharedImpl();
RefPtr<ArrayBufferView> possiblySharedImpl();
bool isNeutered() { return hasArrayBuffer() && !vector(); }
void neuter();
void* vector() const { return m_poisonedVector.getMayBeNull(); }
unsigned byteOffset();
unsigned length() const { return m_length; }
DECLARE_EXPORT_INFO;
static ptrdiff_t offsetOfPoisonedVector() { return OBJECT_OFFSETOF(JSArrayBufferView, m_poisonedVector); }
static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(JSArrayBufferView, m_length); }
static ptrdiff_t offsetOfMode() { return OBJECT_OFFSETOF(JSArrayBufferView, m_mode); }
static RefPtr<ArrayBufferView> toWrapped(VM&, JSValue);
static uintptr_t poisonFor(JSType type)
{
return g_typedArrayPoisons[(type - FirstTypedArrayType) & TypedArrayPoisonIndexMask];
}
static uintptr_t poisonFor(TypedArrayType typedArrayType)
{
ASSERT(isTypedView(typedArrayType));
return poisonFor(typeForTypedArrayType(typedArrayType));
}
private:
static void finalize(JSCell*);
protected:
friend class LLIntOffsetsExtractor;
ArrayBuffer* existingBufferInButterfly();
static String toStringName(const JSObject*, ExecState*);
class Poison {
public:
template<typename PoisonedType>
inline static uintptr_t key(const PoisonedType* poisonedPtr)
{
uintptr_t poisonedVectorAddress = bitwise_cast<uintptr_t>(poisonedPtr);
uintptr_t baseAddress = poisonedVectorAddress - OBJECT_OFFSETOF(JSArrayBufferView, m_poisonedVector);
JSArrayBufferView* thisObject = bitwise_cast<JSArrayBufferView*>(baseAddress);
return poisonFor(thisObject->type());
}
};
PoisonedCagedBarrierPtr<Poison, Gigacage::Primitive, void> m_poisonedVector;
uint32_t m_length;
TypedArrayMode m_mode;
};
}
namespace WTF {
JS_EXPORT_PRIVATE void printInternal(PrintStream&, JSC::TypedArrayMode);
}