JSGenericTypedArrayView.h [plain text]
#ifndef JSGenericTypedArrayView_h
#define JSGenericTypedArrayView_h
#include "JSArrayBufferView.h"
#include "ToNativeFromValue.h"
namespace JSC {
JS_EXPORT_PRIVATE const ClassInfo* getInt8ArrayClassInfo();
JS_EXPORT_PRIVATE const ClassInfo* getInt16ArrayClassInfo();
JS_EXPORT_PRIVATE const ClassInfo* getInt32ArrayClassInfo();
JS_EXPORT_PRIVATE const ClassInfo* getUint8ArrayClassInfo();
JS_EXPORT_PRIVATE const ClassInfo* getUint8ClampedArrayClassInfo();
JS_EXPORT_PRIVATE const ClassInfo* getUint16ArrayClassInfo();
JS_EXPORT_PRIVATE const ClassInfo* getUint32ArrayClassInfo();
JS_EXPORT_PRIVATE const ClassInfo* getFloat32ArrayClassInfo();
JS_EXPORT_PRIVATE const ClassInfo* getFloat64ArrayClassInfo();
template<typename Adaptor>
class JSGenericTypedArrayView : public JSArrayBufferView {
public:
typedef JSArrayBufferView Base;
static const unsigned elementSize = sizeof(typename Adaptor::Type);
protected:
JSGenericTypedArrayView(VM&, ConstructionContext&);
public:
static JSGenericTypedArrayView* create(ExecState*, Structure*, unsigned length);
static JSGenericTypedArrayView* createUninitialized(ExecState*, Structure*, unsigned length);
static JSGenericTypedArrayView* create(ExecState*, Structure*, PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
static JSGenericTypedArrayView* create(VM&, Structure*, PassRefPtr<typename Adaptor::ViewType> impl);
static JSGenericTypedArrayView* create(Structure*, JSGlobalObject*, PassRefPtr<typename Adaptor::ViewType> impl);
unsigned byteLength() const { return m_length * sizeof(typename Adaptor::Type); }
size_t byteSize() const { return sizeOf(m_length, sizeof(typename Adaptor::Type)); }
const typename Adaptor::Type* typedVector() const
{
return static_cast<const typename Adaptor::Type*>(m_vector);
}
typename Adaptor::Type* typedVector()
{
return static_cast<typename Adaptor::Type*>(m_vector);
}
bool canGetIndexQuickly(unsigned i)
{
return i < m_length;
}
bool canSetIndexQuickly(unsigned i)
{
return i < m_length;
}
typename Adaptor::Type getIndexQuicklyAsNativeValue(unsigned i)
{
ASSERT(i < m_length);
return typedVector()[i];
}
double getIndexQuicklyAsDouble(unsigned i)
{
return Adaptor::toDouble(getIndexQuicklyAsNativeValue(i));
}
JSValue getIndexQuickly(unsigned i)
{
return Adaptor::toJSValue(getIndexQuicklyAsNativeValue(i));
}
void setIndexQuicklyToNativeValue(unsigned i, typename Adaptor::Type value)
{
ASSERT(i < m_length);
typedVector()[i] = value;
}
void setIndexQuicklyToDouble(unsigned i, double value)
{
setIndexQuicklyToNativeValue(i, toNativeFromValue<Adaptor>(value));
}
void setIndexQuickly(unsigned i, JSValue value)
{
setIndexQuicklyToNativeValue(i, toNativeFromValue<Adaptor>(value));
}
bool setIndex(ExecState* exec, unsigned i, JSValue jsValue)
{
typename Adaptor::Type value = toNativeFromValue<Adaptor>(exec, jsValue);
if (exec->hadException())
return false;
if (i >= m_length)
return false;
setIndexQuicklyToNativeValue(i, value);
return true;
}
bool canAccessRangeQuickly(unsigned offset, unsigned length)
{
return offset <= m_length
&& offset + length <= m_length
&& offset + length >= offset;
}
bool validateRange(ExecState*, unsigned offset, unsigned length);
bool set(ExecState*, JSObject*, unsigned offset, unsigned length);
PassRefPtr<typename Adaptor::ViewType> typedImpl()
{
return Adaptor::ViewType::create(buffer(), byteOffset(), length());
}
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(vm, globalObject, prototype, TypeInfo(typeForTypedArrayType(Adaptor::typeValue), StructureFlags), info(), NonArray);
}
static const ClassInfo s_info;
static const ClassInfo* info()
{
switch (Adaptor::typeValue) {
case TypeInt8:
return getInt8ArrayClassInfo();
case TypeInt16:
return getInt16ArrayClassInfo();
case TypeInt32:
return getInt32ArrayClassInfo();
case TypeUint8:
return getUint8ArrayClassInfo();
case TypeUint8Clamped:
return getUint8ClampedArrayClassInfo();
case TypeUint16:
return getUint16ArrayClassInfo();
case TypeUint32:
return getUint32ArrayClassInfo();
case TypeFloat32:
return getFloat32ArrayClassInfo();
case TypeFloat64:
return getFloat64ArrayClassInfo();
default:
RELEASE_ASSERT_NOT_REACHED();
return 0;
}
}
ArrayBuffer* existingBuffer();
static const TypedArrayType TypedArrayStorageType = Adaptor::typeValue;
protected:
friend struct TypedArrayClassInfos;
static const unsigned StructureFlags = OverridesGetPropertyNames | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | Base::StructureFlags;
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
static bool deleteProperty(JSCell*, ExecState*, PropertyName);
static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static void visitChildren(JSCell*, SlotVisitor&);
static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
static ArrayBuffer* slowDownAndWasteMemory(JSArrayBufferView*);
static PassRefPtr<ArrayBufferView> getTypedArrayImpl(JSArrayBufferView*);
private:
template<typename OtherAdaptor>
bool setWithSpecificType(
ExecState*, JSGenericTypedArrayView<OtherAdaptor>*,
unsigned offset, unsigned length);
};
template<typename Adaptor>
inline PassRefPtr<typename Adaptor::ViewType> toNativeTypedView(JSValue value)
{
typename Adaptor::JSViewType* wrapper = jsDynamicCast<typename Adaptor::JSViewType*>(value);
if (!wrapper)
return 0;
return wrapper->typedImpl();
}
}
#endif // JSGenericTypedArrayView_h