#ifndef DirectArguments_h
#define DirectArguments_h
#include "DirectArgumentsOffset.h"
#include "GenericArguments.h"
namespace JSC {
class DirectArguments : public GenericArguments<DirectArguments> {
private:
DirectArguments(VM&, Structure*, unsigned length, unsigned capacity);
public:
static DirectArguments* createUninitialized(VM&, Structure*, unsigned length, unsigned capacity);
static DirectArguments* create(VM&, Structure*, unsigned length, unsigned capacity);
static DirectArguments* createByCopying(ExecState*);
static size_t estimatedSize(JSCell*);
static void visitChildren(JSCell*, SlotVisitor&);
static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
uint32_t internalLength() const
{
return m_length;
}
uint32_t length(ExecState* exec) const
{
if (UNLIKELY(m_overrides))
return get(exec, exec->propertyNames().length).toUInt32(exec);
return m_length;
}
bool canAccessIndexQuickly(uint32_t i) const
{
return i < m_length && (!m_overrides || !m_overrides.get()[i]);
}
bool canAccessArgumentIndexQuicklyInDFG(uint32_t i) const
{
return i < m_length && !overrodeThings();
}
JSValue getIndexQuickly(uint32_t i) const
{
ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
return const_cast<DirectArguments*>(this)->storage()[i].get();
}
void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
{
ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
storage()[i].set(vm, this, value);
}
WriteBarrier<JSFunction>& callee()
{
return m_callee;
}
WriteBarrier<Unknown>& argument(DirectArgumentsOffset offset)
{
ASSERT(offset);
ASSERT_WITH_SECURITY_IMPLICATION(offset.offset() < std::max(m_length, m_minCapacity));
return storage()[offset.offset()];
}
bool overrodeThings() const { return !!m_overrides; }
void overrideThings(VM&);
void overrideThingsIfNecessary(VM&);
void overrideArgument(VM&, unsigned index);
void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
DECLARE_INFO;
static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
static ptrdiff_t offsetOfCallee() { return OBJECT_OFFSETOF(DirectArguments, m_callee); }
static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(DirectArguments, m_length); }
static ptrdiff_t offsetOfMinCapacity() { return OBJECT_OFFSETOF(DirectArguments, m_minCapacity); }
static ptrdiff_t offsetOfOverrides() { return OBJECT_OFFSETOF(DirectArguments, m_overrides); }
static size_t storageOffset()
{
return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(DirectArguments));
}
static size_t offsetOfSlot(uint32_t index)
{
return storageOffset() + sizeof(WriteBarrier<Unknown>) * index;
}
static size_t allocationSize(uint32_t capacity)
{
return offsetOfSlot(capacity);
}
private:
WriteBarrier<Unknown>* storage()
{
return bitwise_cast<WriteBarrier<Unknown>*>(bitwise_cast<char*>(this) + storageOffset());
}
unsigned overridesSize();
WriteBarrier<JSFunction> m_callee;
uint32_t m_length; uint32_t m_minCapacity; CopyBarrier<bool> m_overrides; };
}
#endif // DirectArguments_h